summaryrefslogtreecommitdiffstats
path: root/src/usr/runtime
diff options
context:
space:
mode:
authorChristian Geddes <crgeddes@us.ibm.com>2017-10-20 15:45:05 -0500
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2017-12-15 16:06:35 -0500
commitfd12b61b55f27a6a9f83e4571b2034e8d6191ba0 (patch)
tree44f36605c2c457c1fe49db1c7b767f6bb6b67244 /src/usr/runtime
parent04dca99153cae852c2b7a3e63fc497d7cf0f2dda (diff)
downloadtalos-hostboot-fd12b61b55f27a6a9f83e4571b2034e8d6191ba0.tar.gz
talos-hostboot-fd12b61b55f27a6a9f83e4571b2034e8d6191ba0.zip
Add hbHypCommArea struct to end of Hostboot Data reserved mem section
The Hypervisor needs a way to send down an address to the host so that the host can account for the HRMOR moving and still be able to boot on an MPIPL. To do this we are adding another subsection to the existing reserved memory section which already was holding VPD and attribute info. This subsection will serve as the HB-HYP communication region. For now PHYP is the only hypervisor using this space and they are only using it to store the HRMOR if they decide to move it. In order for the hypervisor to easily find where to write the HRMOR we added an address pointer to HDAT that hostboot will fill in to tell PHYP where to write the HRMOR. This is all setting up for us to be able to read the HRMOR after an MPIPL so that we can load the hypervisor in at the correct address. Change-Id: I5d3687a207296bd87d2a7120dd17505e0022b748 RTC: 180959 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/48651 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Matt Derksen <mderkse1@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Martin Gloff <mgloff@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src/usr/runtime')
-rw-r--r--src/usr/runtime/hdatservice.C46
-rw-r--r--src/usr/runtime/hdatstructs.H34
-rw-r--r--src/usr/runtime/populate_hbruntime.C80
3 files changed, 155 insertions, 5 deletions
diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C
index 3212881e8..721e9ccc9 100644
--- a/src/usr/runtime/hdatservice.C
+++ b/src/usr/runtime/hdatservice.C
@@ -885,6 +885,48 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
if( errhdl ) { break; }
}
+ else if( RUNTIME::HRMOR_STASH == i_section )
+ {
+ //Look up the tuple that this section is located in
+ errhdl = getAndCheckTuple(i_section, tuple);
+ if( errhdl) {break; }
+
+ TRACUCOMP( g_trac_runtime, "HRMOR_STASH tuple=%p", tuple );
+ uint64_t base_addr = 0;
+ //Find the virtual address of the tuple we found
+ errhdl = getSpiraTupleVA(tuple, base_addr);
+ if( errhdl ) { break; }
+
+ //Set up the MDT(memory description tree) header
+ //(see hdatstructs.H and 11.2.1 MS Area Structure)
+ hdatHDIF_t* mdt_header =
+ reinterpret_cast<hdatHDIF_t*>(base_addr);
+
+ // Check the headers and version info
+ errhdl = check_header( mdt_header,
+ MDT_HEADER );
+ if( errhdl ) { break; }
+
+ //Array of ptrs to different subsections of the MDT
+ hdatHDIFDataHdr_t* mdt_data_ptrs =
+ reinterpret_cast<hdatHDIFDataHdr_t*>
+ (mdt_header->hdatDataPtrOffset + base_addr);
+
+ //ensure the memory range we are passing out is valid hdat address space
+ errhdl = verify_hdat_address(mdt_data_ptrs,
+ mdt_header->hdatDataPtrCnt * sizeof(hdatHDIFDataHdr_t) );
+ if( errhdl ) { break; }
+
+ //The address passed out will point to where hostboot can store an
+ //address that PHYP can look up to figure out where to write the HRMOR
+ //when it changes
+ o_dataAddr = mdt_data_ptrs[MDT_MAINSTORE_ADDR_SECTION].hdatOffset + // offset to ms addr section
+ base_addr + // base of hdat
+ MDT_MAINSTORE_ADDR_SECTION_HYP_HB_COMM_ADDR_OFFSET; // 0x1C
+
+ o_dataSize = MDT_MAINSTORE_ADDR_SECTION_HYP_HB_COMM_ADDR_SIZE; // 8 bytes
+
+ }
// Not sure how we could get here...
else
{
@@ -1460,6 +1502,10 @@ errlHndl_t hdatService::getAndCheckTuple(const SectionId i_section,
l_spiraS = SPIRAS_HSVC_DATA;
l_spiraL = SPIRAL_HSVC_DATA;
break;
+ case RUNTIME::HRMOR_STASH:
+ l_spiraS = SPIRAS_MDT;
+ l_spiraL = SPIRAL_MDT;
+ break;
default:
TRACFCOMP(g_trac_runtime, ERR_MRK"getAndCheckTuple> section %d not supported",
i_section );
diff --git a/src/usr/runtime/hdatstructs.H b/src/usr/runtime/hdatstructs.H
index 1ea8319bd..41cbd1b19 100644
--- a/src/usr/runtime/hdatstructs.H
+++ b/src/usr/runtime/hdatstructs.H
@@ -374,4 +374,38 @@ struct hdatMsVpdRhbAddrRange_t
uint8_t reserved[7]; // 0x0059 Reserved
} __attribute__ ((packed));
+// Supported versions
+enum hbHypCommAreaVersionInfo {
+ STRUCT_VERSION_FIRST = 0x1,
+ STRUCT_VERSION_LATEST = 0x1,
+};
+
+// Size of supported versions - must be 8-byte aligned
+const size_t HB_HYP_COMM_STRUCT_SIZES[STRUCT_VERSION_LATEST+1]
+{
+ 0,
+ 32, // ver1: size of struct is 32 bytes
+};
+
+// Magic number for hbHypCommArea (ASCII = "HYPECOMM")
+const uint64_t HYPECOMM_MAGIC_NUM = 0x48595045434f4d4d;
+
+// Number of bytes into struct for HRMOR address
+// (offset to start of data in hbHypCommArea_t struct)
+const uint8_t HYPCOMM_STRUCT_HRMOR_OFFSET = 24;
+
+struct hbHypCommArea_t
+{
+ uint64_t magicNum; // 8 bytes 0x48595045434f4d4d = HYPECOMM
+ size_t size; // 8 bytes
+ uint32_t version; // 4 bytes
+ uint8_t padding[4]; // 4 bytes put padding in so hrmor is 8 byte aligned
+ //Start Data // 0x18 or 24 byte offset to data
+ uint64_t hrmorAddress; // 8 bytes
+ hbHypCommArea_t(): magicNum(HYPECOMM_MAGIC_NUM), size(HB_HYP_COMM_STRUCT_SIZES[STRUCT_VERSION_LATEST]),
+ version(STRUCT_VERSION_LATEST), padding{0,0,0,0}, hrmorAddress(0)
+ {
+ }
+} PACKED;
+
#endif
diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C
index 8f62d84ac..ed23522d2 100644
--- a/src/usr/runtime/populate_hbruntime.C
+++ b/src/usr/runtime/populate_hbruntime.C
@@ -376,6 +376,14 @@ errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address,
ALIGN_PAGE(l_hbTOC.entry[l_hbTOC.total_entries].size);
l_hbTOC.total_entries++;
+ // Fill in HYPCOMM size
+ l_hbTOC.entry[l_hbTOC.total_entries].label = Util::HBRT_MEM_LABEL_HYPCOMM;
+ l_hbTOC.entry[l_hbTOC.total_entries].offset = 0;
+ l_hbTOC.entry[l_hbTOC.total_entries].size = sizeof(hbHypCommArea_t);
+ l_totalSectionSize +=
+ ALIGN_PAGE(l_hbTOC.entry[l_hbTOC.total_entries].size);
+ l_hbTOC.total_entries++;
+
l_totalSectionSize += sizeof(l_hbTOC); // Add 4KB Table of Contents
// Fill in PADDING size
@@ -477,14 +485,14 @@ errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address,
switch ( l_hbTOC.entry[i].label )
{
case Util::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> ATTROVER v 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 Util::HBRT_MEM_LABEL_ATTR:
- TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> ATTR address 0x%.16llX, size: %lld", l_prevDataAddr, aligned_size);
+ TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> ATTR v address 0x%.16llX, size: %lld", l_prevDataAddr, aligned_size);
l_elog = TARGETING::AttrRP::save(
reinterpret_cast<uint8_t*>(l_prevDataAddr),
aligned_size);
@@ -497,7 +505,7 @@ errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address,
TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> TARGETING::AttrRP::save(0x%.16llX) done", l_prevDataAddr);
break;
case Util::HBRT_MEM_LABEL_VPD:
- TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> VPD address 0x%.16llX, size: %lld", l_prevDataAddr, aligned_size);
+ TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> VPD v address 0x%.16llX, size: %lld", l_prevDataAddr, aligned_size);
l_elog = VPD::vpd_load_rt_image(l_prevDataAddr);
if(l_elog)
{
@@ -505,8 +513,71 @@ errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address,
"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);
+ TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> VPD v address 0x%.16llX, size: %lld done", l_prevDataAddr, aligned_size);
+ break;
+ case Util::HBRT_MEM_LABEL_HYPCOMM:
+ {
+ TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> HYPCOMM v address 0x%.16llX, size: %lld", l_prevDataAddr, aligned_size);
+ //This will call default contructor setting up the version and magic number,
+ // and zero'ing out the data area
+ TARGETING::Target * sys = NULL;
+ TARGETING::targetService().getTopLevelTarget( sys );
+ assert(sys != NULL);
+
+ // Figure out what kind of payload we have
+ TARGETING::PAYLOAD_KIND payload_kind
+ = sys->getAttr<TARGETING::ATTR_PAYLOAD_KIND>();
+
+ hbHypCommArea_t l_hbCommArea;
+ uint64_t l_hdatPtrToHrmorStashAddr = 0;
+ size_t l_hdatPtrHrmorStashSize = 0;
+ //TODO RTC 180959 enable this when HDAT has added in HRMOR ptr space in MS Addr Config section of HDAT
+// uint64_t * l_pHdatPtrToHrmorStashAddr;
+// memcpy a copy of the hbHypCommArea struct to the end of the hbData section
+ memcpy( reinterpret_cast<void*>(l_prevDataAddr),
+ reinterpret_cast<void*>(&l_hbCommArea),
+ sizeof(hbHypCommArea_t));
+
+ if(payload_kind != TARGETING::PAYLOAD_KIND_NONE)
+ {
+ //Find the v addr in hdat that the hypervisor will look
+ //at to determine where to write HRMOR and possibly in
+ //the future information in hostboot's reserved memory section.
+ l_elog = RUNTIME::get_host_data_section( RUNTIME::HRMOR_STASH,
+ 0,
+ l_hdatPtrToHrmorStashAddr,
+ l_hdatPtrHrmorStashSize );
+ if(l_elog)
+ {
+ TRACFCOMP( g_trac_runtime,
+ "fill_RsvMem_hbData> failed to find HRMOR stash address in HDAT" );
+ break;
+ }
+
+ //This should always return a size of 8 as this is a 64 bit address
+ assert(l_hdatPtrHrmorStashSize == sizeof(uint64_t),
+ "The size of the HRMOR_STASH area should always be %d bytes, not %d",
+ sizeof(uint64_t), l_hdatPtrHrmorStashSize);
+
+ //Cast the value returned from get_host_data_section to a uint64_t pointer
+ // l_pHdatPtrToHrmorStashAddr = reinterpret_cast<uint64_t *>(l_hdatPtrToHrmorStashAddr);
+
+ //TODO RTC 180959 enable this when HDAT has added in HRMOR ptr space in MS Addr Config section of HDAT
+ //Set the value of the pointer to be the physical address
+ //of the hrmor stash in the hb-hyp communication area
+ // *l_pHdatPtrToHrmorStashAddr = io_start_address + l_hbTOC.entry[i].offset + HYPCOMM_STRUCT_HRMOR_OFFSET;
+
+ TRACFCOMP( g_trac_runtime,
+ "fill_RsvMem_hbData> HYPCOMM v address 0x%.16llX, size: %lld done",
+ l_prevDataAddr, aligned_size);
+ }
+ else
+ {
+ TRACFCOMP( g_trac_runtime,
+ "fill_RsvMem_hbData> Payload kind was determined to be NONE, skipping setting up HYP comm");
+ }
break;
+ }
default:
break;
}
@@ -525,7 +596,6 @@ errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address,
memcpy( reinterpret_cast<void*>(l_vAddr),
&l_hbTOC,
sizeof(l_hbTOC));
-
} while (0);
if (l_vAddr != 0)
OpenPOWER on IntegriCloud