summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorMissy Connell <missyc@us.ibm.com>2012-10-29 13:55:23 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-11-09 08:51:25 -0600
commit0db3db91302876adc4490b9c3c1ff10945b38044 (patch)
tree3ec7d6bd4730420e7103bb0b6b326c01f295092d /src/kernel
parented66b035444144109e66283e4b97087b918c6b93 (diff)
downloadtalos-hostboot-0db3db91302876adc4490b9c3c1ff10945b38044.tar.gz
talos-hostboot-0db3db91302876adc4490b9c3c1ff10945b38044.zip
Terminate Immediate on a shutdown and assert
Change-Id: I37c8956afb11c69201f4936821cff5e153327780 RTC:43793 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/2194 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/cpumgr.C54
-rw-r--r--src/kernel/misc.C142
-rw-r--r--src/kernel/syscall.C15
-rw-r--r--src/kernel/terminate.C38
4 files changed, 181 insertions, 68 deletions
diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C
index 162b49f41..47edb8ca2 100644
--- a/src/kernel/cpumgr.C
+++ b/src/kernel/cpumgr.C
@@ -39,6 +39,9 @@
#include <errno.h>
#include <kernel/deferred.H>
#include <kernel/misc.H>
+#include <kernel/terminate.H>
+#include <kernel/hbterminatetypes.H>
+#include <kernel/kernel_reasoncodes.H>
cpu_t** CpuManager::cv_cpus[KERNEL_MAX_SUPPORTED_NODES];
bool CpuManager::cv_shutdown_requested = false;
@@ -107,6 +110,16 @@ void CpuManager::requestShutdown(uint64_t i_status)
__sync_synchronize();
cv_shutdown_requested = true;
+ // If the shutdown was not called with a Good shutdown status
+ // then we know we are shutting down due to error and the
+ // status passed back is instead a PLID
+ if (i_status != SHUTDOWN_STATUS_GOOD)
+ {
+ termWritePlid(TI_SHUTDOWN, i_status);
+
+ printk("TI initiated on all threads (shutdown)\n");
+ }
+
class ExecuteShutdown : public DeferredWork
{
public:
@@ -118,6 +131,8 @@ void CpuManager::requestShutdown(uint64_t i_status)
if(c->master)
HeapManager::stats();
#endif
+
+
}
void activeMainWork()
@@ -395,3 +410,42 @@ void CpuManager::forceMemoryPeriodic()
{
cv_forcedMemPeriodic = true;
}
+
+
+void CpuManager::critAssert(uint64_t i_failAddr)
+{
+ /* create SRC amd call terminate immediate*/
+
+ termWriteSRC(TI_CRIT_ASSERT,RC_SHUTDOWN, i_failAddr);
+
+ class ExecuteCritAssert : public DeferredWork
+ {
+ public:
+ void masterPreWork()
+ {
+ // print status to the console.
+ printk("TI initiated on all threads (crit_assert)\n");
+
+ }
+
+ void activeMainWork()
+ {
+ // Call the function to perform the TI
+ terminateExecuteTI();
+ }
+
+ void nonactiveMainWork()
+ {
+ // Something wasn't synchronized correctly if we got to here.
+ // Should not have CPUs coming online while trying to execute
+ // a shutdown.
+ terminateExecuteTI();
+ }
+ };
+
+ DeferredQueue::insert(new ExecuteCritAssert());
+
+ // Force executeion of the deferred queue.
+ DeferredQueue::execute();
+
+}
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();
}
}
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C
index 23239a8a3..6535e7c19 100644
--- a/src/kernel/syscall.C
+++ b/src/kernel/syscall.C
@@ -95,6 +95,7 @@ namespace Systemcalls
void MmVirtToPhys(task_t *t);
void MmExtend(task_t *t);
void MmLinearMap(task_t *t);
+ void CritAssert(task_t *t);
syscall syscalls[] =
@@ -136,6 +137,8 @@ namespace Systemcalls
&MmVirtToPhys, // MM_VIRT_TO_PHYS
&MmExtend, // MM_EXTEND
&MmLinearMap, // MM_LINEAR_MAP
+ &CritAssert, // MISC_CRITASSERT
+
};
};
@@ -822,5 +825,17 @@ namespace Systemcalls
TASK_SETRTN(t, VmmManager::mmLinearMap(paddr,size));
}
+ /**
+ * Call Crit assert to perform the terminate Immediate
+ * @param[in] t: the task calling the critical assert
+ */
+ void CritAssert(task_t* t)
+ {
+ uint64_t i_failAddr = (uint64_t)(TASK_GETARG0(t));
+
+ CpuManager::critAssert(i_failAddr);
+ }
+
+
};
diff --git a/src/kernel/terminate.C b/src/kernel/terminate.C
index b5834a7b3..10daec717 100644
--- a/src/kernel/terminate.C
+++ b/src/kernel/terminate.C
@@ -28,6 +28,7 @@
#include <kernel/console.H>
#include <builtins.h>
+#include <kernel/kernel_reasoncodes.H>
extern "C" void p8_force_attn() NO_RETURN;
@@ -38,19 +39,34 @@ HB_TI_DataArea kernel_TIDataArea;
/* Instance of the HB desriptor struct */
HB_Descriptor kernel_hbDescriptor = {&kernel_TIDataArea};
-void terminateAndUpdateSaveArea(uint16_t i_type, uint16_t i_source, uint64_t *i_src, uint64_t
- plid)
+
+
+void terminateExecuteTI()
{
+ // Call the function that actually executes the TI code.
+ p8_force_attn();
+}
-printk("Inside terminateandupdateSaveArea!!!!!!!!!!!!!!! \n");
- kernel_TIDataArea.type = i_type;
- kernel_TIDataArea.source = i_source;
- memcpy(i_src, kernel_TIDataArea.src, sizeof (kernel_TIDataArea.src));
- kernel_TIDataArea.plid = plid;
-
+void termWritePlid(uint16_t i_source, uint64_t plid)
+{
+ kernel_TIDataArea.type = TI_WITH_PLID;
+ kernel_TIDataArea.source = i_source;
+ kernel_TIDataArea.plid = plid;
+}
+
+void termWriteSRC(uint16_t i_source, uint16_t i_reasoncode,uint64_t i_failAddr)
+{
+ // Update the TI structure with the type of TI and who called.
+ kernel_TIDataArea.type = TI_WITH_SRC;
+ kernel_TIDataArea.source = i_source;
-printk("Calling p8_force_attn!!! dying.... \n");
- // After the data is set up .. call the function that actually executes the TI.
- p8_force_attn();
+ // Update TID data area with the SRC info we have avail
+ kernel_TIDataArea.src.ID = 0xBC;
+ kernel_TIDataArea.src.subsystem = 0x11;
+ kernel_TIDataArea.src.reasoncode = i_reasoncode;
+ kernel_TIDataArea.src.moduleID = MOD_KERNEL_TERMINATE;
+ kernel_TIDataArea.src.iType = TI_WITH_SRC;
+ // Update User Data with address of fail location
+ kernel_TIDataArea.src.word6 = i_failAddr;
}
OpenPOWER on IntegriCloud