summaryrefslogtreecommitdiffstats
path: root/import/chips/p9/procedures/ppe_closed/cme
diff options
context:
space:
mode:
authorChristopher M. Riedl <cmriedl@us.ibm.com>2017-07-18 09:06:15 -0500
committerJoshua Hunsberger <jahunsbe@us.ibm.com>2017-10-23 18:40:03 -0500
commitd47c3d351b061ab18d84f1d0d46b6035b0422d35 (patch)
treedc63664e9cf4a8fd0935c0badc60b90f962a61bb /import/chips/p9/procedures/ppe_closed/cme
parent20c11979e9e1adc7bbd4762759f9f2a3a88354f6 (diff)
downloadtalos-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')
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_intercme.c4
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.c43
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h14
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_db.c28
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c86
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)
{
OpenPOWER on IntegriCloud