summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c5
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c43
2 files changed, 40 insertions, 8 deletions
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c
index 8775ffbf..1dd7395b 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c
@@ -282,6 +282,11 @@ p9_sgpe_stop_exit_handoff_cme(uint32_t cindex)
#endif
+ // clear possible phantom interrupts after handoff to cme
+ // there shouldnt be any valid entry or exit to process
+ out32(OCB_OPITNPRA_CLR(2), BIT32(cindex));
+ out32(OCB_OPITNPRA_CLR(3), BIT32(cindex));
+
// From IPC prospective, core is active when handoff to cme
// and if core from quad is active, the quad is active
G_sgpe_stop_record.group.core[VECTOR_ACTIVE] |= BIT32(cindex);
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c
index 25986506..f9a6ca05 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c
@@ -258,6 +258,8 @@ p9_sgpe_pig_type23_parser(const uint32_t type)
uint32_t cindex = 0;
uint32_t cpending = 0;
uint32_t cpayload = 0;
+ uint32_t payload2 = 0;
+ uint32_t payload3 = 0;
uint32_t vector_index = 0;
uint32_t request_index = 0;
uint32_t suspend_index = 0;
@@ -393,23 +395,48 @@ p9_sgpe_pig_type23_parser(const uint32_t type)
// read wakeup_notify_select
GPE_GETSCOM(GPE_SCOM_ADDR_CORE(CPPM_CPMMR, cindex), scom_data.value);
+ // phantom can be processed when WNS already handoff to cme by a different wakeup
+ // OR can be delayed long enough when WNS handoff back to sgpe by next cme entry
+
+ // In latter case, if left over type2 software dec wakeup happen to catch up with
+ // WNS = 1 by next entry(could be type 2 or 3), we want to detect the type2 entry
+ // and process it instead of this phantom; if type 3 entry, then ignore both
+ // as type3 needs to be hanndled in type3 handler while current is obvious type2
+
+ if ((scom_data.words.upper & BIT32(13)) && cpayload == 0x400)
+ {
+ payload2 = in32(OCB_OPIT2CN(cindex));
+ payload3 = in32(OCB_OPIT3CN(cindex));
+
+ if ((!(payload2 & TYPE2_PAYLOAD_EXIT_EVENT)) &&
+ (payload2 & TYPE2_PAYLOAD_STOP_LEVEL))
+ {
+ PK_TRACE_INF("WARNING: Leftover dec wakeup following by new TYPE2 entry PIG");
+ cpayload = payload2;
+ }
+ else if ((!(payload3 & TYPE2_PAYLOAD_EXIT_EVENT)) &&
+ (payload3 & TYPE2_PAYLOAD_STOP_LEVEL))
+ {
+ PK_TRACE_INF("WARNING: Leftover dec wakeup following by new TYPE3 entry PIG");
+ continue;
+ }
+ }
+
// request exit
if (cpayload & TYPE2_PAYLOAD_EXIT_EVENT)
{
- // phantom can be processed when WNS already handoff to cme by a different wakeup
- // OR can be delayed long enough when WNS handoff back to sgpe by next cme entry
- if ((!(scom_data.words.upper & BIT32(13))) ||
- (G_sgpe_stop_record.level[qloop][cloop] == 0))
+ if (!(scom_data.words.upper & BIT32(13)))
{
// type2 duplicate wakeup can happen due to manual PCWU vs other HW wakeup
- if (type == 2)
+ if (cpayload == 0x400)
{
- PK_TRACE_INF("WARNING: Ignore Phantom Type2 Wakeup PIG \
+ PK_TRACE_INF("WARNING: Ignore Phantom Software PC/Decrementer Wakeup PIG \
(already handoff cme by other wakeup");
}
- else // otherwise PPM shouldnt send duplicate pig if wakeup is present
+ // otherwise PPM shouldnt send duplicate pig if wakeup is present
+ else
{
- PK_TRACE_INF("ERROR: Received Phantom Type3 Wakeup PIG \
+ PK_TRACE_INF("ERROR: Received Phantom Hardware Type2/3 Wakeup PIG \
When Wakeup_notify_select = 0. HALT SGPE!");
PK_PANIC(SGPE_PIG_TYPE23_EXIT_WNS_CME);
}
OpenPOWER on IntegriCloud