summaryrefslogtreecommitdiffstats
path: root/src/kernel/misc.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/misc.C')
-rw-r--r--src/kernel/misc.C142
1 files changed, 85 insertions, 57 deletions
diff --git a/src/kernel/misc.C b/src/kernel/misc.C
index beddbbb81..329bc4fbc 100644
--- a/src/kernel/misc.C
+++ b/src/kernel/misc.C
@@ -27,6 +27,8 @@
#include <kernel/barrier.H>
#include <kernel/scheduler.H>
#include <assert.h>
+#include <kernel/terminate.H>
+#include <kernel/hbterminatetypes.H>
extern "C"
void kernel_shutdown(size_t, uint64_t, uint64_t, uint64_t) NO_RETURN;
@@ -42,19 +44,31 @@ namespace KernelMisc
{
// Update scratch SPR for shutdown status.
cpu_t* c = CpuManager::getCurrentCPU();
+ register uint64_t status = CpuManager::getShutdownStatus();
+
if (c->master)
{
- register uint64_t status = CpuManager::getShutdownStatus();
- printk("Shutdown Requested. Status = 0x%lx\n", status);
+ // If good shutdown requested print out status
+ if(status == SHUTDOWN_STATUS_GOOD)
+ {
+ printk("Shutdown Requested. Status = 0x%lx\n", status);
+ }
+ // Shtudown was called due to error.. print out plid of the
+ // errorlog that caused the failure
+ else
+ {
+ printk("Shutdown Requested. PLID = %ld (due to failure)\n",
+ status);
+ }
register uint64_t scratch_address = 0; // Values from PervSpec
switch(CpuID::getCpuType())
{
- case CORE_POWER8_MURANO:
- case CORE_POWER8_VENICE:
- case CORE_UNKNOWN:
- scratch_address = 0x40;
- break;
+ case CORE_POWER8_MURANO:
+ case CORE_POWER8_VENICE:
+ case CORE_UNKNOWN:
+ scratch_address = 0x40;
+ break;
}
asm volatile("mtspr 276, %0\n"
@@ -63,69 +77,83 @@ namespace KernelMisc
:: "r" (scratch_address), "r" (status));
}
- // dump whatever is left in g_tracBinary
- MAGIC_INSTRUCTION(MAGIC_CONTINUOUS_TRACE);
-
- // See magic_instruction_callback() in
- // src/build/debug/simics-debug-framework.py
- // for exactly how this is handled.
- MAGIC_INSTRUCTION(MAGIC_SHUTDOWN);
-
- // Check for a valid payload address.
- if ((0 == g_payload_base) && (0 == g_payload_entry))
+ // If the Shutdown was called with a status of GOOD then
+ // perform a regular shutdown, otherwise assume we have an
+ // error with a status value of the plid and perform a TI.
+ if(status == SHUTDOWN_STATUS_GOOD)
{
- // We really don't know what we're suppose to do now, so just
- // sleep all the processors.
- if (c->master)
- {
- printk("No payload... nap'ing all threads.\n");
- }
+ // dump whatever is left in g_tracBinary
+ MAGIC_INSTRUCTION(MAGIC_CONTINUOUS_TRACE);
- // Clear LPCR values that wakes up from nap. LPCR[49, 50, 51]
- setLPCR(getLPCR() & (~0x0000000000007000));
-
- while(1)
- {
- nap();
- }
- }
- else
- {
- static Barrier* l_barrier = new Barrier(CpuManager::getCpuCount());
- static uint64_t l_lowestPIR = 0xffffffffffffffffull;
+ // See magic_instruction_callback() in
+ // src/build/debug/simics-debug-framework.py
+ // for exactly how this is handled.
+ MAGIC_INSTRUCTION(MAGIC_SHUTDOWN);
- if (c->master)
+ // Check for a valid payload address.
+ if ((0 == g_payload_base) && (0 == g_payload_entry))
{
- printk("Preparing to enter payload...%lx:%lx\n",
- g_payload_base, g_payload_entry);
- }
+ // We really don't know what we're suppose to do now, so just
+ // sleep all the processors.
- // Need to identify the thread with the lowest PIR because it needs
- // to be the last one to jump to PHYP.
- uint64_t l_pir = getPIR();
- do
- {
- uint64_t currentPIR = l_lowestPIR;
- if (l_pir > currentPIR)
+ if (c->master)
{
- break;
+ printk("No payload... nap'ing all threads.\n");
}
- if (__sync_bool_compare_and_swap(&l_lowestPIR,
- currentPIR, l_pir))
+ // Clear LPCR values that wakes up from nap. LPCR[49, 50, 51]
+ setLPCR(getLPCR() & (~0x0000000000007000));
+
+ while(1)
{
- break;
+ nap();
}
+ }
+ else
+ {
+ static Barrier* l_barrier = new Barrier(CpuManager::getCpuCount());
+ static uint64_t l_lowestPIR = 0xffffffffffffffffull;
- } while(1);
-
- l_barrier->wait();
+ if (c->master)
+ {
+ printk("Preparing to enter payload...%lx:%lx\n",
+ g_payload_base, g_payload_entry);
+ }
- kernel_shutdown(CpuManager::getCpuCount(),
- g_payload_base,
- g_payload_entry,
- l_lowestPIR);
+ // Need to identify the thread with the lowest PIR because it needs
+ // to be the last one to jump to PHYP.
+ uint64_t l_pir = getPIR();
+ do
+ {
+ uint64_t currentPIR = l_lowestPIR;
+ if (l_pir > currentPIR)
+ {
+ break;
+ }
+
+ if (__sync_bool_compare_and_swap(&l_lowestPIR,
+ currentPIR, l_pir))
+ {
+ break;
+ }
+
+ } while(1);
+
+ l_barrier->wait();
+
+ kernel_shutdown(CpuManager::getCpuCount(),
+ g_payload_base,
+ g_payload_entry,
+ l_lowestPIR);
+ }
+ }
+ else
+ {
+ // Got a nonzero status value indicating we had a shutdown request
+ // with a PLID and there force need to do TI. The plid info was
+ // written to the data area earlier in CpuManager::requestShutdown
+ terminateExecuteTI();
}
}
OpenPOWER on IntegriCloud