Skip to content

Commit

Permalink
STOP: Abort Entry on Error
Browse files Browse the repository at this point in the history
Key_Cronus_Test=PM_REGRESS

Change-Id: Ia54a4b2a5f13d62d4f7ec2c28b2a1baf0aa5d0dc
Original-Change-Id: Ifbea7f6a0b0ffd0a124131bfe957f206466c0ff5
CQ: SW416545
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/53425
Reviewed-by: Michael S. Floyd <mfloyd@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Cronus HW CI <cronushw-ci+hostboot@us.ibm.com>
Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
  • Loading branch information
davidduyue authored and op-jenkins committed Aug 22, 2018
1 parent 80df64d commit 5048828
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,30 @@ p9_cme_stop_entry()
PK_TRACE("+++++ +++++ STOP LEVEL 4 ENTRY +++++ +++++");
//----------------------------------------------------------------------

// NDD2: OOB bits wired to SISR
// not implemented in DD1
// bit0 is System checkstop
// bit1 is Recoverable Error
// bit2 is Special Attention
// bit3 is Core Checkstop

if ((core & CME_MASK_C0) && (in32(CME_LCL_SISR) & BITS32(12, 4)))
{
PK_TRACE_INF("WARNING: Core0 Xstop/Attn/Recov Present, Abort Entry");
core -= CME_MASK_C0;
}

if ((core & CME_MASK_C1) && (in32_sh(CME_LCL_SISR) & BITS64SH(60, 4)))
{
PK_TRACE_INF("WARNING: Core1 Xstop/Attn/Recov Present, Abort Entry");
core -= CME_MASK_C1;
}

if (!core)
{
break;
}

//===============================
MARK_TAG(SE_POWER_OFF_CORE, core)
//===============================
Expand All @@ -1342,56 +1366,42 @@ p9_cme_stop_entry()

#if !STOP_PRIME

// NDD2: OOB bits wired to SISR
// not implemented in DD1
// bit0 is System checkstop
// bit1 is Recoverable Error
// bit2 is Special Attention
// bit3 is Core Checkstop
if (((core & CME_MASK_C0) && (in32(CME_LCL_SISR) & BITS32(12, 4))) ||
((core & CME_MASK_C1) && (in32_sh(CME_LCL_SISR) & BITS64SH(60, 4))))
if(in32(CME_LCL_FLAGS) & BIT32(CME_FLAGS_VDM_OPERABLE))
{
PK_TRACE_INF("WARNING: Xstop/Attn/Recov Present, Skip Core Power Off");
PK_TRACE_DBG("Clear Poweron bit in VDMCR");
CME_PUTSCOM(PPM_VDMCR_CLR, core, BIT64(0));
}
else
{
if(in32(CME_LCL_FLAGS) & BIT32(CME_FLAGS_VDM_OPERABLE))
{
PK_TRACE_DBG("Clear Poweron bit in VDMCR");
CME_PUTSCOM(PPM_VDMCR_CLR, core, BIT64(0));
}

PK_TRACE("Drop vdd_pfet_val/sel_override/regulation_finger_en via PFCS[4,5,8]");
// vdd_pfet_val/sel_override = 0 (disbaled)
// vdd_pfet_regulation_finger_en = 0 (controled by FSM)
CME_PUTSCOM(PPM_PFCS_CLR, core, BIT64(4) | BIT64(5) | BIT64(8));
PK_TRACE("Drop vdd_pfet_val/sel_override/regulation_finger_en via PFCS[4,5,8]");
// vdd_pfet_val/sel_override = 0 (disbaled)
// vdd_pfet_regulation_finger_en = 0 (controled by FSM)
CME_PUTSCOM(PPM_PFCS_CLR, core, BIT64(4) | BIT64(5) | BIT64(8));

PK_TRACE("Power off core VDD via PFCS[0-1]");
// vdd_pfet_force_state = 01 (Force Voff)
CME_PUTSCOM(PPM_PFCS_OR, core, BIT64(1));
PK_TRACE("Power off core VDD via PFCS[0-1]");
// vdd_pfet_force_state = 01 (Force Voff)
CME_PUTSCOM(PPM_PFCS_OR, core, BIT64(1));

PK_TRACE("Poll for vdd_pfets_disabled_sense via PFSNS[1]");
PK_TRACE("Poll for vdd_pfets_disabled_sense via PFSNS[1]");

CME_GETSCOM_OR( CPPM_CSAR, core, scom_data.value );
CME_GETSCOM_OR( CPPM_CSAR, core, scom_data.value );

if( BIT64(CPPM_CSAR_STOP_HCODE_ERROR_INJECT) & scom_data.value )
{
PK_TRACE_DBG("CME STOP ENTRY ERROR INJECT TRAP");
PK_PANIC(CME_STOP_ENTRY_TRAP_INJECT);
}
if( BIT64(CPPM_CSAR_STOP_HCODE_ERROR_INJECT) & scom_data.value )
{
PK_TRACE_DBG("CME STOP ENTRY ERROR INJECT TRAP");
PK_PANIC(CME_STOP_ENTRY_TRAP_INJECT);
}

do
{
CME_GETSCOM_AND(PPM_PFSNS, core, scom_data.value);
}
while(!(scom_data.words.upper & BIT32(1)));
do
{
CME_GETSCOM_AND(PPM_PFSNS, core, scom_data.value);
}
while(!(scom_data.words.upper & BIT32(1)));

PK_TRACE("Turn off force voff via PFCS[0-1]");
// vdd_pfet_force_state = 00 (Nop)
CME_PUTSCOM(PPM_PFCS_CLR, core, BITS64(0, 2));
PK_TRACE("Turn off force voff via PFCS[0-1]");
// vdd_pfet_force_state = 00 (Nop)
CME_PUTSCOM(PPM_PFCS_CLR, core, BITS64(0, 2));

PK_TRACE_INF("SE.4A: Core[%d] Powered Off", core);
}
PK_TRACE_INF("SE.4A: Core[%d] Powered Off", core);

#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ p9_sgpe_stop_entry()
uint32_t cloop = 0;
uint32_t climit = 0;
uint32_t cindex = 0;
uint32_t quad_error = 0;
uint64_t host_attn = 0;
uint64_t local_xstop = 0;
data64_t scom_data = {0};
Expand Down Expand Up @@ -276,19 +277,51 @@ p9_sgpe_stop_entry()



for(qloop = 0; qloop < MAX_QUADS; qloop++)
{
// if this ex is not up to entry, skip
if (!(ex = G_sgpe_stop_record.group.ex01[qloop]))
{
continue;
}

// In order to preserve state for PRD,
// If host attn or local xstop present,
// abort L2 Purge and rest of Entry
// Note: Need to read status before stopclocks
// while these registers are still accessible
PK_TRACE("Checking status of Host Attention");
GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_HOST_ATTN, qloop), host_attn);

PK_TRACE("Checking status of Local Checkstop");
GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_LOCAL_XSTOP_ERR, qloop), local_xstop);

if ((host_attn | local_xstop) & BIT64(0))
{
PK_TRACE_INF("WARNING: HostAttn or LocalXstop Present, Abort EX Entry for Quad[%d]", qloop);
quad_error |= BIT32(qloop);
continue;
}
}



// NDD1 workaround to save cme image size
// Permanent workaround to save cme image size
#if NIMBUS_DD_LEVEL == 10 || DISABLE_STOP8 == 1

//--------------------------------------------------------------------------
PK_TRACE("+++++ +++++ EX STOP ENTRY [L2 PURGE(NDD1 ONLY)] +++++ +++++");
//--------------------------------------------------------------------------
//-----------------------------------------------------------
PK_TRACE("+++++ +++++ EX STOP ENTRY [L2 PURGE] +++++ +++++");
//-----------------------------------------------------------

PK_TRACE("Assert L2+NCU purge and NCU tlbie quiesce via SICR[18,21,22]");

for(qloop = 0; qloop < MAX_QUADS; qloop++)
{
if (quad_error & BIT32(qloop))
{
continue;
}

// insert tlbie quiesce before ncu purge to avoid window condition
// of ncu traffic still happening when purging starts
// Note: chtm purge and drop tlbie quiesce will be done in SGPE
Expand All @@ -310,6 +343,11 @@ p9_sgpe_stop_entry()

for(qloop = 0; qloop < MAX_QUADS; qloop++)
{
if (quad_error & BIT32(qloop))
{
continue;
}

if (G_sgpe_stop_record.group.ex01[qloop] & FST_EX_IN_QUAD)
{
do
Expand All @@ -333,7 +371,7 @@ p9_sgpe_stop_entry()
}
}

PK_TRACE("NDD1: L2 and NCU Purged by SGPE");
PK_TRACE_INF("SE.5+: L2 and NCU Purged by SGPE");

#endif

Expand All @@ -343,7 +381,7 @@ p9_sgpe_stop_entry()
for(qloop = 0; qloop < MAX_QUADS; qloop++)
{
// if this ex is not up to entry, skip
if (!(ex = G_sgpe_stop_record.group.ex01[qloop]))
if ((!(ex = G_sgpe_stop_record.group.ex01[qloop])) || (quad_error & BIT32(qloop)))
{
continue;
}
Expand Down Expand Up @@ -570,6 +608,31 @@ p9_sgpe_stop_entry()
continue;
}

// In order to preserve state for PRD,
// If host attn or local xstop present,
// abort L3 Purge and rest of Entry
// Note: Need to read status before stopclocks
// while these registers are still accessible
PK_TRACE("Checking status of Host Attention");
GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_HOST_ATTN, qloop), host_attn);

PK_TRACE("Checking status of Local Checkstop");
GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_LOCAL_XSTOP_ERR, qloop), local_xstop);

if ((host_attn | local_xstop) & BIT64(0))
{
PK_TRACE_INF("WARNING: HostAttn or LocalXstop Present, Abort L3 Purge on Quad[%d]", qloop);
quad_error |= BIT32(qloop);
}

// for L3 Purge check above and L2 Purge check earlier
if (quad_error & BIT32(qloop))
{
// Take this out for rest of Stop11 entry and IPC code at the end
G_sgpe_stop_record.group.quad[VECTOR_ENTRY] &= ~BIT32(qloop);
continue;
}

// ------------------------------------------------------------------------
PK_TRACE("+++++ +++++ QUAD STOP ENTRY [LEVEL 11-15, L3 PURGE] +++++ +++++");
// ------------------------------------------------------------------------
Expand Down Expand Up @@ -1024,16 +1087,6 @@ p9_sgpe_stop_entry()

PK_TRACE_DBG("NCU Status Clean");

// In order to preserve state for PRD,
// skip power off if host attn or local xstop present
// Need to read status before stopclocks
// while these registers are still accessible
PK_TRACE("Checking status of Host Attention");
GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_HOST_ATTN, qloop), host_attn);

PK_TRACE("Checking status of Local Checkstop");
GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_LOCAL_XSTOP_ERR, qloop), local_xstop);

// PGPE may have already cleared bit26: DPLL_ENABLE if booted,
// but SGPE can always do it in case PGPE isnt booted
PK_TRACE("Drop CME_INTERPPM_IVRM/ACLK/VDATA_ENABLE via QPMMR[20,22,24]");
Expand Down Expand Up @@ -1216,50 +1269,43 @@ p9_sgpe_stop_entry()

#if !STOP_PRIME

if ((host_attn | local_xstop) & BIT64(0))
{
PK_TRACE_INF("WARNING: HostAttn or LocalXstop Present, Skip Cache Power Off");
}
else
{
PK_TRACE("Drop vdd/vcs_pfet_val/sel_override/regulation_finger_en via PFCS[4-7,8]");
// vdd_pfet_val/sel_override = 0 (disbaled)
// vcs_pfet_val/sel_override = 0 (disbaled)
// vdd_pfet_regulation_finger_en = 0 (controled by FSM)
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_CLR, qloop),
BITS64(4, 4) | BIT64(8));
PK_TRACE("Drop vdd/vcs_pfet_val/sel_override/regulation_finger_en via PFCS[4-7,8]");
// vdd_pfet_val/sel_override = 0 (disbaled)
// vcs_pfet_val/sel_override = 0 (disbaled)
// vdd_pfet_regulation_finger_en = 0 (controled by FSM)
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_CLR, qloop),
BITS64(4, 4) | BIT64(8));

PK_TRACE("Power off VCS via PFCS[2-3]");
// vcs_pfet_force_state = 01 (Force Voff)
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_OR, qloop), BIT64(3));
PK_TRACE("Power off VCS via PFCS[2-3]");
// vcs_pfet_force_state = 01 (Force Voff)
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_OR, qloop), BIT64(3));

PK_TRACE("Poll for vcs_pfets_disabled_sense via PFSNS[3]");
PK_TRACE("Poll for vcs_pfets_disabled_sense via PFSNS[3]");

do
{
GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFSNS, qloop), scom_data.value);
}
while(!(scom_data.words.upper & BIT32(3)));
do
{
GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFSNS, qloop), scom_data.value);
}
while(!(scom_data.words.upper & BIT32(3)));

PK_TRACE("Power off VDD via PFCS[0-1]");
// vdd_pfet_force_state = 01 (Force Voff)
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_OR, qloop), BIT64(1));
PK_TRACE("Power off VDD via PFCS[0-1]");
// vdd_pfet_force_state = 01 (Force Voff)
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_OR, qloop), BIT64(1));

PK_TRACE("Poll for vdd_pfets_disabled_sense via PFSNS[1]");
PK_TRACE("Poll for vdd_pfets_disabled_sense via PFSNS[1]");

do
{
GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFSNS, qloop), scom_data.value);
}
while(!(scom_data.words.upper & BIT32(1)));
do
{
GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFSNS, qloop), scom_data.value);
}
while(!(scom_data.words.upper & BIT32(1)));

PK_TRACE("Turn off force voff via PFCS[0-3]");
// vdd_pfet_force_state = 00 (Nop)
// vcs_pfet_force_state = 00 (Nop)
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_CLR, qloop), BITS64(0, 4));
PK_TRACE("Turn off force voff via PFCS[0-3]");
// vdd_pfet_force_state = 00 (Nop)
// vcs_pfet_force_state = 00 (Nop)
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_CLR, qloop), BITS64(0, 4));

PK_TRACE_INF("SE.11E: Cache Powered Off");
}
PK_TRACE_INF("SE.11E: Cache Powered Off");

#endif

Expand Down

0 comments on commit 5048828

Please sign in to comment.