summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/initservice/mboxRegs.H12
-rw-r--r--src/include/usr/secureboot/drtm.H156
-rw-r--r--src/include/usr/secureboot/secure_reasoncodes.H1
-rw-r--r--src/include/usr/secureboot/service.H55
-rw-r--r--src/include/usr/secureboot/settings.H73
-rw-r--r--src/makefile2
-rwxr-xr-xsrc/usr/i2c/tpmdd.C2
-rw-r--r--src/usr/initservice/extinitsvc/extinitsvctasks.H16
-rw-r--r--src/usr/isteps/istep06/host_gard.C22
-rw-r--r--src/usr/isteps/istep14/call_host_mpipl_service.C42
-rw-r--r--src/usr/isteps/istep21/call_host_start_payload.C39
-rw-r--r--src/usr/secureboot/HBconfig14
-rw-r--r--src/usr/secureboot/base/service.C16
-rw-r--r--src/usr/secureboot/base/settings.C135
-rw-r--r--src/usr/secureboot/common/securetrace.H8
-rw-r--r--src/usr/secureboot/ext/drtm.C723
-rw-r--r--src/usr/secureboot/ext/makefile6
-rw-r--r--src/usr/secureboot/trusted/trustedboot.C103
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.C24
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types_hb.xml47
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/target_types_hb.xml3
-rwxr-xr-xsrc/usr/targeting/targetservicestart.C21
22 files changed, 1478 insertions, 42 deletions
diff --git a/src/include/usr/initservice/mboxRegs.H b/src/include/usr/initservice/mboxRegs.H
index 716311385..2f0314c54 100644
--- a/src/include/usr/initservice/mboxRegs.H
+++ b/src/include/usr/initservice/mboxRegs.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -99,6 +99,16 @@ namespace SPLESS
} PACKED;
};
+ // Mailbox Scratch Register 7
+ union MboxScratch7_t
+ {
+ uint32_t data32;
+ struct
+ {
+ uint32_t drtmPayloadAddrMb :32; //0
+ } PACKED;
+ };
+
// Mailbox Scratch Register 8
union MboxScratch8_t
{
diff --git a/src/include/usr/secureboot/drtm.H b/src/include/usr/secureboot/drtm.H
new file mode 100644
index 000000000..e061502ae
--- /dev/null
+++ b/src/include/usr/secureboot/drtm.H
@@ -0,0 +1,156 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/secureboot/drtm.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* [+] 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. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __SECUREBOOT_DRTM_H
+#define __SECUREBOOT_DRTM_H
+
+#include <initservice/mboxRegs.H>
+#include <config.h>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <vector>
+#include <secureboot/settings.H>
+#include <targeting/common/targetservice.H>
+
+namespace SECUREBOOT
+{
+
+namespace DRTM
+{
+
+/**
+ * @brief Determine HW DRTM state and cache for code to use
+ *
+ * @par Detailed Description:
+ * Reads DRTM related scratch registers, attributes, and proc chip security
+ * settings to determine the DRTM state, and caches DRTM settings in
+ * attributes for use by the code. It will return an error log if a DRTM
+ * consistency violation is detected.
+ *
+ * @param[in] i_scratchReg7 Value of scratch register 7
+ * @param[in] i_scratchReg8 Value of scratch register 8
+ *
+ * @return errHndl_t Error log handle indicating success or failure
+ * @retval nullptr Discovered/configured DRTM state successfully
+ * @retval !nullptr Error log providing failure details
+ */
+errlHndl_t discoverDrtmState(
+ const INITSERVICE::SPLESS::MboxScratch7_t& i_scratchReg7,
+ const INITSERVICE::SPLESS::MboxScratch8_t& i_scratchReg8);
+
+/**
+ * @brief Returns whether this is a DRTM MPIPL or not
+ *
+ * @param[out] o_isDrtmMpipl Returns whether this is a DRTM MPIPL or not
+ */
+void isDrtmMpipl(bool& o_isDrtmMpipl);
+
+/**
+ * @brief Determines whether DRTM HW settings are consistent across all
+ * processors in a node
+ *
+ * @par Detailed Description:
+ * Ensures that, when coming up in a DRTM MPIPL, the L4A, LQA, and SUL bits
+ * are set + LLP and LLS are clear in the processor security register for
+ * all processors in a node. If this is not the case, it returns an error
+ * log. Must only be called after FSI path is established and presence
+ * detect has been confirmed.
+ *
+ * @return errHndl_t Error log handle indicating success or failure
+ * @retval nullptr All processors in node have correct DRTM HW signature
+ * @retval !nullptr Error log providing failure details
+ */
+errlHndl_t validateDrtmHwSignature();
+
+/**
+ * @brief Validates and extends the DRTM payload
+ *
+ * @par Detailed Description:
+ * When coming up in a DRTM MPIPL, locates the DRTM payload preserved in
+ * memory, validates its secure signature, and extends its measurement to
+ * TPM dynamic PCR range / dynamic log.
+ *
+ * @return errHndl_t Error log handle indicating success or failure
+ * @retval nullptr Validated/extended the DRTM payload
+ * @retval !nullptr Error log providing failure details
+ */
+errlHndl_t validateDrtmPayload();
+
+/**
+ * @brief Completes the DRTM sequence
+ *
+ * @par Detailed Description:
+ * Completes the DRTM sequence by clearing the LQA and L4A security switch
+ * register bits on all the functional processors
+ *
+ * @return errHndl_t Error log handle indicating success or failure
+ * @retval nullptr Completed DRTM HW sequencing
+ * @retval !nullptr Error log providing failure details
+ */
+errlHndl_t completeDrtm();
+
+#ifdef CONFIG_DRTM_TRIGGERING
+/**
+ * @brief Initiates a DRTM sequence
+ *
+ * @par Detailed Description:
+ * Initiates a DRTM sequence. This pins the task running this code to the
+ * master processor and sets the LLP bit (for master proc chip) and LLS bit
+ * (for non-masters) on every processor, setting the LL bit for the
+ * processor this task is running on last, so that it doesn't get clobbered
+ * by the SBE core quiesce logic. It also sets up the master processor
+ * scratch registers to indicate presence and address of the DRTM payload.
+ * If successful, the function will never return becaue the core it's
+ * running on will be quiesced by SBE.
+ *
+ * @note: Only valid for RIT protection
+ *
+ * @return errHndl_t Error log handle indicating success or failure
+ * @retval nullptr Not possible; on success the function never returns.
+ * @retval !nullptr Error log providing failure details
+ */
+errlHndl_t initiateDrtm();
+
+/**
+ * @brief Updates DRTM related scratch registers with DRTM payload details
+ *
+ * @par Detailed Description:
+ * Updates scratch register 7+8 to record details of the DRTM payload
+ * preserved in memory. This should be called prior to initiating the
+ * DRTM late launch sequence.
+ *
+ * @note: Only valid for RIT protection
+ *
+ * @param[in] i_drtmPayloadAddrMb DRTM payload physical address in MB
+ */
+void setDrtmPayloadPhysAddrMb(uint32_t i_drtmPayloadPhysAddrMb);
+#endif
+
+} // End DRTM namespace
+
+} // End SECUREBOOT namespace
+
+#endif // End __SECUREBOOT_DRTM_H
+
diff --git a/src/include/usr/secureboot/secure_reasoncodes.H b/src/include/usr/secureboot/secure_reasoncodes.H
index 2bbed2b23..1609e1a5f 100644
--- a/src/include/usr/secureboot/secure_reasoncodes.H
+++ b/src/include/usr/secureboot/secure_reasoncodes.H
@@ -38,6 +38,7 @@ namespace SECUREBOOT
MOD_SECURE_ROM_CLEANUP = 0x04,
MOD_SECURE_ROM_SHA512 = 0x05,
MOD_SECURE_READ_REG = 0x06,
+ MOD_SECURE_WRITE_REG = 0x07,
};
enum SECUREReasonCode
diff --git a/src/include/usr/secureboot/service.H b/src/include/usr/secureboot/service.H
index afb3ed934..a328b7337 100644
--- a/src/include/usr/secureboot/service.H
+++ b/src/include/usr/secureboot/service.H
@@ -48,20 +48,6 @@ typedef uint8_t PAGE_TABLE_ENTRY_t[HASH_PAGE_TABLE_ENTRY_SIZE];
namespace SECUREBOOT
{
- // these constants represent the scom addresses and masks we need
- // to obtain secure boot settings from the system
- enum class ProcSecurity : uint64_t
- {
- SabBit = 0x8000000000000000ull,
- SwitchRegister = 0x00010005ull,
- };
-
- enum class ProcCbsControl : uint64_t
- {
- JumperStateBit = 0x0400000000000000ull,
- StatusRegister = 0x00050001ull,
- };
-
/** @brief Perform initialization of Secureboot for the Base image.
*
* - Copy secure header from original location.
@@ -107,6 +93,47 @@ namespace SECUREBOOT
TARGETING::Target* i_targ
= TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL);
+ /**
+ * @brief Clear specified bits in the processor security switch register
+ *
+ * @par Detailed Description:
+ * Clears the specified bits in the processor security switch register.
+ *
+ * @param[in] i_bits Vector of ProcSecurity (bit) enums
+ * @param[in] i_pTarget Processor target to write. Must be either
+ * the master processor target sentinel or valid processor target.
+ * Must not be NULL.
+ *
+ * @return errHndl_t Error log handle indicating success or failure
+ * @retval nullptr Cleared specified security switch register bits
+ * successfully
+ * @retval !nullptr Error log providing failure details
+ */
+ errlHndl_t clearSecuritySwitchBits(
+ const std::vector<SECUREBOOT::ProcSecurity>& i_bits,
+ TARGETING::Target* i_pTarget =
+ TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL);
+
+ /**
+ * @brief Set specified bits in the processor security switch register
+ *
+ * @par Detailed Description:
+ * Sets the specified bits in the processor security switch register.
+ *
+ * @param[in] i_bits Vector of ProcSecurity (bit) enums
+ * @param[in] i_pTarget Processor target to write. Must be either
+ * the master processor target sentinel or valid processor target.
+ * Must not be NULL.
+ *
+ * @return errHndl_t Error log handle indicating success or failure
+ * @retval nullptr Set specified security switch register bits
+ * successfully
+ * @retval !nullptr Error log providing failure details
+ */
+ errlHndl_t setSecuritySwitchBits(
+ const std::vector<SECUREBOOT::ProcSecurity>& i_bits,
+ TARGETING::Target* i_pTarget =
+ TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL);
/** @brief Returns the state of the secure jumper as reported by the
* given processor.
diff --git a/src/include/usr/secureboot/settings.H b/src/include/usr/secureboot/settings.H
index d6f83126d..08681e08e 100644
--- a/src/include/usr/secureboot/settings.H
+++ b/src/include/usr/secureboot/settings.H
@@ -29,6 +29,7 @@
#include <targeting/common/target.H>
#include <targeting/common/targetservice.H>
#include <cstdint>
+#include <vector>
namespace SECUREBOOT
{
@@ -38,6 +39,39 @@ namespace SECUREBOOT
SECURITY_ASSERTED = 0b1,
};
+ // these constants represent the scom addresses and masks we need
+ // to obtain secure boot settings from the system
+ enum class ProcSecurity : uint64_t
+ {
+ SabBit = 0x8000000000000000ull, // Secure access (mirrored)
+ LLPBit = 0x4000000000000000ull, // Late launch primary
+ LLSBit = 0x2000000000000000ull, // Late launch secondary
+ LQABit = 0x1000000000000000ull, // Local quiesce achieved
+ SULBit = 0x0800000000000000ull, // Security update lock
+ L4ABit = 0x0400000000000000ull, // Locality 4 access
+ SDBBit = 0x0200000000000000ull, // Secure chip debug mode
+ CMFSIBit = 0x0100000000000000ull, // cMFSI access protection
+ ABUSBit = 0x0080000000000000ull, // Abus mailbox protection
+ RNGBit = 0x0040000000000000ull, // Random number generator lock
+ // Spare = 0x0020000000000000ull,
+ // Spare = 0x0010000000000000ull,
+ TDPBit = 0x0008000000000000ull, // TPM deconfig protection
+ // Spare = 0x0004000000000000ull,
+ // Spare = 0x0002000000000000ull,
+ // Spare = 0x0001000000000000ull,
+
+ SwitchRegister = 0x00010005ull,
+ SwitchRegisterClear = 0x00010006ull,
+ };
+
+ enum class ProcCbsControl : uint64_t
+ {
+ SabBit = 0x0800000000000000ull, // Secure access
+ JumperStateBit = 0x0400000000000000ull, // Secure jumper
+
+ StatusRegister = 0x00050001ull,
+ };
+
/** @class Settings
*
* @brief Caches and parses the hardware settings for Secureboot.
@@ -58,6 +92,23 @@ namespace SECUREBOOT
TARGETING::Target* i_targ
= TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) const;
+ /**
+ * @brief Clear bits in the processor security swith register. See
+ * full documentation in service.H.
+ */
+ errlHndl_t clearSecuritySwitchBits(
+ const std::vector<SECUREBOOT::ProcSecurity>& i_bits,
+ TARGETING::Target* i_pTarget =
+ TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) const;
+ /**
+ * @brief Set bits in the processor security swith register. See
+ * full documentation in service.H.
+ */
+ errlHndl_t setSecuritySwitchBits(
+ const std::vector<SECUREBOOT::ProcSecurity>& i_bits,
+ TARGETING::Target* i_pTarget =
+ TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) const;
+
/** @brief Returns the state of the secure jumper as reported by the
* given processor. See wrapper in Secureboot's service.H
* for documenation.
@@ -91,6 +142,28 @@ namespace SECUREBOOT
const uint64_t i_scomAddress,
uint64_t& o_regValue) const;
+ /**
+ * @brief Write a generic security related register
+ *
+ * @par Detailed Description:
+ * Writes a given security register given a proc target, SCOM
+ * address, and value.
+ *
+ * @param[in] i_pTarget Processor target to write. Must be either
+ * the master processor target sentinel or valid processor
+ * target. Must not be NULL.
+ * @param[in] i_scomAddress SCOM address to write
+ * @param[in] i_data Data to write to given SCOM address
+ *
+ * @return errHndl_t Error log handle indicating success or failure
+ * @retval nullptr Wrote data to SCOM address successfully
+ * @retval !nullptr Error log providing failure details
+ */
+ errlHndl_t writeSecurityRegister(
+ TARGETING::Target* i_pTarget,
+ uint64_t i_scomAddress,
+ uint64_t i_data) const;
+
/** Cached secure boot enabled value */
bool iv_enabled;
};
diff --git a/src/makefile b/src/makefile
index 6a1040291..de74f6420 100644
--- a/src/makefile
+++ b/src/makefile
@@ -198,7 +198,7 @@ EXTENDED_MODULES += p9_stop_util
EXTENDED_MODULES += isteps_mss
EXTENDED_MODULES += p9_cpuWkup
EXTENDED_MODULES += $(if $(CONFIG_ENABLE_HDAT_IN_HOSTBOOT),hdat)
-
+EXTENDED_MODULES += $(if $(CONFIG_SECUREBOOT),secureboot_ext)
#***************************************
# Working test modules
diff --git a/src/usr/i2c/tpmdd.C b/src/usr/i2c/tpmdd.C
index 3e34a357b..fc67ff59c 100755
--- a/src/usr/i2c/tpmdd.C
+++ b/src/usr/i2c/tpmdd.C
@@ -795,7 +795,7 @@ errlHndl_t tpmWrite ( void * i_buffer,
{
TRACFCOMP(g_trac_tpmdd,
ERR_MRK"tpmWrite(): I2C Write-Offset! "
- "p/e/dA=%d/%d/0x%X, OP=%d, ",
+ "p/e/dA=%d/%d/0x%X, OP=%d, "
"offset=0x%X, aS=%d, len=%d",
i_tpmInfo.port,
i_tpmInfo.engine, i_tpmInfo.devAddr,
diff --git a/src/usr/initservice/extinitsvc/extinitsvctasks.H b/src/usr/initservice/extinitsvc/extinitsvctasks.H
index 02050f6b6..4b326e2fc 100644
--- a/src/usr/initservice/extinitsvc/extinitsvctasks.H
+++ b/src/usr/initservice/extinitsvc/extinitsvctasks.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2016 */
+/* Contributors Listed Below - COPYRIGHT 2011,2017 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -70,6 +70,20 @@ const TaskInfo g_exttaskinfolist[] = {
},
#endif
+#ifdef CONFIG_SECUREBOOT
+ /**
+ * @brief Secureboot extended
+ */
+ {
+ "libsecureboot_ext.so", // taskname
+ NULL, // no pointer to fn
+ {
+ INIT_TASK, // task type
+ EXT_IMAGE, // Extended Module
+ }
+ },
+#endif
+
/**
* @brief targeting task,
*/
diff --git a/src/usr/isteps/istep06/host_gard.C b/src/usr/isteps/istep06/host_gard.C
index 0b6464d2c..f8dc30f1b 100644
--- a/src/usr/isteps/istep06/host_gard.C
+++ b/src/usr/isteps/istep06/host_gard.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -53,6 +53,10 @@
// Custom compile configs
#include <config.h>
+#ifdef CONFIG_DRTM
+#include <secureboot/drtm.H>
+#endif
+
#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS
#include <hwpf/hwp/occ/occ.H>
#include <hwpf/hwp/occ/occ_common.H>
@@ -203,6 +207,22 @@ void* host_gard( void *io_pArgs )
msg_free(core_msg);
break;
}
+
+#ifdef CONFIG_DRTM
+ bool drtmMpipl = false;
+ SECUREBOOT::DRTM::isDrtmMpipl(drtmMpipl);
+ if(drtmMpipl)
+ {
+ l_err = SECUREBOOT::DRTM::validateDrtmHwSignature();
+ if(l_err)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, ERR_MRK
+ "host_gard: Failed in call to validateDrtmHwSignature");
+ break;
+ }
+ }
+#endif
+
} while (0);
if (l_err)
diff --git a/src/usr/isteps/istep14/call_host_mpipl_service.C b/src/usr/isteps/istep14/call_host_mpipl_service.C
index af29cb5be..6be572e45 100644
--- a/src/usr/isteps/istep14/call_host_mpipl_service.C
+++ b/src/usr/isteps/istep14/call_host_mpipl_service.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,6 +40,12 @@
#include <vfs/vfs.H>
#include <dump/dumpif.H>
+#include <config.h>
+
+#ifdef CONFIG_DRTM
+#include <secureboot/drtm.H>
+#endif
+
using namespace ISTEP;
using namespace ISTEP_ERROR;
using namespace ERRORLOG;
@@ -88,6 +94,40 @@ void* call_host_mpipl_service (void *io_pArgs)
}
+#ifdef CONFIG_DRTM
+
+ if(!l_err)
+ {
+ do {
+
+ bool drtmMpipl = false;
+ SECUREBOOT::DRTM::isDrtmMpipl(drtmMpipl);
+ if(drtmMpipl)
+ {
+ l_err = SECUREBOOT::DRTM::validateDrtmPayload();
+ if(l_err)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, ERR_MRK
+ "call_host_mpipl_service: Failed in call to "
+ "validateDrtmPayload()");
+ break;
+ }
+
+ l_err = SECUREBOOT::DRTM::completeDrtm();
+ if(l_err)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, ERR_MRK
+ "call_host_mpipl_service: Failed in call to "
+ "completeDrtm()" );
+ break;
+ }
+ }
+
+ } while(0);
+ }
+
+#endif
+
//Determine if we should perform dump ops
//Note that this is only called in MPIPL context, so don't
//have to check MPIPL
diff --git a/src/usr/isteps/istep21/call_host_start_payload.C b/src/usr/isteps/istep21/call_host_start_payload.C
index 776159ca5..3dcdd83b0 100644
--- a/src/usr/isteps/istep21/call_host_start_payload.C
+++ b/src/usr/isteps/istep21/call_host_start_payload.C
@@ -52,6 +52,11 @@
#include <fapi2/plat_hwp_invoker.H>
#include <p9_cpu_special_wakeup.H>
#include <ipmi/ipmiwatchdog.H>
+#include <config.h>
+
+#ifdef CONFIG_DRTM_TRIGGERING
+#include <secureboot/drtm.H>
+#endif
using namespace ERRORLOG;
@@ -195,6 +200,40 @@ void* call_host_start_payload (void *io_pArgs)
l_errl = INITSERVICE::executeUnitTests();
}
+#ifdef CONFIG_DRTM_TRIGGERING
+
+ if(l_errl == nullptr)
+ {
+ bool drtmMpipl = false;
+ SECUREBOOT::DRTM::isDrtmMpipl(drtmMpipl);
+ if(!drtmMpipl)
+ {
+ TARGETING::Target* pSysTarget = nullptr;
+ TARGETING::targetService().getTopLevelTarget(pSysTarget);
+ if(pSysTarget == nullptr)
+ {
+ assert(false,"call_host_start_payload: BUG! System target was "
+ "nullptr.");
+ }
+
+ auto forceDrtm = pSysTarget->getAttr<
+ TARGETING::ATTR_FORCE_PRE_PAYLOAD_DRTM>();
+
+ if(forceDrtm)
+ {
+ l_errl = SECUREBOOT::DRTM::initiateDrtm();
+ if(l_errl)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, ERR_MRK
+ "call_host_start_payload: Failed in call to "
+ "initiateDrtm()");
+ }
+ }
+ }
+ }
+
+#endif
+
if( l_errl == NULL )
{
l_errl = disableSpecialWakeup();
diff --git a/src/usr/secureboot/HBconfig b/src/usr/secureboot/HBconfig
index ac092ad73..0ef8bc748 100644
--- a/src/usr/secureboot/HBconfig
+++ b/src/usr/secureboot/HBconfig
@@ -3,3 +3,17 @@ config SECUREBOOT
default y
help
Enable secure boot
+
+config DRTM #TODO RTC: 170487 Disable for relevant platforms
+ default y if (SECUREBOOT && TPMDD)
+ depends on (SECUREBOOT && TPMDD)
+ help
+ Enable DRTM support
+
+config DRTM_TRIGGERING #TODO RTC: 170487 Disable for relevant platforms
+ default y if DRTM
+ depends on DRTM
+ help
+ Enable triggering DRTM from Hostboot when the
+ ATTR_FORCE_PRE_PAYLOAD_DRTM attribute is overridden
+
diff --git a/src/usr/secureboot/base/service.C b/src/usr/secureboot/base/service.C
index a381c4fd2..54b7d7fb7 100644
--- a/src/usr/secureboot/base/service.C
+++ b/src/usr/secureboot/base/service.C
@@ -109,6 +109,22 @@ errlHndl_t getJumperState(SecureJumperState& o_state, TARGETING::Target* i_targ)
return Singleton<Settings>::instance().getJumperState(o_state, i_targ);
}
+errlHndl_t clearSecuritySwitchBits(
+ const std::vector<SECUREBOOT::ProcSecurity>& i_bits,
+ TARGETING::Target* const i_pTarget)
+{
+ return Singleton<Settings>::instance().clearSecuritySwitchBits(
+ i_bits, i_pTarget);
+}
+
+errlHndl_t setSecuritySwitchBits(
+ const std::vector<SECUREBOOT::ProcSecurity>& i_bits,
+ TARGETING::Target* const i_pTarget)
+{
+ return Singleton<Settings>::instance().setSecuritySwitchBits(
+ i_bits, i_pTarget);
+}
+
void handleSecurebootFailure(errlHndl_t &io_err, bool i_waitForShutdown)
{
TRACFCOMP( g_trac_secure, ENTER_MRK"handleSecurebootFailure()");
diff --git a/src/usr/secureboot/base/settings.C b/src/usr/secureboot/base/settings.C
index bd8f129f0..83e5365e3 100644
--- a/src/usr/secureboot/base/settings.C
+++ b/src/usr/secureboot/base/settings.C
@@ -129,6 +129,141 @@ namespace SECUREBOOT
return l_errl;
}
+ errlHndl_t Settings::clearSecuritySwitchBits(
+ const std::vector<SECUREBOOT::ProcSecurity>& i_bits,
+ TARGETING::Target* const i_pTarget) const
+ {
+ uint64_t bitsToClear = 0;
+ for(const auto &bit : i_bits)
+ {
+ bitsToClear |= static_cast<uint64_t>(bit);
+ }
+
+ auto pError = writeSecurityRegister(
+ i_pTarget,
+ static_cast<uint64_t>(ProcSecurity::SwitchRegisterClear),
+ bitsToClear);
+
+ if(pError)
+ {
+ SB_ERR("clearSecuritySwitchBits: writeSecurityRegister "
+ "(SwitchRegisterClear) failed. Target HUID = 0x%08X, data = "
+ "0x%016llX.",
+ get_huid(i_pTarget),bitsToClear);
+ SB_ERR("clearSecuritySwitchBits: plid=0x%08X, eid=0x%08X, "
+ "reason=0x%04X",
+ ERRL_GETPLID_SAFE(pError),
+ ERRL_GETEID_SAFE(pError),
+ ERRL_GETRC_SAFE(pError));
+ }
+
+ return pError;
+ }
+
+ errlHndl_t Settings::setSecuritySwitchBits(
+ const std::vector<SECUREBOOT::ProcSecurity>& i_bits,
+ TARGETING::Target* const i_pTarget) const
+ {
+ uint64_t bitsToSet = 0;
+ for(const auto &bit : i_bits)
+ {
+ bitsToSet |= static_cast<uint64_t>(bit);
+ }
+
+ auto pError = writeSecurityRegister(
+ i_pTarget,
+ static_cast<uint64_t>(ProcSecurity::SwitchRegister),
+ bitsToSet);
+
+ if(pError)
+ {
+ SB_ERR("setSecuritySwitchBits: writeSecurityRegister "
+ "(SwitchRegister) failed. Target HUID = 0x%08X, data = "
+ "0x%016llX.",
+ get_huid(i_pTarget),bitsToSet);
+ SB_ERR("setSecuritySwitchBits: plid=0x%08X, eid=0x%08X, "
+ "reason=0x%04X",
+ ERRL_GETPLID_SAFE(pError),
+ ERRL_GETEID_SAFE(pError),
+ ERRL_GETRC_SAFE(pError));
+ }
+
+ return pError;
+ }
+
+ errlHndl_t Settings::writeSecurityRegister(
+ TARGETING::Target* const i_pTarget,
+ const uint64_t i_scomAddress,
+ const uint64_t i_data) const
+ {
+ errlHndl_t pError = nullptr;
+
+ do
+ {
+
+ // Target must be the sentinel or some other non-NULL proc value
+ if ( (i_pTarget != TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL)
+ && ( (i_pTarget == nullptr)
+ || ( (i_pTarget->getAttr<TARGETING::ATTR_TYPE>())
+ != (TARGETING::TYPE_PROC) ) ) )
+ {
+ SB_ERR("writeSecurityRegister: Caller invoked API with bad target; "
+ "Target HUID = 0x%08X.",get_huid(i_pTarget));
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid SECUREBOOT::MOD_SECURE_WRITE_REG
+ * @reasoncode SECUREBOOT::RC_SECURE_BAD_TARGET
+ * @userdata1 Target pointer value
+ * @userdata2 Target's HUID or 0 if NULL target pointer
+ * @devdesc Invalid target used to write security
+ * register.
+ * @custdesc Unexpected internal firmware error.
+ */
+ pError = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SECUREBOOT::MOD_SECURE_WRITE_REG,
+ SECUREBOOT::RC_SECURE_BAD_TARGET,
+ reinterpret_cast<uint64_t>(i_pTarget),
+ TO_UINT64(get_huid(i_pTarget)),
+ true);
+ pError->collectTrace(SECURE_COMP_NAME, ERROR_TRACE_SIZE);
+ break;
+ }
+
+ // Write security switch settings to processor
+ const size_t expSize = sizeof(i_data);
+ size_t actSize = expSize;
+ pError = deviceWrite(
+ i_pTarget,
+ const_cast<uint64_t*>(&i_data), actSize,
+ DEVICE_SCOM_ADDRESS(i_scomAddress));
+ if (nullptr != pError)
+ {
+ SB_ERR("writeSecurityRegister: deviceWrite failed; target HUID = "
+ "0x%08X, SCOM addr = 0x%016llX, data = 0x%016llX.",
+ get_huid(i_pTarget),i_scomAddress,i_data);
+ break;
+ }
+
+ assert(actSize == expSize,
+ "writeSecurityRegister: BUG! size returned from device write (%d) "
+ "is not the expected size of %d",actSize,expSize);
+
+ } while(0);
+
+ if(pError)
+ {
+ SB_ERR("writeSecurityRegister: plid=0x%08X, eid=0x%08X, "
+ "reason=0x%04X",
+ ERRL_GETPLID_SAFE(pError),
+ ERRL_GETEID_SAFE(pError),
+ ERRL_GETRC_SAFE(pError));
+ }
+
+ return pError;
+ }
+
errlHndl_t Settings::readSecurityRegister(Target* i_targ,
const uint64_t i_scomAddress,
uint64_t& o_regValue) const
diff --git a/src/usr/secureboot/common/securetrace.H b/src/usr/secureboot/common/securetrace.H
index 17c6988c7..06d3bc6b5 100644
--- a/src/usr/secureboot/common/securetrace.H
+++ b/src/usr/secureboot/common/securetrace.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -61,4 +61,10 @@ extern trace_desc_t* g_trac_secure;
#define SB_DBG_BIN(args...) \
TRACDBIN(SECUREBOOT::g_trac_secure,args)
+#define SB_UNIT(args...) \
+ TRACUCOMP(SECUREBOOT::g_trac_secure,"U> " args)
+
+#define SB_UNIT_BIN(args...) \
+ TRACUBIN(SECUREBOOT::g_trac_secure,args)
+
#endif
diff --git a/src/usr/secureboot/ext/drtm.C b/src/usr/secureboot/ext/drtm.C
new file mode 100644
index 000000000..1497e35e3
--- /dev/null
+++ b/src/usr/secureboot/ext/drtm.C
@@ -0,0 +1,723 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/ext/drtm.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* [+] 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. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include <stdint.h>
+#include <config.h>
+#include <builtins.h>
+#include <limits.h>
+#include <string.h>
+#include <vector>
+#include <algorithm>
+
+#include <sys/mm.h>
+#include <sys/task.h>
+#include <util/align.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <targeting/common/util.H>
+#include <targeting/common/utilFilter.H>
+#include <targeting/common/commontargeting.H>
+#include <arch/pirformat.H>
+#include <initservice/mboxRegs.H>
+#include <util/utilmbox_scratch.H>
+#include <secureboot/settings.H>
+#include <secureboot/service.H>
+#include <secureboot/secure_reasoncodes.H>
+#include <secureboot/trustedbootif.H>
+#include <secureboot/drtm.H>
+
+#include "../common/securetrace.H"
+
+// Set to "1" to enable unit tracing
+#if 0
+ // Enable SB_UNIT
+ #define TRACUCOMP(args...) TRACFCOMP(args)
+ // Enable SB_UNIT_BIN
+ #define TRACUBIN(args...) TRACFBIN(args)
+#else
+ #define TRACUCOMP(args...)
+ #define TRACUBIN(args...)
+#endif
+
+// Makes the math more intuitive
+#define BYTES_PER_MEGABYTE MEGABYTE
+
+namespace SECUREBOOT
+{
+
+namespace DRTM
+{
+
+#ifdef CONFIG_DRTM_TRIGGERING
+
+// RIT protection DRTM payload address in megabytes
+// Use reserved area immediately before payload base
+const uint32_t DRTM_RIT_PAYLOAD_PHYS_ADDR_MB = 256-1;
+
+// RIT protection payload
+const char DRTM_RIT_PAYLOAD[] = {'D','R','T','M'};
+
+const char* const DRTM_RIT_LOG_TEXT = "DrtmPayload";
+
+#endif
+
+errlHndl_t discoverDrtmState(
+ const INITSERVICE::SPLESS::MboxScratch7_t& i_scratchReg7,
+ const INITSERVICE::SPLESS::MboxScratch8_t& i_scratchReg8)
+{
+ SB_ENTER("discoverDrtmState: i_scratchReg7=0x%08X, "
+ "i_scratchReg8 = 0x%08X",
+ i_scratchReg7.data32,i_scratchReg8.data32);
+
+ errlHndl_t pError = nullptr;
+
+ do
+ {
+
+ TARGETING::Target* pSysTarget = nullptr;
+ TARGETING::targetService().getTopLevelTarget(pSysTarget);
+
+ if(pSysTarget == nullptr)
+ {
+ // TODO: RTC 167205: GA error handling
+ assert(false,"discoverDrtmState: BUG! nullptr system target detected.");
+ break;
+ }
+
+ TARGETING::Target* pMasterProc = nullptr;
+ pError = TARGETING::targetService().queryMasterProcChipTargetHandle(
+ pMasterProc);
+ if(pError)
+ {
+ SB_ERR("discoverDrtmState: Failed in call to "
+ "queryMasterProcChipTargetHandle().");
+ break;
+ }
+
+ uint64_t securitySwitches = 0;
+ pError = SECUREBOOT::getSecuritySwitch(securitySwitches,
+ pMasterProc);
+ if(pError)
+ {
+ SB_ERR("discoverDrtmState: Failed in call to getSecuritySwitch() for "
+ "proc = 0x%08X.",
+ get_huid(pMasterProc));
+ break;
+ }
+
+ const bool masterProcL4A = securitySwitches
+ & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::L4ABit);
+ const bool masterProcLQA = securitySwitches
+ & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::LQABit);
+ const bool masterProcLLP = securitySwitches
+ & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::LLPBit);
+
+ const bool drtmPayloadValid = i_scratchReg8.validDrtmPayloadAddr;
+ const bool isMpiplBoot = pSysTarget->getAttr<TARGETING::ATTR_IS_MPIPL_HB>();
+ const bool securebootEnabled = SECUREBOOT::enabled();
+
+ SB_INF("discoverDrtmState: masterProcL4A = %d, drtmPayloadValid = %d, "
+ "isMpiplBoot = %d, securebootEnabled = %d, "
+ "masterProcLQA = %d, i_scratchReg7 = 0x%08X, "
+ "masterProcLLP = %d.",
+ masterProcL4A,drtmPayloadValid,isMpiplBoot,
+ securebootEnabled,masterProcLQA,i_scratchReg7.drtmPayloadAddrMb,
+ masterProcLLP);
+
+ TARGETING::ATTR_IS_DRTM_MPIPL_HB_type drtmMpIpl = false;
+ if(masterProcL4A || drtmPayloadValid)
+ {
+ // Note: We don't care if trusted boot is not enabled, if not, the
+ // measurement will simply be ignored later
+ if( !masterProcL4A
+ || !drtmPayloadValid
+ || !isMpiplBoot
+ || !securebootEnabled
+ || !masterProcLQA
+ || masterProcLLP)
+ {
+ // TODO: RTC 167205: GA error handling
+ assert(false,"discoverDrtmState: BUG! Inconsistent DRTM state "
+ "detected. masterProcL4A = %d, drtmPayloadValid = %d, "
+ "isMpiplBoot = %d, securebootEnabled = %d, "
+ "masterProcLQA = %d, masterProcLLP = %d.",
+ masterProcL4A,drtmPayloadValid,isMpiplBoot,
+ securebootEnabled,masterProcLQA,masterProcLLP);
+ break;
+ }
+ else
+ {
+ drtmMpIpl = true;
+ }
+ }
+
+ if( drtmMpIpl
+ && (i_scratchReg7.drtmPayloadAddrMb == 0))
+ {
+ // TODO: RTC 167205: GA error handling
+ assert(false,"discoverDrtmState: BUG! DRTM payload address "
+ "should not be 0 on a DRTM boot.");
+ break;
+ }
+
+ const auto drtmPayloadAddrMb = drtmMpIpl ?
+ i_scratchReg7.drtmPayloadAddrMb : 0;
+
+ pSysTarget->setAttr<TARGETING::ATTR_IS_DRTM_MPIPL_HB>(drtmMpIpl);
+ pSysTarget->setAttr<TARGETING::ATTR_DRTM_PAYLOAD_ADDR_MB_HB>(
+ drtmPayloadAddrMb);
+
+ // NOTE: It should be SBE job to clear the DRTM scratch regs
+ // on any given non-DRTM boot flow, hence Hostboot never has to clear them.
+
+ } while(0);
+
+ if(pError)
+ {
+ SB_ERR("discoverDrtmState: plid=0x%08X, eid=0x%08X, reason=0x%04X",
+ ERRL_GETPLID_SAFE(pError),
+ ERRL_GETEID_SAFE(pError),
+ ERRL_GETRC_SAFE(pError));
+ }
+
+ SB_EXIT("discoverDrtmState");
+
+ return pError;
+}
+
+void isDrtmMpipl(bool& o_isDrtmMpipl)
+{
+ TARGETING::Target* pSysTarget = nullptr;
+ TARGETING::targetService().getTopLevelTarget(pSysTarget);
+
+ if(pSysTarget == nullptr)
+ {
+ // TODO: RTC 167205: GA error handling
+ assert(false,"isDrtmMpipl: BUG! nullptr system target detected");
+ }
+
+ o_isDrtmMpipl = pSysTarget->getAttr<TARGETING::ATTR_IS_DRTM_MPIPL_HB>();
+}
+
+errlHndl_t validateDrtmHwSignature()
+{
+ SB_ENTER("validateDrtmHwSignature");
+
+ errlHndl_t pError = nullptr;
+
+ do
+ {
+ bool drtmMpIpl = false;
+ isDrtmMpipl(drtmMpIpl);
+
+ if(drtmMpIpl)
+ {
+ SB_DBG("validateDrtmHwSignature: DRTM active, checking L4A, LQA, "
+ "SUL, LLS and LLP on node's functional proc chips.");
+
+ TARGETING::TargetHandleList funcProcChips;
+ TARGETING::getAllChips(funcProcChips,
+ TARGETING::TYPE_PROC);
+ for(auto &pFuncProc :funcProcChips)
+ {
+ uint64_t securitySwitches = 0;
+ pError = SECUREBOOT::getSecuritySwitch(securitySwitches,
+ pFuncProc);
+ if(pError)
+ {
+ SB_ERR("validateDrtmHwSignature: getSecuritySwitch() "
+ "failed for proc = 0x%08X.",
+ get_huid(pFuncProc));
+ break;
+ }
+
+ const bool L4A = securitySwitches
+ & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::L4ABit);
+ const bool LQA = securitySwitches
+ & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::LQABit);
+ const bool SUL = securitySwitches
+ & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::SULBit);
+ const bool LLP = securitySwitches
+ & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::LLPBit);
+ const bool LLS = securitySwitches
+ & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::LLSBit);
+
+ SB_INF("validateDrtmHwSignature: Proc 0x%08X has L4A = %d, "
+ "LQA = %d, SUL = %d, LLP = %d, LLS = %d.",
+ get_huid(pFuncProc),L4A,LQA,SUL,LLP,LLS);
+
+ if(!L4A || !LQA || !SUL || LLP || LLS)
+ {
+ // TODO: RTC 167205: GA error handling, including whether
+ // to attempt on every processor
+ assert(false,"validateDrtmHwSignature: BUG! In DRTM flow, "
+ "all functional proc chips should have L4A, LQA, and "
+ "SUL set + LLP and LLS clear, however proc 0x%08X has "
+ "L4A = %d, LQA = %d, SUL = %d, LLP = %d, LLS = %d.",
+ get_huid(pFuncProc),L4A,LQA,SUL,LLP,LLS);
+ break;
+ }
+ }
+
+ if(pError)
+ {
+ break;
+ }
+ }
+ else
+ {
+ SB_INF("validateDrtmHwSignature: DRTM not active, skipping check "
+ "for L4A, LQA, SUL, LLP and LLS on node's functional procs");
+ }
+
+ } while(0);
+
+ if(pError)
+ {
+ SB_ERR("validateDrtmHwSignature: plid=0x%08X, eid=0x%08X, "
+ "reason=0x%04X",
+ ERRL_GETPLID_SAFE(pError),
+ ERRL_GETEID_SAFE(pError),
+ ERRL_GETRC_SAFE(pError));
+ }
+
+ SB_EXIT("validateDrtmHwSignature");
+
+ return pError;
+}
+
+errlHndl_t validateDrtmPayload()
+{
+ SB_ENTER("validateDrtmPayload");
+
+ errlHndl_t pError = nullptr;
+ const void* drtmPayloadVirtAddr = nullptr;
+
+ do
+ {
+ bool drtmMpIpl = false;
+ isDrtmMpipl(drtmMpIpl);
+
+ if(drtmMpIpl)
+ {
+ SB_DBG("validateDrtmPayload: DRTM active, validating DRTM payload."
+ "proc chips.");
+
+ TARGETING::Target* pSysTarget = nullptr;
+ TARGETING::targetService().getTopLevelTarget(pSysTarget);
+
+ if(pSysTarget == nullptr)
+ {
+ // TODO: RTC 167205: GA error handling
+ assert(false,"validateDrtmPayload: BUG! nullptr system target "
+ "detected");
+ break;
+ }
+
+ const auto drtmPayloadPhysAddrMb = pSysTarget->getAttr<
+ TARGETING::ATTR_DRTM_PAYLOAD_ADDR_MB_HB>();
+
+ if(drtmPayloadPhysAddrMb == 0)
+ {
+ assert(false,"validateDrtmPayload: BUG! DRTM payload physical "
+ "address should not be 0.");
+ break;
+ }
+
+ const uint64_t drtmPayloadPhysAddr =
+ drtmPayloadPhysAddrMb*BYTES_PER_MEGABYTE;
+
+ SB_INF("validateDrtmPayload: DRTM payload available at physical "
+ "address of %d MB (0x%16llX).",
+ drtmPayloadPhysAddrMb,drtmPayloadPhysAddr);
+
+ // Compute DRTM payload size
+ // TODO: RTC 167205: Once the DRTM save area is known/defined,
+ // need to figure out a better initial size to map. For example,
+ // perhaps we map just one page to begin with, in order to read out
+ // the actual total size. Also, a size is available, assert if the
+ // size is 0.
+ uint64_t drtmPayloadSize = 0;
+ #ifdef CONFIG_DRTM_TRIGGERING
+ drtmPayloadSize = ALIGN_PAGE(sizeof(DRTM_RIT_PAYLOAD));
+ #endif
+
+ // Map in the physical memory to virtual memory
+ drtmPayloadVirtAddr = mm_block_map (
+ reinterpret_cast<void*>(drtmPayloadPhysAddr),drtmPayloadSize);
+ if(drtmPayloadVirtAddr == nullptr)
+ {
+ // TODO: RTC 167205: GA error handling
+ assert(false,"validateDrtmPayload: BUG! mm_block_map returned "
+ "nullptr for physical address 0x%016llX and size "
+ "0x%016llX.",
+ drtmPayloadPhysAddr,drtmPayloadSize);
+ break;
+ }
+
+ #ifdef CONFIG_DRTM_TRIGGERING
+
+ // Verify the payload matches expected result
+ if(memcmp(drtmPayloadVirtAddr,DRTM_RIT_PAYLOAD,
+ sizeof(DRTM_RIT_PAYLOAD) != 0))
+ {
+ const uint32_t* pAddrAct = reinterpret_cast<const uint32_t*>(
+ drtmPayloadVirtAddr);
+ const uint32_t* pAddrExp = reinterpret_cast<const uint32_t*>(
+ &DRTM_RIT_PAYLOAD);
+
+ SB_ERR("validateDrtmPayload: DRTM RIT: payload content at "
+ "0x%16llX was not as expected. Expected value = 0x%08X, "
+ "actual = 0x%08X",
+ drtmPayloadVirtAddr,
+ *pAddrAct,
+ *pAddrExp);
+
+ // TODO: RTC 167205: GA error handling
+ assert(false,"validateDrtmPayload: BUG: DRTM payload content "
+ "at 0x%16llX was not as expected. Expected value = "
+ "0x%08X, actual = 0x%08X",
+ drtmPayloadVirtAddr,
+ *pAddrAct,
+ *pAddrExp);
+ break;
+ }
+
+ // Extend (arbitrary) measurement to PCR17
+ SHA512_t hash = {0};
+ memcpy(hash,DRTM_RIT_PAYLOAD,sizeof(DRTM_RIT_PAYLOAD));
+ pError = TRUSTEDBOOT::pcrExtend(TRUSTEDBOOT::PCR_DRTM_17, hash,
+ sizeof(SHA512_t),DRTM_RIT_LOG_TEXT);
+ if(pError)
+ {
+ SB_ERR("validateDrtmPayload: Failed in pcrExtend() for PCR 17");
+ break;
+ }
+
+ #else
+
+ // TODO: RTC 167205: Securely verify the measured launch environment
+ // TODO: RTC 167205: Really measure+extend the payload
+
+ #endif
+ }
+ else
+ {
+ SB_INF("validateDrtmPayload: DRTM not active, skipping DRTM "
+ "payload verification ");
+ }
+
+ } while(0);
+
+ if(drtmPayloadVirtAddr)
+ {
+ auto rc = mm_block_unmap(const_cast<void*>(drtmPayloadVirtAddr));
+ if(rc != 0)
+ {
+ // TODO: RTC 167205: GA error handling
+ assert(false,"validateDrtmPayload: BUG! mm_block_unmap failed for "
+ "virtual address 0x%16llX.",
+ drtmPayloadVirtAddr);
+
+ }
+ }
+
+ if(pError)
+ {
+ SB_ERR("validateDrtmPayload: plid=0x%08X, eid=0x%08X, reason=0x%04X",
+ ERRL_GETPLID_SAFE(pError),
+ ERRL_GETEID_SAFE(pError),
+ ERRL_GETRC_SAFE(pError));
+ }
+
+ SB_EXIT("validateDrtmPayload");
+
+ return pError;
+}
+
+errlHndl_t completeDrtm()
+{
+ SB_ENTER("completeDrtm");
+
+ errlHndl_t pError = nullptr;
+
+ do
+ {
+ bool drtmMpIpl = false;
+ isDrtmMpipl(drtmMpIpl);
+
+ if(drtmMpIpl)
+ {
+ SB_INF("completeDrtm: Clearing L4A and LQA on node's functional "
+ "proc chips.");
+
+ const std::vector<SECUREBOOT::ProcSecurity> bitsToClear {
+ SECUREBOOT::ProcSecurity::L4ABit,
+ SECUREBOOT::ProcSecurity::LQABit
+ };
+
+ TARGETING::TargetHandleList funcProcChips;
+ TARGETING::getAllChips(funcProcChips,
+ TARGETING::TYPE_PROC);
+
+ for(auto &pFuncProc :funcProcChips)
+ {
+ pError = SECUREBOOT::clearSecuritySwitchBits(bitsToClear,
+ pFuncProc);
+ if(pError)
+ {
+ // TODO: RTC 167205: GA error handling to attempt on every
+ // processor
+ SB_ERR("completeDrtm: clearSecuritySwitchBits() failed for "
+ "proc = 0x%08X. Tried to clear LQA + L4A.",
+ get_huid(pFuncProc));
+ break;
+ }
+ }
+
+ if(pError)
+ {
+ break;
+ }
+
+ }
+ else
+ {
+ SB_INF("completeDrtm: DRTM not active, not clearing LQA or L4A "
+ "bits.");
+ }
+
+ } while(0);
+
+ if(pError)
+ {
+ SB_ERR("completeDrtm: plid=0x%08X, eid=0x%08X, reason=0x%04X",
+ ERRL_GETPLID_SAFE(pError),
+ ERRL_GETEID_SAFE(pError),
+ ERRL_GETRC_SAFE(pError));
+ }
+
+ SB_EXIT("completeDrtm");
+
+ return pError;
+}
+
+#ifdef CONFIG_DRTM_TRIGGERING
+
+errlHndl_t initiateDrtm()
+{
+ SB_ENTER("initiateDrtm");
+
+ errlHndl_t pError = nullptr;
+
+ // For DRTM, the thread has to be pinned to a core (and therefore pinned to
+ // a chip)
+ task_affinity_pin();
+
+ void* drtmPayloadVirtAddr = nullptr;
+
+ do
+ {
+ const std::vector<SECUREBOOT::ProcSecurity> LLP {
+ SECUREBOOT::ProcSecurity::LLPBit,
+ };
+
+ const std::vector<SECUREBOOT::ProcSecurity> LLS {
+ SECUREBOOT::ProcSecurity::LLSBit,
+ };
+
+ // Determine which fabric group and chip this task is executing on and
+ // create a filter to find the matching chip target
+ auto cpuId = task_getcpuid();
+ auto groupId = PIR_t::groupFromPir(cpuId);
+ auto chipId = PIR_t::chipFromPir(cpuId);
+ TARGETING::PredicateAttrVal<TARGETING::ATTR_FABRIC_GROUP_ID>
+ matchesGroup(groupId);
+ TARGETING::PredicateAttrVal<TARGETING::ATTR_FABRIC_CHIP_ID>
+ matchesChip(chipId);
+ TARGETING::PredicatePostfixExpr matchesGroupAndChip;
+ matchesGroupAndChip.push(&matchesGroup).push(&matchesChip).And();
+
+ // Get all the functional proc chips and find the chip we're running on
+ TARGETING::TargetHandleList funcProcChips;
+ TARGETING::getAllChips(funcProcChips,
+ TARGETING::TYPE_PROC);
+ if(funcProcChips.empty())
+ {
+ // TODO: RTC 167205: GA error handling
+ assert(false,"initiateDrtm: BUG! Functional proc chips is empty, "
+ "yet this code is running on a functional chip!");
+ break;
+ }
+
+ // NOTE: std::find_if requires predicates to be copy constructable, but
+ // predicates are not; hence use a wrapper lambda function to bypass
+ // that limitation
+ auto pMatch =
+ std::find_if(funcProcChips.begin(),funcProcChips.end(),
+ [&matchesGroupAndChip] ( TARGETING::Target* pTarget )
+ {
+ return matchesGroupAndChip(pTarget);
+ } );
+
+ if(pMatch == funcProcChips.end())
+ {
+ // TODO: RTC 167205: GA error handling
+ assert(false, "initiateDrtm: BUG! No functional chip found "
+ "to be running this code");
+ break;
+ }
+
+ // Move the matching target to the end of the list.
+ // NOTE: If reverse iterators were supported, we could have verified the
+ // last element of the container is not the match, and done a
+ // std::iter_swap of the match and the last element
+ TARGETING::Target* const pMatchTarget = *pMatch;
+ funcProcChips.erase(pMatch);
+ funcProcChips.push_back(pMatchTarget);
+
+ // Map to the DRTM payload area in mainstore
+ const uint32_t drtmPayloadPhysAddrMb = DRTM_RIT_PAYLOAD_PHYS_ADDR_MB;
+ drtmPayloadVirtAddr = mm_block_map(
+ reinterpret_cast<void*>(drtmPayloadPhysAddrMb*BYTES_PER_MEGABYTE),
+ PAGESIZE);
+ if(drtmPayloadVirtAddr == nullptr)
+ {
+ // TODO: RTC 167205: GA error handling
+ assert(false, "initiateDrtm: BUG! Failed in call to mm_block_map "
+ "to map the DRTM payload.");
+ break;
+ }
+
+ // Copy the DRTM payload to the DRTM payload area
+ memcpy(
+ reinterpret_cast<uint32_t*>(drtmPayloadVirtAddr),
+ DRTM_RIT_PAYLOAD,
+ sizeof(DRTM_RIT_PAYLOAD));
+
+ // The required generic sequencing to initiate DRTM is as follows:
+ // 1) Initiating task must pin itself to a core (to ensure it
+ // will not be accidentally queisced by SBE)
+ // 2) It must set the DRTM payload information in the master processor
+ // mailbox scratch registers (registers 7 and 8) before it goes
+ // offline
+ // 3) It must determine the processor it's currently running on
+ // 4) It must set the late launch bit (LL) on all other processors
+ // 4a) If the given processor is an active master, it must set
+ // late launch primary (LLP) bit
+ // 4b) Otherwise it must set late launch secondary (LLS) bit
+ // 5) Finally, it must its own processor's LL bit last, according to the
+ // rules of step 4.
+ for(auto &pFuncProc :funcProcChips)
+ {
+ const auto procMasterType = pFuncProc->getAttr<
+ TARGETING::ATTR_PROC_MASTER_TYPE>();
+
+ // If master chip, set the DRTM payload address and validity
+ if(procMasterType == TARGETING::PROC_MASTER_TYPE_ACTING_MASTER)
+ {
+ (void)setDrtmPayloadPhysAddrMb(drtmPayloadPhysAddrMb);
+ }
+
+ pError = SECUREBOOT::setSecuritySwitchBits(procMasterType ==
+ TARGETING::PROC_MASTER_TYPE_ACTING_MASTER ?
+ LLP : LLS,
+ pFuncProc);
+ if(pError)
+ {
+ SB_ERR("initiateDrtm: setSecuritySwitchBits() failed for proc "
+ "= 0x%08X. Tried to set LLP or LLS.",
+ get_huid(pFuncProc));
+ break;
+ }
+ }
+
+ if(pError)
+ {
+ break;
+ }
+
+
+ SB_INF("initiateDrtm: SBE should eventually quiesce all cores; until "
+ "then, endlessly yield the task");
+ while(1)
+ {
+ task_yield();
+ }
+
+ } while(0);
+
+ // If we -do- come back from this function (on error path only), then we
+ // should unpin
+ task_affinity_unpin();
+
+ if(drtmPayloadVirtAddr)
+ {
+ auto rc = mm_block_unmap(const_cast<void*>(drtmPayloadVirtAddr));
+ if(rc != 0)
+ {
+ // TODO: RTC 167205: GA error handling
+ assert(false,"initiateDrtm: BUG! mm_block_unmap failed for virtual "
+ "address 0x%16llX.",
+ drtmPayloadVirtAddr);
+ }
+ }
+
+ if(pError)
+ {
+ SB_ERR("initiateDrtm: plid=0x%08X, eid=0x%08X, reason=0x%04X",
+ ERRL_GETPLID_SAFE(pError),
+ ERRL_GETEID_SAFE(pError),
+ ERRL_GETRC_SAFE(pError));
+ }
+
+ SB_EXIT("initiateDrtm");
+
+ return pError;
+}
+
+void setDrtmPayloadPhysAddrMb(
+ const uint32_t i_drtmPayloadPhysAddrMb)
+{
+ // Set the address
+ Util::writeScratchReg(
+ INITSERVICE::SPLESS::MBOX_SCRATCH_REG7,i_drtmPayloadPhysAddrMb);
+
+ // Mark as valid if non-0, else invalid
+ INITSERVICE::SPLESS::MboxScratch8_t scratch8 =
+ { .data32 = Util::readScratchReg(
+ INITSERVICE::SPLESS::MBOX_SCRATCH_REG8) };
+ scratch8.validDrtmPayloadAddr =
+ i_drtmPayloadPhysAddrMb ? true : false;
+ Util::writeScratchReg(
+ INITSERVICE::SPLESS::MBOX_SCRATCH_REG8,scratch8.data32);
+}
+
+#endif // CONFIG_DRTM_TRIGGERING
+
+} // End DRTM namespace
+
+} // End SECUREBOOT namespace
+
diff --git a/src/usr/secureboot/ext/makefile b/src/usr/secureboot/ext/makefile
index ddc0261cc..952a8cc56 100644
--- a/src/usr/secureboot/ext/makefile
+++ b/src/usr/secureboot/ext/makefile
@@ -5,7 +5,9 @@
#
# OpenPOWER HostBoot Project
#
-# COPYRIGHT International Business Machines Corp. 2013,2014
+# Contributors Listed Below - COPYRIGHT 2013,2017
+# [+] 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.
@@ -24,7 +26,7 @@ ROOTPATH = ../../../..
MODULE = secureboot_ext
SUBDIRS +=
-OBJS +=
+OBJS += $(if $(CONFIG_DRTM),drtm.o)
CFLAGS += -iquote ../
include ${ROOTPATH}/config.mk
diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C
index b6bbd313b..2009ab07a 100644
--- a/src/usr/secureboot/trusted/trustedboot.C
+++ b/src/usr/secureboot/trusted/trustedboot.C
@@ -56,6 +56,9 @@
#include "tpmLogMgr.H"
#include "base/trustedbootMsg.H"
#include <secureboot/settings.H>
+#ifdef CONFIG_DRTM
+#include <secureboot/drtm.H>
+#endif
namespace TRUSTEDBOOT
{
@@ -375,10 +378,18 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target)
io_target.initAttempted = true;
io_target.failed = false;
- bool drtm = false;
- /// @todo #157140 Add ability to check for DRTM
+ bool sendStartup = true;
+
+#ifdef CONFIG_DRTM
+ bool drtmMpipl = false;
+ (void)SECUREBOOT::DRTM::isDrtmMpipl(drtmMpipl);
+ if(drtmMpipl)
+ {
+ sendStartup = false;
+ }
+#endif
// Don't run STARTUP during DRTM
- if (!drtm)
+ if (sendStartup)
{
// TPM_STARTUP
err = tpmCmdStartup(&io_target);
@@ -395,11 +406,13 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target)
break;
}
+#ifdef CONFIG_DRTM
// For a DRTM we need to reset PCRs 17-22
- if (drtm)
+ if (drtmMpipl)
{
- /// @todo Implement PCR reset
+ /// @TODO RTC 167667 Implement PCR reset
}
+#endif
} while ( 0 );
@@ -596,7 +609,7 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target)
}
void pcrExtendSingleTpm(TpmTarget & io_target,
- TPM_Pcr i_pcr,
+ const TPM_Pcr i_pcr,
TPM_Alg_Id i_algId,
const uint8_t* i_digest,
size_t i_digestSize,
@@ -606,6 +619,26 @@ void pcrExtendSingleTpm(TpmTarget & io_target,
TCG_PCR_EVENT2 eventLog;
bool unlock = false;
+ TPM_Pcr pcr = i_pcr;
+ bool useStaticLog = true;
+
+#ifdef CONFIG_DRTM
+ // In a DRTM flow, all extensions must be re-rerouted to PCR 17
+ // (which will end up using locality 2).
+ bool drtmMpipl = false;
+ (void)SECUREBOOT::DRTM::isDrtmMpipl(drtmMpipl);
+ if(drtmMpipl)
+ {
+ TRACFCOMP(g_trac_trustedboot,
+ INFO_MRK " pcrExtendSingleTpm(): DRTM active; re-routing PCR %d "
+ "extend to PCR 17",
+ i_pcr);
+
+ pcr = PCR_DRTM_17;
+ useStaticLog = false;
+ }
+#endif
+
memset(&eventLog, 0, sizeof(eventLog));
do
{
@@ -617,22 +650,29 @@ void pcrExtendSingleTpm(TpmTarget & io_target,
!io_target.failed)
{
// Fill in TCG_PCR_EVENT2 and add to log
- eventLog = TpmLogMgr_genLogEventPcrExtend(i_pcr,
+ eventLog = TpmLogMgr_genLogEventPcrExtend(pcr,
i_algId, i_digest,
i_digestSize,
TPM_ALG_SHA1, i_digest,
i_digestSize,
i_logMsg);
- err = TpmLogMgr_addEvent(io_target.logMgr,&eventLog);
- if (NULL != err)
+ if(useStaticLog)
{
- break;
+ err = TpmLogMgr_addEvent(io_target.logMgr,&eventLog);
+ if (NULL != err)
+ {
+ break;
+ }
}
+ // TODO: RTC 145689: Add DRTM support for using dynamic
+ // log instead of static log; until then, inhibit DRTM logging
+ // entirely
+
// Perform the requested extension and also force into the
// SHA1 bank
err = tpmCmdPcrExtend2Hash(&io_target,
- i_pcr,
+ pcr,
i_algId,
i_digest,
i_digestSize,
@@ -685,16 +725,34 @@ void pcrExtendSeparator(TpmTarget & io_target)
mutex_lock( &io_target.tpmMutex );
unlock = true;
- for (TPM_Pcr curPcr = PCR_0; curPcr <= PCR_7;
- curPcr = static_cast<TPM_Pcr>(curPcr + 1))
+ std::vector<TPM_Pcr> pcrs =
+ {PCR_0,PCR_1,PCR_2,PCR_3,PCR_4,PCR_5,PCR_6,PCR_7};
+ bool useStaticLog = true;
+
+#ifdef CONFIG_DRTM
+ // In a DRTM flow, all extensions must be re-rerouted to PCR 17
+ // (which will end up using locality 2).
+ bool drtmMpipl = false;
+ (void)SECUREBOOT::DRTM::isDrtmMpipl(drtmMpipl);
+ if(drtmMpipl)
{
+ TRACFCOMP(g_trac_trustedboot,
+ INFO_MRK " pcrExtendSeparator(): DRTM active; extending "
+ "separator to PCR 17 instead of PCR 0..7.");
+
+ pcrs = { PCR_DRTM_17 };
+ useStaticLog = false;
+ }
+#endif
+ for (const auto &pcr : pcrs)
+ {
// Log the separator
if (io_target.available &&
!io_target.failed)
{
// Fill in TCG_PCR_EVENT2 and add to log
- eventLog = TpmLogMgr_genLogEventPcrExtend(curPcr,
+ eventLog = TpmLogMgr_genLogEventPcrExtend(pcr,
TPM_ALG_SHA1,
sha1_digest,
sizeof(sha1_digest),
@@ -702,15 +760,24 @@ void pcrExtendSeparator(TpmTarget & io_target)
sha256_digest,
sizeof(sha256_digest),
logMsg);
- err = TpmLogMgr_addEvent(io_target.logMgr,&eventLog);
- if (NULL != err)
+
+ if(useStaticLog)
{
- break;
+ err = TpmLogMgr_addEvent(io_target.logMgr,&eventLog);
+ if (NULL != err)
+ {
+ break;
+ }
}
+ // TODO: RTC 145689: Add DRTM support for using dynamic
+ // log (which will happen any time useStaticLog is false).
+ // Until then, we cannot log DRTM events, since they are only
+ // allowed to go to the dynamic log
+
// Perform the requested extension
err = tpmCmdPcrExtend2Hash(&io_target,
- curPcr,
+ pcr,
TPM_ALG_SHA1,
sha1_digest,
sizeof(sha1_digest),
diff --git a/src/usr/secureboot/trusted/trustedbootCmds.C b/src/usr/secureboot/trusted/trustedbootCmds.C
index 9e5875933..a052c0571 100644
--- a/src/usr/secureboot/trusted/trustedbootCmds.C
+++ b/src/usr/secureboot/trusted/trustedbootCmds.C
@@ -37,6 +37,8 @@
// ----------------------------------------------
#include <string.h>
#include <stdlib.h>
+#include <config.h>
+
#ifdef __HOSTBOOT_MODULE
#include <secureboot/trustedboot_reasoncodes.H>
#else
@@ -47,6 +49,10 @@
#include "trustedboot.H"
#include "trustedTypes.H"
+#ifdef CONFIG_DRTM
+#include <secureboot/drtm.H>
+#endif
+
#ifdef __cplusplus
namespace TRUSTEDBOOT
{
@@ -844,10 +850,26 @@ errlHndl_t tpmCmdPcrExtend2Hash(TpmTarget * io_target,
i_digestSize_2 : fullDigestSize_2));
}
+ tpm_locality_t tpmLocality = TPM_LOCALITY_0;
+#ifdef CONFIG_DRTM
+ bool drtmMpipl = false;
+ SECUREBOOT::DRTM::isDrtmMpipl(drtmMpipl);
+ if(drtmMpipl)
+ {
+ assert(i_pcr == TRUSTEDBOOT::PCR_DRTM_17,
+ "BUG! All DRTM extensions must be to PCR 17 (instead of %d)",
+ i_pcr);
+
+ TRACFCOMP(g_trac_trustedboot,
+ INFO_MRK " tpmCmdPcrExtend2Hash(): DRTM active, redirecting "
+ "PCR extend request from locality 0 to locality 2.");
+ tpmLocality = TPM_LOCALITY_2;
+ }
+#endif
err = tpmTransmitCommand(io_target,
dataBuf,
sizeof(dataBuf),
- TPM_LOCALITY_0);
+ tpmLocality);
if (TB_SUCCESS != err)
{
diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
index 8888fff33..94b571b17 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
@@ -1705,6 +1705,53 @@ ID for the sensor number returned with the elog. -->
</attribute>
<attribute>
+ <id>IS_DRTM_MPIPL_HB</id>
+ <description>
+ Indicates if this is a DRTM MPIPL flow or not.
+ 0x00 = Not a DRTM MPIPL
+ 0x01 = DRTM MPIPL
+ </description>
+ <simpleType>
+ <uint8_t><default>0</default></uint8_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
+<attribute>
+ <id>DRTM_PAYLOAD_ADDR_MB_HB</id>
+ <description>
+ Physical address of DRTM payload in megabytes. 0 MB is not considered to
+ be a valid DRTM payload address
+ </description>
+ <simpleType>
+ <uint32_t><default>0</default></uint32_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
+<attribute>
+ <id>FORCE_PRE_PAYLOAD_DRTM</id>
+ <description>
+ If Hostboot is compiled with CONFIG_DRTM_TRIGGERING, controls
+ whether Hostboot will initiate a DRTM late launch sequence in place of
+ loading the payload. This attribute should always be compiled in not to
+ force the late launch sequence; it is designed to be changed via
+ attribute overrides only, to facilitate testing.
+ 0x00: Do not force a DRTM late launch sequence
+ 0x01: Force a DRTM late launch sequence (if not a DRTM boot)
+ </description>
+ <simpleType>
+ <uint8_t><default>0</default></uint8_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+</attribute>
+
+<attribute>
<id>ATTN_CHK_ALL_PROCS</id>
<description>
Used to tell ATTN code whether to chk MASTER(0) OR all PROCs(1)
diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml
index 486b2c40a..811edd5fa 100755
--- a/src/usr/targeting/common/xmltohb/target_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml
@@ -81,6 +81,9 @@
<attribute><id>OCC_COMMON_AREA_PHYS_ADDR</id> </attribute>
<attribute><id>ATTN_CHK_ALL_PROCS</id> </attribute>
<attribute><id>MASTER_MBOX_SCRATCH</id> </attribute>
+ <attribute><id>IS_DRTM_MPIPL_HB</id></attribute>
+ <attribute><id>DRTM_PAYLOAD_ADDR_MB_HB</id></attribute>
+ <attribute><id>FORCE_PRE_PAYLOAD_DRTM</id></attribute>
</targetTypeExtension>
<targetTypeExtension>
diff --git a/src/usr/targeting/targetservicestart.C b/src/usr/targeting/targetservicestart.C
index 575d22e3d..62edd569c 100755
--- a/src/usr/targeting/targetservicestart.C
+++ b/src/usr/targeting/targetservicestart.C
@@ -55,7 +55,11 @@
#include <errl/errlmanager.H>
#include <devicefw/userif.H>
#include <config.h>
+#include <initservice/initserviceif.H>
+#ifdef CONFIG_DRTM
+#include <secureboot/drtm.H>
+#endif
using namespace INITSERVICE::SPLESS;
//******************************************************************************
@@ -151,6 +155,23 @@ static void initTargeting(errlHndl_t& io_pError)
l_pTopLevel->getAttrAsString<ATTR_MODEL>());
}
+#ifdef CONFIG_DRTM
+ const INITSERVICE::SPLESS::MboxScratch7_t scratch7 =
+ {.data32 = l_scratch[SCRATCH_7] };
+ const INITSERVICE::SPLESS::MboxScratch8_t scratch8 =
+ {.data32 = l_scratch[SCRATCH_8] };
+
+ errlHndl_t pError = SECUREBOOT::DRTM::discoverDrtmState(
+ scratch7,scratch8);
+ if(pError)
+ {
+ auto plid = pError->plid();
+ errlCommit(pError,SECURE_COMP_ID);
+ // TODO: RTC 167205: Better GA error handling
+ INITSERVICE::doShutdown(plid, true);
+ }
+#endif
+
// No error module loaded in VPO to save load time
#ifndef CONFIG_VPO_COMPILE
// call ErrlManager function - tell him that TARG is ready!
OpenPOWER on IntegriCloud