diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2013-05-20 12:03:29 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-06-06 11:47:27 -0500 |
commit | 5623531a2f9efa10450a5e1e3b1eb6bd4a998357 (patch) | |
tree | 23225e612af65ec60cf3a324df22111bb5c13eef /src/kernel/machchk.C | |
parent | 66474f4f93fd10ad3b35ed89cecc3d6b11e99eed (diff) | |
download | talos-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.C | 118 |
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; +} + + +} +} |