summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2013-05-20 13:35:51 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-06-14 09:08:38 -0500
commit92255af10842c672550a586d342c67ac1c7e11ca (patch)
tree1ae64d3211fd3c98bad46e205cca7ad5135bd25a /src/kernel
parent709f06b2332d2f0e3309bf6fdcef2af0be250df3 (diff)
downloadtalos-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.C42
-rw-r--r--src/kernel/machchk.C7
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;
+}
+
}
}
OpenPOWER on IntegriCloud