From b0da5312bac172bdea608371f647fd1bafb87bce Mon Sep 17 00:00:00 2001 From: crgeddes Date: Mon, 14 Aug 2017 16:39:58 -0500 Subject: Use keyAddr stash chipop to pass rsv mem addr through SBE for MPIPL Previously we were relying on the reservedMem section to be a certain address for the attrrp to find after an MPIPL. With this change the address is passed through the SBE so the reservedMem data can be anywhere RTC: 165369 Change-Id: I06521c049088c4a53a8c0a51fa07e5200da09483 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/44624 Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Brian E. Bakke Reviewed-by: Martin Gloff Tested-by: FSP CI Jenkins Reviewed-by: Daniel M. Crowell --- src/include/usr/sbeio/sbe_psudd.H | 42 +----- src/include/usr/sbeio/sbe_sp_intf.H | 15 +- src/include/usr/sbeio/sbeioif.H | 19 ++- src/usr/runtime/populate_hbruntime.C | 259 ++++++++++++++++++++--------------- src/usr/sbeio/sbe_memRegionMgr.C | 4 +- src/usr/sbeio/sbe_stashKeyAddr.C | 24 ++++ src/usr/targeting/attrrp.C | 24 +++- 7 files changed, 226 insertions(+), 161 deletions(-) mode change 100755 => 100644 src/include/usr/sbeio/sbe_sp_intf.H (limited to 'src') diff --git a/src/include/usr/sbeio/sbe_psudd.H b/src/include/usr/sbeio/sbe_psudd.H index cd8b08050..d4fd7e642 100644 --- a/src/include/usr/sbeio/sbe_psudd.H +++ b/src/include/usr/sbeio/sbe_psudd.H @@ -36,6 +36,7 @@ #include #include +#include "sbe_sp_intf.H" #include namespace SBEIO @@ -516,47 +517,6 @@ class SbePsu */ static const uint64_t MAX_PSU_SHORT_TIMEOUT_NS=90*NS_PER_SEC; //=90sec - /** - * @brief enums for primary SBE response - * - */ - enum sbePrimResponse - { - SBE_PRI_OPERATION_SUCCESSFUL = 0x00, - SBE_PRI_INVALID_COMMAND = 0x01, - SBE_PRI_INVALID_DATA = 0x02, - SBE_PRI_SEQUENCE_ERROR = 0x03, - SBE_PRI_INTERNAL_ERROR = 0x04, - SBE_PRI_GENERIC_EXECUTION_FAILURE = 0xFE, - }; - - /** - * @brief enums for secondary SBE response - * Discuss on SBE_SEC_INVALID_TARGET_ID_PASSED - * - */ - enum sbeSecondaryResponse - { - SBE_SEC_OPERATION_SUCCESSFUL = 0x00, - SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED = 0x01, - SBE_SEC_COMMAND_NOT_SUPPORTED = 0x02, - SBE_SEC_INVALID_ADDRESS_PASSED = 0x03, - SBE_SEC_INVALID_TARGET_TYPE_PASSED = 0x04, - SBE_SEC_INVALID_TARGET_ID_PASSED = 0x05, - SBE_SEC_SPECIFIED_TARGET_NOT_PRESENT = 0x06, - SBE_SEC_SPECIFIED_TARGET_NOT_FUNCTIONAL = 0x07, - SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE = 0x08, - SBE_SEC_FUNCTIONALITY_NOT_SUPPORTED = 0x09, - SBE_SEC_GENERIC_FAILURE_IN_EXECUTION = 0x0A, - SBE_SEC_BACKLISTED_ACCESS = 0x0B, - SBE_SEC_OS_FAILURE = 0x0C, - SBE_SEC_HOST_MBX_REG_ACCESS_FAILURE = 0x0D, - SBE_SEC_INSUFFICIENT_DATA_PASSED = 0x0E, - SBE_SEC_EXCESS_DATA_PASSED = 0x0F, - SBE_SEC_SBE_BUSY_TO_HANDLE_COMMAND = 0x10, - SBE_SEC_MEM_REGION_NOT_FOUND = 0x11, - SBE_SEC_EXCEEDED_MAX_NUM_MEM_REGIONS = 0x12, - }; enum SBE_TARGET_TYPES { diff --git a/src/include/usr/sbeio/sbe_sp_intf.H b/src/include/usr/sbeio/sbe_sp_intf.H old mode 100755 new mode 100644 index 8ed182a46..fe5fa9981 --- a/src/include/usr/sbeio/sbe_sp_intf.H +++ b/src/include/usr/sbeio/sbe_sp_intf.H @@ -177,8 +177,9 @@ enum sbePrimResponse SBE_PRI_OPERATION_SUCCESSFUL = 0x00, SBE_PRI_INVALID_COMMAND = 0x01, SBE_PRI_INVALID_DATA = 0x02, - SBE_PRI_SEQUENCE_ERROR = 0x03, + SBE_PRI_USER_ERROR = 0x03, SBE_PRI_INTERNAL_ERROR = 0x04, + SBE_PRI_UNSECURE_ACCESS_DENIED = 0x05, SBE_PRI_GENERIC_EXECUTION_FAILURE = 0xFE, }; @@ -195,13 +196,13 @@ enum sbeSecondaryResponse SBE_SEC_COMMAND_NOT_SUPPORTED = 0x02, SBE_SEC_INVALID_ADDRESS_PASSED = 0x03, SBE_SEC_INVALID_TARGET_TYPE_PASSED = 0x04, - SBE_SEC_INVALID_TARGET_ID_PASSED = 0x05, + SBE_SEC_INVALID_CHIPLET_ID_PASSED = 0x05, SBE_SEC_SPECIFIED_TARGET_NOT_PRESENT = 0x06, SBE_SEC_SPECIFIED_TARGET_NOT_FUNCTIONAL = 0x07, SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE = 0x08, SBE_SEC_FUNCTIONALITY_NOT_SUPPORTED = 0x09, SBE_SEC_GENERIC_FAILURE_IN_EXECUTION = 0x0A, - SBE_SEC_SECURITY_VALIDATION_FAILED = 0x0B, + SBE_SEC_BLACKLISTED_REG_ACCESS = 0x0B, SBE_SEC_OS_FAILURE = 0x0C, SBE_SEC_FIFO_ACCESS_FAILURE = 0x0D, SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA = 0x0E, @@ -210,6 +211,11 @@ enum sbeSecondaryResponse SBE_SEC_PCB_PIB_ERR = 0x11, SBE_SEC_FIFO_PARITY_ERROR = 0x12, SBE_SEC_TIMER_ALREADY_STARTED = 0x13, + SBE_SEC_BLACKLISTED_MEM_ACCESS = 0x14, + SBE_SEC_MEM_REGION_NOT_FOUND = 0x15, + SBE_SEC_MAXIMUM_MEM_REGION_EXCEEDED = 0x16, + SBE_SEC_MEM_REGION_AMEND_ATTEMPTED = 0x17, + SBE_SEC_INPUT_BUFFER_OVERFLOW = 0x18, }; /** @@ -293,6 +299,7 @@ enum sbeMemoryAccessFlags SBE_MEM_ACCESS_FLAGS_FAST_MODE_ON = 0x0020, SBE_MEM_ACCESS_FLAGS_LCO_ENABLED = 0x0040, //required only in PBA-PUT SBE_MEM_ACCESS_FLAGS_CACHE_INHIBIT = 0x0080, //required in I/O oper ADU + SBE_MEM_ACCESS_FLAGS_HOST_PASS_THROUGH = 0x0100, // Host pass through mode (PBA) SBE_MEM_ACCESS_FLAGS_INJECT_ON = 0x0200, // Inject mode ( PBA put ) }; @@ -472,6 +479,8 @@ typedef enum SBE_RING_MODE_SET_PULSE_ALL = 0x0010, ///< Set pulse with pulse /// to all hold types SBE_RING_MODE_FASTARRAY = 0x0020, //Fast array mode + + SBE_RING_MODE_APPLY_OVERRIDE = 0x0040, //override mode } sbeRingAccessModes_t; // Trace array chip-op operation bitmaps diff --git a/src/include/usr/sbeio/sbeioif.H b/src/include/usr/sbeio/sbeioif.H index 6bf1568ab..3e3a3dbae 100644 --- a/src/include/usr/sbeio/sbeioif.H +++ b/src/include/usr/sbeio/sbeioif.H @@ -29,6 +29,15 @@ namespace SBEIO { + enum KeyAddrStashKeys + { + RSV_MEM_ATTR_ADDR = 0x01, //Start at non-zero + //On SBE side struct is defaulted so that + //Keys are 0xFF and Vals are 0xFFFFFFFFFFFFFFFF + //So a key w/ FF means its empty or at its default val + SBE_DEFAULT = 0xFF + }; + /** * @brief Start Deadman loop * @@ -86,16 +95,18 @@ namespace SBEIO errlHndl_t sendPsuQuiesceSbe(TARGETING::Target * i_target); /** - * @brief Sends a PSU chipOp to quiesce the SBE + * @brief Sends a PSU chipOp to stash away a key,addr pair on the SBE * - * @param[in] i_key The key used to identify what the value is - * @param[in] i_value Value that will be passed (likely an address) + * @param[in] i_key The key used to identify what the value is + * @param[in] i_value Value that will be passed (likely an address) + * @param[in] i_procChip The proc we wish to send the op to * * @return errlHndl_t Error log handle on failure. * */ errlHndl_t sendPsuStashKeyAddrRequest(const uint8_t i_key, - const uint64_t i_value); + const uint64_t i_value, + TARGETING::Target * i_procChip); /** * @brief Get SCOM via SBE FIFO diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C index e1f17bdae..e1ccf9888 100644 --- a/src/usr/runtime/populate_hbruntime.C +++ b/src/usr/runtime/populate_hbruntime.C @@ -589,127 +589,127 @@ errlHndl_t hbResvLoadSecureSection (const PNOR::SectionId i_sec, do { #ifdef CONFIG_SECUREBOOT - // Securely Load PNOR section - l_elog = loadSecureSection(i_sec); - if (l_elog) - { - TRACFCOMP( g_trac_runtime, - ERR_MRK"hbResvloadSecureSection() - Error from " - "loadSecureSection(%s)", PNOR::SectionIdToString(i_sec)); - break; - } + // Securely Load PNOR section + l_elog = loadSecureSection(i_sec); + if (l_elog) + { + TRACFCOMP( g_trac_runtime, + ERR_MRK"hbResvloadSecureSection() - Error from " + "loadSecureSection(%s)", PNOR::SectionIdToString(i_sec)); + break; + } #endif - l_elog = PNOR::getSectionInfo( i_sec, l_info ); - if(l_elog) - { - //No need to commit error here, it gets handled later - //just break out to escape this function - TRACFCOMP( g_trac_runtime, ERR_MRK"hbResvloadSecureSection() getSectionInfo failed"); - break; - } + l_elog = PNOR::getSectionInfo( i_sec, l_info ); + if(l_elog) + { + //No need to commit error here, it gets handled later + //just break out to escape this function + TRACFCOMP( g_trac_runtime, ERR_MRK"hbResvloadSecureSection() getSectionInfo failed"); + break; + } - auto l_pnorVaddr = l_info.vaddr; - auto l_imgSize = l_info.size; - // If section is signed, only the protected size was loaded into memory + auto l_pnorVaddr = l_info.vaddr; + auto l_imgSize = l_info.size; + // If section is signed, only the protected size was loaded into memory #ifdef CONFIG_SECUREBOOT - if (l_info.secure) - { - l_imgSize = l_info.secureProtectedPayloadSize; - // Include secure header - l_pnorVaddr -= PAGESIZE; - l_imgSize += PAGESIZE; - } + if (l_info.secure) + { + l_imgSize = l_info.secureProtectedPayloadSize; + // Include secure header + l_pnorVaddr -= PAGESIZE; + l_imgSize += PAGESIZE; + } #endif - // Align size for OPAL - size_t l_imgSizeAligned = ALIGN_X(l_imgSize, HBRT_RSVD_MEM_OPAL_ALIGN); + // Align size for OPAL + size_t l_imgSizeAligned = ALIGN_X(l_imgSize, HBRT_RSVD_MEM_OPAL_ALIGN); - // For PHYP we build up starting at the end of the previously allocated - // areas, for OPAL we build downwards from the top of memory - uint64_t l_imgAdd = 0x0; - if(TARGETING::is_phyp_load()) - { - l_imgAdd = io_prevAddr + io_prevSize; - } - else if(TARGETING::is_sapphire_load()) - { - l_imgAdd = io_prevAddr - l_imgSizeAligned; - } + // For PHYP we build up starting at the end of the previously allocated + // areas, for OPAL we build downwards from the top of memory + uint64_t l_imgAdd = 0x0; + if(TARGETING::is_phyp_load()) + { + l_imgAdd = io_prevAddr + io_prevSize; + } + else if(TARGETING::is_sapphire_load()) + { + l_imgAdd = io_prevAddr - l_imgSizeAligned; + } - auto l_lids = Util::getPnorSecLidIds(i_sec); - TRACFCOMP(g_trac_runtime, "hbResvloadSecureSection() getPnorSecLidIds lid = 0x%X, containerLid = 0x%X", - l_lids.lid, l_lids.containerLid); - assert(l_lids.lid != Util::INVALID_LIDID,"Pnor Section = %s not associated with any Lids", PNOR::SectionIdToString(i_sec)); - -// @TODO RTC:178163 enabled when HDAT support is complete for extra HB resv mem entries -// PHYP will use these 2 entries in the future -/* - // Verified Lid - Header Only - char l_containerLidStr [Util::lidIdStrLength]; - snprintf (l_containerLidStr, Util::lidIdStrLength, "%X", - l_lids.containerLid); - l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_VERIFIED_LIDS, - i_rangeId, - l_imgAdd, - l_imgSizeAligned, - l_containerLidStr); - if(l_elog) - { - TRACFCOMP( g_trac_runtime, ERR_MRK"hbResvloadSecureSection() setNextHbRsvMemEntry Lid header failed"); - break; - } + auto l_lids = Util::getPnorSecLidIds(i_sec); + TRACFCOMP(g_trac_runtime, "hbResvloadSecureSection() getPnorSecLidIds lid = 0x%X, containerLid = 0x%X", + l_lids.lid, l_lids.containerLid); + assert(l_lids.lid != Util::INVALID_LIDID,"Pnor Section = %s not associated with any Lids", PNOR::SectionIdToString(i_sec)); + + // @TODO RTC:178163 enabled when HDAT support is complete for extra HB resv mem entries + // PHYP will use these 2 entries in the future + /* + // Verified Lid - Header Only + char l_containerLidStr [Util::lidIdStrLength]; + snprintf (l_containerLidStr, Util::lidIdStrLength, "%X", + l_lids.containerLid); + l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_VERIFIED_LIDS, + i_rangeId, + l_imgAdd, + l_imgSizeAligned, + l_containerLidStr); + if(l_elog) + { + TRACFCOMP( g_trac_runtime, ERR_MRK"hbResvloadSecureSection() setNextHbRsvMemEntry Lid header failed"); + break; + } - // Verified Lid - Content Only - char l_lidStr[Util::lidIdStrLength]; - snprintf (l_lidStr, Util::lidIdStrLength, "%X",l_lids.lid); - l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_VERIFIED_LIDS, - i_rangeId, - l_imgAdd+PAGE_SIZE, - l_imgSizeAligned, - l_lidStr); - if(l_elog) - { - TRACFCOMP( g_trac_runtime, ERR_MRK"hbResvloadSecureSection() setNextHbRsvMemEntry Lid content failed"); - break; - } -*/ - // Verified PNOR - Header + Content - l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_VERIFIED_PNOR, - i_rangeId, - l_imgAdd, - l_imgSizeAligned, - PNOR::SectionIdToString(i_sec)); - if(l_elog) - { - TRACFCOMP( g_trac_runtime, ERR_MRK"hbResvloadSecureSection() setNextHbRsvMemEntry PNOR content failed"); - break; - } + // Verified Lid - Content Only + char l_lidStr[Util::lidIdStrLength]; + snprintf (l_lidStr, Util::lidIdStrLength, "%X",l_lids.lid); + l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_VERIFIED_LIDS, + i_rangeId, + l_imgAdd+PAGE_SIZE, + l_imgSizeAligned, + l_lidStr); + if(l_elog) + { + TRACFCOMP( g_trac_runtime, ERR_MRK"hbResvloadSecureSection() setNextHbRsvMemEntry Lid content failed"); + break; + } + */ + // Verified PNOR - Header + Content + l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_VERIFIED_PNOR, + i_rangeId, + l_imgAdd, + l_imgSizeAligned, + PNOR::SectionIdToString(i_sec)); + if(l_elog) + { + TRACFCOMP( g_trac_runtime, ERR_MRK"hbResvloadSecureSection() setNextHbRsvMemEntry PNOR content failed"); + break; + } - io_prevAddr = l_imgAdd; - // Use aligned size for OPAL alignment even if that means there is some - // wasted space. - io_prevSize = l_imgSizeAligned; + io_prevAddr = l_imgAdd; + // Use aligned size for OPAL alignment even if that means there is some + // wasted space. + io_prevSize = l_imgSizeAligned; - // Load the Verified image into HB resv memory - l_elog = mapPhysAddr(l_imgAdd, l_imgSize, l_tmpVaddr); - if(l_elog) - { - TRACFCOMP( g_trac_runtime, ERR_MRK"hbResvloadSecureSection() mapPhysAddr failed"); - break; - } + // Load the Verified image into HB resv memory + l_elog = mapPhysAddr(l_imgAdd, l_imgSize, l_tmpVaddr); + if(l_elog) + { + TRACFCOMP( g_trac_runtime, ERR_MRK"hbResvloadSecureSection() mapPhysAddr failed"); + break; + } - // Include Header page from pnor image. - memcpy(reinterpret_cast(l_tmpVaddr), - reinterpret_cast(l_pnorVaddr), - l_imgSize); + // Include Header page from pnor image. + memcpy(reinterpret_cast(l_tmpVaddr), + reinterpret_cast(l_pnorVaddr), + l_imgSize); - l_elog = unmapVirtAddr(l_tmpVaddr); - if(l_elog) - { - TRACFCOMP( g_trac_runtime, ERR_MRK"hbResvloadSecureSection() unmapVirtAddr failed"); - break; - } + l_elog = unmapVirtAddr(l_tmpVaddr); + if(l_elog) + { + TRACFCOMP( g_trac_runtime, ERR_MRK"hbResvloadSecureSection() unmapVirtAddr failed"); + break; + } } while(0); return l_elog; @@ -877,6 +877,26 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) break; } + // Loop through all functional Procs + for (const auto & l_procChip: l_procChips) + { + //Pass start address down to SBE via chipop + l_elog = SBEIO::sendPsuStashKeyAddrRequest(SBEIO::RSV_MEM_ATTR_ADDR, + l_startAddr, + l_procChip); + if (l_elog) + { + TRACFCOMP( g_trac_runtime, "sendPsuStashKeyAddrRequest failed for target: %x", + TARGETING::get_huid(l_procChip) ); + break; + } + } + + if (l_elog) + { + break; + } + l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_HBRT, i_nodeId, l_startAddr, @@ -986,7 +1006,7 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) uint64_t l_sbeffdcSize = SBEIO::SbePsu::getTheInstance().getSbeFFDCBufferSize(); - // Algin size for OPAL + // Align size for OPAL size_t l_sbeCommSizeAligned = ALIGN_X( l_sbeCommSize, HBRT_RSVD_MEM_OPAL_ALIGN ); size_t l_sbeffdcSizeAligned = ALIGN_X( l_sbeffdcSize, @@ -1985,6 +2005,27 @@ errlHndl_t populate_hbRuntimeData( void ) { TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData failed" ); } + + // Get list of processor chips + TARGETING::TargetHandleList l_procChips; + getAllChips( l_procChips, + TARGETING::TYPE_PROC, + true); + //Pass start address down to SBE via chipop + // Loop through all functional Procs + for (const auto & l_procChip: l_procChips) + { + //Pass start address down to SBE via chip-op + l_elog = SBEIO::sendPsuStashKeyAddrRequest(SBEIO::RSV_MEM_ATTR_ADDR, + l_startAddr, + l_procChip); + if (l_elog) + { + TRACFCOMP( g_trac_runtime, "sendPsuStashKeyAddrRequest failed for target: %x", + TARGETING::get_huid(l_procChip) ); + break; + } + } } break; } diff --git a/src/usr/sbeio/sbe_memRegionMgr.C b/src/usr/sbeio/sbe_memRegionMgr.C index 01c6ed5c5..eb0bef9cd 100644 --- a/src/usr/sbeio/sbe_memRegionMgr.C +++ b/src/usr/sbeio/sbe_memRegionMgr.C @@ -682,9 +682,9 @@ errlHndl_t MemRegionMgr::doUnsecureMemRegionOp(regionData & i_region) // includes the Unsecure Memory Region commands) Informational if ((!SECUREBOOT::enabled()) && (l_psuResponse.primaryStatus == - SbePsu::SBE_PRI_INVALID_COMMAND) && + SBE_PRI_INVALID_COMMAND) && (l_psuResponse.secondaryStatus == - SbePsu::SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED) + SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED) ) { SBE_TRACF(ERR_MRK "doUnsecureMemRegionOp: Secureboot NOT " diff --git a/src/usr/sbeio/sbe_stashKeyAddr.C b/src/usr/sbeio/sbe_stashKeyAddr.C index a6af2ba6a..8ce3e6833 100644 --- a/src/usr/sbeio/sbe_stashKeyAddr.C +++ b/src/usr/sbeio/sbe_stashKeyAddr.C @@ -77,6 +77,30 @@ namespace SBEIO SbePsu::SBE_STASH_KEY_ADDR_REQ_USED_REGS, SbePsu::SBE_STASH_KEY_ADDR_RSP_USED_REGS); + if (errl) + { + SBE_TRACF(ERR_MRK "sendPsuStashKeyAddrRequest: PSU Cmd Failed: " + "err rc=0x%.4X plid=0x%.8X", + ERRL_GETRC_SAFE(errl), ERRL_GETPLID_SAFE(errl)); + + // If the error states that the command is not supported on SBE then set as informational log + if ((l_psuResponse.primaryStatus == + SBE_PRI_INVALID_COMMAND) && + (l_psuResponse.secondaryStatus == + SBE_SEC_COMMAND_NOT_SUPPORTED) + ) + { + SBE_TRACF(ERR_MRK "sendPsuStashKeyAddrRequest: Changing 'Command Not Supported' Error Log To Informational."); + errl->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL); + errl->collectTrace(SBEIO_COMP_NAME); + } + else if (l_psuResponse.secondaryStatus == SBE_SEC_INPUT_BUFFER_OVERFLOW) + { + SBE_TRACF(ERR_MRK "sendPsuStashKeyAddrRequest: Input buffer overflow, we are attempting to stash too many pairs"); + errl->collectTrace(SBEIO_COMP_NAME); + } + } + SBE_TRACD(EXIT_MRK "stashKeyAddr"); return errl; diff --git a/src/usr/targeting/attrrp.C b/src/usr/targeting/attrrp.C index 2c9f0b6fe..b4d5ce155 100755 --- a/src/usr/targeting/attrrp.C +++ b/src/usr/targeting/attrrp.C @@ -53,6 +53,9 @@ #include #include #include +#include +#include +#include using namespace INITSERVICE; using namespace ERRORLOG; @@ -377,8 +380,25 @@ namespace TARGETING uint64_t l_attr_data_size = 0; // Setup physical TOC address - uint64_t l_toc_addr = cpu_spr_value(CPU_SPR_HRMOR) + - VMM_HB_DATA_TOC_START_OFFSET; + uint64_t l_toc_addr = 0; + + Bootloader::keyAddrPair_t l_keyAddrPairs = + g_BlToHbDataManager.getKeyAddrPairs(); + + for (uint8_t keyIndex = 0; keyIndex < MAX_ROW_COUNT; keyIndex++) + { + if(l_keyAddrPairs.key[keyIndex] == SBEIO::RSV_MEM_ATTR_ADDR) + { + l_toc_addr = l_keyAddrPairs.addr[keyIndex]; + } + } + + if(!l_toc_addr) + { + // Setup physical TOC address to hardcoded value + l_toc_addr = cpu_spr_value(CPU_SPR_HRMOR) + + VMM_HB_DATA_TOC_START_OFFSET; + } // Now map the TOC to find the ATTR label address & size Util::hbrtTableOfContents_t * l_toc_ptr = -- cgit v1.2.1