summaryrefslogtreecommitdiffstats
path: root/src/kernel/machchk.C
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2013-05-20 12:03:29 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-06-06 11:47:27 -0500
commit5623531a2f9efa10450a5e1e3b1eb6bd4a998357 (patch)
tree23225e612af65ec60cf3a324df22111bb5c13eef /src/kernel/machchk.C
parent66474f4f93fd10ad3b35ed89cecc3d6b11e99eed (diff)
downloadtalos-hostboot-5623531a2f9efa10450a5e1e3b1eb6bd4a998357.tar.gz
talos-hostboot-5623531a2f9efa10450a5e1e3b1eb6bd4a998357.zip
Tolerate memory UEs during dump extraction.
Change-Id: I0dc57ec047beb47b557b816162d619a5b2a54108 RTC: 64619 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/4600 Tested-by: Jenkins Server Reviewed-by: ADAM R. MUHLE <armuhle@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/kernel/machchk.C')
-rw-r--r--src/kernel/machchk.C118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/kernel/machchk.C b/src/kernel/machchk.C
new file mode 100644
index 000000000..746c77c83
--- /dev/null
+++ b/src/kernel/machchk.C
@@ -0,0 +1,118 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/kernel/machchk.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <kernel/machchk.H>
+#include <kernel/console.H>
+#include <kernel/vmmmgr.H>
+#include <sys/mmio.h>
+
+namespace Kernel
+{
+namespace MachineCheck
+{
+
+bool handleLoadUE(task_t* t)
+{
+ bool handled = false;
+
+ static const uint32_t LDX_INSTR_MASK = 0xFC0007FE;
+ static const uint32_t LDX_INSTR = 0x7C00002A;
+ static const uint32_t LDX_RA_MASK = 0x001F0000;
+ static const uint32_t LDX_RB_MASK = 0x0000F800;
+ static const uint32_t LDX_RT_MASK = 0x03E00000;
+
+ do
+ {
+ //Get instruction that caused the SUE
+ uint64_t physInstAddr = VmmManager::findKernelAddress(
+ reinterpret_cast<uint64_t>(t->context.nip));
+ uint32_t* instruction = reinterpret_cast<uint32_t*>(physInstAddr);
+
+ if((*instruction & LDX_INSTR_MASK) != LDX_INSTR)
+ {
+ //Not an LDX instruction, unhandled exception
+ printk("MachineCheck::handleUE: Instruction 0x%.8x not handled.\n",
+ *instruction);
+ break;
+ }
+
+ uint64_t ueMagicValue = 0x0;
+
+ // If task is tolerating UEs, replace with "Dead Data".
+ if (t->tolerate_ue)
+ {
+ ueMagicValue = MM_UE_MAGIC_VALUE;
+ }
+ // Otherwise, check for specific MMIO addresses.
+ else
+ {
+ //Compute the accessed address
+ uint32_t rA = (*instruction & LDX_RA_MASK) >> 16;
+ uint32_t rB = (*instruction & LDX_RB_MASK) >> 11;
+
+ uint64_t vaddr = 0;
+ if(rA != 0)
+ {
+ vaddr = t->context.gprs[rA] +
+ t->context.gprs[rB];
+ }
+ else
+ {
+ vaddr = t->context.gprs[rB];
+ }
+
+ uint64_t phys = VmmManager::findPhysicalAddress(vaddr);
+
+ //Check if address is in IBSCOM MMIO Range.
+ if((phys >= MMIO_IBSCOM_START) &&
+ (phys <= MMIO_IBSCOM_END))
+ {
+ ueMagicValue = MMIO_IBSCOM_UE_DETECTED;
+ }
+ else
+ {
+ printk("MachineCheck::handleUE: Unrecognized address %lx\n",
+ phys);
+ break;
+ }
+ }
+
+ // Write pattern into result register.
+ uint32_t rT = (*instruction & LDX_RT_MASK) >> 21;
+ t->context.gprs[rT] = ueMagicValue;
+
+ // Advance to next instruction.
+ uint32_t* nextInst = reinterpret_cast<uint32_t*>(t->context.nip);
+ nextInst++;
+ t->context.nip = reinterpret_cast<void*>(nextInst);
+
+ // Successfully handled.
+ handled = true;
+
+ } while (false);
+
+ return handled;
+}
+
+
+}
+}
OpenPOWER on IntegriCloud