diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/usr/sbeio/sbeioif.H | 9 | ||||
-rw-r--r-- | src/include/usr/sbeio/sbeioreasoncodes.H | 2 | ||||
-rw-r--r-- | src/include/usr/targeting/attrrp.H | 128 | ||||
-rw-r--r-- | src/include/usr/targeting/common/targreasoncodes.H | 3 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/istepdispatcher.C | 15 | ||||
-rw-r--r-- | src/usr/isteps/istep21/call_host_start_payload.C | 8 | ||||
-rw-r--r-- | src/usr/mbox/mailboxsp.C | 14 | ||||
-rw-r--r-- | src/usr/runtime/populate_hbruntime.C | 8 | ||||
-rw-r--r-- | src/usr/sbeio/sbe_psuQuiesce.C | 54 | ||||
-rwxr-xr-x | src/usr/targeting/attrrp.C | 282 | ||||
-rwxr-xr-x | src/usr/targeting/common/xmltohb/attribute_types_hb.xml | 24 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/target_types_hb.xml | 3 | ||||
-rw-r--r-- | src/usr/targeting/makefile | 6 |
13 files changed, 494 insertions, 62 deletions
diff --git a/src/include/usr/sbeio/sbeioif.H b/src/include/usr/sbeio/sbeioif.H index 1da44c646..65fa474f1 100644 --- a/src/include/usr/sbeio/sbeioif.H +++ b/src/include/usr/sbeio/sbeioif.H @@ -101,12 +101,17 @@ namespace SBEIO /** * @brief Sends a PSU chipOp to quiesce the SBE * - * @param[in] i_target Target with SBE to quiesce + * @param[in] i_pProc Processor target with SBE to quiesce. + * Throws error if requested target is nullptr or does not + * refer to a processor. + * + * @note Sets the requested processor's ASSUME_SBE_QUIESCED attribute + * to true to inhibit future quiesce sensitive operations. * * @return errlHndl_t Error log handle on failure. * */ - errlHndl_t sendPsuQuiesceSbe(TARGETING::Target * i_target); + errlHndl_t sendPsuQuiesceSbe(TARGETING::Target* i_pProc); /** * @brief Get the capabilities of the SBE via PSU diff --git a/src/include/usr/sbeio/sbeioreasoncodes.H b/src/include/usr/sbeio/sbeioreasoncodes.H index 44a493d35..3134ec2cc 100644 --- a/src/include/usr/sbeio/sbeioreasoncodes.H +++ b/src/include/usr/sbeio/sbeioreasoncodes.H @@ -57,6 +57,7 @@ enum sbeioModuleId SBEIO_GET_FFDC_HANDLER = 0x0C, SBEIO_GET_SBE_RC = 0x0D, SBEIO_HANDLE_VITAL_ATTN = 0x0E, + SBEIO_SEND_PSU_QUIESCE_SBE = 0x0F, }; /** @@ -75,6 +76,7 @@ enum sbeioReasonCode SBEIO_PSU_NOT_READY = SBEIO_COMP_ID | 0x03, SBEIO_PSU_FFDC_MISSING = SBEIO_COMP_ID | 0x04, SBEIO_PSU_SEND = SBEIO_COMP_ID | 0x05, + SBEIO_PSU_INVALID_TARGET = SBEIO_COMP_ID | 0x06, // SBE FIFO error codes SBEIO_FIFO_UPSTREAM_TIMEOUT = SBEIO_COMP_ID | 0x10, diff --git a/src/include/usr/targeting/attrrp.H b/src/include/usr/targeting/attrrp.H index c863c8417..c25fa8290 100644 --- a/src/include/usr/targeting/attrrp.H +++ b/src/include/usr/targeting/attrrp.H @@ -325,6 +325,54 @@ class AttrRP #ifndef __HOSTBOOT_RUNTIME /** + * @enum msg_mm_rp_runtime_prep_t + * + * @brief Message subtypes for the MSG_MM_RP_RUNTIME_PREP message + */ + enum msg_mm_rp_runtime_prep_t + { + // data[0] = MSG_MM_RP_RUNTIME_PREP_BEGIN or + // data[0] = MSG_MM_RP_RUNTIME_PREP_END + MSG_MM_RP_RUNTIME_PREP_BEGIN, ///< Force all pages to be validated + MSG_MM_RP_RUNTIME_PREP_END, ///< Disable force validation + }; + + /** + * @enum ATTRRP_MSG_TYPE + * + * @brief Non-kernel message types for the attribute resource provider + * message handler + */ + enum ATTRRP_MSG_TYPE : uint32_t + { + // Prepare runtime for secure transition of attributes + MSG_MM_RP_RUNTIME_PREP = 0x00000002, + // Arm service to synchronize attributes when Hostboot shuts down + MSG_PRIME_SHUTDOWN_ATTR_SYNC = 0x00000003, + // Invoke attribute synchronization at shutdown + MSG_INVOKE_SHUTDOWN_ATTR_SYNC = 0x00000004, + }; + + /** + * @enum RESOURCE + * + * @brief Enumeration which indicates a specific resource (service, + * condition, etc.) + */ + enum RESOURCE : uint8_t + { + MAILBOX, ///< FSI mailbox service + }; + + /** + * @brief Notifies the attribute resource provider that a specific + * resource of interest is ready/available + * + * @param[in] i_resource Resource that is ready/available + */ + static void notifyResourceReady(RESOURCE i_resource); + + /** * @brief Modifies the memory R/W permissions on VMM pages for a * given type of AttrRP_Section. Valid types can be found * in the generated file pnorheader.H. Valid permissions @@ -433,8 +481,9 @@ class AttrRP */ AttrRP() #ifndef __HOSTBOOT_RUNTIME - : iv_msgQ(NULL), iv_sections(NULL), iv_sectionCount(0), - iv_isMpipl(false) + : iv_msgQ(nullptr), iv_attrSyncMsgQ(msg_q_create()), + iv_sections(nullptr), iv_sectionCount(0), + iv_shutdownAttrSyncPrimed(false),iv_isMpipl(false) #else : iv_isTempInstance(false), iv_isMpipl(false) #endif @@ -568,16 +617,49 @@ class AttrRP #ifndef __HOSTBOOT_RUNTIME /** + * @brief Notifies the attribute resource provider that a specific + * resource of interest is ready/available + * + * @param[in] i_resource Resource that is ready/available + */ + void _notifyResourceReady(RESOURCE i_resource) const; + + /** + * @brief Synchronizes attributes to FSP during a user space initiated + * shutdown + * + * @par Detailed Description: + * During a user space initiated shutdown, the init service calls + * the resource provider shutdown handler which attempts to + * synchronize attributes down to the FSP. For this to succeed, + * the FSP must be available, the mailbox must be online (and have + * earlier called notifyResourceReady API to arm the + * synchronization), and SBE must not be quiesced (or mailbox + * traffic going through the SBE FIFO in secure mode will fail) + */ + void invokeShutdownAttrSync() const; + + /** * @brief Processes daemon messages * * @par Detailed Description: - * Performs a while(1) waiting for messages from the - * kernel/VMM and handles as appropriately. Reads / writes - * data from / to PNOR for the attribute sections. + * Performs a while(1) waiting for messages from + * kernel/VMM/user space and handles as appropriate. Reads / + * writes data from / to PNOR for the attribute sections for + * kernel/VMM messages. */ void msgServiceTask() const; /** + * @brief Task which processes attribute synchronization requests + * + * @par Detailed Description: + * Processes attribute synchronization requests, especially in + * relation to synchronizing attributes when Hostboot terminates. + */ + void attrSyncTask(); + + /** * @brief Parses the attribute section header in PNOR. * * @par Detailed Description: @@ -656,14 +738,35 @@ class AttrRP */ static void* startMsgServiceTask(void* i_pInstance); + /** + * @brief Starts the attribute provider's attribute synchronization + * task + * + * @par Detailed Description: + * task_create should call this static function to enter the + * daemonized attribute synchronization task which handles + * attribute synchronization requests + * + * @param[in] i_pInstance The AttrRP to call attrSyncTask on. Must not + * be nullptr (or asserts); + */ + static void* startAttrSyncTask(void* i_pInstance); + // Message Queue for VMM requests msg_q_t iv_msgQ; + // Message Queue for attribute sync requests + msg_q_t iv_attrSyncMsgQ; + // Parsed structures of the attribute sections. AttrRP_Section* iv_sections; // Count of attribute sections. size_t iv_sectionCount; + + // Whether service is primed to invoke attribute synchronization when + // Hostboot shuts down under user space control + bool iv_shutdownAttrSyncPrimed; #else // Indicator that AttrRP instance is a temporary one, not the singleton bool iv_isTempInstance; @@ -681,21 +784,8 @@ class AttrRP TARG_DECLARE_SINGLETON(TARGETING::AttrRP,theAttrRP); extern const char* ATTRRP_MSG_Q; +extern const char* ATTRRP_ATTR_SYNC_MSG_Q; -// user-defined message subtype for MSG_MM_RP_RUNTIME_PREP -/** - * @enum msg_mm_rp_runtime_prep_t - * @brief Message type and subtypes for the MSG_MM_RP_RUNTIME_PREP message - */ -enum msg_mm_rp_runtime_prep_t -{ - MSG_MM_RP_RUNTIME_PREP = 0x2, // prepare runtime for secure transition - // of attrs - // data[0] = MSG_MM_RP_RUNTIME_PREP_BEGIN or - // data[0] = MSG_MM_RP_RUNTIME_PREP_END - MSG_MM_RP_RUNTIME_PREP_BEGIN, - MSG_MM_RP_RUNTIME_PREP_END, -}; } // End namespace TARGETING diff --git a/src/include/usr/targeting/common/targreasoncodes.H b/src/include/usr/targeting/common/targreasoncodes.H index ddff835be..bdad3212a 100644 --- a/src/include/usr/targeting/common/targreasoncodes.H +++ b/src/include/usr/targeting/common/targreasoncodes.H @@ -51,6 +51,8 @@ enum TargetingModuleId TARG_HANDLE_ENUM_CHECK_FAILURE = 0x0B, TARG_HANDLE_RANGE_CHECK_FAILURE = 0x0C, TARG_EDIT_PAGE_PERMISSIONS = 0x0D, + TARG_NOTIFY_RESOURCE_READY = 0x0E, + TARG_ATTR_SYNC_TASK = 0x0F, }; enum TargetingReasonCode @@ -80,6 +82,7 @@ enum TargetingReasonCode TARG_RC_ATTRIBUTE_RANGE_CHECK_FAIL = TARG_COMP_ID | 0x17, TARG_RC_CONCURRENT_CODE_UPDATE_FAIL = TARG_COMP_ID | 0x18, TARG_RC_ATTR_OVER_FAPI_TANK_NOT_SUPPORTED = TARG_COMP_ID | 0x19, + TARG_RC_UNSUPPORTED_ATTR_SYNC_MSG = TARG_COMP_ID | 0x1A, }; }; // End TARGETING namespace diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C index 7b5045ed2..7fe1f0038 100644 --- a/src/usr/initservice/istepdispatcher/istepdispatcher.C +++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C @@ -1028,21 +1028,6 @@ errlHndl_t IStepDispatcher::doIstep(uint32_t i_istep, { TRACFCOMP(g_trac_initsvc, ERR_MRK"doIstep: Istep failed, plid 0x%x", err->plid()); - - // istep fails, sync attributes to FSP - if( INITSERVICE::spBaseServicesEnabled() ) - { - TRACFCOMP(g_trac_initsvc, ERR_MRK"doIstep, Sync attributes to FSP"); - errlHndl_t l_errl = TARGETING::syncAllAttributesToFsp(); - - if(l_errl) - { - TRACFCOMP(g_trac_initsvc, ERR_MRK"doIstep: Attribute syncing" - " failed see 0x%08X for details", l_errl->eid()); - l_errl->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL); - errlCommit(l_errl, INITSVC_COMP_ID); - } - } } // Check for any attentions and invoke PRD for analysis diff --git a/src/usr/isteps/istep21/call_host_start_payload.C b/src/usr/isteps/istep21/call_host_start_payload.C index 40febc4ac..6178f35f7 100644 --- a/src/usr/isteps/istep21/call_host_start_payload.C +++ b/src/usr/isteps/istep21/call_host_start_payload.C @@ -449,6 +449,14 @@ errlHndl_t callShutdown ( uint64_t i_masterInstance, // Create a task to handle the messages task_create(ISTEP_21::msg_handler, l_msgQ); + // Unregister the AttrRP shutdown handler which synchronizes all + // attributes at shutdown, as closing the SBE memory regions below will + // cause all DMAs (and thus attribute sync) to fail. Intentionally + // ignore the response from unregister. This API will get called on + // all nodes. + auto pAttrMsgQ = msg_q_resolve(TARGETING::ATTRRP_ATTR_SYNC_MSG_Q); + INITSERVICE::unregisterShutdownEvent(pAttrMsgQ); + // Tell SBE to Close All Unsecure Memory Regions err = SBEIO::closeAllUnsecureMemRegions(); if (err) diff --git a/src/usr/mbox/mailboxsp.C b/src/usr/mbox/mailboxsp.C index 618db7538..1e462dbbe 100644 --- a/src/usr/mbox/mailboxsp.C +++ b/src/usr/mbox/mailboxsp.C @@ -52,6 +52,7 @@ #include <sbeio/sbeioif.H> #include <sys/time.h> #include <intr/interrupt.H> +#include <targeting/attrrp.H> // Local functions namespace MBOX @@ -222,8 +223,17 @@ errlHndl_t MailboxSp::_init() #ifndef CONFIG_VPO_COMPILE // Start the the interprocessor communications message handler IPC::IpcSp::init(err); - // call ErrlManager function - tell him that MBOX is ready! - ERRORLOG::ErrlManager::errlResourceReady(ERRORLOG::MBOX); + + // On error VFS won't initialize the mailbox address space, opening up + // the chance of downstream task crashes later. + if(!err) + { + // call ErrlManager function - tell him that MBOX is ready! + ERRORLOG::ErrlManager::errlResourceReady(ERRORLOG::MBOX); + TARGETING::AttrRP::notifyResourceReady( + TARGETING::AttrRP::RESOURCE::MAILBOX); + } + #endif return err; diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C index 7f47c4138..340ee3de7 100644 --- a/src/usr/runtime/populate_hbruntime.C +++ b/src/usr/runtime/populate_hbruntime.C @@ -3497,9 +3497,9 @@ errlHndl_t persistent_rwAttrRuntimeCheck( void ) assert(l_msg != nullptr, "Bug! Message allocation failed!"); - l_msg->type = TARGETING::MSG_MM_RP_RUNTIME_PREP; + l_msg->type = TARGETING::AttrRP::MSG_MM_RP_RUNTIME_PREP; - l_msg->data[0] = TARGETING::MSG_MM_RP_RUNTIME_PREP_BEGIN; + l_msg->data[0] = TARGETING::AttrRP::MSG_MM_RP_RUNTIME_PREP_BEGIN; int rc = msg_sendrecv(l_msgQ, l_msg); @@ -3539,8 +3539,8 @@ errlHndl_t persistent_rwAttrRuntimeCheck( void ) validateAllRwNvAttr( *targets ); } - l_msg->type = TARGETING::MSG_MM_RP_RUNTIME_PREP; - l_msg->data[0] = TARGETING::MSG_MM_RP_RUNTIME_PREP_END; + l_msg->type = TARGETING::AttrRP::MSG_MM_RP_RUNTIME_PREP; + l_msg->data[0] = TARGETING::AttrRP::MSG_MM_RP_RUNTIME_PREP_END; int rc = msg_sendrecv(l_msgQ, l_msg); diff --git a/src/usr/sbeio/sbe_psuQuiesce.C b/src/usr/sbeio/sbe_psuQuiesce.C index 906615157..a10f5e8c3 100644 --- a/src/usr/sbeio/sbe_psuQuiesce.C +++ b/src/usr/sbeio/sbe_psuQuiesce.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2017 */ +/* Contributors Listed Below - COPYRIGHT 2012,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -32,6 +32,7 @@ #include <errl/errlmanager.H> #include <sbeio/sbeioif.H> #include <sbeio/sbe_psudd.H> +#include <sbeio/sbeioreasoncodes.H> extern trace_desc_t* g_trac_sbeio; @@ -43,21 +44,39 @@ TRACFCOMP(g_trac_sbeio,"psuQuiesce: " printf_string,##args) namespace SBEIO { - - /** - * @brief Sends a PSU chipOp to quiesce the SBE - * - * @param[in] i_target Target with SBE to quiesce - * - * @return errlHndl_t Error log handle on failure. - * - */ - errlHndl_t sendPsuQuiesceSbe(TARGETING::Target * i_target) + errlHndl_t sendPsuQuiesceSbe(TARGETING::Target* i_pProc) { - errlHndl_t errl = NULL; + errlHndl_t pError = nullptr; SBE_TRACD(ENTER_MRK "sending psu quiesce command from HB -> SBE"); + do { + + if( (i_pProc == nullptr) + || ( i_pProc->getAttr<TARGETING::ATTR_TYPE>() + != TARGETING::TYPE_PROC)) + { + /*@ + * @errortype + * @moduleid SBEIO_SEND_PSU_QUIESCE_SBE + * @reasoncode SBEIO_PSU_INVALID_TARGET + * @userdata1 Target HUID (0, if invalid pointer) + * @userdata2 Target type (TYPE_NA, if invalid pointer) + * @devdesc Caller requested PSU quiesce against an unassigned + * target or a target that is not a processor. + * @custdesc Firmware logic bug detected + */ + pError = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + SBEIO_SEND_PSU_QUIESCE_SBE, + SBEIO_PSU_INVALID_TARGET, + TARGETING::get_huid(i_pProc), + i_pProc ? i_pProc->getAttr<TARGETING::ATTR_TYPE>() : 0, + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + pError->collectTrace(SBEIO_COMP_NAME); + break; + } + // set up PSU command message SbePsu::psuCommand l_psuCommand( SbePsu::SBE_REQUIRE_RESPONSE, //control flags @@ -66,16 +85,23 @@ namespace SBEIO SbePsu::psuResponse l_psuResponse; - errl = SBEIO::SbePsu::getTheInstance().performPsuChipOp(i_target, + pError = SBEIO::SbePsu::getTheInstance().performPsuChipOp(i_pProc, &l_psuCommand, &l_psuResponse, SbePsu::MAX_PSU_SHORT_TIMEOUT_NS, SbePsu::SBE_QUIESCE_REQ_USED_REGS, SbePsu::SBE_QUIESCE_RSP_USED_REGS); + // Regardless of whether the operation was successful, assume it + // was, in order to suppress future SBE activity like shutdown + // attribute synchronization. + i_pProc->setAttr<TARGETING::ATTR_ASSUME_SBE_QUIESCED>(true); + + } while(0); + SBE_TRACD(EXIT_MRK "sendPsuQuiesceSbe"); - return errl; + return pError; }; } //end namespace SBEIO diff --git a/src/usr/targeting/attrrp.C b/src/usr/targeting/attrrp.C index 9ba04090a..404468aec 100755 --- a/src/usr/targeting/attrrp.C +++ b/src/usr/targeting/attrrp.C @@ -55,6 +55,11 @@ #include <secureboot/service.H> #include <kernel/bltohbdatamgr.H> #include <bootloader/bootloaderif.H> +#include <common_ringId.H> +#include <fapi2.H> +#include <fapi2/plat_hwp_invoker.H> +#include <p9_sbe_ext_defs.H> +#include <p9_get_sbe_msg_register.H> #include <sbeio/sbeioif.H> using namespace INITSERVICE; @@ -66,6 +71,7 @@ namespace TARGETING { const char* ATTRRP_MSG_Q = "attrrpq"; + const char* ATTRRP_ATTR_SYNC_MSG_Q = "attrrpattrsyncq"; void* AttrRP::getBaseAddress(const NODE_ID i_nodeIdUnused) { @@ -80,6 +86,13 @@ namespace TARGETING return NULL; } + void* AttrRP::startAttrSyncTask(void* i_pInstance) + { + TARG_ASSERT(i_pInstance, "No instance passed to startAttrSyncTask"); + static_cast<AttrRP*>(i_pInstance)->attrSyncTask(); + return nullptr; + } + void AttrRP::startup(errlHndl_t& io_taskRetErrl, bool i_isMpipl) { errlHndl_t l_errl = NULL; @@ -112,6 +125,15 @@ namespace TARGETING // Spawn daemon thread. task_create(&AttrRP::startMsgServiceTask, this); + // Register attribute sync message queue so it can be discovered by + // istep 21 in order to deregister it from shutdown event handling. + auto rc = msg_q_register(iv_attrSyncMsgQ, ATTRRP_ATTR_SYNC_MSG_Q); + assert(rc == 0, "Bug! Unable to register attribute sync message " + "queue"); + + // Spawn attribute sync thread + task_create(&AttrRP::startAttrSyncTask, this); + if(iv_isMpipl) { populateAttrsForMpipl(); @@ -131,6 +153,246 @@ namespace TARGETING io_taskRetErrl = l_errl; } + void AttrRP::notifyResourceReady(const RESOURCE i_resource) + { + Singleton<AttrRP>::instance()._notifyResourceReady(i_resource); + } + + void AttrRP::_notifyResourceReady(const RESOURCE i_resource) const + { + TRACFCOMP(g_trac_targeting, ENTER_MRK + "AttrRP::notifyResourceReady: resource type = 0x%02X.", + i_resource); + + auto pMsg = msg_allocate(); + + switch (i_resource) + { + case MAILBOX: + { + pMsg->type = MSG_PRIME_SHUTDOWN_ATTR_SYNC; + } + break; + default: + { + TRACFCOMP(g_trac_targeting, ERR_MRK + "AttrRP::notifyResourceReady: Bug! Unhandled " + "resource type = 0x%02X.", + i_resource); + assert(0); + } + break; + } + + auto rc = msg_send(iv_attrSyncMsgQ,pMsg); + if (rc) + { + TRACFCOMP(g_trac_targeting, ERR_MRK + "AttrRP::notifyResourceReady: Failed in msg_send for " + "resource type = 0x%02X, message type = 0x%08X; rc = %d.", + i_resource,pMsg->type,rc); + /*@ + * @errortype + * @moduleid TARG_NOTIFY_RESOURCE_READY + * @reasoncode TARG_RC_ATTR_MSG_FAIL + * @userdata1 Resource type + * @userdata2 Return code + * @devdesc Failed to alert attribute resource provider that a + * specific resource is available. Various shutdown + * steps, such as synchronizing attributes to FSP, may not + * trigger as a result. + * @custdesc Unexpected boot firmware error occurred + */ + errlHndl_t pError = new ErrlEntry( + ERRL_SEV_UNRECOVERABLE, + TARG_NOTIFY_RESOURCE_READY, + TARG_RC_ATTR_MSG_FAIL, + i_resource, + static_cast<uint64_t>(rc), + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + + errlCommit(pError,TARG_COMP_ID); + } + + TRACFCOMP(g_trac_targeting, EXIT_MRK + "AttrRP::notifyResourceReady: rc = %d.",rc); + } + + void AttrRP::invokeShutdownAttrSync() const + { + errlHndl_t pError = nullptr; + + do { + + if(!iv_shutdownAttrSyncPrimed) + { + TRACFCOMP(g_trac_targeting, INFO_MRK "invokeShutdownAttrSync: " + "Shutdown attribute sync not primed; suppressing " + "attribute sync."); + break; + } + + // Nothing to do unless FSP is available to respond to the attribute + // sync request + if(!INITSERVICE::spBaseServicesEnabled()) + { + TRACFCOMP(g_trac_targeting, INFO_MRK "invokeShutdownAttrSync: " + "FSP services not available; suppressing " + "attribute sync."); + break; + } + + // Ensure that SBE is not quiesced (in which case mailbox related SBE + // FIFO traffic will not be serviced) + TARGETING::Target* pMasterProc=nullptr; + + // Master processor is assumed to be functional since we're running on + // it; if no functional master is found, we'll error out. + pError = TARGETING::targetService().queryMasterProcChipTargetHandle( + pMasterProc); + if(pError) + { + TRACFCOMP(g_trac_targeting, ERR_MRK "invokeShutdownAttrSync: " + "Failed to determine master processor target; " + "suppressing attribute sync."); + break; + } + + if(pMasterProc->getAttr<TARGETING::ATTR_ASSUME_SBE_QUIESCED>()) + { + TRACFCOMP(g_trac_targeting, INFO_MRK "invokeShutdownAttrSync; SBE " + "is quiesced; suppressing attribute sync."); + break; + } + + pError = syncAllAttributesToFsp(); + if(pError) + { + TRACFCOMP(g_trac_targeting, ERR_MRK "invokeShutdownAttrSync: " + "Failed syncing attributes to FSP."); + break; + } + + } while(0); + + if(pError) + { + errlCommit(pError,TARG_COMP_ID); + } + } + + void AttrRP::attrSyncTask() + { + // Crash Hostboot if this task dies + (void)task_detach(); + + TRACFCOMP(g_trac_targeting, ENTER_MRK "AttrRP::attrSyncTask."); + + // Register to synchronize applicable attributes down to FSP when + // a shutdown occurs. NO_PRIORITY priority forces the attribute + // synchronization to complete prior to the mailbox shutdown. + // Intentionally ignores the return code that simply indicates if this + // registration happened already. + INITSERVICE::registerShutdownEvent(TARG_COMP_ID, + iv_attrSyncMsgQ, + MSG_INVOKE_SHUTDOWN_ATTR_SYNC, + INITSERVICE::NO_PRIORITY); + while(1) + { + int rc = 0; + + auto pMsg = msg_wait(iv_attrSyncMsgQ); + if (!pMsg) + { + continue; + } + + TRACFCOMP(g_trac_targeting, INFO_MRK + "AttrRP: attrSyncTask: " + "Received message of type = 0x%08X.", + pMsg->type); + + do { + + switch(pMsg->type) + { + case MSG_PRIME_SHUTDOWN_ATTR_SYNC: + { + iv_shutdownAttrSyncPrimed=true; + TRACFCOMP(g_trac_targeting, INFO_MRK + "AttrRP: attrSyncTask: " + "Attribute provider primed to synchronize " + "attributes at shutdown."); + } + break; + case MSG_INVOKE_SHUTDOWN_ATTR_SYNC: + { + TRACFCOMP(g_trac_targeting, INFO_MRK + "AttrRP: attrSyncTask: " + "Invoking shutdown attribute sync."); + + (void)invokeShutdownAttrSync(); + } + break; + default: + { + TRACFCOMP(g_trac_targeting,ERR_MRK + "AttrRP: attrSyncTask: " + "Unhandled message type = 0x%08X.", + pMsg->type); + rc = -EINVAL; + } + break; + } + + } while (0); + + if (rc != 0) + { + /*@ + * @errortype + * @moduleid TARG_ATTR_SYNC_TASK + * @reasoncode TARG_RC_UNSUPPORTED_ATTR_SYNC_MSG + * @userdata1 Return code + * @userdata2 Message type + * @devdesc Invalid message type requested through the + * attribute resource provider's attribute synchronization + * sync daemon. + * @custdesc Unexpected boot firmware failure + */ + auto pError = new ErrlEntry( + ERRL_SEV_UNRECOVERABLE, + TARG_ATTR_SYNC_TASK, + TARG_RC_UNSUPPORTED_ATTR_SYNC_MSG, + TO_UINT64(rc), + TO_UINT64(pMsg->type), + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + errlCommit(pError,TARG_COMP_ID); + } + + if(msg_is_async(pMsg)) + { + // When caller sends an async message, the receiver must + // deallocate the message + (void)msg_free(pMsg); + // Free doesn't nullify the caller's pointer automatically, + pMsg=nullptr; + } + else + { + // Respond to request. + pMsg->data[1] = rc; + rc = msg_respond(iv_attrSyncMsgQ, pMsg); + if (rc) + { + TRACFCOMP(g_trac_targeting,ERR_MRK + "AttrRP: attrSyncTask: " + "Bad rc = %d from msg_respond.", rc); + } + } + } + } + void AttrRP::msgServiceTask() const { TRACFCOMP(g_trac_targeting, ENTER_MRK "AttrRP::msgServiceTask"); @@ -152,17 +414,27 @@ namespace TARGETING uint64_t size = 0; TRACDCOMP(g_trac_targeting, INFO_MRK "AttrRP: Message recv'd: " - "0x%x"); + "0x%08X",msg->type); + + // These messages are sent directly from the kernel and have + // virtual/physical addresses for data 0 and 1 respectively. + const std::array<uint32_t,2> kernelMessageTypes = + {MSG_MM_RP_READ, + MSG_MM_RP_WRITE}; do { - if (msg->type != MSG_MM_RP_RUNTIME_PREP) + if( std::find(kernelMessageTypes.begin(), + kernelMessageTypes.end(), + msg->type) + != kernelMessageTypes.end()) { vAddr = msg->data[0]; pAddr = reinterpret_cast<void*>(msg->data[1]); - TRACDCOMP(g_trac_targeting, - INFO_MRK "AttrRP: vAddr=0x%lx pAddr=0x%p", + TRACDCOMP(g_trac_targeting,INFO_MRK + "AttrRP: message type = 0x%08X, vAddr = 0x%016llX, " + "pAddr = 0x%016llX.", msg->type, vAddr, pAddr); // Locate corresponding attribute section for message. @@ -337,7 +609,7 @@ namespace TARGETING if (rc) { TRACFCOMP(g_trac_targeting, - ERR_MRK "AttrRP: Bad rc from msg_respond: %d", rc); + ERR_MRK"AttrRP: Bad rc from msg_respond: %d", rc); } } } diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml index 3b8dfe27b..fcef2071a 100755 --- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml @@ -52,6 +52,30 @@ </attribute> <attribute> + <id>ASSUME_SBE_QUIESCED</id> + <description> + Returns whether to treat SBE as quiesced or not. When Hostboot goes + through an SBE update (always during key transition, possibly during + normal flow), it may attempt to quiesce the SBE. Whether or not this + was successful, firmware should treat the SBE as if it had been + quiesced (and inhibit attribute synchronization during shutdown, etc.) + + Valid values (bool): + 0x00: Do not assume SBE is quiesced + !0x00: Assume SBE is quiesced + </description> + <simpleType> + <uint8_t> + <default>0</default> + </uint8_t> + </simpleType> + <persistency>volatile-zeroed</persistency> + <readable/> + <writeable/> + <hbOnly/> + </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 3e5991649..7ac29598f 100644 --- a/src/usr/targeting/common/xmltohb/target_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml @@ -87,6 +87,9 @@ <targetTypeExtension> <id>chip-processor</id> <attribute> + <id>ASSUME_SBE_QUIESCED</id> + </attribute> + <attribute> <id>FSI_MASTER_MUTEX</id> </attribute> <attribute> diff --git a/src/usr/targeting/makefile b/src/usr/targeting/makefile index cc2ed607b..531c3fb7f 100644 --- a/src/usr/targeting/makefile +++ b/src/usr/targeting/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2011,2017 +# Contributors Listed Below - COPYRIGHT 2011,2018 # [+] International Business Machines Corp. # # @@ -37,6 +37,10 @@ TARGETING_REL_PATH = . include ${TARGETING_REL_PATH}/hostboot_common.mk +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/sbe +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc + ATTR_RP_OBJS += attrrp.o ATTR_RP_OBJS += attrsync.o ATTR_RP_OBJS += targplatutil.o |