diff options
-rw-r--r-- | src/include/usr/secureboot/phys_presence_if.H | 68 | ||||
-rw-r--r-- | src/include/usr/secureboot/secure_reasoncodes.H | 19 | ||||
-rw-r--r-- | src/usr/gpio/gpio_pca9551.C | 2 | ||||
-rw-r--r-- | src/usr/gpio/gpiodd.C | 3 | ||||
-rw-r--r-- | src/usr/isteps/istep06/call_host_update_master_tpm.C | 28 | ||||
-rw-r--r-- | src/usr/isteps/istep10/call_host_update_redundant_tpm.C | 24 | ||||
-rw-r--r-- | src/usr/runtime/hdatstructs.H | 7 | ||||
-rw-r--r-- | src/usr/runtime/populate_hbruntime.C | 7 | ||||
-rw-r--r-- | src/usr/secureboot/HBconfig | 14 | ||||
-rw-r--r-- | src/usr/secureboot/ext/makefile | 3 | ||||
-rw-r--r-- | src/usr/secureboot/ext/phys_presence.C | 479 | ||||
-rwxr-xr-x | src/usr/targeting/common/xmltohb/attribute_types_hb.xml | 50 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/target_types_hb.xml | 9 |
13 files changed, 700 insertions, 13 deletions
diff --git a/src/include/usr/secureboot/phys_presence_if.H b/src/include/usr/secureboot/phys_presence_if.H new file mode 100644 index 000000000..a723e8726 --- /dev/null +++ b/src/include/usr/secureboot/phys_presence_if.H @@ -0,0 +1,68 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/secureboot/phys_presence_if.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2019 */ +/* [+] 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 */ +/** + * @file phys_presence_if.H + * + * @brief Interfaces to Detect and Open Physical Presence Windows + * + */ +#ifndef __PHYS_PRESENCE_H +#define __PHYS_PRESENCE_H +// ----------------------------------------------- +// Includes +// ----------------------------------------------- + +#include <errl/errlentry.H> +#include <targeting/common/commontargeting.H> +#include <config.h> + +namespace SECUREBOOT +{ + /** + * @brief Checks if the Physical Presence Window was opened and if + * Physical Presence was asserted. + * + * @post Will ensure the window is closed at the end of the function + * + * @return errlHndl_t nullptr on success; non-nullptr on error. + */ + errlHndl_t detectPhysPresence(void); + + /** + * @brief Handle Physical Presence Window first checks to see if a physical + * presence window should be opened. Then, if necessary, it sets up + * the physical presence detect circuit and then shuts down the + * system. + * + * @post If successful, this function will shutdown the system + * + * @return errlHndl_t nullptr on success; non-nullptr on error. + */ + errlHndl_t handlePhysPresenceWindow(void); + +} // namespace SECUREBOOT + + +#endif // __PHYS_PRESENCE_H diff --git a/src/include/usr/secureboot/secure_reasoncodes.H b/src/include/usr/secureboot/secure_reasoncodes.H index d121fc7b9..9e0e52c6e 100644 --- a/src/include/usr/secureboot/secure_reasoncodes.H +++ b/src/include/usr/secureboot/secure_reasoncodes.H @@ -53,7 +53,7 @@ namespace SECUREBOOT MOD_CHECK_RISK_LEVEL_FOR_SMF = 0x13, MOD_SMF_SPLIT_SMF_MEM = 0x14, - // Use 0x20-0x2F range for Node Communications + // Use 0x20-0x3F range for Node Communications MOD_NCDD_CHECK_FOR_ERRORS = 0x20, MOD_NCDD_WAIT_FOR_CMD_COMP = 0x21, MOD_NC_XBUS_TEST = 0x22, @@ -70,7 +70,12 @@ namespace SECUREBOOT MOD_NC_PROCESS_SLAVE_QUOTE = 0x2D, MOD_NCT_SEND = 0x2E, MOD_NCT_RECEIVE = 0x2F, - }; + + // Use 0x40-0x4F range for Physical Presence Detection + MOD_PHYS_PRES_DETECT = 0x40, + MOD_PHYS_PRES_OPEN_WINDOW = 0x41, + + }; enum SECUREReasonCode { @@ -123,6 +128,16 @@ namespace SECUREBOOT RC_NCT_INITIATION_MISMATCH = SECURE_COMP_ID | 0x33, RC_NCEX_NO_FUNCTIONAL_PRIMARY_TPM = SECURE_COMP_ID | 0x34, + // Use 0x20-0x3F range for Node Communications + + // RC_PHYS_PRES_WINDOW_OPENED_SHUTDOWN Must have one unique use + // for Shutdown path since FSP relies on it. + // termination_rc + RC_PHYS_PRES_WINDOW_OPENED_SHUTDOWN = SECURE_COMP_ID | 0x40, + RC_PHYS_PRES_ATTR_NOT_FOUND = SECURE_COMP_ID | 0x41, + RC_PHYS_PRES_WINDOW_NOT_CLOSED = SECURE_COMP_ID | 0x42, + RC_PHYS_PRES_WINDOW_NOT_OPENED = SECURE_COMP_ID | 0x43, + // Reason codes 0xA0 - 0xEF reserved for trustedboot_reasoncodes.H }; diff --git a/src/usr/gpio/gpio_pca9551.C b/src/usr/gpio/gpio_pca9551.C index 2bc4b955b..6edbd1a9a 100644 --- a/src/usr/gpio/gpio_pca9551.C +++ b/src/usr/gpio/gpio_pca9551.C @@ -47,7 +47,7 @@ extern trace_desc_t* g_trac_gpio; -// Set to TRACFCOMP to enble unit race +// Set to TRACFCOMP to enable unit trace #define TRACUCOMP(args...) TRACDCOMP(args) using namespace DeviceFW; diff --git a/src/usr/gpio/gpiodd.C b/src/usr/gpio/gpiodd.C index 69cde2b70..50fa193c5 100644 --- a/src/usr/gpio/gpiodd.C +++ b/src/usr/gpio/gpiodd.C @@ -77,8 +77,7 @@ errlHndl_t gpioPerformOp(DeviceFW::OperationType i_opType, gpioInfo.deviceType = va_arg( i_args, uint64_t ); gpioInfo.portAddr = va_arg( i_args, uint64_t ); -//MAB make TRACD - TRACFCOMP(g_trac_gpio, ENTER_MRK"gpioPerformOp(): " + TRACDCOMP(g_trac_gpio, ENTER_MRK"gpioPerformOp(): " "optype %d deviceType %d portAddr %d", i_opType, gpioInfo.deviceType, gpioInfo.portAddr); diff --git a/src/usr/isteps/istep06/call_host_update_master_tpm.C b/src/usr/isteps/istep06/call_host_update_master_tpm.C index 284d43450..fa374f279 100644 --- a/src/usr/isteps/istep06/call_host_update_master_tpm.C +++ b/src/usr/isteps/istep06/call_host_update_master_tpm.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2018 */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -31,6 +31,8 @@ #include <trustedbootif.H> #include <initservice/isteps_trace.H> #include <secureboot/service.H> +#include <secureboot/phys_presence_if.H> +#include <config.h> namespace ISTEP_06 { @@ -39,7 +41,7 @@ void* call_host_update_master_tpm( void *io_pArgs ) { ISTEP_ERROR::IStepError l_stepError; - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_update_master_tpm entry" ); errlHndl_t l_err = nullptr; @@ -67,10 +69,28 @@ void* call_host_update_master_tpm( void *io_pArgs ) ERRORLOG::errlCommit( l_err, SECURE_COMP_ID ); } - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "call_host_update_master_tpm exit" ); + // Check for Physical Presence +#ifdef CONFIG_PHYS_PRES_PWR_BUTTON + l_err = SECUREBOOT::detectPhysPresence(); + if (l_err) + { + // @TODO RTC 210301 - Handle Error Log Correctly, but for now + // just delete it + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_host_update_master_tpm: Error back from " + "SECUREBOOT::detectPhysPresence: rc=0x%X, plid=0x%X. " + "Deleting error for now", + ERRL_GETRC_SAFE(l_err), ERRL_GETPLID_SAFE(l_err)); + delete l_err; + l_err = nullptr; + } +#endif + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_host_update_master_tpm exit" ); return l_stepError.getErrorHandle(); + + } }; diff --git a/src/usr/isteps/istep10/call_host_update_redundant_tpm.C b/src/usr/isteps/istep10/call_host_update_redundant_tpm.C index 878b1b1e3..d0870d817 100644 --- a/src/usr/isteps/istep10/call_host_update_redundant_tpm.C +++ b/src/usr/isteps/istep10/call_host_update_redundant_tpm.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2018 */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -40,6 +40,7 @@ #include <util/algorithm.H> #include <istepHelperFuncs.H> #include <secureboot/trustedbootif.H> +#include <secureboot/phys_presence_if.H> namespace ISTEP_10 { @@ -50,6 +51,7 @@ void* call_host_update_redundant_tpm (void *io_pArgs) ENTER_MRK"call_host_update_redundant_tpm"); ISTEP_ERROR::IStepError l_istepError; + #ifdef CONFIG_TPMDD TARGETING::Target* l_backupTpm = nullptr; @@ -67,6 +69,26 @@ void* call_host_update_redundant_tpm (void *io_pArgs) } while(0); #endif +#ifdef CONFIG_PHYS_PRES_PWR_BUTTON + // Check to see if a Physical Presence Window should be opened, + // and if so, open it. This could result in the system being shutdown + // to allow the system administrator to assert physical presence + errlHndl_t l_err = nullptr; + l_err = SECUREBOOT::handlePhysPresenceWindow(); + if (l_err) + { + // @TODO RTC 210301 - Handle Error Log Correctly, but for now + // just delete it + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_host_update_redundant_tpm: Error back from " + "SECUREBOOT::handlePhysPresence: rc=0x%X, plid=0x%X. " + "Deleting error for now", + ERRL_GETRC_SAFE(l_err), ERRL_GETPLID_SAFE(l_err)); + delete l_err; + l_err = nullptr; + } +#endif + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, EXIT_MRK"call_host_update_redundant_tpm"); diff --git a/src/usr/runtime/hdatstructs.H b/src/usr/runtime/hdatstructs.H index 94f4c1b71..46cde05f7 100644 --- a/src/usr/runtime/hdatstructs.H +++ b/src/usr/runtime/hdatstructs.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2018 */ +/* Contributors Listed Below - COPYRIGHT 2012,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -453,7 +453,10 @@ typedef struct sysSecSets // NOTE: This bit is labeled "Platform Security Overrides Allowed" // in the section 6.1.1 of HDAT spec. uint16_t sbeSecBackdoor : 1; - uint16_t reserved : 13; + + // bit 3: "System Physical Presence has been asserted" + uint16_t physicalPresenceAsserted : 1; + uint16_t reserved : 12; } SysSecSets; #endif diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C index 78fafd406..3b726c3a9 100644 --- a/src/usr/runtime/populate_hbruntime.C +++ b/src/usr/runtime/populate_hbruntime.C @@ -1879,6 +1879,13 @@ errlHndl_t populate_hbSecurebootData ( void ) // populate security override setting l_sysSecSets->sbeSecBackdoor = SECUREBOOT::getSbeSecurityBackdoor(); + // populate "System Physical Presence has been asserted" + TARGETING::Target* sys = nullptr; + TARGETING::targetService().getTopLevelTarget( sys ); + assert(sys != nullptr, "populate_hbSecurebootData() - Could not obtain top level target"); + l_sysSecSets->physicalPresenceAsserted = + sys->getAttr<TARGETING::ATTR_PHYS_PRES_ASSERTED>(); + // populate TPM config bits in hdat bool tpmRequired = false; #ifdef CONFIG_TPMDD diff --git a/src/usr/secureboot/HBconfig b/src/usr/secureboot/HBconfig index af987887c..4f1a179b4 100644 --- a/src/usr/secureboot/HBconfig +++ b/src/usr/secureboot/HBconfig @@ -22,3 +22,17 @@ config TPM_NVIDX_VALIDATE depends on TPMDD help Validate TPM MFG NV Index Provisioning during IPL + +config PHYS_PRES_PWR_BUTTON + default n + depends on !PHYS_PRES_JUMPER + help + Support asserting Physical Presence via pushing the Power Button + on the system + +config PHYS_PRES_JUMPER + default n + depends on !PHYS_PRES_PRW_BUTTON + help + Support asserting Physical Presence via a jumper on the TPM Card + Currently not supported. diff --git a/src/usr/secureboot/ext/makefile b/src/usr/secureboot/ext/makefile index 9b5adeaf7..d573515c6 100644 --- a/src/usr/secureboot/ext/makefile +++ b/src/usr/secureboot/ext/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2013,2018 +# Contributors Listed Below - COPYRIGHT 2013,2019 # [+] International Business Machines Corp. # # @@ -30,6 +30,7 @@ PERV_HWP_PATH = $(ROOTPATH)/src/import/chips/p9/procedures/hwp/perv OBJS += $(if $(CONFIG_DRTM),drtm.o) OBJS += $(if $(CONFIG_SECUREBOOT), service_ext.o) +OBJS += $(if $(CONFIG_PHYS_PRES_PWR_BUTTON), phys_presence.o) VPATH += $(PERV_HWP_PATH) diff --git a/src/usr/secureboot/ext/phys_presence.C b/src/usr/secureboot/ext/phys_presence.C new file mode 100644 index 000000000..a9e0231bf --- /dev/null +++ b/src/usr/secureboot/ext/phys_presence.C @@ -0,0 +1,479 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/secureboot/ext/phys_presence.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2019 */ +/* [+] 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 */ +/** + * @file phys_presence.C + * + * @brief Implements Interfaces to Detect and Open Physical Presence Windows + * + */ + +#include <config.h> +#include <targeting/common/util.H> +#include <targeting/common/target.H> +#include <errl/errlentry.H> +#include <errl/errlmanager.H> +#include <errl/errludtarget.H> +#include <devicefw/driverif.H> +#include <console/consoleif.H> +#include <util/misc.H> +#include <initservice/initserviceif.H> +#include <initservice/istepdispatcherif.H> +#include <secureboot/secure_reasoncodes.H> +#include <secureboot/phys_presence_if.H> +#include "../common/securetrace.H" +#include <gpio/gpioif.H> + +using namespace TARGETING; +using namespace GPIO; + +namespace SECUREBOOT +{ + +errlHndl_t detectPhysPresence(void) +{ + errlHndl_t err = nullptr; + + SB_ENTER("detectPhysPresence"); + + // Not supported in simics + if (Util::isSimicsRunning()) + { + SB_ERR("detectPhysPresence: Skipping as not supported in simics"); + + // Normally don't have multiple return statements, but + // this solves having 2 do-while loops + return err; + } + + // Declare local variables here as there might be an operation + // after the do-while() loop + Target * mproc = nullptr; + uint8_t led_data = 0; + ATTR_GPIO_INFO_PHYS_PRES_type gpioInfo = {}; + uint8_t led_window_open = 0; + uint8_t led_phys_pres_asserted = 0; + bool is_window_open = false; + bool is_phys_pres_asserted = false; + + // Get the attributes associated with Physical Presence + TargetService& tS = targetService(); + Target* sys = nullptr; + (void) tS.getTopLevelTarget( sys ); + assert(sys, "detectPhysPresence: system target is nullptr"); + + do + { + uint8_t attr_open_window = + sys->getAttr<ATTR_PHYS_PRES_REQUEST_OPEN_WINDOW>(); + + uint8_t attr_fake_assert = sys->getAttr<ATTR_PHYS_PRES_FAKE_ASSERT>(); + // NOTE: Using attributes to request opening the physical presence window + // and/or fake the assertion of physical presence is only for testing + // purposes. Both attributes will default to 'no' and cannot be changed + // when security is enabled in a production driver since attribute + // overrides are not allowed in that scenario. + SB_INF("detectPhysPresence: attr_open_window=%d (0x%X), " + "attr_fake_assert=%d (0x%X)", + attr_open_window, attr_open_window, + attr_fake_assert, attr_fake_assert); + + // The PCA9551 device that controls the "window open" and + // "physical presence asserted" logic is connected to the master processor + err = targetService().queryMasterProcChipTargetHandle(mproc); + if(err) + { + SB_ERR("detectPhysPresence: call to queryMasterProcChipTargetHandle " + "failed. err_plid=0x%X, err_rc=0x%X", + ERRL_GETPLID_SAFE(err), + ERRL_GETRC_SAFE(err)); + + err->collectTrace(SECURE_COMP_NAME); + break; + } + + // Get the attribute with the needed GPIO information + if (mproc->tryGetAttr<ATTR_GPIO_INFO_PHYS_PRES>(gpioInfo)) + { + SB_INF("detectPhysPresence: gpioInfo: e%d/p%d/devAddr=0x%X, " + "windowOpenPin=%d, physPresPin=%d", + gpioInfo.engine, gpioInfo.port, gpioInfo.devAddr, + gpioInfo.windowOpenPin, gpioInfo.physicalPresencePin); + } + else + { + SB_ERR("detectPhysPresence: couldn't find GPIO_INFO_PHYS_PRES " + "on mproc 0x%.08X", get_huid(mproc)); + + /*@ + * @errortype + * @reasoncode RC_PHYS_PRES_ATTR_NOT_FOUND + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_PHYS_PRES_DETECT + * @userdata1 HUID of Master Processor Target + * @userdata2 ATTR_GPIO_INFO_PHYS_PRES hash value + * @devdesc Master processor target did not have + * ATTR_GPIO_INFO_PHYS_PRES associated with it + * @custdesc A problem occurred during the IPL + * of the system. + */ + err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_PHYS_PRES_DETECT, + RC_PHYS_PRES_ATTR_NOT_FOUND, + get_huid(mproc), + ATTR_GPIO_INFO_PHYS_PRES, + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + + err->collectTrace( SECURE_COMP_NAME ); + break; + } + + // Get "window open" and "physical presence asserted" LEDs/Pins + led_window_open = PCA9551_LED0 << gpioInfo.windowOpenPin; + led_phys_pres_asserted = PCA9551_LED0 << gpioInfo.physicalPresencePin; + + // Read PCA9551 INPUT Register to get LED Values + led_data = 0; + err = gpioPca9551GetLeds(mproc, led_data); + if(err) + { + SB_ERR("detectPhysPresence: Reading LEDs failed"); + break; + } + + // Look for "window open" and "physical presence asserted" + // LEDs/PINs represent "WINDOW_OPEN_N" and "PHYS_PRESENCE_N" so need + // to invert their values to get their true meaning + is_window_open = ! (led_window_open & led_data); + + // Only care if its asserted if the window is open + // (technically it's not supposed to be asserted unless the window is open) + is_phys_pres_asserted = is_window_open && + (! (led_phys_pres_asserted & led_data)); + + + // Look for special case to fake assertion + if ((is_window_open == true ) && + (is_phys_pres_asserted == false) && + (attr_fake_assert != 0 )) + { + is_phys_pres_asserted = true; + SB_INF("detectPhysPresence: FAKING Physical Assertion: " + "is_WO=%d, is_PPA=%d, attr_FA=0x%X", + is_window_open, is_phys_pres_asserted, + attr_fake_assert); + + // Write the attribute so faking the assert only happens once + sys->setAttr<ATTR_PHYS_PRES_FAKE_ASSERT>(0x00); + } + + SB_INF("detectPhysPresence: LEDs=0x%.2X, led_WO=0x%X, led_PPA=0x%X, " + "attrWO=0x%X, attr_FA=0x%X, is_WO=%d, is_PPA=%d", + led_data, led_window_open, led_phys_pres_asserted, + attr_open_window, attr_fake_assert, + is_window_open, is_phys_pres_asserted); + + } while(0); + + // Regardless of any previous error, attempt to close the window here + // if it was already opened + if (is_window_open == true) + { + errlHndl_t err_close = nullptr; + err_close = gpioPca9551SetLed(mproc, + static_cast<GPIO::PCA9551_LEDS_t> + (led_window_open), + PCA9551_OUTPUT_HIGH_IMPEDANCE, + led_data); + + if (err_close == nullptr) + { + // Verify that window was closed + // LEDs/PIN represents "WINDOW_OPEN_N" so looking for a "1" in + // that position + if (!(led_data & led_window_open)) + { + SB_ERR("detectPhysPresence: Closed Window LEDs = 0x%.2X " + "indicated that LED %d is showing window is still open", + led_data, led_window_open); + + /*@ + * @errortype + * @reasoncode RC_PHYS_PRES_WINDOW_NOT_CLOSED + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_PHYS_PRES_DETECT + * @userdata1 HUID of Master Processor Target + * @userdata2[0:31] LED Data from PCA9551 + * @userdata[32:63] LED Windoow Open LED (aka PIN) + * @devdesc Attempt to close physical presence window + * did not close the window + * @custdesc A problem occurred during the IPL + * of the system. + */ + err_close = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_PHYS_PRES_DETECT, + RC_PHYS_PRES_WINDOW_NOT_CLOSED, + get_huid(mproc), + TWO_UINT32_TO_UINT64( + led_data, + led_window_open), + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + } + else + { + SB_INF("detectPhysPresence: Closed Window LEDs = 0x%.2X", + led_data); + } + + } + + if (err_close) + { + if (err) + { + // commit new erro with PLID or original err + err_close->plid(err->plid()); + SB_ERR("detectPhysPresence: Error in closing window. " + "Committing err_close eid=0x%X " + "with plid of original err: 0x%X", + err_close->eid(), err_close->plid()); + + err_close->collectTrace( SECURE_COMP_NAME ); + errlCommit(err_close, SECURE_COMP_ID); + } + else + { + SB_ERR("detectPhysPresence: Error in closing window. " + "err_close eid=0x%X plid=0x%X", + err_close->eid(), err_close->plid()); + err_close->collectTrace( SECURE_COMP_NAME ); + err = err_close; + err_close = nullptr; + } + } + } // end of 'must close window' + + if (err == nullptr) + { + // If no error, including in closing the window, then write attribute + // for Physical Presence Assertion + sys->setAttr<ATTR_PHYS_PRES_ASSERTED>(is_phys_pres_asserted); + } + + SB_EXIT("detectPhysPresence: err rc=0x%X", + ERRL_GETRC_SAFE(err)); + + return err; +} + +errlHndl_t handlePhysPresenceWindow(void) +{ + errlHndl_t err = nullptr; + + SB_ENTER("handlePhysPresenceWindow"); + + // Declare local variables here as there might be an operation + // after the do-while() loop + Target * mproc = nullptr; + uint8_t led_data = 0; + ATTR_GPIO_INFO_PHYS_PRES_type gpioInfo = {}; + uint8_t led_window_open = 0; + bool is_window_open = false; + + do + { + + // Not supported in simics + if (Util::isSimicsRunning()) + { + SB_INF("handlePhysPresenceWindow: Skipping as not supported in simics"); + break; + } + + // Get the attributes associated with Physical Presence + TargetService& tS = targetService(); + Target* sys = nullptr; + (void) tS.getTopLevelTarget( sys ); + assert(sys, "handlePhysPresenceWindow: system target is nullptr"); + + // NOTE: Using attributes to request opening the physical presence window + // and/or fake the assertion of physical presence is only for testing + // purposes. Both attributes will default to 'no' and cannot be changed + // when security is enabled in a production driver since attribute + // overrides are not allowed in that scenario. + uint8_t attr_open_window = + sys->getAttr<ATTR_PHYS_PRES_REQUEST_OPEN_WINDOW>(); + uint8_t attr_phys_pres_asserted = sys->getAttr<ATTR_PHYS_PRES_ASSERTED>(); + + if (attr_open_window == 0) + { + SB_INF("handlePhysPresenceWindow: attr_open_window=0x%.2X: " + "no need to open window (attr_phys_pres_asserted=0x%.2X)", + attr_open_window, attr_phys_pres_asserted); + break; + } + // This solves the issue of using attribute overrides to open the window, + // as they don't always get cleared on re-IPLs and attr_open_window might + // still != 0 + else if (attr_phys_pres_asserted != 0) + { + SB_INF("handlePhysPresenceWindow: attr_open_window=0x%.2X, but " + "attr_phys_pres_asserted=0x%.2X, so no need to open window. " + "Clearing open window request", + attr_open_window, attr_phys_pres_asserted); + + // Close request to open the window + sys->setAttr<ATTR_PHYS_PRES_REQUEST_OPEN_WINDOW>(0x00); + break; + } + else + { + SB_INF("handlePhysPresenceWindow: attr_open_window=0x%.2X, " + "attr_phys_pres_asserted=0x%.2X: " + "Will Open Window To Detect Physical Presence", + attr_open_window, attr_phys_pres_asserted); + } + + // The PCA9551 device that controls the "window open" and + // "physical presence asserted" logic is connected to the master processor + err = targetService().queryMasterProcChipTargetHandle(mproc); + if(err) + { + SB_ERR("handlePhysPresenceWindow: call to queryMasterProcChipTargetHandle " + "failed. err_plid=0x%X, err_rc=0x%X", + ERRL_GETPLID_SAFE(err), + ERRL_GETRC_SAFE(err)); + + err->collectTrace(SECURE_COMP_NAME); + break; + } + + // Get "window open" LED/Pin + led_window_open = PCA9551_LED0 << gpioInfo.windowOpenPin; + + + // Open The Window + led_data=0; // For INPUT register read-back + err = gpioPca9551SetLed(mproc, + static_cast<GPIO::PCA9551_LEDS_t> + (led_window_open), + PCA9551_OUTPUT_LOW, + led_data); + + // Verify that the "window open" LED is set + // LEDs/PINs represent "WINDOW_OPEN_N" and "PHYS_PRESENCE_N" so need + // to invert their values to get their true meaning + is_window_open = ! (led_window_open & led_data); + if (is_window_open == true) + { + SB_INF("handlePhysPresenceWindow: Window is Opened: " + "led_window_open=0x%X, led_data=0x%.2X", + led_window_open, led_data); + } + else + { + SB_ERR("handlePhysPresenceWindow: ERROR: Window is NOT Opened: " + "led_window_open=0x%X, led_data=0x%.2X", + led_window_open, led_data); + + /*@ + * @errortype + * @reasoncode RC_PHYS_PRES_WINDOW_NOT_OPENED + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_PHYS_PRES_OPEN_WINDOW + * @userdata1 HUID of Master Processor Target + * @userdata2[0:31] LED Data from PCA9551 + * @userdata2[32:63] LED Windoow Open LED (aka PIN) + * @devdesc Attempt to open physical presence window + * did not close the window + * @custdesc A problem occurred during the IPL + * of the system. + */ + err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_PHYS_PRES_OPEN_WINDOW, + RC_PHYS_PRES_WINDOW_NOT_OPENED, + get_huid(mproc), + TWO_UINT32_TO_UINT64( + led_data, + led_window_open), + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + + err->collectTrace( SECURE_COMP_NAME ); + break; + } + + // Close request to open the window and sync attributes + sys->setAttr<ATTR_PHYS_PRES_REQUEST_OPEN_WINDOW>(0x00); + + if(INITSERVICE::spBaseServicesEnabled()) + { + // Sync all attributes to FSP before powering off + err = TARGETING::AttrRP::syncAllAttributesToFsp(); + if( err ) + { + // Failed to sync all attributes to FSP; this is not + // necessarily fatal. The power off will continue, + // but this issue will be logged. + SB_ERR("handlePhysPresenceWindow: Error syncing " + "attributes to FSP, RC=0x%04X, PLID=0x%08X", + ERRL_GETRC_SAFE(err), + ERRL_GETPLID_SAFE(err)); + errlCommit(err,SECURE_COMP_ID ); + } + } + + // Alert the users that the system will power off +#ifdef CONFIG_CONSOLE + CONSOLE::displayf(SECURE_COMP_NAME, "Opened Physical Presence Detection Window\n"); + CONSOLE::displayf(SECURE_COMP_NAME, "System Will Power Off and Wait For Manual Power On\n"); + CONSOLE::flush(); +#endif + + // Power Off the System +#ifdef CONFIG_BMC_IPMI + // Initiate a graceful power off + SB_INF("handlePhysPresenceWindow: Opened Physical Presence Detection Window. " + "System Will Power Off and Wait For Manual Power On. " + "Requesting power off"); + INITSERVICE::requestPowerOff(); +#else //non-IPMI + SB_INF("handlePhysPresenceWindow: Opened Physical Presence Detection Window. " + "Calling INITSERVICE::doShutdown() with " + "RC_PHYS_PRES_WINDOW_OPENED_SHUTDOWN = 0x%08X", + RC_PHYS_PRES_WINDOW_OPENED_SHUTDOWN); + INITSERVICE::doShutdown(RC_PHYS_PRES_WINDOW_OPENED_SHUTDOWN); +#endif + + + } while (0); + + SB_EXIT("handlePhysPresenceWindow: err_rc=0x%X", + ERRL_GETRC_SAFE(err)); + + return err; +} + +} // namespace SECUREBOOT diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml index 8be123d99..5978de341 100755 --- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml @@ -1250,6 +1250,56 @@ </attribute> <attribute> + <description>Designates if the Physical Presence Window was Asserted: + 0 - Physiscal Presence was NOT Asserted + 1 - Physical Presence was Asserted + </description> + <id>PHYS_PRES_ASSERTED</id> + <simpleType> + <uint8_t> + <default>0x0</default> + </uint8_t> + </simpleType> + <persistency>volatile-zeroed</persistency> + <readable/> + <writeable/> + </attribute> + + <attribute> + <description>Designates if the assertion of Physical Presence should + be faked: + 0 - Do NOT Fake Physical Presence + 1 - Fake Physical Presence + </description> + <id>PHYS_PRES_FAKE_ASSERT</id> + <simpleType> + <uint8_t> + <default>0x0</default> + </uint8_t> + </simpleType> + <persistency>volatile-zeroed</persistency> + <readable/> + <writeable/> + </attribute> + + <attribute> + <description>Designates if there is a request to open the Physical Presence + Window: + 0 - No Request to Open Window (ie, do NOT open window) + 1 - Request to Open Window + </description> + <id>PHYS_PRES_REQUEST_OPEN_WINDOW</id> + <simpleType> + <uint8_t> + <default>0x0</default> + </uint8_t> + </simpleType> + <persistency>volatile-zeroed</persistency> + <readable/> + <writeable/> + </attribute> + + <attribute> <id>SBE_COMM_ADDR</id> <description> Virtual address where SBE Communications are placed in mainstore. diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml index 080fbecae..8cb8bae1c 100644 --- a/src/usr/targeting/common/xmltohb/target_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml @@ -360,6 +360,15 @@ <attribute> <id>PDA_THREAD_REG_STATE_ENTRY_FORMAT</id> </attribute> + <attribute> + <id>PHYS_PRES_ASSERTED</id> + </attribute> + <attribute> + <id>PHYS_PRES_FAKE_ASSERT</id> + </attribute> + <attribute> + <id>PHYS_PRES_REQUEST_OPEN_WINDOW</id> + </attribute> </targetTypeExtension> <targetTypeExtension> |