summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bootloader/bl_start.S5
-rwxr-xr-xsrc/build/tools/listdeps.pl1
-rw-r--r--src/include/kernel/machchk.H32
-rw-r--r--src/include/kernel/syscalls.H5
-rw-r--r--src/include/sys/misc.h12
-rw-r--r--src/include/usr/xscom/xscomif.H11
-rw-r--r--src/kernel/bltohbdatamgr.C8
-rw-r--r--src/kernel/exception.C5
-rw-r--r--src/kernel/machchk.C45
-rw-r--r--src/kernel/start.S5
-rw-r--r--src/kernel/syscall.C15
-rw-r--r--src/lib/syscall_misc.C10
-rw-r--r--src/usr/isteps/istep06/host_start_occ_xstop_handler.C57
-rw-r--r--src/usr/xscom/xscom.C26
14 files changed, 201 insertions, 36 deletions
diff --git a/src/bootloader/bl_start.S b/src/bootloader/bl_start.S
index 0110c2401..0780575d6 100644
--- a/src/bootloader/bl_start.S
+++ b/src/bootloader/bl_start.S
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015,2017
+# Contributors Listed Below - COPYRIGHT 2015,2018
# [+] Google Inc.
# [+] International Business Machines Corp.
#
@@ -74,11 +74,10 @@ _start:
;// Set thread priority high.
or 2,2,2
- ;// Clear MSR[TA] (bit 1) and enable MSR[ME] (bit 51).
+ ;// Clear MSR[TA] (bit 1)
mfmsr r2
rldicl r2,r2,1,1 ;// Clear bit 1 - result [1-63,0]
rotrdi r2,r2,1 ;// Rotate right 1 - result [0,63]
- ori r2,r2,4096 ;// Set bit 51
;// Set up SRR0 / SRR1 to enable new MSR.
mtsrr1 r2
li r2, _start_postmsr@l
diff --git a/src/build/tools/listdeps.pl b/src/build/tools/listdeps.pl
index d3c9ce495..3561bb2f5 100755
--- a/src/build/tools/listdeps.pl
+++ b/src/build/tools/listdeps.pl
@@ -223,6 +223,7 @@ my $resident_modules = {
"libsecureboot_trusted.so" => '1',
"libsecureboot_base.so" => '1',
"libscom.so" => '1',
+ "libxscom.so" => '1',
};
# A list of the dependent libraries in each istep.
diff --git a/src/include/kernel/machchk.H b/src/include/kernel/machchk.H
index af4243807..aebef6235 100644
--- a/src/include/kernel/machchk.H
+++ b/src/include/kernel/machchk.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2013,2014 */
+/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -43,6 +45,34 @@ namespace Kernel
* @return bool - True if MC successfully handled, false otherwise.
*/
bool handleSLB(task_t* t);
+
+ /**
+ * Constants to define the FIR bit to use to force a checkstop
+ * for an unhandled machine check.
+ */
+#ifdef CONFIG_P9_SYSTEM
+ constexpr uint64_t MCHK_XSTOP_FIR_SCOM_ADDR = 0x05012000;
+ constexpr uint64_t MCHK_XSTOP_FIR_VALUE = 0x0000000100000000ull;//31
+#endif
+
+ /** @fn setCheckstopData
+ * @brief Tells the kernel how to force a checkstop for unrecoverable
+ * machine checks
+ * @param[in] i_xstopAddr - XSCOM MMIO address of FIR to write
+ * @param[in] i_xstopData - Data to write into FIR to trigger xstop
+ *
+ * @return none
+ */
+ void setCheckstopData(uint64_t i_xstopAddr,
+ uint64_t i_xstopData);
+
+ /** @fn forceCheckstop
+ * @brief Force a checkstop if we know how in order to get better
+ * error isolation for cache/memory UEs
+ *
+ * @return none
+ */
+ void forceCheckstop();
}
}
diff --git a/src/include/kernel/syscalls.H b/src/include/kernel/syscalls.H
index 35c6a5fe8..c7a03d6b6 100644
--- a/src/include/kernel/syscalls.H
+++ b/src/include/kernel/syscalls.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2010,2017 */
+/* Contributors Listed Below - COPYRIGHT 2010,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -123,6 +123,9 @@ namespace Systemcalls
/** critassert() */
MISC_CRITASSERT,
+ /** set_mchk_data() */
+ MISC_SETMCHKDATA,
+
SYSCALL_MAX
};
diff --git a/src/include/sys/misc.h b/src/include/sys/misc.h
index 6b57e7e4e..af44d7ce8 100644
--- a/src/include/sys/misc.h
+++ b/src/include/sys/misc.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -248,6 +248,16 @@ int cpu_all_winkle();
*/
void cpu_crit_assert(uint64_t i_failAddr);
+/** @fn set_mchk_data
+ * @brief Tells the kernel how to force a checkstop for unrecoverable
+ * machine checks
+ * @param[in] i_xstopAddr - XSCOM MMIO address of FIR to write
+ * @param[in] i_xstopData - Data to write into FIR to trigger xstop
+ *
+ * @return none
+ */
+void set_mchk_data(uint64_t i_xstopAddr, uint64_t i_xstopData);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/include/usr/xscom/xscomif.H b/src/include/usr/xscom/xscomif.H
index 1afdfafcb..65b7410f1 100644
--- a/src/include/usr/xscom/xscomif.H
+++ b/src/include/usr/xscom/xscomif.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -34,6 +34,15 @@ namespace XSCOM
*/
uint64_t get_master_bar( void );
+/**
+ * @brief Generate a fully-qualified MMIO address for a physical scom
+ * address, relative to the given processor target
+ * @param[in] i_proc - Processor
+ * @param[in] i_scomAddr - Physical scom address to convert
+ * @return uint64_t - MMIO address
+ */
+uint64_t generate_mmio_addr( TARGETING::Target* i_proc,
+ uint64_t i_scomAddr );
}; // namespace XSCOM
diff --git a/src/kernel/bltohbdatamgr.C b/src/kernel/bltohbdatamgr.C
index e33fab6ef..a0c89b034 100644
--- a/src/kernel/bltohbdatamgr.C
+++ b/src/kernel/bltohbdatamgr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -145,7 +145,6 @@ printk("Version=%lX\n",i_data.version);
// were set correctly, instead use BLTOHB_SECURE_OVERRIDES version.
if( iv_data.version >= Bootloader::BLTOHB_SECURE_OVERRIDES )
{
-printk("lpc=%lX, xscom=%lX\n", i_data.lpcBAR, i_data.xscomBAR );
kassert(i_data.lpcBAR>0);
kassert(i_data.xscomBAR>0);
iv_data.lpcBAR = i_data.lpcBAR;
@@ -158,9 +157,10 @@ printk("lpc=%lX, xscom=%lX\n", i_data.lpcBAR, i_data.xscomBAR );
iv_data.xscomBAR = MMIO_GROUP0_CHIP0_XSCOM_BASE_ADDR;
}
+ printk("lpc=%lX, xscom=%lX\n", i_data.lpcBAR, i_data.xscomBAR );
-printk("lpc=%lX, xscom=%lX, iv_data=%p\n", iv_data.lpcBAR, iv_data.xscomBAR,
- static_cast<void *>(&iv_data) );
+ printk("iv_lpc=%lX, iv_xscom=%lX, iv_data=%p\n",
+ iv_data.lpcBAR, iv_data.xscomBAR, static_cast<void *>(&iv_data) );
// Check if bootloader advertised the size of the structure it saw;
// otherwise use the default padded size
diff --git a/src/kernel/exception.C b/src/kernel/exception.C
index 0ece19a63..cf2a35c81 100644
--- a/src/kernel/exception.C
+++ b/src/kernel/exception.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2010,2017 */
+/* Contributors Listed Below - COPYRIGHT 2010,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -328,6 +328,7 @@ void kernel_execute_machine_check()
t->tid, getPIR(),
getSRR0(), getSRR1(), getDSISR(), getDAR());
MAGIC_INSTRUCTION(MAGIC_BREAK_ON_ERROR);
+ Kernel::MachineCheck::forceCheckstop();
kassert(false);
}
@@ -388,6 +389,7 @@ void kernel_execute_machine_check()
t->tid, getPIR(),
getSRR0(), getSRR1(), getDSISR(), getDAR());
MAGIC_INSTRUCTION(MAGIC_BREAK_ON_ERROR);
+ Kernel::MachineCheck::forceCheckstop();
TaskManager::endTask(t, NULL, TASK_STATUS_CRASHED);
}
}
@@ -425,3 +427,4 @@ void kernel_execute_unhandled_exception()
termWriteSRC(TI_UNHANDLED_EX, KERNEL::RC_UNHANDLED_EX, exception);
terminateExecuteTI();
}
+
diff --git a/src/kernel/machchk.C b/src/kernel/machchk.C
index 79edf4240..2a96b5896 100644
--- a/src/kernel/machchk.C
+++ b/src/kernel/machchk.C
@@ -27,12 +27,20 @@
#include <kernel/vmmmgr.H>
#include <sys/mmio.h>
#include <arch/memorymap.H>
+#include <arch/ppc.H>
namespace Kernel
{
namespace MachineCheck
{
+//Keep track of the MMIO address that we can use to force a checkstop
+static uint64_t* g_xstopRegPtr = nullptr;
+
+//Keep track of the data to write into the xstop reg
+static uint64_t g_xstopRegValue = 0;
+
+
bool handleLoadUE(task_t* t)
{
bool handled = false;
@@ -132,5 +140,42 @@ bool handleSLB(task_t* t)
}
+/**
+ * @brief Tells the kernel how to force a checkstop for unrecoverable
+ * machine checks
+ */
+void setCheckstopData(uint64_t i_xstopAddr, uint64_t i_xstopData)
+{
+ g_xstopRegPtr = reinterpret_cast<uint64_t*>(i_xstopAddr
+ |VmmManager::FORCE_PHYS_ADDR);
+ g_xstopRegValue = i_xstopData;
+ printk( "Set MchChk Xstop: %p=%.16lX\n", g_xstopRegPtr, g_xstopRegValue );
+
+ // Now that the machine check handler can do the xscom we
+ // can set MSR[ME]=1 to enable the regular machine check
+ // handling
+ uint64_t l_msr = getMSR();
+ l_msr |= 0x0000000000001000; //set bit 51
+ setMSR(l_msr);
+}
+
+/**
+ * @brief Force a checkstop if we know how in order to get better
+ * error isolation for cache/memory UEs
+ */
+void forceCheckstop()
+{
+ if( g_xstopRegPtr != nullptr )
+ {
+ printk( "Forcing a xstop with %p = %.16lX\n",
+ g_xstopRegPtr, g_xstopRegValue );
+ *g_xstopRegPtr = g_xstopRegValue;
+ }
+ else
+ {
+ printk( "Unable to force checkstop, No xstop reg set\n" );
+ }
+}
+
}
}
diff --git a/src/kernel/start.S b/src/kernel/start.S
index 40ff3b0ed..979235276 100644
--- a/src/kernel/start.S
+++ b/src/kernel/start.S
@@ -33,11 +33,10 @@ _start:
;// Set thread priority high.
or 2,2,2
- ;// Clear MSR[TA] (bit 1) and enable MSR[ME] (bit 51).
+ ;// Clear MSR[TA] (bit 1)
mfmsr r2
rldicl r2,r2,1,1 ;// Clear bit 1 - result [1-63,0]
rotrdi r2,r2,1 ;// Rotate right 1 - result [0,63]
- ori r2,r2,4096 ;// Set bit 51
;// Set up SRR0 / SRR1 to enable new MSR.
mtsrr1 r2
li r2, _start_postmsr@l
@@ -473,7 +472,7 @@ kernel_dispatch_task:
stdcx. r0, TASK_CPUPTR, r1 ;// the CPU pointer in the task.
mfmsr r2 ;// Get current MSR
- ori r2,r2, 0xD030 ;// Enable MSR[EE,ME,PR,IR,DR].
+ ori r2,r2, 0xC030 ;// Enable MSR[EE,PR,IR,DR].
rldicl r2,r2,50,1 ;// Clear ...
rotldi r2,r2,14 ;// MSR[FP]
ld r3, TASK_MSR_MASK(r1) ;// Load MSR mask.
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C
index 04c65eb10..9dc6bd720 100644
--- a/src/kernel/syscall.C
+++ b/src/kernel/syscall.C
@@ -45,6 +45,7 @@
#include <kernel/doorbell.H>
#include <sys/sync.h>
#include <errno.h>
+#include <kernel/machchk.H>
namespace KernelIpc
{
@@ -142,6 +143,7 @@ namespace Systemcalls
void MmExtend(task_t *t);
void MmLinearMap(task_t *t);
void CritAssert(task_t *t);
+ void SetMchkData(task_t *t);
syscall syscalls[] =
@@ -185,6 +187,7 @@ namespace Systemcalls
&MmExtend, // MM_EXTEND
&MmLinearMap, // MM_LINEAR_MAP
&CritAssert, // MISC_CRITASSERT
+ &SetMchkData, // MISC_SETMCHKDATA
};
};
@@ -988,6 +991,18 @@ namespace Systemcalls
CpuManager::critAssert(i_failAddr);
}
+ /**
+ * @brief Tells the kernel how to force a checkstop for unrecoverable
+ * machine checks
+ * @param[in] t: the task calling the critical assert
+ */
+ void SetMchkData(task_t* t)
+ {
+ uint64_t i_xstopAddr = (uint64_t)(TASK_GETARG0(t));
+ uint64_t i_xstopData = (uint64_t)(TASK_GETARG1(t));
+
+ Kernel::MachineCheck::setCheckstopData(i_xstopAddr,i_xstopData);
+ }
};
diff --git a/src/lib/syscall_misc.C b/src/lib/syscall_misc.C
index dff702ddd..a2b4ab1e4 100644
--- a/src/lib/syscall_misc.C
+++ b/src/lib/syscall_misc.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -137,3 +137,11 @@ void cpu_crit_assert(uint64_t i_failAddr)
{
_syscall1(MISC_CRITASSERT, reinterpret_cast<void*>(i_failAddr));
}
+
+
+void set_mchk_data(uint64_t i_xstopAddr, uint64_t i_xstopData)
+{
+ _syscall2(MISC_SETMCHKDATA,
+ reinterpret_cast<void*>(i_xstopAddr),
+ reinterpret_cast<void*>(i_xstopData));
+}
diff --git a/src/usr/isteps/istep06/host_start_occ_xstop_handler.C b/src/usr/isteps/istep06/host_start_occ_xstop_handler.C
index 683041916..611dfd75b 100644
--- a/src/usr/isteps/istep06/host_start_occ_xstop_handler.C
+++ b/src/usr/isteps/istep06/host_start_occ_xstop_handler.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,7 +39,10 @@
#ifdef CONFIG_BMC_IPMI
#include <ipmi/ipmisensor.H>
#endif
-
+#include <sys/misc.h>
+#include <xscom/xscomif.H>
+#include <initservice/initserviceif.H>
+#include <kernel/machchk.H>
namespace ISTEP_06
{
@@ -47,12 +50,19 @@ void* host_start_occ_xstop_handler( void *io_pArgs )
{
ISTEP_ERROR::IStepError l_stepError;
+ errlHndl_t l_err = nullptr;
+
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"host_start_occ_xstop_handler entry" );
+ TARGETING::Target* masterproc = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle(masterproc);
+
do
{
-// if ( Util::isSimicsRunning() ) break; //Skip if running in Simics
+ // If we have nothing external (FSP or OCC) to handle checkstops we are
+ // better off just crashing and having a chance to pull the HB
+ // traces off the system live
TARGETING::Target * l_sys = nullptr;
TARGETING::targetService().getTopLevelTarget( l_sys );
@@ -68,7 +78,7 @@ void* host_start_occ_xstop_handler( void *io_pArgs )
if ((l_mnfgFlags & TARGETING::MNFG_FLAG_SRC_TERM) &&
!(l_mnfgFlags & TARGETING::MNFG_FLAG_IMMEDIATE_HALT))
{
- errlHndl_t l_err = nullptr;
+ l_err = nullptr;
//If HB_VOLATILE MFG_TERM_REBOOT_ENABLE flag is set at this point
//Create errorlog to terminate the boot.
@@ -91,7 +101,6 @@ void* host_start_occ_xstop_handler( void *io_pArgs )
0,
true /*HB SW error*/ );
l_stepError.addErrorDetails(l_err);
- ERRORLOG::errlCommit(l_err, ISTEP_COMP_ID);
break;
}
@@ -111,7 +120,6 @@ void* host_start_occ_xstop_handler( void *io_pArgs )
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
"Failed to enable BMC auto reboots....");
l_stepError.addErrorDetails(l_err);
- ERRORLOG::errlCommit(l_err, HWPF_COMP_ID);
break;
}
}
@@ -119,11 +127,6 @@ void* host_start_occ_xstop_handler( void *io_pArgs )
#ifdef CONFIG_IPLTIME_CHECKSTOP_ANALYSIS
- errlHndl_t l_errl = NULL;
-
- TARGETING::Target* masterproc = NULL;
- TARGETING::targetService().masterProcChipTargetHandle(masterproc);
-
void* l_homerVirtAddrBase = reinterpret_cast<void*>
(VmmManager::INITIAL_MEM_SIZE);
uint64_t l_homerPhysAddrBase = mm_virt_to_phys(l_homerVirtAddrBase);
@@ -133,33 +136,49 @@ void* host_start_occ_xstop_handler( void *io_pArgs )
" l_homerPhysAddrBase=0x%x, l_commonPhysAddr=0x%x",
l_homerPhysAddrBase, l_commonPhysAddr);
- l_errl = HBPM::loadPMComplex(masterproc,
+ // Load the OCC directly into SRAM and start it in a special mode
+ // that only handles checkstops
+ l_err = HBPM::loadPMComplex(masterproc,
l_homerPhysAddrBase,
l_commonPhysAddr,
HBPM::PM_LOAD,
true);
- if(l_errl)
+ if(l_err)
{
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
"loadPMComplex failed");
- l_stepError.addErrorDetails(l_errl);
- ERRORLOG::errlCommit(l_errl, HWPF_COMP_ID);
+ l_stepError.addErrorDetails(l_err);
break;
}
- l_errl = HBOCC::startOCCFromSRAM(masterproc);
- if(l_errl)
+ l_err = HBOCC::startOCCFromSRAM(masterproc);
+ if(l_err)
{
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
"startOCCFromSRAM failed");
- l_stepError.addErrorDetails(l_errl);
- ERRORLOG::errlCommit(l_errl, HWPF_COMP_ID);
+ l_stepError.addErrorDetails(l_err);
break;
}
#endif
}while(0);
+ if(l_err)
+ {
+ ERRORLOG::errlCommit(l_err, HWPF_COMP_ID);
+ }
+
+ // Now that the checkstop handler is running (or we don't have one),
+ // setup the machine check code to trigger a checkstop for UE
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Enabling machine check handler to generate checkstops" );
+
+ uint64_t l_xstopXscom = XSCOM::generate_mmio_addr( masterproc,
+ Kernel::MachineCheck::MCHK_XSTOP_FIR_SCOM_ADDR );
+
+ set_mchk_data( l_xstopXscom,
+ Kernel::MachineCheck::MCHK_XSTOP_FIR_VALUE );
+
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"host_start_occ_xstop_handler exit" );
diff --git a/src/usr/xscom/xscom.C b/src/usr/xscom/xscom.C
index c9afe0273..a28897f8b 100644
--- a/src/usr/xscom/xscom.C
+++ b/src/usr/xscom/xscom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -866,5 +866,29 @@ uint64_t get_master_bar( void )
return mm_virt_to_phys(g_masterProcVirtAddr);
}
+/**
+ * @brief Generate a fully-qualified MMIO address for a physical scom
+ * address, relative to the given processor target
+ */
+uint64_t generate_mmio_addr( TARGETING::Target* i_proc,
+ uint64_t i_scomAddr )
+{
+ uint64_t l_returnAddr = 0;
+
+ // Get the target chip's physical mmio address
+ uint64_t l_XSComBaseAddr =
+ i_proc->getAttr<TARGETING::ATTR_XSCOM_BASE_ADDRESS>();
+
+ // Build the XSCom address (relative to group 0, chip 0)
+ XSComP9Address l_mmioAddr(i_scomAddr);
+
+ // Get the offset
+ uint64_t l_offset = l_mmioAddr.offset();
+
+ // Compute value relative to target chip
+ l_returnAddr = l_XSComBaseAddr + l_offset;
+
+ return l_returnAddr;
+}
} // end namespace
OpenPOWER on IntegriCloud