diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2013-05-20 13:35:51 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-06-14 09:08:38 -0500 |
commit | 92255af10842c672550a586d342c67ac1c7e11ca (patch) | |
tree | 1ae64d3211fd3c98bad46e205cca7ad5135bd25a /src/kernel | |
parent | 709f06b2332d2f0e3309bf6fdcef2af0be250df3 (diff) | |
download | talos-hostboot-92255af10842c672550a586d342c67ac1c7e11ca.tar.gz talos-hostboot-92255af10842c672550a586d342c67ac1c7e11ca.zip |
Handle SLB machine check errs by resetting SLB.
Change-Id: I8a74a88e6eb812406c64976e7842903e1063021a
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/4605
Tested-by: Jenkins Server
Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com>
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')
-rw-r--r-- | src/kernel/exception.C | 42 | ||||
-rw-r--r-- | src/kernel/machchk.C | 7 |
2 files changed, 44 insertions, 5 deletions
diff --git a/src/kernel/exception.C b/src/kernel/exception.C index 47d8a3c01..ac8638585 100644 --- a/src/kernel/exception.C +++ b/src/kernel/exception.C @@ -237,6 +237,7 @@ void kernel_execute_softpatch() const uint64_t EXCEPTION_MSR_PR_BIT_MASK = 0x0000000000004000; const uint64_t EXCEPTION_SRR1_LOADSTORE_ERR = 0x0000000000200000; const uint64_t EXCEPTION_DSISR_LD_UE_INTERRUPT = 0x0000000000008000; +const uint64_t EXCEPTION_DSISR_SLB_ERRORS = 0x00000000000000C0; extern "C" void kernel_execute_machine_check() @@ -258,15 +259,46 @@ void kernel_execute_machine_check() bool handled = false; - // SUE on load instruction. - if ((getSRR1() & EXCEPTION_SRR1_LOADSTORE_ERR) && - (getDSISR() & EXCEPTION_DSISR_LD_UE_INTERRUPT)) + // Error in load/store. + if (getSRR1() & EXCEPTION_SRR1_LOADSTORE_ERR) { - handled = Kernel::MachineCheck::handleLoadUE(t); + // SUE on load instruction. + if (getDSISR() & EXCEPTION_DSISR_LD_UE_INTERRUPT) + { + handled = Kernel::MachineCheck::handleLoadUE(t); + } + // SLB parity or multi-hit. + else if (getDSISR() & EXCEPTION_DSISR_SLB_ERRORS) + { + handled = Kernel::MachineCheck::handleSLB(t); + } } + // Error in instruction fetch. else { - + enum + { + SRR1_ERR_RESERVED = 0, //< Reserved + SRR1_ERR_IFU_UE = 1, //< UE on Instruction + SRR1_ERR_IFU_SLB_P = 2, //< SLB Parity + SRR1_ERR_IFU_SLB_MH = 3, //< SLB Multihit + SRR1_ERR_IFU_SLB_MHP = 4, //< SLB Multihit & Parity + SRR1_ERR_IFU_TLB_MH = 5, //< TLB Multihit + SRR1_ERR_IFU_TLB_MH_RELOAD = 6, //< TLB Multihit on Reload + SRR1_ERR_IFU_UNKNOWN = 7 //< Unknown error. + }; + + // Extract bits 43:45. + uint64_t error = (getSRR1() >> 18) & 0x7; + + switch (error) + { + case SRR1_ERR_IFU_SLB_P: + case SRR1_ERR_IFU_SLB_MH: + case SRR1_ERR_IFU_SLB_MHP: + handled = Kernel::MachineCheck::handleSLB(t); + break; + } } if (!handled) diff --git a/src/kernel/machchk.C b/src/kernel/machchk.C index 746c77c83..ad56a498f 100644 --- a/src/kernel/machchk.C +++ b/src/kernel/machchk.C @@ -113,6 +113,13 @@ bool handleLoadUE(task_t* t) return handled; } +bool handleSLB(task_t* t) +{ + // Reinitialize the SLB. + VmmManager::init_slb(); + return true; +} + } } |