diff options
author | Matt Derksen <mderkse1@us.ibm.com> | 2017-05-30 15:25:20 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-06-12 11:42:37 -0400 |
commit | 94010840e9551be4711ac135c9855b7f0cecb3a3 (patch) | |
tree | 2398d28f8123c7f262160e6b87f993756be98eb7 | |
parent | 1c2fcebe0a3fde901e9a621a6f7362fb2cf1d200 (diff) | |
download | talos-hostboot-94010840e9551be4711ac135c9855b7f0cecb3a3.tar.gz talos-hostboot-94010840e9551be4711ac135c9855b7f0cecb3a3.zip |
Consolidating HBRT reserved memory (ATTR,ATTR_OVERRIDE,VPD) into a single entry
Change-Id: I9fc5846d9901ac79c59bb149b8f55b5c7ca2fa73
RTC: 171863
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/41141
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Martin Gloff <mgloff@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r-- | src/include/runtime/interface.h | 2 | ||||
-rw-r--r-- | src/include/usr/runtime/runtime_reasoncodes.H | 2 | ||||
-rw-r--r-- | src/include/usr/targeting/attrrp.H | 16 | ||||
-rw-r--r-- | src/include/usr/targeting/targplatreasoncodes.H | 1 | ||||
-rw-r--r-- | src/include/usr/util/runtime/util_rt.H | 84 | ||||
-rw-r--r-- | src/include/usr/vmmconst.h | 9 | ||||
-rw-r--r-- | src/include/usr/vpd/vpd_if.H | 8 | ||||
-rw-r--r-- | src/usr/isteps/istep21/call_host_runtime_setup.C | 23 | ||||
-rw-r--r-- | src/usr/runtime/populate_hbruntime.C | 516 | ||||
-rwxr-xr-x | src/usr/targeting/attrrp.C | 67 | ||||
-rw-r--r-- | src/usr/targeting/runtime/attrPlatOverride_rt.C | 29 | ||||
-rw-r--r-- | src/usr/targeting/runtime/attrrp_rt.C | 5 | ||||
-rw-r--r-- | src/usr/targeting/runtime/test/testtargeting.H | 4 | ||||
-rw-r--r-- | src/usr/testcore/rtloader/loader.H | 221 | ||||
-rw-r--r-- | src/usr/util/runtime/makefile | 3 | ||||
-rw-r--r-- | src/usr/util/runtime/util_rt.C | 107 | ||||
-rw-r--r-- | src/usr/vpd/rtvpd_load.C | 17 | ||||
-rw-r--r-- | src/usr/vpd/runtime/rt_vpd.C | 47 |
18 files changed, 793 insertions, 368 deletions
diff --git a/src/include/runtime/interface.h b/src/include/runtime/interface.h index 3a94146be..e3231b625 100644 --- a/src/include/runtime/interface.h +++ b/src/include/runtime/interface.h @@ -129,6 +129,8 @@ enum MemoryError_t #define HBRT_RSVD_MEM__SBE_COMM "ibm,sbe-comm" #define HBRT_RSVD_MEM__SBE_FFDC "ibm,sbe-ffdc" #define HBRT_RSVD_MEM__SECUREBOOT "ibm,secure-crypt-algo-code" +#define HBRT_RSVD_MEM__DATA "ibm,hbrt-data" + /** diff --git a/src/include/usr/runtime/runtime_reasoncodes.H b/src/include/usr/runtime/runtime_reasoncodes.H index 81eeb90cc..d5af4f2a6 100644 --- a/src/include/usr/runtime/runtime_reasoncodes.H +++ b/src/include/usr/runtime/runtime_reasoncodes.H @@ -55,6 +55,7 @@ namespace RUNTIME MOD_MAP_PHYS_ADDR = 0x17, /**< populate_hbruntime.C */ MOD_UNMAP_VIRT_ADDR = 0x18, /**< populate_hbruntime.C */ MOD_POPULATE_TPMINFOBYNODE = 0x19, /**< populate_hbruntime.C */ + MOD_FILL_RSVMEM_HBDATA = 0x20, /**< populate_hbruntime.C */ }; enum RuntimeReasonCode @@ -98,6 +99,7 @@ namespace RUNTIME RC_I2C_DEVICE_DUPLICATE_IN_MRW = RUNTIME_COMP_ID | 0x24, RC_EXTRA_I2C_DEVICE_IN_MRW = RUNTIME_COMP_ID | 0x25, RC_GETTUPLE_UNSUPPORTED = RUNTIME_COMP_ID | 0x26, + RC_EXCEEDED_MEMORY = RUNTIME_COMP_ID | 0x27, }; enum UserDetailsTypes diff --git a/src/include/usr/targeting/attrrp.H b/src/include/usr/targeting/attrrp.H index b9059db96..7e0006bd2 100644 --- a/src/include/usr/targeting/attrrp.H +++ b/src/include/usr/targeting/attrrp.H @@ -171,6 +171,19 @@ class AttrRP static void* save(uint64_t& io_addr); /** + * @brief Copies all present attribute sections to memory. + * + * @param[in] i_dest + * Physical address to copy override data into + * @param[in,out] io_size + * in: Maximum size of allocated space in bytes + * out: Actual number of bytes used (zero means no overrides) + * + * @return Error log + */ + static errlHndl_t save(uint8_t * i_dest, size_t & io_size); + + /** * @brief Returns size needed to save all attributes * * HDAT requires up front knowledge of largest section @@ -328,6 +341,9 @@ class AttrRP /** Internal implementation of save function. */ void* _save(uint64_t&); + /** Internal implementation of save function. */ + errlHndl_t _save(uint8_t* i_dest, size_t& io_size ); + /** Internal implementation of saveOverrides function. */ errlHndl_t _saveOverrides( uint8_t* i_dest, size_t& io_size ); diff --git a/src/include/usr/targeting/targplatreasoncodes.H b/src/include/usr/targeting/targplatreasoncodes.H index 56faa3025..de2283bac 100644 --- a/src/include/usr/targeting/targplatreasoncodes.H +++ b/src/include/usr/targeting/targplatreasoncodes.H @@ -57,6 +57,7 @@ enum PlatTargetingModuleId TARG_MOD_SET_MASTER_NODE = 0x81, TARG_MOD_ATTRRP_RT = 0x82, TARG_MOD_SAVE_OVERRIDE_TANK = 0x83, + TARG_MOD_SAVE_ATTR_TANK = 0x84, }; /** diff --git a/src/include/usr/util/runtime/util_rt.H b/src/include/usr/util/runtime/util_rt.H new file mode 100644 index 000000000..01aebaf1f --- /dev/null +++ b/src/include/usr/util/runtime/util_rt.H @@ -0,0 +1,84 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/util/runtime/util_rt.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 <limits.h> // for KILOBYTE definition + + +/** + * 8-byte ascii entry labels for hbrt TOC + */ +typedef uint64_t hbrt_mem_label_t; + +// Ascii label "VPD " in hex +constexpr hbrt_mem_label_t HBRT_MEM_LABEL_VPD = 0x5650442020202020; + +// Ascii label "ATTR " in hex +constexpr hbrt_mem_label_t HBRT_MEM_LABEL_ATTR = 0x4154545220202020; + +// Ascii label "ATTROVER" in hex +constexpr hbrt_mem_label_t HBRT_MEM_LABEL_ATTROVER = 0x415454524F564552; + +// Ascii label "PADDING " in hex +constexpr hbrt_mem_label_t HBRT_MEM_LABEL_PADDING = 0x50414444494E4720; + +/** @brief A 32 byte table of contents entry */ +struct hbrtTableOfContentsEntry_t +{ + uint64_t label; // ASCII HBRT_LABEL_x constants + uint64_t size; // data entry size in bytes + uint64_t offset; // offset into section + uint64_t reserved; // incase of future change +} __attribute__ ((packed)); + +// MAX ENTRIES = (4 KB - 64 byte header) / 32 bytes per entry = 126 +#define HBRT_TOC_MAX_ENTRIES \ + (((4*KILOBYTE) - 64) / sizeof(hbrtTableOfContentsEntry_t)) + +/** @brief A 4KB Table of Contents */ +struct hbrtTableOfContents_t +{ + char toc_header[32]; // "Hostboot Table of Contents" + uint8_t toc_version; // version + uint16_t total_entries; // Total entries in TOC + uint64_t total_size; // Total data section size (64k aligned) + uint8_t rsvd[21]; // reserved + hbrtTableOfContentsEntry_t entry[HBRT_TOC_MAX_ENTRIES]; +} __attribute__ ((packed)); + +// Versions of table of contents +const uint8_t HBRT_TOC_VERSION_1 = 0x01; + +/** + * @brief Get the address of a reserved hostboot memory region by its label + * @param[in] i_label HBRT_MEM_LABEL_... constant + * @param[in] i_instance instance number + * @param[out] o_size size of returned region in bytes + * @return virtual address of region or 0 + * @platform FSP, OpenPOWER + **/ +uint64_t hb_get_rt_rsvd_mem( hbrt_mem_label_t i_label, + uint32_t i_instance, + uint64_t & o_size ); + diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h index 2f25d7d14..3c57c50f4 100644 --- a/src/include/usr/vmmconst.h +++ b/src/include/usr/vmmconst.h @@ -194,6 +194,15 @@ enum BlockPriority #define DUMP_TEST_MEMORY_ADDR \ (VMM_ATTR_DATA_START_OFFSET + VMM_ATTR_DATA_SIZE) /* currently 202MB */ #define DUMP_TEST_MEMORY_SIZE (4*MEGABYTE) +/** End of Dump Source Table = 206MB */ + +/** Memory for hostboot data Table of Contents */ +#define VMM_HB_DATA_TOC_START_OFFSET \ + (DUMP_TEST_MEMORY_ADDR + DUMP_TEST_MEMORY_SIZE) /* currently 206MB */ +#define VMM_HB_DATA_TOC_END_OFFSET (VMM_HB_DATA_TOC_START_OFFSET + (4*KILOBYTE)) +/** End of HB DATA TOC Area = 206MB + 4KB */ + + /** Internode communication area outside of the HB image. * Preserved between mpipl. diff --git a/src/include/usr/vpd/vpd_if.H b/src/include/usr/vpd/vpd_if.H index c34a465a4..4162e48bc 100644 --- a/src/include/usr/vpd/vpd_if.H +++ b/src/include/usr/vpd/vpd_if.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2016 */ +/* Contributors Listed Below - COPYRIGHT 2013,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -49,10 +49,12 @@ namespace VPD /** * @brief Load the runtime VPD image into memory - * @param[out] The physical address of the VPD image + * @param[in/out] The physical or virtual address of the VPD image + * @param[in] Is the address virtual? * @return error handle if there was an error */ - errlHndl_t vpd_load_rt_image(uint64_t & o_vpd_addr); + errlHndl_t vpd_load_rt_image(uint64_t & io_vpd_addr, + bool i_virtualAddr = false); /** * @brief This function checks to see if the given mvpd target diff --git a/src/usr/isteps/istep21/call_host_runtime_setup.C b/src/usr/isteps/istep21/call_host_runtime_setup.C index 0654239cd..bfc931224 100644 --- a/src/usr/isteps/istep21/call_host_runtime_setup.C +++ b/src/usr/isteps/istep21/call_host_runtime_setup.C @@ -178,20 +178,21 @@ void* call_host_runtime_setup (void *io_pArgs) "Failed hbTpmInfo setup" ); break; } + } - // Fill in Hostboot runtime data for all nodes - // (adjunct partition) - // Write the HB runtime data into mainstore - l_err = RUNTIME::populate_hbRuntimeData(); - if ( l_err ) - { - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "Failed hbRuntimeData setup" ); - // break from do loop if error occured - break; - } + // Fill in Hostboot runtime data for all nodes + // (adjunct partition) + // Write the HB runtime data into mainstore + l_err = RUNTIME::populate_hbRuntimeData(); + if ( l_err ) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "Failed hbRuntimeData setup" ); + // break from do loop if error occurred + break; } + #ifdef CONFIG_START_OCC_DURING_BOOT bool l_activatePM = TARGETING::is_sapphire_load(); #else diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C index 8a2ddd944..998c5a61c 100644 --- a/src/usr/runtime/populate_hbruntime.C +++ b/src/usr/runtime/populate_hbruntime.C @@ -67,6 +67,7 @@ #include <sbeio/sbe_psudd.H> #include <sbeio/runtime/sbe_msg_passing.H> #include <kernel/bltohbdatamgr.H> +#include <util/runtime/util_rt.H> namespace RUNTIME @@ -508,6 +509,296 @@ errlHndl_t setNextHbRsvMemEntry(const HDAT::hdatMsVpdRhbAddrRangeType i_type, } /** + * @brief Load the HB_DATA section for reserved memory + * + * ----- HB Data Layout ------- + * io_start_address + * -- HB Table of Contents + * -- ATTR Override Data + * -- ATTR Data + * -- VPD + * -- Padding + * io_end_address + * + * Either pass in a low starting physical address (io_start_address) or + * a high ending physical address (io_end_address). + * The function will then calculate the size of data and + * determine the opposite address. + * Set i_startAddressValid to true, if you set io_start_address. + * Set i_startAddressValid to false, if you set io_end_address. + * + * @param[in/out] io_start_address where to start loading data + * @param[in/out] io_end_address where to stop loading data + * @param[in] i_startAddressValid Is io_start_address valid? + * @param[out] io_size if not zero, maxSize in bytes allowed + * returns Total 64kb aligned size for all the data + * @return Error handle if error + */ +errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address, + uint64_t & io_end_address, + bool i_startAddressValid, + uint64_t & io_size) +{ + TRACFCOMP( g_trac_runtime, ENTER_MRK"fill_RsvMem_hbData> io_start_address=0x%.16llX,io_end_address=0x%.16llX,startAddressValid=%d", + io_start_address, io_end_address, i_startAddressValid?1:0 ); + + errlHndl_t l_elog = nullptr; + uint64_t l_vAddr = 0x0; + uint64_t l_prevDataAddr = 0; + uint64_t l_prevDataSize = 0; + + // TOC to be filled in and added to beginning of HB Data section + hbrtTableOfContents_t l_hbTOC; + strcpy(l_hbTOC.toc_header, "Hostboot Table of Contents"); + l_hbTOC.toc_version = HBRT_TOC_VERSION_1; + l_hbTOC.total_entries = 0; + + ///////////////////////////////////////////////////////////// + // Figure out the total size needed so we can place the TOC + // at the beginning + ///////////////////////////////////////////////////////////// + uint64_t l_totalSectionSize = 0; + + // Begin with ATTROVER + + // default to the minimum space we have to allocate anyway + size_t l_attrOverMaxSize = 64*KILOBYTE; + + // copy overrides into local buffer + uint8_t* l_overrideData = + reinterpret_cast<uint8_t*>(malloc(l_attrOverMaxSize)); + size_t l_actualSize = l_attrOverMaxSize; + l_elog = TARGETING::AttrRP::saveOverrides( l_overrideData, + l_actualSize ); + if( l_elog ) + { + // check if the issue was a lack of space (unlikely) + if( unlikely( l_actualSize > 0 ) ) + { + TRACFCOMP( g_trac_runtime, "Expanding override section to %d", l_actualSize ); + free(l_overrideData); + l_overrideData = + reinterpret_cast<uint8_t*>(malloc(l_actualSize)); + l_elog = TARGETING::AttrRP::saveOverrides( l_overrideData, + l_actualSize ); + } + + // overrides are not critical so just commit this + // and keep going without any + if( l_elog ) + { + TRACFCOMP( g_trac_runtime, "Errors applying overrides, just skipping" ); + errlCommit( l_elog, RUNTIME_COMP_ID ); + l_elog = NULL; + l_actualSize = 0; + } + } + + // Should we create an ATTROVER section? + if (l_actualSize > 0) + { + l_hbTOC.entry[l_hbTOC.total_entries].label = + HBRT_MEM_LABEL_ATTROVER; + l_hbTOC.entry[l_hbTOC.total_entries].offset = 0; + l_hbTOC.entry[l_hbTOC.total_entries].size = l_actualSize; + l_totalSectionSize += ALIGN_PAGE(l_actualSize); + l_hbTOC.total_entries++; + } + + // Now calculate ATTR size + l_hbTOC.entry[l_hbTOC.total_entries].label = HBRT_MEM_LABEL_ATTR; + l_hbTOC.entry[l_hbTOC.total_entries].offset = 0; + l_hbTOC.entry[l_hbTOC.total_entries].size = + TARGETING::AttrRP::maxSize(); + l_totalSectionSize += + ALIGN_PAGE(l_hbTOC.entry[l_hbTOC.total_entries].size); + l_hbTOC.total_entries++; + + // Fill in VPD size + l_hbTOC.entry[l_hbTOC.total_entries].label = HBRT_MEM_LABEL_VPD; + l_hbTOC.entry[l_hbTOC.total_entries].offset = 0; + l_hbTOC.entry[l_hbTOC.total_entries].size = VMM_RT_VPD_SIZE; + l_totalSectionSize += + ALIGN_PAGE(l_hbTOC.entry[l_hbTOC.total_entries].size); + l_hbTOC.total_entries++; + + // Fill in PADDING size + // Now calculate how much padding is needed for 64KB alignment + // of the whole data section + size_t l_totalSizeAligned = ALIGN_X( l_totalSectionSize, 64*KILOBYTE ); + + // l_actualSizeAligned will bring section to 64k alignment + uint64_t l_actualSizeAligned = l_totalSizeAligned - l_totalSectionSize; + + // Do we need a Padding section? + if (l_actualSizeAligned > 0) + { + // Add padding section + l_hbTOC.entry[l_hbTOC.total_entries].label = HBRT_MEM_LABEL_PADDING; + l_hbTOC.entry[l_hbTOC.total_entries].offset = 0; + l_hbTOC.entry[l_hbTOC.total_entries].size = l_actualSizeAligned; + l_hbTOC.total_entries++; + } + + // Set total_size to the 64k aligned size + l_hbTOC.total_size = l_totalSizeAligned; + + do { + + if ((io_size != 0) && (io_size < l_totalSizeAligned)) + { + // create an error + TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData - Will exceed max allowed size %lld, need %lld", + io_size, l_totalSizeAligned); + + /*@ errorlog tag + * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid RUNTIME::MOD_FILL_RSVMEM_HBDATA + * @reasoncode RUNTIME::RC_EXCEEDED_MEMORY + * @userdata1 Total size needed + * @userdata2 Size allowed + * + * @devdesc Unable to fill in HB data memory + */ + l_elog = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_FILL_RSVMEM_HBDATA, + RUNTIME::RC_EXCEEDED_MEMORY, + l_totalSizeAligned, + io_size, + true); + break; + } + + // update return size to amount filled in + io_size = l_totalSizeAligned; + + + // Figure out the start and end addresses + if (i_startAddressValid) + { + io_end_address = io_start_address + l_totalSizeAligned - 1; + } + else + { + io_start_address = io_end_address - l_totalSizeAligned + 1; + } + + + TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> mapping 0x%.16llX address, size %lld", + io_start_address, l_totalSizeAligned ); + + // Grab the virtual address for the entire HB Data section + l_elog = mapPhysAddr(io_start_address, l_totalSizeAligned, l_vAddr); + if(l_elog) + { + break; + } + + TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> virtual start address: %p", l_vAddr); + + // Skip TOC at the beginning, pretend it was added + l_prevDataAddr = l_vAddr; + l_prevDataSize = sizeof(l_hbTOC); + uint64_t l_offset = 0; + + int i = 0; + while ( i < l_hbTOC.total_entries ) + { + uint64_t actual_size = l_hbTOC.entry[i].size; + uint64_t aligned_size = ALIGN_PAGE(actual_size); + + l_offset += l_prevDataSize; + + // update offset to current data section + l_hbTOC.entry[i].offset = l_offset; + + l_prevDataAddr += l_prevDataSize; + l_prevDataSize = aligned_size; + + switch ( l_hbTOC.entry[i].label ) + { + case HBRT_MEM_LABEL_ATTROVER: + TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> ATTROVER address 0x%.16llX, size: %lld", l_prevDataAddr, aligned_size); + TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> memcpy %d size", actual_size); + memcpy( reinterpret_cast<void*>(l_prevDataAddr), + l_overrideData, + actual_size); + break; + case HBRT_MEM_LABEL_ATTR: + TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> ATTR address 0x%.16llX, size: %lld", l_prevDataAddr, aligned_size); + l_elog = TARGETING::AttrRP::save( + reinterpret_cast<uint8_t*>(l_prevDataAddr), + aligned_size); + if(l_elog) + { + TRACFCOMP( g_trac_runtime, + "populate_HbRsvMem fail ATTR save call" ); + break; + } + TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> TARGETING::AttrRP::save(0x%.16llX) done", l_prevDataAddr); + break; + case HBRT_MEM_LABEL_VPD: + TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> VPD address 0x%.16llX, size: %lld", l_prevDataAddr, aligned_size); + l_elog = VPD::vpd_load_rt_image(l_prevDataAddr, true); + if(l_elog) + { + TRACFCOMP( g_trac_runtime, + "fill_RsvMem_hbData> failed VPD call" ); + break; + } + TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> VPD address 0x%.16llX, size: %lld done", l_prevDataAddr, aligned_size); + break; + default: + break; + } + i++; + } + + // exit if we hit an error + if(l_elog) + { + break; + } + + TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> TOC address 0x%.16llX, size: %lld", l_vAddr, sizeof(l_hbTOC)); + + // Now copy the TOC at the head of the HB Data section + memcpy( reinterpret_cast<void*>(l_vAddr), + &l_hbTOC, + sizeof(l_hbTOC)); + + } while (0); + + if (l_vAddr != 0) + { + // release the virtual address + errlHndl_t l_errl = unmapVirtAddr(l_vAddr); + if (l_errl) + { + TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> unmap %p failed", l_vAddr ); + if (l_elog) + { + // Already have an error log so just commit this new one + errlCommit(l_errl, RUNTIME_COMP_ID); + } + else + { + l_elog = l_errl; + } + } + l_vAddr = 0; + } + + // free ATTR_OVERRIDE memory + free(l_overrideData); + + TRACFCOMP( g_trac_runtime,EXIT_MRK"fill_RsvMem_hbData> io_start_address=0x%.16llX,io_end_address=0x%.16llX,size=%lld", + io_start_address, io_end_address, io_size ); + return l_elog; +} + +/** * @brief Load the HDAT HB Reserved Memory * address range structures on given node * @param[in] i_nodeId Node ID @@ -603,10 +894,12 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) // -----HOMER_N---------- // -----...-------------- // -----HOMER_0---------- - // -----VPD-------------- - // -----ATTR Data------------ - // -----ATTR Override Data--- - // -----HBRT Image----------- + // -----HB Data --------- + // -- VPD + // -- ATTR Data + // -- ATTR Override Data + // -- HB TOC + // -----HBRT Image------- // -----SBE Comm--------- // -----SBE FFDC--------- // -----Secureboot cryptographic algorithms code--------- @@ -660,204 +953,59 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) #endif } - // Establish a couple variables to keep track of where the - // next section lands as we deal with the less statically - // sized areas. These values must always remain 64KB - // aligned - uint64_t l_prevDataAddr = 0; - uint64_t l_prevDataSize = 0; + + //////////////////////////////////////////////////// + // HB Data area + //////////////////////////////////////////////////// //==================== // Note that for PHYP we build up starting at the end of the // previously allocated HOMER/OCC areas, for OPAL we build // downwards from the top of memory where the HOMER/OCC // areas were placed - - - /////////////////////////////////////////////////// - // VPD entry - uint64_t l_vpdAddr = 0x0; + uint64_t l_startAddr = 0; + uint64_t l_endAddr = 0; + uint64_t l_totalSizeAligned = 0; + bool startAddressValid = true; if(TARGETING::is_phyp_load()) { - l_vpdAddr = cpu_spr_value(CPU_SPR_HRMOR) - + VMM_VPD_START_OFFSET; + l_startAddr = cpu_spr_value(CPU_SPR_HRMOR) + + VMM_HB_DATA_TOC_START_OFFSET; } else if(TARGETING::is_sapphire_load()) { - // @todo RTC 170298 Reduce space allocated for VPD at runtime - l_vpdAddr = l_topMemAddr - - VMM_RT_VPD_OFFSET; - } - - l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_HBRT, - i_nodeId, - l_vpdAddr, - VMM_RT_VPD_SIZE, - HBRT_RSVD_MEM__VPD_CACHE); - if(l_elog) - { - break; - } - - l_prevDataAddr = l_vpdAddr; - l_prevDataSize = VMM_RT_VPD_SIZE; - - // Load the VPD into memory - l_elog = mapPhysAddr(l_vpdAddr, VMM_RT_VPD_SIZE, l_vAddr); - if(l_elog) - { - break; + l_endAddr = l_topMemAddr - + VMM_ALL_HOMER_OCC_MEMORY_SIZE; + startAddressValid = false; } - l_elog = VPD::vpd_load_rt_image(l_vAddr); - if(l_elog) - { - TRACFCOMP( g_trac_runtime, - "populate_HbRsvMem fail VPD call" ); - break; - } + // fills in the reserved memory with HD Data and + // will update addresses and totalSize + l_elog = fill_RsvMem_hbData(l_startAddr, l_endAddr, + startAddressValid, l_totalSizeAligned); - l_elog = unmapVirtAddr(l_vAddr); - if(l_elog) + if (l_elog) { break; } - - /////////////////////////////////////////////////// - // ATTR Data entry - uint64_t l_attrDataAddr = 0x0; - uint64_t l_attrSize = TARGETING::AttrRP::maxSize(); - - // Minimum 64K size for Opal - size_t l_attrSizeAligned = ALIGN_X( l_attrSize, 64*KILOBYTE ); - - if(TARGETING::is_phyp_load()) - { - l_attrDataAddr = l_prevDataAddr + l_prevDataSize; - } - else if(TARGETING::is_sapphire_load()) - { - l_attrDataAddr = l_prevDataAddr - l_attrSizeAligned; - } - l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_HBRT, i_nodeId, - l_attrDataAddr, - l_attrSizeAligned, - HBRT_RSVD_MEM__ATTRIBUTES); + l_startAddr, + l_totalSizeAligned, + HBRT_RSVD_MEM__DATA); if(l_elog) { break; } - l_prevDataAddr = l_attrDataAddr; - l_prevDataSize = l_attrSizeAligned; - - // Load the attribute data into memory - l_elog = mapPhysAddr(l_attrDataAddr, l_attrSize, l_vAddr); - if(l_elog) - { - break; - } - - TARGETING::AttrRP::save(l_vAddr); - - l_elog = unmapVirtAddr(l_vAddr); - if(l_elog) - { - break; - } - - - /////////////////////////////////////////////////// - // ATTR Overrides entry - uint64_t l_attrOverDataAddr = 0x0; - - // default to the minimum space we have to allocate anyway - size_t l_attrOverMaxSize = 64*KILOBYTE; - //@fixme-RTC:171863-fill in real size - - // copy overrides into local buffer - uint8_t* l_overrideData = - reinterpret_cast<uint8_t*>(malloc(l_attrOverMaxSize)); - size_t l_actualSize = l_attrOverMaxSize; - l_elog = TARGETING::AttrRP::saveOverrides( l_overrideData, - l_actualSize ); - if( l_elog ) - { - // check if the issue was a lack of space (unlikely) - if( unlikely( l_actualSize > 0 ) ) - { - TRACFCOMP( g_trac_runtime, "Expanding override section to %d", l_actualSize ); - free(l_overrideData); - l_overrideData = - reinterpret_cast<uint8_t*>(malloc(l_actualSize)); - l_elog = TARGETING::AttrRP::saveOverrides( l_overrideData, - l_actualSize ); - } - - // overrides are not critical so just commit this - // and keep going without any - if( l_elog ) - { - TRACFCOMP( g_trac_runtime, "Errors applying overrides, just skipping" ); - errlCommit( l_elog, RUNTIME_COMP_ID ); - l_elog = NULL; - l_actualSize = 0; - } - } - - // only add a section if there are actually overrides - if( l_actualSize > 0 ) - { - // Minimum 64K size for Opal - size_t l_actualSizeAligned = ALIGN_X( l_actualSize, 64*KILOBYTE ); - - // phyp/opal build in reverse... - if(TARGETING::is_phyp_load()) - { - l_attrOverDataAddr = l_prevDataAddr + l_prevDataSize; - } - else if(TARGETING::is_sapphire_load()) - { - l_attrOverDataAddr = l_prevDataAddr - l_actualSizeAligned; - } - - l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_HBRT, - i_nodeId, - l_attrOverDataAddr, - l_actualSizeAligned, - HBRT_RSVD_MEM__OVERRIDES); - if(l_elog) - { - break; - } - - l_prevDataAddr = l_attrOverDataAddr; - l_prevDataSize = l_actualSizeAligned; - - // Load the attribute data into memory - l_elog = mapPhysAddr(l_attrOverDataAddr, - ALIGN_PAGE(l_actualSize), - l_vAddr); - if(l_elog) - { - break; - } - - memcpy( reinterpret_cast<void*>(l_vAddr), - l_overrideData, - l_actualSize ); - free(l_overrideData); - - l_elog = unmapVirtAddr(l_vAddr); - if(l_elog) - { - break; - } - } + // Establish a couple variables to keep track of where the + // next section lands as we deal with the less statically + // sized areas. These values must always remain 64KB + // aligned + uint64_t l_prevDataAddr = l_startAddr; + uint64_t l_prevDataSize = l_totalSizeAligned; /////////////////////////////////////////////////// @@ -1905,6 +2053,22 @@ errlHndl_t populate_hbRuntimeData( void ) TRACFCOMP( g_trac_runtime, "populate_HbRsvMem failed" ); } } + else + { + // still fill in HB DATA for testing + uint64_t l_startAddr = cpu_spr_value(CPU_SPR_HRMOR) + + VMM_HB_DATA_TOC_START_OFFSET; + uint64_t l_endAddr = 0; + uint64_t l_totalSizeAligned = 0; + bool startAddressValid = true; + + l_elog = fill_RsvMem_hbData(l_startAddr, l_endAddr, + startAddressValid, l_totalSizeAligned); + if(l_elog != nullptr) + { + TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData failed" ); + } + } break; } diff --git a/src/usr/targeting/attrrp.C b/src/usr/targeting/attrrp.C index 2536f2769..28ffe8133 100755 --- a/src/usr/targeting/attrrp.C +++ b/src/usr/targeting/attrrp.C @@ -41,6 +41,7 @@ #include <vmmconst.h> #include <targeting/adapters/assertadapter.H> #include <targeting/common/targreasoncodes.H> +#include <targeting/targplatreasoncodes.H> #include <targeting/attrrp.H> #include <targeting/common/trace.H> #include <targeting/common/attributeTank.H> @@ -650,6 +651,11 @@ namespace TARGETING return Singleton<AttrRP>::instance()._save(io_addr); } + errlHndl_t AttrRP::save( uint8_t* i_dest, size_t& io_size ) + { + // Call save on singleton instance. + return Singleton<AttrRP>::instance()._save(i_dest,io_size); + } uint64_t AttrRP::maxSize( ) { @@ -711,6 +717,67 @@ namespace TARGETING return region; } + errlHndl_t AttrRP::_save( uint8_t* i_dest, size_t& io_size ) + { + TRACFCOMP( g_trac_targeting, ENTER_MRK"AttrRP::_save: i_dest=%p, io_size=%ld", i_dest, io_size ); + errlHndl_t l_err = nullptr; + uint8_t* pointer = i_dest; + uint64_t l_totalSize = 0; + uint64_t l_maxSize = io_size; + uint64_t l_filledSize = 0; + + // Copy content. + for (size_t i = 0; i < iv_sectionCount; ++i) + { + l_totalSize += iv_sections[i].size; + if (l_totalSize <= l_maxSize) + { + l_filledSize = l_totalSize; + memcpy(pointer, + reinterpret_cast<void*>(iv_sections[i].vmmAddress), + iv_sections[i].size); + + pointer = &pointer[ALIGN_PAGE(iv_sections[i].size)]; + } + else + { + // Need a larger buffer + TRACFCOMP( g_trac_targeting, ERR_MRK"AttrRP::_save - max size %d exceeded, missing section %d, size %d", + io_size,i, iv_sections[i].size); + } + } + + if (l_totalSize > io_size) + { + // Need to increase size of the buffer + /*@ + * @errortype + * @moduleid TARG_MOD_SAVE_ATTR_TANK + * @reasoncode TARG_SPACE_OVERRUN + * @userdata1 Maximum Available size + * @userdata2 Required size + * + * @devdesc Size of attribute data exceeds available + * buffer space + * + * @custdesc Internal firmware error applying + * custom configuration settings + */ + l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + TARG_MOD_SAVE_ATTR_TANK, + TARG_SPACE_OVERRUN, + io_size, + l_totalSize, + true /*SW Error */); + } + + io_size = l_filledSize; + + TRACFCOMP(g_trac_targeting, EXIT_MRK"AttrRP::_save: i_dest=%p, io_size=%ld, size needed=%ld", i_dest, io_size, l_totalSize ); + return l_err; + } + + errlHndl_t AttrRP::_saveOverrides( uint8_t* i_dest, size_t& io_size ) { diff --git a/src/usr/targeting/runtime/attrPlatOverride_rt.C b/src/usr/targeting/runtime/attrPlatOverride_rt.C index 3c5ebb8ae..a8bf17f94 100644 --- a/src/usr/targeting/runtime/attrPlatOverride_rt.C +++ b/src/usr/targeting/runtime/attrPlatOverride_rt.C @@ -35,6 +35,8 @@ #include <secureboot/service.H> #include <targeting/common/targreasoncodes.H> #include <devicefw/userif.H> +#include <util/runtime/util_rt.H> + using namespace TARGETING; @@ -129,34 +131,29 @@ void applyTempOverrides() bool l_usingStash = false; // Get a pointer to the reserved memory where HB - // saved the overrides during boot - uint64_t l_overAddr = 0; - uint8_t* l_overPtr = nullptr; - if( g_hostInterfaces != NULL && - g_hostInterfaces->get_reserved_mem ) - { - l_overAddr = g_hostInterfaces - ->get_reserved_mem("ibm,hbrt-targetoverride-image",0); - if( l_overAddr != 0 ) - { - TRACFCOMP(g_trac_targeting, "Overrides found at %.16X", l_overAddr ); - l_overPtr = reinterpret_cast<uint8_t*>(l_overAddr); - } - } + // saved the overrides during boot + uint64_t l_overAttrSize = 0; + uint64_t l_overAddr = hb_get_rt_rsvd_mem(HBRT_MEM_LABEL_ATTROVER, + 0, l_overAttrSize); + // Having no overrides is a normal thing - if( l_overPtr == nullptr ) + if( (l_overAddr == 0) ) { TRACFCOMP(g_trac_targeting, "No Overrides found" ); TRACFCOMP(g_trac_targeting, EXIT_MRK"applyTempOverrides"); return; } + else + { + TRACFCOMP(g_trac_targeting, "Overrides found at %.16llX", l_overAddr ); + } // Use a faux PNOR Section that is associated // with the data in mainstore PNOR::SectionInfo_t l_info; l_info.vaddr = l_overAddr; - l_info.size = 64*KILOBYTE; //@fixme-RTC:171863-use real size + l_info.size = l_overAttrSize; l_info.id = PNOR::ATTR_TMP; l_info.name = "HBRT Overrides"; diff --git a/src/usr/targeting/runtime/attrrp_rt.C b/src/usr/targeting/runtime/attrrp_rt.C index 4f323e699..857b58fd0 100644 --- a/src/usr/targeting/runtime/attrrp_rt.C +++ b/src/usr/targeting/runtime/attrrp_rt.C @@ -29,6 +29,7 @@ #include <errl/errlentry.H> #include <targeting/common/targreasoncodes.H> #include <targeting/targplatreasoncodes.H> +#include <util/runtime/util_rt.H> #include "../attrrp_common.C" @@ -43,10 +44,10 @@ namespace TARGETING do { + uint64_t attr_size = 0; TargetingHeader* l_header = reinterpret_cast<TargetingHeader*>( - g_hostInterfaces-> - get_reserved_mem(HBRT_RSVD_MEM__ATTRIBUTES,0)); + hb_get_rt_rsvd_mem(HBRT_MEM_LABEL_ATTR,0,attr_size)); if ((NULL == l_header) || (l_header->eyeCatcher != PNOR_TARG_EYE_CATCHER)) diff --git a/src/usr/targeting/runtime/test/testtargeting.H b/src/usr/targeting/runtime/test/testtargeting.H index 99c0fbbb4..db9c74415 100644 --- a/src/usr/targeting/runtime/test/testtargeting.H +++ b/src/usr/targeting/runtime/test/testtargeting.H @@ -126,6 +126,8 @@ class TargetingTestSuite : public CxxTest::TestSuite { using namespace TARGETING; TRACFCOMP(g_trac_targeting,"testIplOverrides"); +#if 0 +// @TODO RTC 144077 - rt_get_targ_override() no longer sets attribute up //See rt_get_targ_override() for setup details about setting // SYSTEM:ATTR_SCRATCH_INT32_1 = -99 @@ -146,8 +148,10 @@ class TargetingTestSuite : public CxxTest::TestSuite TS_FAIL("testIplOverrides> SCRATCH_INT32_1=%d, expected %d", l_val, -99 ); } } +#endif } + void testApplyAttrOverrides() { using namespace TARGETING; diff --git a/src/usr/testcore/rtloader/loader.H b/src/usr/testcore/rtloader/loader.H index 1870754a5..4613d1c66 100644 --- a/src/usr/testcore/rtloader/loader.H +++ b/src/usr/testcore/rtloader/loader.H @@ -44,6 +44,9 @@ #include <ipmi/ipmiif.H> #include <targeting/common/attributeTank.H> #include <config.h> +#include <util/runtime/util_rt.H> +#include <sys/misc.h> + trace_desc_t* g_trac_hbrt = NULL; TRAC_INIT(&g_trac_hbrt, "HBRT_TEST", 2*KILOBYTE); @@ -175,6 +178,33 @@ class RuntimeLoaderTest : public CxxTest::TestSuite } private: + void tearDown() + { + if (cv_hb_data_addr != 0) + { + // unmap virtual memory + TRACFCOMP( g_trac_hbrt, "tearDown(): unmap hb_data virt addr %p", + reinterpret_cast<void*>(cv_hb_data_addr)); + + int l_rc = mm_block_unmap( + reinterpret_cast<void*>(cv_hb_data_addr)); + if(l_rc) + { + TRACFCOMP( g_trac_hbrt, + "tearDown(): failed to unmap virt addr %p", + reinterpret_cast<void*>(cv_hb_data_addr)); + } + else + { + cv_hb_data_addr = 0; + } + } + else + { + TRACFCOMP( g_trac_hbrt, "tearDown(): skipping unmap hb_data virt addr"); + } + } + uint64_t callViaCtr(uint64_t entry, void* param0, void* param1) { register uint64_t result = 0; @@ -348,18 +378,83 @@ class RuntimeLoaderTest : public CxxTest::TestSuite static uint64_t rt_get_reserved_mem(const char* i_region, uint32_t i_instance) { - if (0 == strcmp(i_region, HBRT_RSVD_MEM__VPD_CACHE)) - return rt_get_vpd(); - else if (0 == strcmp(i_region, HBRT_RSVD_MEM__ATTRIBUTES)) - return rt_get_targ(); - else if (0 == strcmp(i_region, HBRT_RSVD_MEM__OVERRIDES)) - return rt_get_targ_override(); - else if (0 == strcmp(i_region, HBRT_RSVD_MEM__SBE_COMM)) + if (0 == strcmp(i_region, HBRT_RSVD_MEM__SBE_COMM)) return rt_get_comm(i_instance); + else if (0 == strcmp(i_region, HBRT_RSVD_MEM__DATA)) + return rt_get_hb_data(i_instance); else return 0; } + static uint64_t rt_get_hb_data(uint32_t i_instance) + { + TRACFCOMP( g_trac_hbrt, ENTER_MRK"rt_get_hb_data> i_instance=%d", i_instance ); + + uint64_t l_totalSize = 0; + uint64_t l_vAddr = 0; + + if (cv_hb_data_addr != 0) + { + TRACFCOMP(g_trac_hbrt, EXIT_MRK"rt_get_hb_data: " + "stored cv_hb_data_addr: 0x%.16llX", cv_hb_data_addr); + return cv_hb_data_addr; + } + + + uint64_t l_physical_addr = cpu_spr_value(CPU_SPR_HRMOR) + + VMM_HB_DATA_TOC_START_OFFSET; + + TRACFCOMP(g_trac_hbrt, "rt_get_hb_data: " + "mapping physical address:0x%.1611X", l_physical_addr); + + // Map to the virtual address to access data + l_vAddr = reinterpret_cast<uint64_t>(mm_block_map( + reinterpret_cast<void*>(l_physical_addr), + sizeof(hbrtTableOfContents_t))); + + TRACFCOMP(g_trac_hbrt, "rt_get_hb_data: mapped " + "physical address 0x%.16llX -> virtual address 0x%.16llX", + l_physical_addr, l_vAddr); + + // check that map worked + assert(l_vAddr != 0,"rt_get_hb_data. Could not map HB DATA memory"); + + // find the total size + hbrtTableOfContents_t * toc_ptr = + reinterpret_cast<hbrtTableOfContents_t *>(l_vAddr); + l_totalSize = toc_ptr->total_size; + TRACFCOMP(g_trac_hbrt, "rt_get_hb_data: " + "total_size for HB Data = %lld", l_totalSize); + + // unmap + int l_rc = mm_block_unmap(reinterpret_cast<void*>(l_vAddr)); + if(l_rc) + { + TRACFCOMP( g_trac_hbrt, + "rt_get_hb_data. fail to unmap virt addr %p", + reinterpret_cast<void*>(l_vAddr)); + assert(false, "rt_get_hb_data. failed to unmap virt addr"); + } + + // Map to the virtual address to access ALL data + cv_hb_data_addr = reinterpret_cast<uint64_t>(mm_block_map( + reinterpret_cast<void*>(l_physical_addr), l_totalSize)); + + TRACFCOMP(g_trac_hbrt, "rt_get_hb_data: " + "mapped physical address:0x%.16llX -> virtual address 0x%.16llX", + l_physical_addr, cv_hb_data_addr); + + // check that map worked + assert(cv_hb_data_addr != 0, + "rt_get_hb_data. Could not map entire HB DATA memory"); + + TRACFCOMP( g_trac_hbrt, + EXIT_MRK"rt_get_hb_data> i_instance=%d, addr: 0x%.16llX", + i_instance, cv_hb_data_addr); + + return cv_hb_data_addr; + } + static PNOR::SectionId find_sectionId (const char* i_partitionName) { @@ -512,104 +607,6 @@ class RuntimeLoaderTest : public CxxTest::TestSuite } //-------------------------------------------------------------------- - static uint64_t rt_get_vpd() - { - if(cv_vpd_addr != 0) - { - return cv_vpd_addr; - } - - // runtime VPD area not setup yet. - // Need to map the area into virtual memory - errlHndl_t err = VPD::vpd_load_rt_image(cv_vpd_phys_addr); - - if(!err) - { - - uint8_t * vpd_ptr = - reinterpret_cast<uint8_t *>(cv_vpd_phys_addr); - - void * vptr = mm_block_map(vpd_ptr, VMM_RT_VPD_SIZE); - - assert(vptr != NULL,"rt_get_vpd. Could not map VPD memory"); - - - // Store the address in a class variable so we only - // need to load vpd once. - cv_vpd_addr = reinterpret_cast<uint64_t>(vptr); - } - else - { - errlCommit(err,CXXTEST_COMP_ID); - } - - return cv_vpd_addr; - - } - - //-------------------------------------------------------------------- - static uint64_t rt_get_targ() - { - if (cv_targ_addr != 0) - { - return cv_targ_addr; - } - - // Ensure cv_vpd_phys_addr is primed. - rt_get_vpd(); - - cv_targ_phys_addr = cv_vpd_phys_addr; - cv_targ_addr = reinterpret_cast<uint64_t>( - TARGETING::AttrRP::save(cv_targ_phys_addr)); - - return cv_targ_addr; - } - - //-------------------------------------------------------------------- - static uint64_t rt_get_targ_override() - { - using namespace TARGETING; - if (cv_targ_over_addr != 0) - { - return cv_targ_over_addr; - } - - // add an override to use in a later test - AttributeTank* l_tank = - &Target::theTargOverrideAttrTank(); - ATTR_SCRATCH_INT32_1_type l_val = -99; - l_tank->setAttribute(ATTR_SCRATCH_INT32_1, - TYPE_SYS, - AttributeTank::ATTR_POS_NA, - AttributeTank::ATTR_UNIT_POS_NA, - AttributeTank::ATTR_NODE_NA, - 0, sizeof(l_val), &l_val); - - // copy overrides into local buffer - size_t l_actualSize = 64*KILOBYTE; - uint8_t* l_overrideData = - reinterpret_cast<uint8_t*>(malloc(l_actualSize)); - errlHndl_t l_elog = TARGETING::AttrRP::saveOverrides( - l_overrideData, - l_actualSize ); - if(l_elog) - { - TRACFCOMP( g_trac_hbrt, ERR_MRK" Attribute Overrides exceed allocated space" ); - errlCommit( l_elog, CXXTEST_COMP_ID ); - } - else if( l_actualSize == 0 ) - { - TRACFCOMP( g_trac_hbrt, INFO_MRK" No Attribute Overrides Present" ); - } - else - { - cv_targ_over_addr = reinterpret_cast<uint64_t>(l_overrideData); - } - - return cv_targ_over_addr; - } - - //-------------------------------------------------------------------- static uint64_t rt_get_comm(uint32_t i_instance) { if (cv_comm_addr != 0) @@ -688,12 +685,7 @@ class RuntimeLoaderTest : public CxxTest::TestSuite return l_plid; } - - static uint64_t cv_vpd_addr; - static uint64_t cv_vpd_phys_addr; - static uint64_t cv_targ_addr; - static uint64_t cv_targ_phys_addr; - static uint64_t cv_targ_over_addr; + static uint64_t cv_hb_data_addr; static uint64_t cv_comm_addr; static uint64_t cv_comm_phys_addr; }; @@ -701,11 +693,8 @@ class RuntimeLoaderTest : public CxxTest::TestSuite RuntimeLoaderTest::SCOM_MAP RuntimeLoaderTest::cv_scomMap; std::map<void*, UtilLidMgr*> RuntimeLoaderTest::cv_loadedLids; -uint64_t RuntimeLoaderTest::cv_vpd_addr = 0; -uint64_t RuntimeLoaderTest::cv_vpd_phys_addr = 0; -uint64_t RuntimeLoaderTest::cv_targ_addr = 0; -uint64_t RuntimeLoaderTest::cv_targ_phys_addr = 0; -uint64_t RuntimeLoaderTest::cv_targ_over_addr = 0; + +uint64_t RuntimeLoaderTest::cv_hb_data_addr = 0; uint64_t RuntimeLoaderTest::cv_comm_addr = 0; uint64_t RuntimeLoaderTest::cv_comm_phys_addr = 0; diff --git a/src/usr/util/runtime/makefile b/src/usr/util/runtime/makefile index e61091cc5..6512606d2 100644 --- a/src/usr/util/runtime/makefile +++ b/src/usr/util/runtime/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2013,2016 +# Contributors Listed Below - COPYRIGHT 2013,2017 # [+] International Business Machines Corp. # # @@ -33,6 +33,7 @@ OBJS += utillidmgr_rt.o OBJS += utilfile.o OBJS += utillidpnor.o OBJS += rt_cmds.o +OBJS += util_rt.o SUBDIRS += test.d diff --git a/src/usr/util/runtime/util_rt.C b/src/usr/util/runtime/util_rt.C new file mode 100644 index 000000000..633456248 --- /dev/null +++ b/src/usr/util/runtime/util_rt.C @@ -0,0 +1,107 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/util/runtime/util_rt.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 <targeting/common/trace.H> +#include <trace/interface.H> +#include <runtime/interface.h> +#include <util/runtime/util_rt.H> + +/** + * @brief Get the address of a reserved hostboot memory region by its label + * @param[in] i_label HBRT_MEM_LABEL_ constant + * @param[in] i_instance instance number + * @param[out] o_size size of returned region in bytes + * @return virtual address of region or 0 + * @platform FSP, OpenPOWER + **/ +uint64_t hb_get_rt_rsvd_mem(hbrt_mem_label_t i_label, + uint32_t i_instance, + uint64_t & o_size) +{ + uint64_t l_label_data_addr = 0; + o_size = 0; + + TRACFCOMP(TARGETING::g_trac_targeting, ENTER_MRK"hb_get_rt_rsvd_mem(0x%llX, %d, %ld) -> 0x%X", + i_label,i_instance, o_size,l_label_data_addr); + + switch(i_label) + { + case HBRT_MEM_LABEL_VPD: + case HBRT_MEM_LABEL_ATTR: + case HBRT_MEM_LABEL_ATTROVER: + case HBRT_MEM_LABEL_PADDING: + if( (g_hostInterfaces != NULL) && + (g_hostInterfaces->get_reserved_mem) ) + { + uint64_t hb_data_addr = + g_hostInterfaces->get_reserved_mem(HBRT_RSVD_MEM__DATA, + i_instance); + if (0 != hb_data_addr) + { + hbrtTableOfContents_t * toc_ptr = + reinterpret_cast<hbrtTableOfContents_t *>(hb_data_addr); + + // Find offset of label section + for (uint16_t i = 0; i < toc_ptr->total_entries; i++) + { + if (toc_ptr->entry[i].label == i_label) + { + l_label_data_addr = hb_data_addr + + toc_ptr->entry[i].offset; + o_size = toc_ptr->entry[i].size; + TRACFCOMP(TARGETING::g_trac_targeting, "hb_get_rt_rsvd_mem: Entry found at 0x%.16llX, size %ld", + l_label_data_addr, o_size); + break; + } + } + + if (0 == o_size) + { + TRACFCOMP(TARGETING::g_trac_targeting, "hb_get_rt_rsvd_mem: Entry %.16llX not found", i_label); + } + } + else + { + // unable to find HBRT_RSVD_MEM__DATA section + TRACFCOMP(TARGETING::g_trac_targeting, "hb_get_rt_rsvd_mem: Unable to find HBRT_RSVD_MEM__DATA section"); + } + } + else + { + // g_hostInterfaces is either NULL or + // get_reserved_mem function isn't defined + TRACFCOMP(TARGETING::g_trac_targeting, "hb_get_rt_rsvd_mem: g_hostInterfaces->get_reserved_mem is invalid"); + } + break; + default: + // unknown label? + TRACFCOMP(TARGETING::g_trac_targeting, "hb_get_rt_rsvd_mem: unknown label 0x%.16llX", i_label); + break; + } + + TRACFCOMP(TARGETING::g_trac_targeting, EXIT_MRK"hb_get_rt_rsvd_mem(0x%X, %d, %ld) -> 0x%X", + i_label,i_instance, o_size,l_label_data_addr); + + return l_label_data_addr; +} diff --git a/src/usr/vpd/rtvpd_load.C b/src/usr/vpd/rtvpd_load.C index af528692c..5fb8948e2 100644 --- a/src/usr/vpd/rtvpd_load.C +++ b/src/usr/vpd/rtvpd_load.C @@ -102,26 +102,27 @@ errlHndl_t bld_vpd_image(PNOR::SectionId vpd_type, } // External function see vpd_if.H -errlHndl_t VPD::vpd_load_rt_image(uint64_t & o_vpd_addr) +errlHndl_t VPD::vpd_load_rt_image(uint64_t & io_vpd_addr, bool i_virtualAddr) { errlHndl_t err = NULL; do { - void* vptr = reinterpret_cast<void*>(o_vpd_addr); + void* vptr = reinterpret_cast<void*>(io_vpd_addr); uint8_t* vpd_ptr = reinterpret_cast<uint8_t*>(vptr); bool l_is_no_load = TARGETING::is_no_load(); - if( l_is_no_load ) + if( l_is_no_load && !i_virtualAddr) { - o_vpd_addr = TARGETING::get_top_mem_addr(); - assert (o_vpd_addr != 0, + io_vpd_addr = TARGETING::get_top_mem_addr(); + assert (io_vpd_addr != 0, "vpd_load_rt_image: Top of memory was 0!"); - o_vpd_addr -= VMM_RT_VPD_OFFSET; + io_vpd_addr -= VMM_RT_VPD_OFFSET; - vptr = mm_block_map(reinterpret_cast<void*>(o_vpd_addr), + vptr = mm_block_map(reinterpret_cast<void*>(io_vpd_addr), VMM_RT_VPD_SIZE); + vpd_ptr = reinterpret_cast<uint8_t*>(vptr); assert(vptr != NULL,"vpd_load_rt_image: Could not map VPD memory"); @@ -153,7 +154,7 @@ errlHndl_t VPD::vpd_load_rt_image(uint64_t & o_vpd_addr) break; } - if ( l_is_no_load ) + if ( l_is_no_load && !i_virtualAddr) { mm_block_unmap(vptr); } diff --git a/src/usr/vpd/runtime/rt_vpd.C b/src/usr/vpd/runtime/rt_vpd.C index 44ca261bf..e83889381 100644 --- a/src/usr/vpd/runtime/rt_vpd.C +++ b/src/usr/vpd/runtime/rt_vpd.C @@ -32,6 +32,7 @@ #include <i2c/eepromif.H> #include <runtime/interface.h> #include <targeting/common/util.H> +#include <util/runtime/util_rt.H> #include "vpd.H" #include "mvpd.H" #include "cvpd.H" @@ -96,51 +97,27 @@ errlHndl_t getPnorAddr( pnorInformation & i_pnorInfo, // Get the reserved_mem_addr only once if( g_reserved_mem_addr == 0 ) { - if( g_hostInterfaces != NULL && - g_hostInterfaces->get_reserved_mem) - { - g_reserved_mem_addr = - g_hostInterfaces->get_reserved_mem("ibm,hbrt-vpd-image",0); + uint64_t l_vpdSize; + g_reserved_mem_addr = hb_get_rt_rsvd_mem(HBRT_MEM_LABEL_VPD, + 0, + l_vpdSize); - if( g_reserved_mem_addr == 0 ) - { - TRACFCOMP(g_trac_vpd,ERR_MRK"rt_vpd: Failed to get VPD addr. " - "vpd_type: %d", - i_pnorInfo.pnorSection); - /*@ - * @errortype - * @moduleid VPD::VPD_RT_GET_ADDR - * @reasoncode VPD::VPD_RT_NULL_VPD_PTR - * @userdata1 VPD type - * @userdata2 0 - * @devdesc Hypervisor returned NULL address for VPD - */ - err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL, - VPD::VPD_RT_GET_ADDR, - VPD::VPD_RT_NULL_VPD_PTR, - i_pnorInfo.pnorSection, - 0); - - err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, - HWAS::SRCI_PRIORITY_HIGH); - - err->collectTrace( "VPD", 256); - } - } - else // interface not set + if( g_reserved_mem_addr == 0 ) { - TRACFCOMP(g_trac_vpd,ERR_MRK"Hypervisor vpd interface not linked"); + TRACFCOMP(g_trac_vpd,ERR_MRK"rt_vpd: Failed to get VPD addr. " + "vpd_type: %d", + i_pnorInfo.pnorSection); /*@ * @errortype * @moduleid VPD::VPD_RT_GET_ADDR - * @reasoncode VPD::VPD_RT_NOT_INITIALIZED + * @reasoncode VPD::VPD_RT_NULL_VPD_PTR * @userdata1 VPD type * @userdata2 0 - * @devdesc Runtime VPD interface not linked. + * @devdesc Hypervisor returned NULL address for VPD */ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL, VPD::VPD_RT_GET_ADDR, - VPD::VPD_RT_NOT_INITIALIZED, + VPD::VPD_RT_NULL_VPD_PTR, i_pnorInfo.pnorSection, 0); |