diff --git a/src/include/usr/runtime/runtime.H b/src/include/usr/runtime/runtime.H index 3b9dfefe15e..0ece1744a5a 100644 --- a/src/include/usr/runtime/runtime.H +++ b/src/include/usr/runtime/runtime.H @@ -98,6 +98,13 @@ errlHndl_t populate_RtDataByNode(uint64_t iNodeId); // HOMER*8/OCC_Common/VPD/ATTR/HBRT_Image/Res/Res/Res #define HB_RSV_MEM_NUM_PTRS 15 +// Range types for HB reserved memory +#define RANGE_TYPE_PRIMARY 0 +#define RANGE_TYPE_HBRT 1 +#define RANGE_TYPE_VERIFIED_LIDS 2 +#define RANGE_TYPE_TPM_LOG 3 +#define RANGE_TYPE_HOMER_OCC 4 + //Note this means the Reserved Mem sub-section is the 6th //(0 based) of the MDT section (See HDAT spec) #define MDT_RESERVED_HB_MEM_SECTION 5 @@ -163,7 +170,7 @@ void saveActualCount( RUNTIME::SectionId i_id, */ errlHndl_t writeActualCount( RUNTIME::SectionId i_id ); -/* +/** * @brief Retrieve and log FFDC data relevant to a given section of * host data memory * @@ -175,13 +182,13 @@ errlHndl_t writeActualCount( RUNTIME::SectionId i_id ); void add_host_data_ffdc( SectionId i_section, errlHndl_t& io_errlog ); -/* +/** * @brief Set the PAYLOAD_BASE attribute * @param[in] i_payloadAddress in MEGABYTES */ void setPayloadBaseAddress(uint64_t i_payloadAddress); -/* +/** * @brief Clear out any cached data and rediscover the location * of the HDAT memory */ diff --git a/src/include/usr/runtime/runtime_reasoncodes.H b/src/include/usr/runtime/runtime_reasoncodes.H index 311851680af..2678c28a0ee 100644 --- a/src/include/usr/runtime/runtime_reasoncodes.H +++ b/src/include/usr/runtime/runtime_reasoncodes.H @@ -50,6 +50,8 @@ namespace RUNTIME MOD_POPULATE_RTDATABYNODE = 0x14, /**< populate_hbruntime.C */ MOD_PM_RT_LOAD_PM_COMPLEX = 0x15, /**< rt_pm.C */ MOD_PM_RT_HCODE_UPDATE = 0x16, /**< rt_pm.C */ + MOD_MAP_PHYS_ADDR = 0x17, /**< populate_hbruntime.C */ + MOD_UNMAP_VIRT_ADDR = 0x18, /**< populate_hbruntime.C */ }; enum RuntimeReasonCode diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h index e6763c7bdbb..98384cf9f5d 100644 --- a/src/include/usr/vmmconst.h +++ b/src/include/usr/vmmconst.h @@ -131,6 +131,10 @@ enum BlockPriority /** Page Size in bits per SLBE */ #define SLBE_b 12 +/** Hostboot reserved memory */ +#define VMM_HRMOR_OFFSET 128*MEGABYTE +#define VMM_HB_RSV_MEM_SIZE 256*MEGABYTE + /** Hardwired offsets from HRMOR to HOMER images in real mem */ /** HOMER starts immediately after our HB memory */ /** + = 160MB */ @@ -158,26 +162,34 @@ enum BlockPriority /** Total Memory required for HOMERs and OCC Common */ #define VMM_ALL_HOMER_OCC_MEMORY_SIZE \ - (VMM_OCC_COMMON_SIZE+VMM_HOMER_REGION_SIZE) - + (VMM_OCC_COMMON_SIZE + VMM_HOMER_REGION_SIZE) -/** Reserved runtime VPD sizes in bytes */ -// must be 64KB aligned -#define VMM_MODULE_VPD_SIZE 0x80000 -#define VMM_CENTAUR_VPD_SIZE 0x40000 -#define VMM_DIMM_JEDEC_VPD_SIZE 0x40000 +/** Memory offset for runtime VPD image */ +// Given value is number of bytes BELOW the top of memory to store +// the runtime image(s) Currently below the OCC HOMER IMAGE +#define VMM_RT_VPD_OFFSET (VMM_RT_VPD_SIZE + \ + VMM_ALL_HOMER_OCC_MEMORY_SIZE) -/** Total VPD image size */ +/** Memory for VPD */ +#define VMM_VPD_START_OFFSET VMM_OCC_COMMON_END_OFFSET +#define VMM_MODULE_VPD_SIZE (512*KILOBYTE) /* must be 64KB aligned */ +#define VMM_CENTAUR_VPD_SIZE (256*KILOBYTE) /* must be 64KB aligned */ +#define VMM_DIMM_JEDEC_VPD_SIZE (256*KILOBYTE) /* must be 64KB aligned */ #define VMM_RT_VPD_SIZE (VMM_MODULE_VPD_SIZE + \ VMM_CENTAUR_VPD_SIZE + \ VMM_DIMM_JEDEC_VPD_SIZE) +/** End of VPD Area = 201MB */ -/** Memory offset for runtime VPD image */ -// Given value is number of bytes BELOW the top of memory to store -// the runtime image(s) Currently below the OCC HOMER IMAGE -#define VMM_RT_VPD_OFFSET (VMM_RT_VPD_SIZE + \ - VMM_ALL_HOMER_OCC_MEMORY_SIZE) +/** Memory for attribute data */ +#define VMM_ATTR_DATA_START_OFFSET \ + (VMM_VPD_START_OFFSET + VMM_RT_VPD_SIZE) +#define VMM_ATTR_DATA_SIZE (1*MEGABYTE) +/** End of Attr Area = 202MB */ +/** Chunk of physical memory used for Dump Source Table */ +#define DUMP_TEST_MEMORY_ADDR \ + (VMM_ATTR_DATA_START_OFFSET + VMM_ATTR_DATA_SIZE) /* currently 202MB */ +#define DUMP_TEST_MEMORY_SIZE (4*MEGABYTE) /** Internode communication area outside of the HB image. * Preserved between mpipl. @@ -215,19 +227,6 @@ enum BlockPriority /** Block size used in remove pages test */ #define VMM_SIZE_RMVPAGE_TEST (8 * PAGESIZE) -/** Chunk of physical memory to use for HostServices Attributes */ -#define MPIPL_ATTR_DATA_ADDR \ - VMM_OCC_COMMON_END_OFFSET + VMM_OCC_COMMON_SIZE /* currently 200MB */ -#define MPIPL_SYSDATA_SIZE (4*KILOBYTE) /* match FSP HDAT code */ -#define MPIPL_NODEDATA_SIZE (256000) /* match FSP HDAT code */ -#define MPIPL_ATTR_DATA_SIZE \ - ALIGN_PAGE((MPIPL_SYSDATA_SIZE+MPIPL_NODEDATA_SIZE)) -#define MPIPL_ATTR_VMM_SIZE (1*MEGABYTE) - -/* Chunk of physical memory used for Dump Source Table */ -#define DUMP_TEST_MEMORY_ADDR (MPIPL_ATTR_DATA_ADDR + MPIPL_ATTR_DATA_SIZE) -#define DUMP_TEST_MEMORY_SIZE (4*MEGABYTE) - /** Physical memory location of the TCE Table */ /** - needs to be aligned on 4MB boundary */ #define TCE_TABLE_ADDR (88*MEGABYTE) diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C index a8d7f36d1d4..32b266788c1 100644 --- a/src/usr/runtime/hdatservice.C +++ b/src/usr/runtime/hdatservice.C @@ -272,18 +272,7 @@ errlHndl_t hdatService::get_standalone_section( { errlHndl_t errhdl = NULL; - if( RUNTIME::HSVC_SYSTEM_DATA == i_section ) - { - o_dataAddr = reinterpret_cast(iv_mem_regions[0].virt_addr); - o_dataSize = MPIPL_SYSDATA_SIZE; - } - else if( RUNTIME::HSVC_NODE_DATA == i_section ) - { - o_dataAddr = reinterpret_cast(iv_mem_regions[0].virt_addr) - + MPIPL_SYSDATA_SIZE; - o_dataSize = MPIPL_NODEDATA_SIZE; - } - else if( RUNTIME::MS_DUMP_SRC_TBL == i_section ) + if( RUNTIME::MS_DUMP_SRC_TBL == i_section ) { o_dataAddr = reinterpret_cast(iv_mem_regions[1].virt_addr); o_dataSize = DUMP_TEST_SRC_MEM_SIZE; @@ -519,12 +508,12 @@ errlHndl_t hdatService::loadHostData(void) FakePayload::load(); // Map in some arbitrary memory for the HostServices code to use - TRACFCOMP( g_trac_runtime, "load_host_data> STANDALONE: Mapping in 0x%X-0x%X (%d MB)", MPIPL_ATTR_DATA_ADDR, - MPIPL_ATTR_DATA_ADDR+MPIPL_ATTR_DATA_SIZE, - MPIPL_ATTR_DATA_SIZE); + TRACFCOMP( g_trac_runtime, "load_host_data> STANDALONE: Mapping in 0x%X-0x%X (%d MB)", VMM_ATTR_DATA_START_OFFSET, + VMM_ATTR_DATA_START_OFFSET+VMM_ATTR_DATA_SIZE, + VMM_ATTR_DATA_SIZE); - errhdl = mapRegion(MPIPL_ATTR_DATA_ADDR, - MPIPL_ATTR_DATA_SIZE, l_dummy); + errhdl = mapRegion(VMM_ATTR_DATA_START_OFFSET, + VMM_ATTR_DATA_SIZE, l_dummy); if(errhdl) { break; diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C index 5dbaa5291f0..e3ec74b09de 100644 --- a/src/usr/runtime/populate_hbruntime.C +++ b/src/usr/runtime/populate_hbruntime.C @@ -29,10 +29,11 @@ * @brief Populate HDAT Area for Host runtime data */ - +#include #include #include #include +#include #include #include #include @@ -46,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -57,19 +59,33 @@ namespace RUNTIME { +mutex_t g_rhbMutex = MUTEX_INITIALIZER; + // used for populating the TPM required bit in HDAT const uint16_t TPM_REQUIRED_BIT = 0x8000; //leftmost bit of uint16_t set to 1 -trace_desc_t *g_trac_runtime = NULL; +trace_desc_t *g_trac_runtime = nullptr; TRAC_INIT(&g_trac_runtime, RUNTIME_COMP_NAME, KILOBYTE); +/** This is the original function used to load the HDAT data + * It contains support for PHYP payload + * It does not support OPAL payload + * OPAL must use the new function below - populate_HbRsvMem() + * RTC 169478 - remove when new rsv_mem structure is supported in FSP + */ errlHndl_t populate_RtDataByNode(uint64_t iNodeId) { - errlHndl_t l_elog = NULL; + errlHndl_t l_elog = nullptr; const char* l_stringLabels[] = { "ibm,hbrt-vpd-image" , "ibm,hbrt-target-image" }; + // OPAL not supported + if(TARGETING::is_sapphire_load()) + { + return l_elog; + } + do { // Wipe out our cache of the NACA/SPIRA pointers RUNTIME::rediscover_hdat(); @@ -85,7 +101,7 @@ errlHndl_t populate_RtDataByNode(uint64_t iNodeId) l_section, l_hbrtDataAddr, l_hbrtDataSizeMax ); - if(l_elog != NULL) + if(l_elog != nullptr) { TRACFCOMP( g_trac_runtime, "populate_RtDataByNode fail getHostDataSection VPD" ); @@ -107,7 +123,7 @@ errlHndl_t populate_RtDataByNode(uint64_t iNodeId) l_section, l_hbrtDataAddr, l_hbrtDataSizeMax ); - if(l_elog != NULL) + if(l_elog != nullptr) { TRACFCOMP( g_trac_runtime, "populate_RtDataByNode fail getHostDataSection VPD data" ); @@ -116,7 +132,7 @@ errlHndl_t populate_RtDataByNode(uint64_t iNodeId) // Put VPD data into the structure now l_elog = VPD::vpd_load_rt_image( l_hbrtDataAddr ); - if(l_elog != NULL) + if(l_elog != nullptr) { TRACFCOMP( g_trac_runtime, "populate_RtDataByNode fail VPD call" ); @@ -129,7 +145,7 @@ errlHndl_t populate_RtDataByNode(uint64_t iNodeId) l_section, l_hbrtDataAddr, l_hbrtDataSizeMax ); - if(l_elog != NULL) + if(l_elog != nullptr) { TRACFCOMP( g_trac_runtime, "populate_RtDataByNode fail getHostDataSection ATTRIB" ); @@ -149,41 +165,43 @@ errlHndl_t populate_RtDataByNode(uint64_t iNodeId) l_section, l_hbrtDataAddr, l_hbrtDataSizeMax ); - if(l_elog != NULL) + if(l_elog != nullptr) { TRACFCOMP( g_trac_runtime, "populate_RtDataByNode fail getHostDataSection ATTRIB data" ); break; } - // Get ATTRIBUTE data + // Load ATTRIBUTE data into HDAT TARGETING::AttrRP::save(l_hbrtDataAddr); //Create a block map of memory so we can save a copy of the attribute //data incase we need to MPIPL //Account HRMOR (non 0 base addr) - uint64_t l_attr_data_addr = cpu_spr_value(CPU_SPR_HRMOR) - + MPIPL_ATTR_DATA_ADDR; + uint64_t l_attrDataAddr = cpu_spr_value(CPU_SPR_HRMOR) + + VMM_ATTR_DATA_START_OFFSET; uint64_t l_attrCopyVmemAddr = reinterpret_cast(mm_block_map( - reinterpret_cast(l_attr_data_addr), - MPIPL_ATTR_VMM_SIZE )); + reinterpret_cast(l_attrDataAddr), + VMM_ATTR_DATA_SIZE )); //Make sure the address returned from the block map call is not NULL if(l_attrCopyVmemAddr != 0) { //The function save() for AttrRP saves then entire HBD data // section of PNOR to the provided vmm address - void * l_region = TARGETING::AttrRP::save(l_attrCopyVmemAddr); + TARGETING::AttrRP::save(l_attrCopyVmemAddr); - //Make sure to unmap the virtual address because we won't need it anymore - int l_rc = mm_block_unmap(reinterpret_cast(l_region)); + //Make sure to unmap the virtual address + // because we won't need it anymore + int l_rc = + mm_block_unmap(reinterpret_cast(l_attrCopyVmemAddr)); if(l_rc) { TRACFCOMP( g_trac_runtime, "populate_RtDataByNode fail to unmap physical addr %p, virt addr %p", - reinterpret_cast(l_attr_data_addr), + reinterpret_cast(l_attrDataAddr), reinterpret_cast(l_attrCopyVmemAddr)); /*@ errorlog tag * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE @@ -198,7 +216,7 @@ errlHndl_t populate_RtDataByNode(uint64_t iNodeId) l_elog = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, RUNTIME::MOD_POPULATE_RTDATABYNODE, RUNTIME::RC_UNMAP_FAIL, - l_attr_data_addr, + l_attrDataAddr, l_attrCopyVmemAddr, true); } @@ -207,8 +225,8 @@ errlHndl_t populate_RtDataByNode(uint64_t iNodeId) { TRACFCOMP( g_trac_runtime, "populate_RtDataByNode fail to map physical addr %p, size %lx", - reinterpret_cast(l_attr_data_addr), - MPIPL_ATTR_VMM_SIZE ); + reinterpret_cast(l_attrDataAddr), + VMM_ATTR_DATA_SIZE ); /*@ errorlog tag * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid RUNTIME::MOD_POPULATE_RTDATABYNODE @@ -222,17 +240,519 @@ errlHndl_t populate_RtDataByNode(uint64_t iNodeId) l_elog = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, RUNTIME::MOD_POPULATE_RTDATABYNODE, RUNTIME::RC_CANNOT_MAP_MEMORY, - l_attr_data_addr, - MPIPL_ATTR_VMM_SIZE, + l_attrDataAddr, + VMM_ATTR_DATA_SIZE, true); } - } while(0); + } while(0); return(l_elog); } // end populate_RtDataByNode +/** + * @brief Get a pointer to the next available + * HDAT HB Reserved Memory entry + * @param[out] o_rngPtr Pointer to the addr range entry + * @return Error handle if error + */ +errlHndl_t getNextRhbAddrRange(hdatMsVpdRhbAddrRange_t* & o_rngPtr) +{ + errlHndl_t l_elog = nullptr; + + mutex_lock( &g_rhbMutex ); + + do { + + TARGETING::Target * l_sys = nullptr; + TARGETING::targetService().getTopLevelTarget( l_sys ); + assert(l_sys != nullptr); + + + uint32_t l_nextSection = + l_sys->getAttr(); + + uint64_t l_rsvMemDataAddr = 0; + uint64_t l_rsvMemDataSizeMax = 0; + + // Get the address of the next section + l_elog = RUNTIME::get_host_data_section( RUNTIME::RESERVED_MEM, + l_nextSection, + l_rsvMemDataAddr, + l_rsvMemDataSizeMax ); + if(l_elog != nullptr) + { + TRACFCOMP( g_trac_runtime, + "getNextRhbAddrRange fail get_host_data_section %d", + l_nextSection ); + break; + } + + o_rngPtr = + reinterpret_cast(l_rsvMemDataAddr); + + l_sys->setAttr + (l_nextSection++); + + } while(0); + + mutex_unlock( &g_rhbMutex ); + + return(l_elog); +} + + +/** + * @brief Map physical address to virtual + * @param[in] i_addr Physical address + * @param[in] i_size Size of block to be mapped + * @param[out] o_addr Virtual address + * @return Error handle if error + */ +errlHndl_t mapPhysAddr(uint64_t i_addr, + uint64_t i_size, + uint64_t& o_addr) +{ + errlHndl_t l_elog = nullptr; + + o_addr = reinterpret_cast(mm_block_map( + reinterpret_cast(i_addr), i_size)); + + // Check if address returned from the block map is NULL + if(o_addr == 0) + { + TRACFCOMP( g_trac_runtime, + "mapPhysAddr fail to map physical addr %p, size %lx", + reinterpret_cast(i_addr), i_size ); + + /*@ errorlog tag + * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid RUNTIME::MOD_MAP_PHYS_ADDR + * @reasoncode RUNTIME::RC_CANNOT_MAP_MEMORY + * @userdata1 Phys address we are trying to map + * @userdata2 Size of memory we are trying to map + * + * @devdesc Error mapping a virtual memory map + * @custdesc Kernel failed to map memory + */ + l_elog = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_MAP_PHYS_ADDR, + RUNTIME::RC_CANNOT_MAP_MEMORY, + i_addr, + i_size, + true); + } + + return l_elog; +} + + +/** + * @brief Unmap virtual address block + * @param[in] i_addr Virtual address + * @return Error handle if error + */ +errlHndl_t unmapVirtAddr(uint64_t i_addr) +{ + errlHndl_t l_elog = nullptr; + + int l_rc = mm_block_unmap(reinterpret_cast(i_addr)); + + if(l_rc) + { + TRACFCOMP( g_trac_runtime, + "unmapVirtAddr fail to unmap virt addr %p", + reinterpret_cast(i_addr)); + /*@ errorlog tag + * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid RUNTIME::MOD_UNMAP_VIRT_ADDR + * @reasoncode RUNTIME::RC_UNMAP_FAIL + * @userdata1 Virtual address we are trying to unmap + * + * @devdesc Error unmapping a virtual memory map + * @custdesc Kernel failed to unmap memory + */ + l_elog = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_UNMAP_VIRT_ADDR, + RUNTIME::RC_UNMAP_FAIL, + i_addr, + true); + } + + return l_elog; +} + + +void traceHbRsvMemRange(hdatMsVpdRhbAddrRange_t* & i_rngPtr ) +{ + TRACFCOMP(g_trac_runtime, + "Setting HDAT HB Reserved Memory Range: " + "%s RangeType 0x%X RangeId 0x%X " + "StartAddress 0x%16X EndAddress 0x%16X", + i_rngPtr->hdatRhbLabelString, + i_rngPtr->hdatRhbRngType, + i_rngPtr->hdatRhbRngId, + i_rngPtr->hdatRhbAddrRngStrAddr, + i_rngPtr->hdatRhbAddrRngEndAddr); +} + + +/** + * @brief Load the HDAT HB Reserved Memory + * address range structures on given node + * @param[in] i_nodeId Node ID + * @return Error handle if error + */ +errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) +{ + errlHndl_t l_elog = nullptr; + + do { + // Wipe out our cache of the NACA/SPIRA pointers + RUNTIME::rediscover_hdat(); + + uint64_t l_topMemAddr = 0x0; + const char* l_label = nullptr; + uint32_t l_labelSize = 0; + hdatMsVpdRhbAddrRange_t* l_rngPtr; + uint64_t l_vAddr = 0x0; + + if(TARGETING::is_phyp_load()) + { + // First phyp entry is for the entire 256M HB space + uint64_t l_hbAddr = cpu_spr_value(CPU_SPR_HRMOR) + - VMM_HRMOR_OFFSET; + l_label = "ibm,hb-rsv-mem"; + l_labelSize = strlen(l_label) + 1; + + // Get a pointer to the next available HDAT HB Rsv Mem entry + l_rngPtr = nullptr; + l_elog = getNextRhbAddrRange(l_rngPtr); + if(l_elog) + { + break; + } + + // Fill in the entry + l_rngPtr->hdatRhbRngType = + static_cast(RANGE_TYPE_PRIMARY); + l_rngPtr->hdatRhbRngId = i_nodeId; + l_rngPtr->hdatRhbAddrRngStrAddr = + l_hbAddr | VmmManager::FORCE_PHYS_ADDR; + l_rngPtr->hdatRhbAddrRngEndAddr = + (l_hbAddr | VmmManager::FORCE_PHYS_ADDR) + + VMM_HB_RSV_MEM_SIZE - 1 ; + l_rngPtr->hdatRhbLabelSize = l_labelSize; + memcpy( l_rngPtr->hdatRhbLabelString, + l_label, + l_labelSize ); + + traceHbRsvMemRange(l_rngPtr); + } + + else if(TARGETING::is_sapphire_load()) + { + // Opal data goes at top_of_mem + l_topMemAddr = TARGETING::get_top_mem_addr(); + assert (l_topMemAddr != 0, + "populate_HbRsvMem: Top of memory was 0!"); + + // Opal HB reserved memory data + // -----TOP_OF_MEM------- + // -----HOMER_0---------- + // -----...-------------- + // -----HOMER_N---------- + // -----OCC Common------- + // -----VPD-------------- + // -----ATTR Data-------- + // -----HBRT Image------- + + // First opal entries are for the HOMERs + uint64_t l_homerAddr = l_topMemAddr; + l_label = "ibm,homer-image"; + l_labelSize = strlen(l_label) + 1; + + // Loop through all functional Procs + TARGETING::TargetHandleList l_procChips; + getAllChips( l_procChips, + TARGETING::TYPE_PROC ); + + for (const auto & l_procChip: l_procChips) + { + l_homerAddr -= VMM_HOMER_INSTANCE_SIZE; + + // Get a pointer to the next available HDAT HB Rsv Mem entry + l_rngPtr = nullptr; + l_elog = getNextRhbAddrRange(l_rngPtr); + if(l_elog) + { + break; + } + + // Fill in the entry + l_rngPtr->hdatRhbRngType = + static_cast(RANGE_TYPE_HOMER_OCC); + l_rngPtr->hdatRhbRngId = + l_procChip->getAttr(); + l_rngPtr->hdatRhbAddrRngStrAddr = + l_homerAddr | VmmManager::FORCE_PHYS_ADDR; + l_rngPtr->hdatRhbAddrRngEndAddr = + (l_homerAddr | VmmManager::FORCE_PHYS_ADDR) + + VMM_HOMER_INSTANCE_SIZE - 1 ; + l_rngPtr->hdatRhbLabelSize = l_labelSize; + memcpy( l_rngPtr->hdatRhbLabelString, + l_label, + l_labelSize ); + + traceHbRsvMemRange(l_rngPtr); + } + + if(l_elog) + { + break; + } + + + // OCC Common entry + uint64_t l_occCommonAddr = l_topMemAddr + - VMM_ALL_HOMER_OCC_MEMORY_SIZE; + l_label = "ibm,occ-common-area"; + l_labelSize = strlen(l_label) + 1; + + // Get a pointer to the next available HDAT HB Rsv Mem entry + l_rngPtr = nullptr; + l_elog = getNextRhbAddrRange(l_rngPtr); + if(l_elog) + { + break; + } + + // Fill in the entry + l_rngPtr->hdatRhbRngType = + static_cast(RANGE_TYPE_HOMER_OCC); + l_rngPtr->hdatRhbRngId = i_nodeId; + l_rngPtr->hdatRhbAddrRngStrAddr = + l_occCommonAddr | VmmManager::FORCE_PHYS_ADDR; + l_rngPtr->hdatRhbAddrRngEndAddr = + (l_occCommonAddr | VmmManager::FORCE_PHYS_ADDR) + + VMM_OCC_COMMON_SIZE - 1 ; + l_rngPtr->hdatRhbLabelSize = l_labelSize; + memcpy( l_rngPtr->hdatRhbLabelString, + l_label, + l_labelSize ); + + traceHbRsvMemRange(l_rngPtr); + } + + + // VPD entry + uint64_t l_vpdAddr = 0x0; + l_label = "ibm,hbrt-vpd-image"; + l_labelSize = strlen(l_label) + 1; + + if(TARGETING::is_phyp_load()) + { + l_vpdAddr = cpu_spr_value(CPU_SPR_HRMOR) + + VMM_VPD_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; + } + + // Get a pointer to the next available HDAT HB Rsv Mem entry + l_rngPtr = nullptr; + l_elog = getNextRhbAddrRange(l_rngPtr); + if(l_elog) + { + break; + } + + // Fill in the entry + l_rngPtr->hdatRhbRngType = + static_cast(RANGE_TYPE_HBRT); + l_rngPtr->hdatRhbRngId = i_nodeId; + l_rngPtr->hdatRhbAddrRngStrAddr = + l_vpdAddr | VmmManager::FORCE_PHYS_ADDR; + l_rngPtr->hdatRhbAddrRngEndAddr = + (l_vpdAddr | VmmManager::FORCE_PHYS_ADDR) + + VMM_RT_VPD_SIZE - 1 ; + l_rngPtr->hdatRhbLabelSize = l_labelSize; + memcpy( l_rngPtr->hdatRhbLabelString, + l_label, + l_labelSize ); + + traceHbRsvMemRange(l_rngPtr); + + // Load the VPD into memory + l_elog = mapPhysAddr(l_vpdAddr, VMM_RT_VPD_SIZE, l_vAddr); + if(l_elog) + { + break; + } + + l_elog = VPD::vpd_load_rt_image(l_vAddr); + if(l_elog) + { + TRACFCOMP( g_trac_runtime, + "populate_HbRsvMem fail VPD call" ); + break; + } + + l_elog = unmapVirtAddr(l_vAddr); + if(l_elog) + { + break; + } + + + // ATTR Data entry + uint64_t l_attrDataAddr = 0x0; + l_label = "ibm,hbrt-target-image"; + l_labelSize = strlen(l_label) + 1; + uint64_t l_attrSize = TARGETING::AttrRP::maxSize(); + + if(TARGETING::is_phyp_load()) + { + l_attrDataAddr = l_vpdAddr + VMM_RT_VPD_SIZE; + l_attrDataAddr = ALIGN_X(l_attrDataAddr,64*KILOBYTE); + } + else if(TARGETING::is_sapphire_load()) + { + l_attrDataAddr = l_vpdAddr - l_attrSize; + l_attrDataAddr = ALIGN_DOWN_X(l_attrDataAddr,64*KILOBYTE); + } + + // Get a pointer to the next available HDAT HB Rsv Mem entry + l_rngPtr = nullptr; + l_elog = getNextRhbAddrRange(l_rngPtr); + if(l_elog) + { + break; + } + + // Fill in the entry + l_rngPtr->hdatRhbRngType = + static_cast(RANGE_TYPE_HBRT); + l_rngPtr->hdatRhbRngId = i_nodeId; + l_rngPtr->hdatRhbAddrRngStrAddr = + l_attrDataAddr | VmmManager::FORCE_PHYS_ADDR; + l_rngPtr->hdatRhbAddrRngEndAddr = + (l_attrDataAddr | VmmManager::FORCE_PHYS_ADDR) + + l_attrSize - 1 ; + l_rngPtr->hdatRhbLabelSize = l_labelSize; + memcpy( l_rngPtr->hdatRhbLabelString, + l_label, + l_labelSize ); + + traceHbRsvMemRange(l_rngPtr); + + // 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; + } + + + // HBRT image entry + if(TARGETING::is_sapphire_load() && + (!INITSERVICE::spBaseServicesEnabled())) + { + uint64_t l_hbrtImageAddr = 0x0; + l_label = "ibm,hbrt-code-image"; + l_labelSize = strlen(l_label) + 1; + + PNOR::SectionInfo_t l_pnorInfo; + l_elog = getSectionInfo( PNOR::HB_RUNTIME , l_pnorInfo); + if (l_elog) + { + break; + } + + // Find start of image. + // For Secureboot we might need to deal with the header but + // for now that is hidden by the PNOR-RP. + uint64_t l_imageStart = l_pnorInfo.vaddr; + + // The "VFS_LAST_ADDRESS" variable is 2 pages in. + uint64_t l_vfsLastAddress = + *reinterpret_cast(l_imageStart + 2*PAGE_SIZE); + + // At the end of the image are the relocations, get the number. + uint64_t l_relocateCount = + *reinterpret_cast + (l_imageStart + l_vfsLastAddress); + + // Sum up the total size. + uint64_t l_imageSize = l_vfsLastAddress + + (l_relocateCount+1)*sizeof(uint64_t); + + // Set the image address, align down 64K for Opal + l_hbrtImageAddr = ALIGN_PAGE_DOWN(l_attrDataAddr - l_imageSize); + l_hbrtImageAddr = ALIGN_DOWN_X(l_hbrtImageAddr,64*KILOBYTE); + + // Get a pointer to the next available HDAT HB Rsv Mem entry + l_rngPtr = nullptr; + l_elog = getNextRhbAddrRange(l_rngPtr); + if(l_elog) + { + break; + } + + // Fill in the entry + l_rngPtr->hdatRhbRngType = + static_cast(RANGE_TYPE_HBRT); + l_rngPtr->hdatRhbRngId = i_nodeId; + l_rngPtr->hdatRhbAddrRngStrAddr = + l_hbrtImageAddr | VmmManager::FORCE_PHYS_ADDR; + l_rngPtr->hdatRhbAddrRngEndAddr = + (l_hbrtImageAddr | VmmManager::FORCE_PHYS_ADDR) + + l_imageSize - 1 ; + l_rngPtr->hdatRhbLabelSize = l_labelSize; + memcpy( l_rngPtr->hdatRhbLabelString, + l_label, + l_labelSize ); + + traceHbRsvMemRange(l_rngPtr); + + // Load the HBRT image into memory + l_elog = mapPhysAddr(l_hbrtImageAddr, l_imageSize, l_vAddr); + if(l_elog) + { + break; + } + + memcpy(reinterpret_cast(l_vAddr), + reinterpret_cast(l_imageStart), + l_imageSize); + + l_elog = unmapVirtAddr(l_vAddr); + if(l_elog) + { + break; + } + } + + } while(0); + + return(l_elog); +} // end populate_HbRsvMem + + errlHndl_t populate_hbSecurebootData ( void ) { using namespace TARGETING; @@ -339,22 +859,23 @@ errlHndl_t populate_hbSecurebootData ( void ) return (l_elog); } // end populate_hbRuntiome + errlHndl_t populate_hbRuntimeData( void ) { - errlHndl_t l_elog = NULL; + errlHndl_t l_elog = nullptr; do { TRACFCOMP(g_trac_runtime, "Running populate_hbRuntimeData"); - TARGETING::Target * sys = NULL; + TARGETING::Target * sys = nullptr; TARGETING::targetService().getTopLevelTarget( sys ); - assert(sys != NULL); + assert(sys != nullptr); TARGETING::ATTR_HB_EXISTING_IMAGE_type hb_images = sys->getAttr(); // Figure out which node we are running on - TARGETING::Target* mproc = NULL; + TARGETING::Target* mproc = nullptr; TARGETING::targetService().masterProcChipTargetHandle(mproc); TARGETING::EntityPath epath = @@ -373,10 +894,19 @@ errlHndl_t populate_hbRuntimeData( void ) { // Single node system, call inline and pass in our node number l_elog = populate_RtDataByNode(nodeid); - if(l_elog != NULL) + if(l_elog != nullptr) { TRACFCOMP( g_trac_runtime, "populate_RtDataByNode failed" ); } + // RTC 169478 - enable for PHYP when supported in FSP + if(TARGETING::is_sapphire_load()) + { + l_elog = populate_HbRsvMem(nodeid); + if(l_elog != nullptr) + { + TRACFCOMP( g_trac_runtime, "populate_HbRsvMem failed" ); + } + } break; } @@ -395,6 +925,7 @@ errlHndl_t populate_hbRuntimeData( void ) // Need to send message to the node (l_node) // When NODE receives the msg it should // call populate_RtDataByNode(itsNodeId) + // call populate_HbRsvMem(itsNodeId) TRACFCOMP( g_trac_runtime, "MsgToNode %d for HBRT Data", l_node ); diff --git a/src/usr/targeting/attrrp.C b/src/usr/targeting/attrrp.C index 3f65f5af605..cc0cc57c1b0 100755 --- a/src/usr/targeting/attrrp.C +++ b/src/usr/targeting/attrrp.C @@ -303,16 +303,16 @@ namespace TARGETING //attribute information on the initial IPL //Account HRMOR (non 0 base addr) uint64_t l_attr_data_addr = cpu_spr_value(CPU_SPR_HRMOR) - + MPIPL_ATTR_DATA_ADDR; + + VMM_ATTR_DATA_START_OFFSET; l_header = reinterpret_cast( mm_block_map(reinterpret_cast(l_attr_data_addr), - MPIPL_ATTR_VMM_SIZE)); + VMM_ATTR_DATA_SIZE)); if(l_header == 0) { TRACFCOMP(g_trac_targeting, "Failed mapping phys addr: %p for %lx bytes", l_attr_data_addr, - MPIPL_ATTR_VMM_SIZE); + VMM_ATTR_DATA_SIZE); //Error mm_block_map returned invalid ptr /*@ * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE @@ -330,7 +330,7 @@ namespace TARGETING TARG_PARSE_ATTR_SECT_HEADER, TARG_RC_MM_BLOCK_FAIL, l_attr_data_addr, - MPIPL_ATTR_VMM_SIZE, + VMM_ATTR_DATA_SIZE, true); break; } diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml index 94b571b172e..5ba1240272e 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml @@ -1782,4 +1782,18 @@ ID for the sensor number returned with the elog. --> + + HB_RSV_MEM_NEXT_SECTION + + The next HB reserved memory section available to assign + a new reserved memory range. + + + + + volatile-zeroed + + + + diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml index 811edd5fa99..be448bf1305 100755 --- a/src/usr/targeting/common/xmltohb/target_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml @@ -84,6 +84,7 @@ IS_DRTM_MPIPL_HB DRTM_PAYLOAD_ADDR_MB_HB FORCE_PRE_PAYLOAD_DRTM + HB_RSV_MEM_NEXT_SECTION