diff options
author | Christopher M. Riedl <cmriedl@us.ibm.com> | 2017-07-18 09:06:15 -0500 |
---|---|---|
committer | Joshua Hunsberger <jahunsbe@us.ibm.com> | 2017-10-23 18:40:03 -0500 |
commit | d47c3d351b061ab18d84f1d0d46b6035b0422d35 (patch) | |
tree | dc63664e9cf4a8fd0935c0badc60b90f962a61bb /import/chips/p9/procedures/ppe_closed/cme | |
parent | 20c11979e9e1adc7bbd4762759f9f2a3a88354f6 (diff) | |
download | talos-hcode-d47c3d351b061ab18d84f1d0d46b6035b0422d35.tar.gz talos-hcode-d47c3d351b061ab18d84f1d0d46b6035b0422d35.zip |
PM: Implement L2 Resclk Function
Change-Id: I0efbab5defe2ffbd5c5fe86690c6e7a498f3c4d1
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/43331
Reviewed-by: YUE DU <daviddu@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Michael S. Floyd <mfloyd@us.ibm.com>
Reviewed-by: BRIAN D. VICTOR <brian.d.victor1@ibm.com>
Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
Diffstat (limited to 'import/chips/p9/procedures/ppe_closed/cme')
5 files changed, 139 insertions, 36 deletions
diff --git a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_intercme.c b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_intercme.c index e326115d..68c14342 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_intercme.c +++ b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_intercme.c @@ -108,9 +108,7 @@ void p9_cme_pstate_intercme_in0_handler(void* arg, PkIrqId irq) out32_sh(CME_LCL_EISR_CLR, G_cme_record.core_enabled << 25);//Clear DB0_C0/C1 - out32(CME_LCL_ICCR_OR, BIT32(5));//Send Direct InterCME_IN0(Ack to QM-CME) - out32(CME_LCL_ICCR_CLR, BIT32(5));//Clear Ack - out32(CME_LCL_EISR_CLR, BIT32(7));//Clear InterCME_IN0 + intercme_direct(INTERCME_DIRECT_IN0, INTERCME_DIRECT_ACK); pk_irq_vec_restore(&ctx); diff --git a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.c b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.c index 9de69983..760a37dd 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.c +++ b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.c @@ -150,7 +150,6 @@ void intercme_msg_send(uint32_t msg, INTERCME_MSG_TYPE type) out32(CME_LCL_ICSR, (msg << 4) | type); PK_TRACE_DBG("imt send | msg=%08x", ((msg << 4) | type)); - PK_TRACE_DBG("buff"); // Block on ack from companion CME while(!(in32(CME_LCL_EISR) & BIT32(30))) {} @@ -163,9 +162,7 @@ void intercme_msg_recv(uint32_t* msg, INTERCME_MSG_TYPE type) // Poll for inter-cme communication from QM while(!(in32(CME_LCL_EISR) & BIT32(29))) {} - // Get the initial pstate value *msg = in32(CME_LCL_ICRR); - PK_TRACE_DBG("imt recv | msg=%08x", *msg); if(*msg & type) @@ -185,6 +182,46 @@ void intercme_msg_recv(uint32_t* msg, INTERCME_MSG_TYPE type) out32(CME_LCL_EISR_CLR, BIT32(29)); } +void intercme_direct(INTERCME_DIRECT_INTF intf, INTERCME_DIRECT_TYPE type) +{ + uint32_t addr_offset = 0; + // Send intercme interrupt, this is the same whether notifying or acking + out32(CME_LCL_ICCR_OR , BIT32(intf)); + out32(CME_LCL_ICCR_CLR, BIT32(intf)); + + // Adjust the EI*R base address based on which intercme direct interface + // is used since the bits are spread across both words in the EI*R registers + if(intf == INTERCME_DIRECT_IN0) + { + // IN0: ICCR[5], EI*R[7] + intf += 2; + } + else + { + // IN1: ICCR[6], EI*R[38], ie. second half EI*R[6] + // IN2: ICCR[7], EI*R[39], ie. second half EI*R[7] + addr_offset = 4; + } + + if(type == INTERCME_DIRECT_NOTIFY) + { + uint32_t intercme_acked = 0; +#if SIMICS_TUNING == 1 + intercme_acked = 1; +#endif + + while(!intercme_acked) + { + if(in32((CME_LCL_EISR + addr_offset)) & BIT32(intf)) + { + intercme_acked = 1; + } + } + } + + out32((CME_LCL_EISR_CLR + addr_offset), BIT32(intf)); // Clear the interrupt +} + #ifdef USE_CME_RESCLK_FEATURE uint32_t p9_cme_resclk_get_index(uint32_t pstate) { diff --git a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h index 00763f51..44cb61a0 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h +++ b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h @@ -132,6 +132,19 @@ typedef enum IMT_SYNC_SIBLING = (uint32_t)0x00000003 } INTERCME_MSG_TYPE; +typedef enum +{ + INTERCME_DIRECT_IN0 = 5, + INTERCME_DIRECT_IN1 = 6, + INTERCME_DIRECT_IN2 = 7 +} INTERCME_DIRECT_INTF; + +typedef enum +{ + INTERCME_DIRECT_NOTIFY = 0, + INTERCME_DIRECT_ACK = 1 +} INTERCME_DIRECT_TYPE; + typedef struct { #if !defined(__IOTA__) @@ -167,6 +180,7 @@ void ippm_read(uint32_t addr, uint64_t* data); void ippm_write(uint32_t addr, uint64_t data); void intercme_msg_send(uint32_t msg, INTERCME_MSG_TYPE type); void intercme_msg_recv(uint32_t* msg, INTERCME_MSG_TYPE type); +void intercme_direct(INTERCME_DIRECT_INTF intf, INTERCME_DIRECT_TYPE type); void p9_cme_analog_control(uint32_t core_mask, ANALOG_CONTROL enable); void p9_cme_pstate_pmsr_updt(uint32_t coreMask); #ifdef USE_CME_RESCLK_FEATURE diff --git a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_db.c b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_db.c index b6bcc4c9..e599d336 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_db.c +++ b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_db.c @@ -245,6 +245,7 @@ void p9_cme_pstate_db_thread(void* arg) PK_PANIC(CME_PSTATE_RESCLK_ENABLED_AT_BOOT); } +#if NIMBUS_DD_LEVEL >= 21 || CUMULUS_DD_LEVEL > 10 ippm_read(QPPM_EXCGCR, &scom_data); // Ignore clk_sync_enable, clkglm_async_reset, clkglm_sel, and reserved scom_data &= ~(BITS64(29, 9) | BITS64(42, 22)); @@ -254,6 +255,8 @@ void p9_cme_pstate_db_thread(void* arg) PK_PANIC(CME_PSTATE_RESCLK_ENABLED_AT_BOOT); } +#endif + #ifdef USE_CME_RESCLK_FEATURE // Resonant Clocking Initialization (QM + Sibling) @@ -501,33 +504,12 @@ inline void p9_cme_pstate_db0_suspend() inline void p9_cme_pstate_notify_sib() { - uint32_t intercme_acked = 0; - uint32_t eisr; - PK_TRACE_INF("DB_TH: Notify Enter\n"); //Notify sibling CME(if any) - if (G_cme_pstate_record.siblingCMEFlag) + if(G_cme_pstate_record.siblingCMEFlag) { - //Send interCME interrupt - out32(CME_LCL_ICCR_OR, BIT32(5)); //Send direct InterCME_IN0 - out32(CME_LCL_ICCR_CLR, BIT32(5));//Clear - -#if SIMICS_TUNING == 1 - intercme_acked = 1; -#endif - - while (!intercme_acked) - { - eisr = in32(CME_LCL_EISR); - - if (eisr & 0x01000000) - { - intercme_acked = 1; - } - } - - out32(CME_LCL_EISR_CLR, BIT32(7));//Clear InterCME_IN0 + intercme_direct(INTERCME_DIRECT_IN0, INTERCME_DIRECT_ACK); } PK_TRACE_INF("DB_TH: Notify Exit\n"); diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c index b387d73d..b54bb458 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c @@ -26,9 +26,11 @@ #include "p9_cme_stop.h" #include "p9_cme_stop_enter_marks.h" #include "p9_cme_irq.h" +#include "p9_cme_pstate.h" -extern CmeStopRecord G_cme_stop_record; -extern CmeRecord G_cme_record; +extern CmeStopRecord G_cme_stop_record; +extern CmePstateRecord G_cme_pstate_record; +extern CmeRecord G_cme_record; @@ -60,7 +62,7 @@ p9_cme_stop_pcwu_handler(void* arg, PkIrqId irq) if (!(scom_data.words.upper & BIT32(10))) { pig.fields.req_intr_type = PIG_TYPE2; - pig.fields.req_intr_payload = 0x400; + pig.fields.req_intr_payload = TYPE2_PAYLOAD_DECREMENTER_WAKEUP; CME_PUTSCOM_NOP(PPM_PIG, core_mask, pig.value); } @@ -94,6 +96,7 @@ p9_cme_stop_pcwu_handler(void* arg, PkIrqId irq) } + // When take an Interrupt on falling edge of SPWU from a CPPM. // 1) Read EINR to check if another one has been set // in the meantime from the same core. If so abort. @@ -234,27 +237,96 @@ p9_cme_stop_enter_handler(void* arg, PkIrqId irq) #endif } + + void p9_cme_stop_db2_handler(void* arg, PkIrqId irq) { PkMachineContext ctx __attribute__((unused)); + cppm_cmedb2_t db2 = {0}; + ppm_pig_t pig = {0}; MARK_TRAP(STOP_DB2_HANDLER) PK_TRACE_DBG("DB2 Handler Trigger %d", irq); // read and clear doorbell uint32_t core = (in32(CME_LCL_EISR) & BITS32(18, 2)) >> SHIFT32(19); + CME_GETSCOM(CPPM_CMEDB2, core, db2.value); CME_PUTSCOM_NOP(CPPM_CMEDB2, core, 0); out32(CME_LCL_EISR_CLR, (core << SHIFT32(19))); - // unmask pc interrupt pending to wakeup that is still pending - core &= (~(G_cme_stop_record.core_running)); - G_cme_stop_record.core_blockpc &= ~core; - g_eimr_override &= ~(((uint64_t)core) << SHIFT64(13)); + switch (db2.fields.cme_message_numbern) + { + case MSGID_DB2_DECREMENTER_WAKEUP: + + // unmask pc interrupt pending to wakeup that is still pending + core &= (~(G_cme_stop_record.core_running)); + G_cme_stop_record.core_blockpc &= ~core; + g_eimr_override &= ~(((uint64_t)core) << SHIFT64(13)); + break; + + case MSGID_DB2_RESONANT_CLOCK_DISABLE: + +#if (NIMBUS_DD_LEVEL < 21 || CUMULUS_DD_LEVEL == 10) && DISABLE_STOP8 == 1 +#ifdef USE_CME_RESCLK_FEATURE + + // Quad going into Stop11, need to potentially disable Resclks + if((in32(CME_LCL_FLAGS) & BIT32(CME_FLAGS_RCLK_OPERABLE)) + && G_cme_pstate_record.qmFlag) + { + PkMachineContext ctx; + pk_critical_section_enter(&ctx); + + p9_cme_resclk_update(ANALOG_COMMON, ANALOG_PSTATE_RESCLK_OFF, + G_cme_pstate_record.resclkData.common_resclk_idx); + + pk_critical_section_exit(&ctx); + } + +#endif +#endif + // Finish handshake with SGPE for Stop11 via PIG + pig.fields.req_intr_type = PIG_TYPE3; + pig.fields.req_intr_payload = TYPE2_PAYLOAD_ENTRY_RCLK | STOP_LEVEL_11; + CME_PUTSCOM_NOP(PPM_PIG, core, pig.value); + break; + + case MSGID_DB2_RESONANT_CLOCK_ENABLE: + +#if (NIMBUS_DD_LEVEL < 21 || CUMULUS_DD_LEVEL == 10) && DISABLE_STOP8 == 1 +#ifdef USE_CME_RESCLK_FEATURE + + // Quad aborted Stop11, need to regressively enable Resclks + // IF wakeup from fully entered Stop11, this is done by QM + if((in32(CME_LCL_FLAGS) & BIT32(CME_FLAGS_RCLK_OPERABLE)) + && G_cme_pstate_record.qmFlag) + { + PkMachineContext ctx; + pk_critical_section_enter(&ctx); + + p9_cme_resclk_update(ANALOG_COMMON, G_cme_pstate_record.quadPstate, + G_cme_pstate_record.resclkData.common_resclk_idx); + + pk_critical_section_exit(&ctx); + } + +#endif +#endif + // Finish handshake with SGPE for Stop11 via PIG + pig.fields.req_intr_type = PIG_TYPE3; + pig.fields.req_intr_payload = TYPE2_PAYLOAD_EXIT_RCLK; + CME_PUTSCOM_NOP(PPM_PIG, core, pig.value); + break; + + default: + break; + } pk_irq_vec_restore(&ctx); } + + void p9_cme_stop_db1_handler(void* arg, PkIrqId irq) { |