summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/isteps/istep_reasoncodes.H1
-rw-r--r--src/include/usr/util/utiltce.H13
-rw-r--r--src/include/usr/vmmconst.h36
-rw-r--r--src/usr/isteps/istep21/call_host_runtime_setup.C336
-rw-r--r--src/usr/runtime/hdatservice.C4
-rw-r--r--src/usr/secureboot/trusted/trustedboot.C2
-rw-r--r--src/usr/util/utillidmgr.C53
-rw-r--r--src/usr/util/utilmclmgr.C7
-rw-r--r--src/usr/util/utiltcemgr.C153
-rw-r--r--src/usr/util/utiltcemgr.H56
10 files changed, 566 insertions, 95 deletions
diff --git a/src/include/usr/isteps/istep_reasoncodes.H b/src/include/usr/isteps/istep_reasoncodes.H
index 1b661f17c..9f75bcfe3 100644
--- a/src/include/usr/isteps/istep_reasoncodes.H
+++ b/src/include/usr/isteps/istep_reasoncodes.H
@@ -63,6 +63,7 @@ namespace ISTEP
MOD_SBE_GET_FFDC_HANDLER = 0x1C,
MOD_SET_IPL_PARMS = 0x1D,
MOD_OCC_XSTOP_HANDLER = 0x1E,
+ MOD_VERIFY_AND_MOVE_PAYLOAD = 0x1F,
};
/**
diff --git a/src/include/usr/util/utiltce.H b/src/include/usr/util/utiltce.H
index 0aaffacf1..b0aaf48ae 100644
--- a/src/include/usr/util/utiltce.H
+++ b/src/include/usr/util/utiltce.H
@@ -50,10 +50,11 @@ namespace TCE
* Size must be less than (512K * PAGESIZE) or will fail.
* Assert if not greater than zero.
*
- * @param[out] o_startingToken - Starting Entry into the table.
- * (This is an offset into the array based on the
- * TCE index * PAGESIZE. Each TCE entry maps to
- * a pagesize of memory)
+ * @param[out] o_startingToken - Key to the Starting Entry into the table.
+ * This is an offset into the array based on the
+ * TCE Index * PAGESIZE.
+ * FSP uses the token as a DMA Address.
+ * Each TCE entry maps to a pagesize of memory.
*
* Note: First time this is called will cause TCE Table to be created and
* the Processors to be setup to point at the TCE Table
@@ -97,7 +98,7 @@ errlHndl_t utilDisableTces(void);
/******************************************************/
/**
- * @brief Responsible for Setting up TCEs for PAYLOAD
+ * @brief Responsible for Setting up TCEs for PAYLOAD, including HDAT
*
* @return errlHndl_t - Return Error Handle if failed
*
@@ -105,7 +106,7 @@ errlHndl_t utilDisableTces(void);
errlHndl_t utilSetupPayloadTces(void);
/**
- * @brief Responsible for closing the TCEs for PAYLOAD
+ * @brief Responsible for closing the TCEs for PAYLOAD, including HDAT
*
* @return errlHndl_t - Return Error Handle if failed
*
diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h
index ed773da09..32be069d6 100644
--- a/src/include/usr/vmmconst.h
+++ b/src/include/usr/vmmconst.h
@@ -206,7 +206,7 @@ enum BlockPriority
* Need to add (ATTR_HB_HRMOR_NODAL_BASE * hbinstance_num) to this
* address to get the physical address
*/
-#define VMM_INTERNODE_PRESERVED_MEMORY_ADDR (96 * MEGABYTE)
+#define VMM_INTERNODE_PRESERVED_MEMORY_ADDR (120 * MEGABYTE)
/**
* Test Constants
@@ -222,6 +222,31 @@ enum BlockPriority
* Physical Memory Constants
*/
+/** Layout
+ * 0MB-4MB: reserved/open
+ * 4MB-87MB: MCL_ADDR, MCL_TMP_ADDR, HDAT_TMP_ADDR
+ * 88MB-120MB: TCE Table (needs to be 4-byte aligned)
+ * 120MB: VMM_INTERNODE_PRESERVED_MEMORY_ADDR (see above)
+ * 128MB-256MB: See HB_HRMOR info above (with HOMERs, OCC, etc)
+ */
+
+/** Two memory locations for MCL processing **/
+// Note: 2 spaces needed so the MCL can be initialized without wiping out PHYP
+// Location for the MCL itself to sit in.
+#define MCL_ADDR (4*MEGABYTE)
+#define MCL_SIZE (16*KILOBYTE)
+// Location for PHYP to be loaded into and reused for all Master Container Lids
+// Verification is done in a temporary, non-secure area of mainstore memory,
+// then relocated to its final, secure location in mainstore.
+#define MCL_TMP_ADDR (MCL_ADDR + MCL_SIZE)
+#define MCL_TMP_SIZE ( (64 * MEGABYTE) + PAGESIZE )
+
+// Location for HDAT to be loaded into via TCEs by FSP
+// Verification is done in a temporary, non-secure area of mainstore memory,
+// then relocated to its final, secure location in mainstore.
+#define HDAT_TMP_ADDR (MCL_TMP_ADDR + MCL_TMP_SIZE)
+#define HDAT_TMP_SIZE (16 * MEGABYTE)
+
/** Physical memory location of the TCE Table */
/** - needs to be aligned on 4MB boundary */
#define TCE_TABLE_ADDR (88*MEGABYTE)
@@ -235,15 +260,6 @@ enum BlockPriority
#define UNSECURE_MEM_REGION_SIZE_TEST (1*KILOBYTE)
-/** Two memory locations for MCL processing **/
-// Note: 2 spaces needed so the MCL can be initialized without wiping out PHYP
-// Location for the MCL itself to sit in.
-#define MCL_ADDR (20*MEGABYTE)
-#define MCL_SIZE (16*KILOBYTE)
-// Location for PHYP to be loaded into and reused for all Master Container Lids
-// Verification is done in the temp space and then loaded into mainstore memory
-#define MCL_TMP_ADDR (MCL_ADDR + MCL_SIZE)
-#define MCL_TMP_SIZE ( (64 * MEGABYTE) + PAGESIZE )
/** PreVerifiedLidMgr test space */
#define PREVERLIDMGR_TEST_ADDR (512*MEGABYTE)
diff --git a/src/usr/isteps/istep21/call_host_runtime_setup.C b/src/usr/isteps/istep21/call_host_runtime_setup.C
index 767f7c422..fbf00c458 100644
--- a/src/usr/isteps/istep21/call_host_runtime_setup.C
+++ b/src/usr/isteps/istep21/call_host_runtime_setup.C
@@ -38,7 +38,10 @@
#include <targeting/common/util.H>
#include <vpd/vpd_if.H>
#include <util/utiltce.H>
+#include <map>
+#include <secureboot/service.H>
+#include <sys/mm.h>
//SBE interfacing
#include <sbeio/sbeioif.H>
#include <sys/misc.h>
@@ -53,9 +56,307 @@
using namespace ERRORLOG;
using namespace ISTEP;
using namespace ISTEP_ERROR;
+using namespace TARGETING;
namespace ISTEP_21
{
+
+// Verify PAYLOAD and Move PAYLOAD+HDAT from Temporary TCE-related
+// memory region to the proper location
+errlHndl_t verifyAndMovePayload(void)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ ENTER_MRK"verifyAndMovePayload()" );
+
+ errlHndl_t l_err = nullptr;
+ void * payload_tmp_virt_addr = nullptr;
+ void * payloadBase_virt_addr = nullptr;
+ void * hdat_tmp_virt_addr = nullptr;
+ void * hdat_final_virt_addr = nullptr;
+
+ enum Map_FailLocs_t {
+ NO_MAP_FAIL = 0x0,
+ PAYLOAD_TMP_MAP_FAIL = 0x1, // payload_tmp_virt_addr
+ PAYLOAD_BASE_MAP_FAIL = 0x2, // payloadBase_virt_addr
+ HDAT_TMP_MAP_FAIL = 0x3, // hdat_tmp_virt_addr
+ HDAT_FINAL_MAP_FAIL = 0x4, // hdat_final_virt_addr
+
+ PAYLOAD_TMP_UNMAP_FAIL = 0x5, // payload_tmp_virt_addr
+ PAYLOAD_BASE_UNMAP_FAIL = 0x6, // payloadBase_virt_addr
+ HDAT_TMP_UNMAP_FAIL = 0x7, // hdat_tmp_virt_addr
+ HDAT_FINAL_UNMAP_FAIL = 0x8, // hdat_final_virt_addr
+ };
+
+ Map_FailLocs_t blockMapFail = NO_MAP_FAIL;
+
+ // Make sure these constants are page-aligned, as they are used below for
+ // mm_block_map:
+ static_assert((MCL_TMP_ADDR % PAGESIZE) == 0, "verifyAndMovePayload() MCL_TMP_ADDR isn't page-aligned");
+ static_assert((MCL_TMP_SIZE % PAGESIZE) == 0, "verifyAndMovePayload() MCL_TMP_SIZE isn't page-aligned");
+ static_assert((HDAT_TMP_ADDR % PAGESIZE) == 0, "verifyAndMovePayload() HDAT_TMP_ADDR isn't page-aligned");
+
+ do{
+
+ if (!TCE::utilUseTcesForDmas())
+ {
+ // If TCEs were not enabled, no need to verify and move
+ break;
+ }
+
+ TARGETING::ATTR_PAYLOAD_KIND_type payload_kind =
+ TARGETING::PAYLOAD_KIND_NONE;
+ bool is_phyp = TARGETING::is_phyp_load(&payload_kind);
+
+ // Only Supporting PHYP/POWERVM and SAPPHIRE/OPAL at this time
+ // @TODO RTC 183831 in case we ever need to support Payload AVPS
+ if( !(TARGETING::PAYLOAD_KIND_PHYP == payload_kind ) &&
+ !(TARGETING::PAYLOAD_KIND_SAPPHIRE == payload_kind ) )
+ {
+ break;
+ }
+
+ // Get Temporary Virtual Address To Payload
+ uint64_t payload_tmp_phys_addr = MCL_TMP_ADDR;
+ uint64_t payload_size = MCL_TMP_SIZE;
+
+ payload_tmp_virt_addr = mm_block_map(
+ reinterpret_cast<void*>(payload_tmp_phys_addr),
+ payload_size);
+
+ // Check for nullptr being returned
+ if (payload_tmp_virt_addr == nullptr)
+ {
+ blockMapFail = PAYLOAD_TMP_MAP_FAIL;
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ ERR_MRK"verifyAndMovePayload(): Fail to mm_block_map "
+ "payload_tmp_virt_addr (loc=0x%X)",
+ blockMapFail);
+ break;
+ }
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,"verifyAndMovePayload() "
+ "Processing PAYLOAD_KIND = %d (is_phyp=%d): "
+ "physAddr=0x%.16llX, virtAddr=0x%.16llX",
+ payload_kind, is_phyp, payload_tmp_phys_addr, payload_tmp_virt_addr );
+
+ // If in Secure Mode Verify PHYP at Temporary TCE-related Memory Location
+ if (SECUREBOOT::enabled())
+ {
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,"verifyAndMovePayload() "
+ "Verifying PAYLOAD: physAddr=0x%.16llX, virtAddr=0x%.16llX",
+ payload_tmp_phys_addr, payload_tmp_virt_addr );
+
+ l_err = SECUREBOOT::verifyContainer(payload_tmp_virt_addr);
+ if (l_err)
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "verifyAndMovePayload(): failed verifyContainer");
+ l_err->collectTrace("ISTEPS_TRACE",256);
+ SECUREBOOT::handleSecurebootFailure(l_err);
+ assert(false,"Bug! handleSecurebootFailure shouldn't return!");
+ }
+ }
+
+ // @TODO RTC 168745 - Verify Component ID with ASCII
+ // @TODO RTC 168745 - Extend PAYLOAD
+
+ // Move PHYP to Final Location
+ // Get Target Service, and the system target.
+ TargetService& tS = targetService();
+ TARGETING::Target* sys = nullptr;
+ (void) tS.getTopLevelTarget( sys );
+ assert(sys != nullptr, "verifyAndMovePayload() sys target is NULL");
+ uint64_t payloadBase = sys->getAttr<TARGETING::ATTR_PAYLOAD_BASE>();
+
+ payloadBase = (payloadBase * MEGABYTE)
+ - PAGESIZE; // Put header before PAYLOAD_BASE
+
+ // @TODO RTC 168745 - Use ContainerHeader to get accurate payload size
+ payloadBase_virt_addr = mm_block_map(
+ reinterpret_cast<void*>(payloadBase),
+ payload_size);
+
+ // Check for nullptr being returned
+ if (payloadBase_virt_addr == nullptr)
+ {
+ blockMapFail = PAYLOAD_BASE_MAP_FAIL;
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ ERR_MRK"verifyAndMovePayload(): Fail to mm_block_map "
+ "payloadBase_virt_addr (loc=0x%X)",
+ blockMapFail);
+ break;
+ }
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "verifyAndMovePayload(): Copy PAYLOAD from 0x%.16llX (va="
+ "0x%llX) to PAYLOAD_BASE = 0x%.16llX (va=%llX), size=0x%llX",
+ payload_tmp_phys_addr, payload_tmp_virt_addr, payloadBase,
+ payloadBase_virt_addr, payload_size);
+
+ memcpy (payloadBase_virt_addr,
+ payload_tmp_virt_addr,
+ payload_size);
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "verifyAndMovePayload(): after PAYLOAD memcpy");
+
+ // Move HDAT temporarily put into HDAT_TMP_ADDR (HDAT_TMP_SIZE) into
+ // its proper place
+ // @TODO RTC 168745 - Update hdatservices calls to return Spira-S offset
+ // Currently just using this known offset 80MB=0x5000000 used in current
+ // PHYP images and then adding 1 PAGESIZE since our virtual address starts
+ // at the secure header of PAYLOAD before PAYLOAD_BASE
+ size_t hdat_cpy_offset = 0x5001000;
+
+ hdat_tmp_virt_addr = mm_block_map(
+ reinterpret_cast<void*>(HDAT_TMP_ADDR),
+ HDAT_TMP_SIZE);
+
+ // Check for nullptr being returned
+ if (hdat_tmp_virt_addr == nullptr)
+ {
+ blockMapFail = HDAT_TMP_MAP_FAIL;
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ ERR_MRK"verifyAndMovePayload(): Fail to mm_block_map "
+ "hdat_tmp_virt_addr (loc=0x%X)",
+ blockMapFail);
+ break;
+ }
+
+ hdat_final_virt_addr = mm_block_map(
+ reinterpret_cast<void*>(payloadBase +
+ hdat_cpy_offset),
+ HDAT_TMP_SIZE);
+
+ // Check for nullptr being returned
+ if (hdat_final_virt_addr == nullptr)
+ {
+ blockMapFail = HDAT_FINAL_MAP_FAIL;
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ ERR_MRK"verifyAndMovePayload(): Fail to mm_block_map "
+ "hdat_final_virt_addr (loc=0x%X)",
+ blockMapFail);
+ break;
+ }
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "verifyAndMovePayload(): Copy HDAT from 0x%.16llX (va="
+ "0x%llX) to HDAT_FINAL = 0x%.16llX (va=0x%llX), size=0x%llX",
+ HDAT_TMP_ADDR, hdat_tmp_virt_addr, payloadBase+hdat_cpy_offset,
+ hdat_final_virt_addr,
+ HDAT_TMP_SIZE);
+
+ memcpy(hdat_final_virt_addr,
+ hdat_tmp_virt_addr,
+ HDAT_TMP_SIZE);
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "verifyAndMovePayload(): after HDAT memcpy");
+
+ } while(0);
+
+ // Handle Possible mm_block_map fails here
+ if (blockMapFail != NO_MAP_FAIL)
+ {
+ // Trace done above. Just create error log here.
+
+ /*@
+ * @errortype
+ * @reasoncode RC_MM_MAP_ERR
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_VERIFY_AND_MOVE_PAYLOAD
+ * @userdata1 Map Fail Location
+ * @userdata2 <UNUSED>
+ * @devdesc mm_block_map failed and returned nullptr
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ errlHndl_t map_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ MOD_VERIFY_AND_MOVE_PAYLOAD,
+ RC_MM_MAP_ERR,
+ blockMapFail,
+ 0x0,
+ true /*Add HB SW Callout*/);
+ map_err->collectTrace("ISTEPS_TRACE",256);
+
+ // if l_err already exists just commit this log; otherwise set to l_err
+ if (l_err == nullptr)
+ {
+ l_err = map_err;
+ map_err = nullptr;
+ }
+ else
+ {
+ errlCommit(map_err, ISTEP_COMP_ID);
+ }
+ }
+
+ // Cleanup/Unmap Memory Blocks
+ std::map<void*,Map_FailLocs_t> ptrs_to_unmap =
+ {
+ { payload_tmp_virt_addr, PAYLOAD_TMP_UNMAP_FAIL },
+ { payloadBase_virt_addr, PAYLOAD_BASE_UNMAP_FAIL },
+ { hdat_tmp_virt_addr, HDAT_TMP_UNMAP_FAIL },
+ { hdat_final_virt_addr, HDAT_FINAL_UNMAP_FAIL },
+ };
+
+ for ( auto ptr : ptrs_to_unmap )
+ {
+ if (ptr.first == nullptr)
+ {
+ continue;
+ }
+
+ int rc = mm_block_unmap(ptr.first);
+
+ if (rc != 0)
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ ERR_MRK"verifyAndMovePayload(): Failed to unmap "
+ "0x%.16llX (loc=0x%X)",
+ ptr.first, ptr.second);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_MM_UNMAP_ERR
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_VERIFY_AND_MOVE_PAYLOAD
+ * @userdata1 Map Fail Location
+ * @userdata2 <UNUSED>
+ * @devdesc mm_block_unmap failed and returned nullptr
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ errlHndl_t unmap_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ MOD_VERIFY_AND_MOVE_PAYLOAD,
+ RC_MM_UNMAP_ERR,
+ blockMapFail,
+ 0x0,
+ true /*Add HB SW Callout*/);
+ unmap_err->collectTrace("ISTEPS_TRACE",256);
+
+ // if l_err already exists just commit this log;
+ // otherwise set to l_err
+ if (l_err == nullptr)
+ {
+ l_err = unmap_err;
+ unmap_err = nullptr;
+ }
+ else
+ {
+ errlCommit(unmap_err, ISTEP_COMP_ID);
+ }
+ }
+ }
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ EXIT_MRK"verifyAndMovePayload(): l_err rc = 0x%X",
+ ERRL_GETRC_SAFE(l_err) );
+
+ return l_err;
+}
+
+
void* call_host_runtime_setup (void *io_pArgs)
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
@@ -71,7 +372,6 @@ void* call_host_runtime_setup (void *io_pArgs)
do
{
// Close PAYLOAD TCEs
- // @TODO RTC 168745 - also close HDAT TCEs
if (TCE::utilUseTcesForDmas())
{
@@ -83,16 +383,6 @@ void* call_host_runtime_setup (void *io_pArgs)
// break from do loop if error occurred
break;
}
-
- // Disable all TCEs
- l_err = TCE::utilDisableTces();
- if ( l_err )
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "Failed TCE::utilDisableTces" );
- // break from do loop if error occurred
- break;
- }
}
//Need to send System Configuration down to SBE
@@ -152,6 +442,7 @@ void* call_host_runtime_setup (void *io_pArgs)
}
// Tell SBE to Close All Unsecure Memory Regions
+ // @TODO RTC 168745 - Move to istep 21.3 (closer to shutdown)
l_err = SBEIO::closeAllUnsecureMemRegions();
if ( l_err )
{
@@ -185,6 +476,14 @@ void* call_host_runtime_setup (void *io_pArgs)
break;
}
+ // Verify PAYLOAD and Move PAYLOAD+HDAT from Temporary TCE-related
+ // memory region to the proper location
+ l_err = verifyAndMovePayload();
+ if(l_err)
+ {
+ break;
+ }
+
// Map the Host Data into the VMM if applicable
l_err = RUNTIME::load_host_data();
if( l_err )
@@ -365,6 +664,19 @@ void* call_host_runtime_setup (void *io_pArgs)
}
#endif
+ if (TCE::utilUseTcesForDmas())
+ {
+ // Disable all TCEs
+ l_err = TCE::utilDisableTces();
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Failed TCE::utilDisableTces" );
+ // break from do loop if error occurred
+ break;
+ }
+ }
+
} while(0);
if( l_err )
@@ -380,7 +692,7 @@ void* call_host_runtime_setup (void *io_pArgs)
}
- TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_host_runtime_setup exit" );
return l_StepError.getErrorHandle();
diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C
index 88d417c38..3212881e8 100644
--- a/src/usr/runtime/hdatservice.C
+++ b/src/usr/runtime/hdatservice.C
@@ -549,7 +549,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
size_t& o_dataSize)
{
errlHndl_t errhdl = NULL;
- TRACFCOMP( g_trac_runtime, "RUNTIME::getHostDataSection( i_section=%d, i_instance=%d )", i_section, i_instance );
+ TRACFCOMP( g_trac_runtime, ENTER_MRK"getHostDataSection> i_section=%d, i_instance=%d", i_section, i_instance );
do
{
@@ -921,7 +921,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
}
} while(0);
- TRACFCOMP( g_trac_runtime, "getHostDataSection> o_dataAddr=0x%X, o_dataSize=%d", o_dataAddr, o_dataSize );
+ TRACFCOMP( g_trac_runtime, EXIT_MRK"getHostDataSection> o_dataAddr=0x%X, o_dataSize=%d", o_dataAddr, o_dataSize );
return errhdl;
}
diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C
index b135d0513..8c9f7fff3 100644
--- a/src/usr/secureboot/trusted/trustedboot.C
+++ b/src/usr/secureboot/trusted/trustedboot.C
@@ -1156,6 +1156,8 @@ void tpmVerifyFunctionalTpmExists()
HWAS::SRCI_PRIORITY_LOW);
err->collectTrace( SECURE_COMP_NAME );
err->collectTrace(TRBOOT_COMP_NAME);
+ err->collectTrace( I2C_COMP_NAME );
+ err->collectTrace( TPMDD_COMP_NAME );
uint32_t errPlid = err->plid();
// HW callout TPMs
diff --git a/src/usr/util/utillidmgr.C b/src/usr/util/utillidmgr.C
index 7f94c50ed..d69d02d0b 100644
--- a/src/usr/util/utillidmgr.C
+++ b/src/usr/util/utillidmgr.C
@@ -35,6 +35,7 @@
#include "utilbase.H"
#include <initservice/initserviceif.H>
#include <sys/mm.h>
+#include <util/align.H>
#include <config.h>
#ifdef CONFIG_SECUREBOOT
@@ -112,7 +113,6 @@ errlHndl_t UtilLidMgr::getLidSize(size_t& o_lidSize)
//ask the FSP for it.
//Send message to FSP asking for info on the current LID.
-
// allocate message buffer
// buffer will be initialized to zero by msg_allocate()
if (iv_spBaseServicesEnabled)
@@ -353,8 +353,12 @@ errlHndl_t UtilLidMgr::getLid(void* i_dest, size_t i_destSize)
uint8_t* dataPtr = nullptr;
void* copyOffset = nullptr;
bool img_in_pnor = false;
+ bool use_tces = 0;
bool tces_allocated = false;
uint32_t tceToken = 0;
+ uint32_t dmaAddr = 0;
+ void* tceStartAddr = nullptr;
+ uint64_t tceSize = 0;
do{
//////////////////////////////////////////////////
@@ -371,12 +375,34 @@ errlHndl_t UtilLidMgr::getLid(void* i_dest, size_t i_destSize)
//Image not in PNOR, request from FSP.
if(iv_spBaseServicesEnabled)
{
+ use_tces = TCE::utilUseTcesForDmas();
+
// If using TCEs, setup TCE Table for FSP to use
- if (TCE::utilUseTcesForDmas())
+ if (use_tces)
{
- // Use Preverification Location and Size
- errl = TCE::utilAllocateTces(MCL_TMP_ADDR,
- MCL_TMP_SIZE,
+ // Assume caller passed in Virtual Address that was already
+ // backed to Physical Memory
+ UTIL_FT("getLid: requesting TCEs for i_dest=0x%.16llX, i_destSize=0x%X (lidId=0x%X)", i_dest, i_destSize, iv_lidId);
+
+ // Need to Allocate TCEs on Page-Aligned Memory
+ size_t i_dest_remainder = reinterpret_cast<uint64_t>(i_dest)
+ % PAGESIZE;
+
+ if (i_dest_remainder != 0)
+ {
+ tceStartAddr = reinterpret_cast<void*>(
+ ALIGN_PAGE_DOWN(reinterpret_cast<uint64_t>(i_dest)));
+ tceSize = i_destSize + i_dest_remainder;
+ UTIL_DT("getLid: requesting non-page-aligned i_dest (%p): adjusted TCE tceStartAddr = %p, tceSize=0x%X", i_dest, tceStartAddr, tceSize);
+ }
+ else
+ {
+ tceStartAddr = i_dest;
+ tceSize = i_destSize;
+ }
+
+ errl = TCE::utilAllocateTces(mm_virt_to_phys(tceStartAddr),
+ tceSize,
tceToken);
if(errl)
{
@@ -384,6 +410,10 @@ errlHndl_t UtilLidMgr::getLid(void* i_dest, size_t i_destSize)
break;
}
tces_allocated = true;
+
+ // Update dmaAddr that FSP needs to use, if necessary
+ dmaAddr = tceToken + i_dest_remainder;
+ UTIL_DT("getLid: got back tceToken=0x%.16llX. DMA_Addr=0x%.16llX", tceToken, dmaAddr);
}
errl = createMsgQueue();
@@ -402,7 +432,7 @@ errlHndl_t UtilLidMgr::getLid(void* i_dest, size_t i_destSize)
UTILLID_ADD_LID_ID( iv_lidId, l_pMsg->data[0] );
UTILLID_ADD_HEADER_FLAG( 0 , l_pMsg->data[0] );
- UTILLID_ADD_TCE_TOKEN( tceToken , l_pMsg->data[1] );
+ UTILLID_ADD_TCE_TOKEN( dmaAddr , l_pMsg->data[1] );
errl = sendMboxMessage( SYNCHRONOUS, l_pMsg );
if(errl)
@@ -444,6 +474,13 @@ errlHndl_t UtilLidMgr::getLid(void* i_dest, size_t i_destSize)
break;
}
+ // In TCE Mode FSP DMAs the entire LID before returning synchronus
+ // message above with the SEND_TO_HB message type
+ if (use_tces && (l_pMsg->type == UTILLID::SEND_TO_HB))
+ {
+ UTIL_DT("getLid: Using TCEs and got back UTILLID::SEND_TO_HB: transfer complete");
+ break;
+ }
//Now wait for FSP to send the LID page-by-page.
do{
@@ -563,7 +600,6 @@ errlHndl_t UtilLidMgr::getLid(void* i_dest, size_t i_destSize)
}
}while(transferred_data < iv_lidSize);
-
}
if(errl)
{
@@ -576,7 +612,7 @@ errlHndl_t UtilLidMgr::getLid(void* i_dest, size_t i_destSize)
{
// Use Preverification Location and Size
auto tce_errl = TCE::utilDeallocateTces(tceToken,
- MCL_TMP_SIZE);
+ tceSize);
if(tce_errl)
{
@@ -592,6 +628,7 @@ errlHndl_t UtilLidMgr::getLid(void* i_dest, size_t i_destSize)
{
// Set errl to tce_errl
errl = tce_errl;
+ tce_errl = nullptr;
}
}
}
diff --git a/src/usr/util/utilmclmgr.C b/src/usr/util/utilmclmgr.C
index 66c3b1a29..81e1c8cff 100644
--- a/src/usr/util/utilmclmgr.C
+++ b/src/usr/util/utilmclmgr.C
@@ -328,7 +328,6 @@ void MasterContainerLidMgr::printCompInfoCache()
errlHndl_t MasterContainerLidMgr::processComponents()
{
errlHndl_t l_errl = nullptr;
-
for (auto & compInfoPair : iv_compInfoCache)
{
// Skip the MCL itself as it's already been processed
@@ -377,7 +376,11 @@ errlHndl_t MasterContainerLidMgr::processComponent(const ComponentID& i_compId,
{
// Skip loading, but still process POWERVM (PHYP) component
l_skipLoad = true;
- UTIL_FT("MasterContainerLidMgr::processComponent skip load but processing POWERVM component");
+
+ // @TODO RTC 168745 - Handle POWERVM Correctly
+ // UTIL_FT("MasterContainerLidMgr::processComponent skip load but processing POWERVM component");
+ UTIL_FT("MasterContainerLidMgr::processComponent - skip loading and processing of POWERVM component");
+ break;
}
else
{
diff --git a/src/usr/util/utiltcemgr.C b/src/usr/util/utiltcemgr.C
index 01f2bf7e6..2424ee686 100644
--- a/src/usr/util/utiltcemgr.C
+++ b/src/usr/util/utiltcemgr.C
@@ -54,6 +54,7 @@ TRAC_INIT(&g_trac_tce, UTILTCE_TRACE_NAME, 4*KILOBYTE);
// ------------------------
// Macros for unit testing - leave extra trace enabled for now
+// @TODO RTC 168745 - Disable TRACUCOMP as the default
#define TRACUCOMP(args...) TRACFCOMP(args)
//#define TRACUCOMP(args...)
@@ -64,13 +65,10 @@ namespace TCE
/************************************************************************/
// Defines
/************************************************************************/
-// @TODO RTC 168745 Currently hardcoded to 128MB when the original plan was
-// to use PNOR payloadInfo.size, but that only was 19MB
-#define TCE_PAYLOAD_SIZE (128*MEGABYTE)
-
// TCE Table Address must be 4MB Aligned
#define TCE_TABLE_ADDRESS_ALIGNMENT (4*MEGABYTE)
+
/************************************************************************/
// External Interface:
// NAME: utilAllocateTces
@@ -123,22 +121,6 @@ UtilTceMgr& getTceManager(void)
return Singleton<UtilTceMgr>::instance();
};
-/***********************************************************************************/
-/* Local function to get PAYLOAD base address and size */
-/***********************************************************************************/
-errlHndl_t getPayloadAddrAndSize(uint64_t& o_addr, size_t& o_size)
-{
- errlHndl_t errl = nullptr;
-
- // Move PAYLOAD to Preverification Location
- o_addr = MCL_TMP_ADDR;
- o_size = MCL_TMP_SIZE;
-
- TRACFCOMP( g_trac_tce,EXIT_MRK"getPayloadAddrAndSize(): o_addr=0x%.16llX, o_size=0x%.16llX", o_addr, o_size);
-
- return errl;
-}
-
errlHndl_t utilSetupPayloadTces(void)
{
errlHndl_t errl = nullptr;
@@ -149,24 +131,24 @@ errlHndl_t utilSetupPayloadTces(void)
do{
- TRACFCOMP(g_trac_tce,ENTER_MRK"utilSetupPayloadTces(): get Address and Size");
+ TRACFCOMP(g_trac_tce,ENTER_MRK"utilSetupPayloadTces()");
- errl = getPayloadAddrAndSize(addr, size);
+ // Allocate TCEs for PAYLOAD to Temporary Space
+ addr = MCL_TMP_ADDR;
+ size = MCL_TMP_SIZE;
+ errl = utilAllocateTces(addr, size, token);
if (errl)
{
- TRACFCOMP(g_trac_tce,"utilSetupPayloadTces(): ERROR back from getPayloadAddrAndSize()");
+ TRACFCOMP(g_trac_tce,"utilSetupPayloadTces(): ERROR back from utilAllocateTces() for PAYLOAD using addr=0x%.16llX, size=0x%llX", addr, size);
break;
}
-
- errl = utilAllocateTces(addr, size, token);
- if (errl)
+ else
{
- TRACFCOMP(g_trac_tce,"utilSetupPayloadTces(): ERROR back from utilAllocateTces() using addr=0x%.16llX, size=0x%llX", addr, size);
- break;
+ TRACUCOMP(g_trac_tce,"utilSetupPayloadTces(): utilAllocateTces() for PAYLOAD: addr=0x%.16llX, size=0x%llX, token=0x%X", addr, size, token);
}
- // Set attribute to tell FSP that Payload has been setup at the start of the TCE Table
- // Get Target Service and the system target to set TCE_START_TOKEN_FOR_PAYLOAD
+ // Set attribute to tell FSP what the PAYLOAD token is
+ // Get Target Service and the system target to set attributes
TARGETING::TargetService& tS = TARGETING::targetService();
TARGETING::Target* sys = nullptr;
(void) tS.getTopLevelTarget( sys );
@@ -174,9 +156,34 @@ errlHndl_t utilSetupPayloadTces(void)
sys->setAttr<TARGETING::ATTR_TCE_START_TOKEN_FOR_PAYLOAD>(token);
+ // Save for internal use since we can't trust FSP won't change the attribute
+ Singleton<UtilTceMgr>::instance().setToken(UtilTceMgr::PAYLOAD_TOKEN,
+ token);
+
+ // Allocate TCEs for HDAT
+ addr = HDAT_TMP_ADDR;
+ size = HDAT_TMP_SIZE;
+ errl = utilAllocateTces(addr, size, token);
+ if (errl)
+ {
+ TRACFCOMP(g_trac_tce,"utilSetupPayloadTces(): ERROR back from utilAllocateTces() for HDAT using addr=0x%.16llX, size=0x%llX", HDAT_TMP_ADDR, HDAT_TMP_SIZE);
+ break;
+ }
+ else
+ {
+ TRACUCOMP(g_trac_tce,"utilSetupPayloadTces(): utilAllocateTces() for HDAT: addr=0x%.16llX, size=0x%llX, token=0x%X", addr, size, token);
+ }
+
+ // Set attribute to tell FSP what the HDAT token is
+ sys->setAttr<TARGETING::ATTR_TCE_START_TOKEN_FOR_HDAT>(token);
+
+ // Save for internal use since we can't trust FSP won't change the attribute
+ Singleton<UtilTceMgr>::instance().setToken(UtilTceMgr::HDAT_TOKEN,
+ token);
+
} while(0);
- TRACFCOMP(g_trac_tce,EXIT_MRK"utilSetupPayloadTces(): Address=0x%.16llX, size=0x%X, token=0x%.8X, errl_rc=0x%X", addr, size, token, ERRL_GETRC_SAFE(errl));
+ TRACFCOMP(g_trac_tce,EXIT_MRK"utilSetupPayloadTces(): errl_rc=0x%X", ERRL_GETRC_SAFE(errl));
return errl;
}
@@ -185,31 +192,26 @@ errlHndl_t utilClosePayloadTces(void)
{
errlHndl_t errl = nullptr;
- uint64_t addr=0x0;
size_t size=0x0;
uint32_t token=0x0;
do{
- TRACFCOMP(g_trac_tce,ENTER_MRK"utilClosePayloadTces(): get Address and Size");
+ TRACFCOMP(g_trac_tce,ENTER_MRK"utilClosePayloadTces()");
- // Get Payload Address and Size
- errl = getPayloadAddrAndSize(addr, size);
+ // size is a constant for PAYLOAD
+ size = MCL_TMP_SIZE;
+ token = Singleton<UtilTceMgr>::instance().getToken(UtilTceMgr::PAYLOAD_TOKEN);
+ errl = utilDeallocateTces(token, size);
if (errl)
{
- TRACFCOMP(g_trac_tce,"utilClosePayloadTces(): ERROR back from getPayloadAddrAndSize()");
+ TRACFCOMP(g_trac_tce,"utilClosePayloadTces(): ERROR back from utilDeallocateTces() using token=0x%.8X, size=0x%llX", token, size);
break;
}
- // Get Starting Payload Token
- // Get Target Service and the system target to set TCE_START_TOKEN_FOR_PAYLOAD
- TARGETING::TargetService& tS = TARGETING::targetService();
- TARGETING::Target* sys = nullptr;
- (void) tS.getTopLevelTarget( sys );
- assert(sys, "utilSetupPayloadTces() system target is NULL");
-
- token = sys->getAttr<TARGETING::ATTR_TCE_START_TOKEN_FOR_PAYLOAD>();
-
+ // size is a constant for HDAT
+ size = HDAT_TMP_SIZE;
+ token = Singleton<UtilTceMgr>::instance().getToken(UtilTceMgr::HDAT_TOKEN);
errl = utilDeallocateTces(token, size);
if (errl)
{
@@ -217,9 +219,10 @@ errlHndl_t utilClosePayloadTces(void)
break;
}
+
} while(0);
- TRACFCOMP(g_trac_tce,EXIT_MRK"utilClosePayloadTces(): token=0x%.8X, size=0x%X, errl_rc=0x%X", token, size, ERRL_GETRC_SAFE(errl));
+ TRACFCOMP(g_trac_tce,EXIT_MRK"utilClosePayloadTces(): errl_rc=0x%X", ERRL_GETRC_SAFE(errl));
return errl;
}
@@ -238,6 +241,8 @@ UtilTceMgr::UtilTceMgr(const uint64_t i_tableAddr, const size_t i_tableSize)
,iv_tceTablePhysAddr(i_tableAddr)
,iv_tceEntryCount(0)
,iv_tceTableSize(i_tableSize)
+ ,iv_payloadToken(INVALID_TOKEN_VALUE)
+ ,iv_hdatToken(INVALID_TOKEN_VALUE)
{
// Table Address must be 4MB Aligned and default input is TCE_TABLE_ADDR
static_assert( TCE_TABLE_ADDR % TCE_TABLE_ADDRESS_ALIGNMENT == 0,"TCE Table must align on 4 MB boundary");
@@ -767,9 +772,12 @@ errlHndl_t UtilTceMgr::allocateTces(const uint64_t i_startingAddress,
TRACDCOMP(g_trac_tce,INFO_MRK"UtilTceMgr::allocateTces: TCE Entry/Token[%d] (hex) = %llX", index, tablePtr[index]);
}
- iv_allocatedAddrs[startingIndex].start_addr = i_startingAddress;
- iv_allocatedAddrs[startingIndex].size = i_size;
- o_startingToken = startingIndex;
+ // Save And Return Information about Allocated TCEs
+ // Key to this map is the token, which is a DMA address that =
+ // (Starting Index in TCE Table) * PAGESIZE
+ o_startingToken = startingIndex*PAGESIZE;
+ iv_allocatedAddrs[o_startingToken].start_addr = i_startingAddress;
+ iv_allocatedAddrs[o_startingToken].size = i_size;
TRACFCOMP(g_trac_tce,"UtilTceMgr::allocateTces: SUCCESSFUL: addr = 0x%.16llX, size = 0x%llX, starting entry=0x%X",i_startingAddress, i_size, startingIndex);
}
@@ -802,7 +810,7 @@ errlHndl_t UtilTceMgr::allocateTces(const uint64_t i_startingAddress,
}
}while(0);
- TRACFCOMP(g_trac_tce, EXIT_MRK"UtilTceMgr::allocateTces: END: addr = 0x%.16llX and size = 0x%X, numTcesNeeded=0x%X", i_startingAddress, i_size, numTcesNeeded);
+ TRACFCOMP(g_trac_tce, EXIT_MRK"UtilTceMgr::allocateTces: END: addr = 0x%.16llX and size = 0x%X, numTcesNeeded=0x%X. returning o_startingToken=0x%.8X", i_startingAddress, i_size, numTcesNeeded, o_startingToken);
printIvMap(); //Debug
return errl;
@@ -830,6 +838,9 @@ errlHndl_t UtilTceMgr::deallocateTces(const uint32_t i_startingToken,
do
{
+ // Assert if i_startingToken is not aligned on PAGESIZE
+ assert((i_startingToken % PAGESIZE) == 0, "UtilTceMgr::deallocateTces: i_startingToken (0x%.8X) is not page aligned", i_startingToken);
+
// Assert if i_size is not greater than zero
assert(i_size > 0, "UtilTceMgr::deallocateTces: i_size = %d, not greater than zero", i_size);
@@ -847,7 +858,7 @@ errlHndl_t UtilTceMgr::deallocateTces(const uint32_t i_startingToken,
}
else
{
- startingIndex = map_itr->first;
+ startingIndex = (map_itr->first) / PAGESIZE;
startingAddress = map_itr->second.start_addr;
}
TRACUCOMP(g_trac_tce,"UtilTceMgr::deallocateTces: numTcesNeeded=0x%X, startingAddress = 0x%X", numTcesNeeded, startingAddress);
@@ -1258,6 +1269,45 @@ errlHndl_t UtilTceMgr::unmapPsiHostBridge(void *& io_psihb_ptr) const
return errl;
}
+/**************************************************************************/
+//
+// NAME: getToken:
+// Returns one of two internally stored tokens
+//
+/**************************************************************************/
+
+uint32_t UtilTceMgr::getToken(const tokenLabels i_tokenLabel)
+{
+ assert((i_tokenLabel==UtilTceMgr::PAYLOAD_TOKEN)||(i_tokenLabel==UtilTceMgr::HDAT_TOKEN),"UtilTceMgr::getToken bad input parm: 0x%X", i_tokenLabel);
+
+ return (i_tokenLabel==UtilTceMgr::PAYLOAD_TOKEN)
+ ? iv_payloadToken : iv_hdatToken;
+
+}
+
+/**************************************************************************/
+//
+// NAME: setToken:
+// Sets one of two internally stored tokens
+//
+/**************************************************************************/
+void UtilTceMgr::setToken(const tokenLabels i_tokenLabel,
+ const uint32_t i_tokenValue)
+{
+ assert((i_tokenLabel==UtilTceMgr::PAYLOAD_TOKEN)||(i_tokenLabel==UtilTceMgr::HDAT_TOKEN),"UtilTceMgr::setToken bad input parm: 0x%X", i_tokenLabel);
+
+ if (i_tokenLabel==UtilTceMgr::PAYLOAD_TOKEN)
+ {
+ iv_payloadToken = i_tokenValue;
+ }
+ else
+ {
+ iv_hdatToken = i_tokenValue;
+ }
+
+ return;
+}
+
/******************************************************/
/* Miscellaneous Functions */
@@ -1290,6 +1340,7 @@ errlHndl_t utilEnableTcesWithoutTceTable(void)
{
errlHndl_t errl = nullptr;
+ // @TODO RTC 168745 - Update to use Singleton UtilTceMgr
// Create local UtilTceMgr with default TCE table address but with a size
// of zero so that all entries are invalid
// NOTE: memory at TCE Table Address is initialized to 0 as part of IPL and
diff --git a/src/usr/util/utiltcemgr.H b/src/usr/util/utiltcemgr.H
index a4689235c..aabf99d5a 100644
--- a/src/usr/util/utiltcemgr.H
+++ b/src/usr/util/utiltcemgr.H
@@ -120,8 +120,12 @@ class UtilTceMgr
/** size of the Tce Table */
size_t iv_tceTableSize;
+ /** Tokens for PAYLOAD and HDAT entries in the TCE Table */
+ uint32_t iv_payloadToken;
+ uint32_t iv_hdatToken;
+
/* Cache of starting addresses of allocated TCEs and their
- * tokens (starting entry in the TCE Table) and size
+ * tokens ((starting entry in the TCE Table) * PAGESIZE) and size
* Indexed by token - the position of the first entry of the TCE Table
* Returns the starting address and size of the memory allocated by the
* entries in the TCE Table
@@ -146,6 +150,12 @@ class UtilTceMgr
PHBSECURE_TCE_ENABLE = 0x2000000000000000,
};
+ /** Values related to tokens */
+ enum tokenValues : uint32_t
+ {
+ INVALID_TOKEN_VALUE = 0xFFFFFFFF,
+ };
+
/**
* @brief Responsible for initalizing the TCE Table and mapping the
* TCE Table into memory
@@ -240,9 +250,11 @@ class UtilTceMgr
* Size must be less than (512K * PAGESIZE) or will fail
* Assert if not greater than zero
* @param[out] o_startingToken - Starting Entry into the table.
- * (This is an offset into the array based on
- * the TCE index * PAGESIZE. Each TCE entry
- * maps to a pagesize of memory)
+ * @param[out] o_startingToken - Key to the Starting Entry into the table.
+ * This is an offset into the array based on the
+ * TCE Index * PAGESIZE.
+ * FSP uses the token as a DMA Address.
+ * Each TCE entry maps to a pagesize of memory.
*
* Note: First time this is called will cause TCE table to be created and
* the Processors to be setup to point at the TCE table
@@ -287,6 +299,42 @@ class UtilTceMgr
*/
errlHndl_t initTceInHdw();
+
+ /** Values related to tokens */
+ enum tokenLabels
+ {
+ PAYLOAD_TOKEN = 0x0,
+ HDAT_TOKEN = 0x1,
+ };
+
+ /**
+ * @brief Returns one of two internally stored tokens
+ *
+ * @param[in] i_tokenLabel - Specifies which token to return
+ * Assert if neither PAYLOAD_TOKEN nor
+ * HDAT_TOKEN
+ *
+ * @return uint32_t - Return specified token
+ *
+ */
+ uint32_t getToken(tokenLabels i_tokenLabel);
+
+ /**
+ * @brief Sets one of two internally stored tokens
+ *
+ * @param[in] i_tokenLabel - Specifies which token to set
+ * Assert if neither PAYLOAD_TOKEN nor
+ * HDAT_TOKEN
+ *
+ * @param[in] i_tokenValue - Value to be set
+ *
+ * @return uint32_t - Set specified token
+ *
+ */
+ void setToken(tokenLabels i_tokenLabel,
+ uint32_t i_tokenValue);
+
+
}; // class UtilTceMgr
/**
OpenPOWER on IntegriCloud