diff options
author | Mike Jones <mjjones@us.ibm.com> | 2011-09-06 08:52:17 -0500 |
---|---|---|
committer | MIKE J. JONES <mjjones@us.ibm.com> | 2011-09-07 08:52:29 -0500 |
commit | dd8d92217c8cebd6aa5408ad7fd4fa50ea248c84 (patch) | |
tree | e407bbb12cc5e6e12546154e6ac9cbe8a4ccc99c | |
parent | 11ea7375f50c8e426e85ebdb4c2d9b67b8ecbb27 (diff) | |
download | blackbird-hostboot-dd8d92217c8cebd6aa5408ad7fd4fa50ea248c84.tar.gz blackbird-hostboot-dd8d92217c8cebd6aa5408ad7fd4fa50ea248c84.zip |
HWPF: Initial Support for Target::getString (ecmd string)
Change-Id: Ifef0e05d780fa3ff0a29ce289a684a37495be943
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/324
Tested-by: Jenkins Server
Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com>
-rw-r--r-- | src/include/usr/hwpf/fapi/fapiTarget.H | 20 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/fapiTestHwp.C | 6 | ||||
-rw-r--r-- | src/usr/hwpf/plat/fapiPlatTarget.C | 162 | ||||
-rw-r--r-- | src/usr/isteps/istep1.C | 5 | ||||
-rw-r--r-- | src/usr/xscom/xscom.C | 82 |
5 files changed, 226 insertions, 49 deletions
diff --git a/src/include/usr/hwpf/fapi/fapiTarget.H b/src/include/usr/hwpf/fapi/fapiTarget.H index 093854155..1ee28236d 100644 --- a/src/include/usr/hwpf/fapi/fapiTarget.H +++ b/src/include/usr/hwpf/fapi/fapiTarget.H @@ -33,7 +33,8 @@ * ------ -------------- ---------- ----------- ---------------------------- * mjjones 04/13/2011 Created. Based on Hlava prototype * mjjones 06/29/2011 Removed incorrect MSB from 2 enums - * mjjones 07/05/2011. Removed const from handle + * mjjones 07/05/2011 Removed const from handle + * mjjones 08/29/2011 Updated toString function */ #ifndef FAPITARGET_H_ @@ -67,6 +68,11 @@ enum TargetType typedef uint32_t TargetTypes_t; /** + * @brief ECMD constants + */ +const uint32_t MAX_ECMD_STRING_LEN = 64; + +/** * @class Target * * This class provides a generic Target of a Hardware Procedure Operation. @@ -172,15 +178,15 @@ public: /** * @brief Convert a target to an ecmd-format target string * - * @note Implemented by platform code + * This is used in order to trace the target in the common SCAN trace * - * @return A pointer to a c-string. If the object cannot be converted to a - * valid ecmd string, a NULL pointer is returned. + * @note Implemented by platform code * - * IMPORTANT: It is the caller's responsibility to free the returned string - * when done with it by calling "free(char*)". + * @param[out] o_ecmdString. Reference to a character array of length + * MAX_ECMD_STRING_LEN. This is filled in with the + * null terminated ECMD string. */ - const char * toString() const; + void toString(char (&o_ecmdString)[MAX_ECMD_STRING_LEN]) const; private: diff --git a/src/usr/hwpf/hwp/fapiTestHwp.C b/src/usr/hwpf/hwp/fapiTestHwp.C index 01d004748..e1d490c98 100644 --- a/src/usr/hwpf/hwp/fapiTestHwp.C +++ b/src/usr/hwpf/hwp/fapiTestHwp.C @@ -35,6 +35,7 @@ * mjjones 06/28/2011 Removed attribute tests * andrewg 07/07/2011 Added test for hw team to fill in * mjjones 08/10/2011 Removed clock HWP + * mjjones 09/01/2011 Call toString in InitialTest * */ @@ -50,6 +51,11 @@ fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip) { FAPI_INF("Performing HWP: hwpInitialTest"); + // Print the ecmd string of the chip + char l_string[fapi::MAX_ECMD_STRING_LEN] = {0}; + i_chip.toString(l_string); + FAPI_INF("hwpInitialTest: Chip: %s", l_string); + fapi::ReturnCode l_rc; // Figure out the scom address and create a 64 bit data buffer diff --git a/src/usr/hwpf/plat/fapiPlatTarget.C b/src/usr/hwpf/plat/fapiPlatTarget.C index 5ec2f00ff..3ef78ef5f 100644 --- a/src/usr/hwpf/plat/fapiPlatTarget.C +++ b/src/usr/hwpf/plat/fapiPlatTarget.C @@ -37,6 +37,9 @@ */ #include <fapiTarget.H> +#include <fapiPlatTrace.H> +#include <targeting/target.H> +#include <string.h> namespace fapi { @@ -69,4 +72,163 @@ void Target::deleteHandle() // Intentionally does nothing. The component must not be deleted } +//****************************************************************************** +// Get the ECMD String +//****************************************************************************** +void Target::toString(char (&o_ecmdString)[MAX_ECMD_STRING_LEN]) const +{ + // Extract the HostBoot target pointer + TARGETING::Target* l_pTarget = + reinterpret_cast<TARGETING::Target*>(iv_pHandle); + + if (l_pTarget == NULL) + { + FAPI_ERR("toString: Called on NULL target"); + strcpy(o_ecmdString, "ecmd-no-target"); + } + else + { + // TODO + // This is a temporary function that constructs the ECMD String from the + // target's physical path attribute, eventually, the ECMD String will be + // its own attribute and this function will be changed to simply get the + // attribute + + // Try to get the physical path attribute + TARGETING::EntityPath l_path; + if (l_pTarget->tryGetAttr<TARGETING::ATTR_PHYS_PATH>(l_path)) + { + uint32_t l_sizePath = l_path.size(); + + // This function returns the ecmd string for chips and chiplets. The + // output string is: + // Chiplet: <chip>.<unit>:kX:nX:sX:pXX:cX + // Chip: <chip>:kX:nX:sX:pXX + // + // <chip> = chip type ("pu" = processor, "memb" = memory buffer) + // <unit> = unit type ("ex", "mcs", "mbs", "mba") + // kX = cage number. Always zero + // nX = node number. Always zero in HostBoot (right now) + // sX = slot number. Always zero + // pXX = chip position + // cX = unit position + // + // Examples: + // pu:k0:n0:s0:p01 + // pu.ex:k0:n0:s0:p01:c0 + const char * const ECMD_CHIP_PROC = "pu"; + const char * const ECMD_CHIP_MEMBUF = "memb"; + const char * const ECMD_CHIPLET_EX = "ex"; + const char * const ECMD_CHIPLET_MCS = "mcs"; + const char * const ECMD_CHIPLET_MBS = "mbs"; + const char * const ECMD_CHIPLET_MBA = "mba"; + + // Look for a chip in the path + const char * l_pChipType = NULL; + uint32_t l_chipPos = 0; + + for (uint32_t i = 0; ((i < l_sizePath) && (l_pChipType == NULL)); + i++) + { + if (l_path[i].type == TARGETING::TYPE_PROC) + { + l_pChipType = ECMD_CHIP_PROC; + l_chipPos = l_path[i].instance; + } + else if (l_path[i].type == TARGETING::TYPE_MEMBUF) + { + l_pChipType = ECMD_CHIP_MEMBUF; + l_chipPos = l_path[i].instance; + } + } + + // Look for a chiplet in the path + const char * l_pChipletType = NULL; + uint32_t l_chipletPos = 0; + + for (uint32_t i = 0; ((i < l_sizePath) && (l_pChipletType == NULL)); + i++) + { + if (l_path[i].type == TARGETING::TYPE_EX) + { + l_pChipletType = ECMD_CHIPLET_EX; + l_chipletPos = l_path[i].instance; + } + else if (l_path[i].type == TARGETING::TYPE_MCS) + { + l_pChipletType = ECMD_CHIPLET_MCS; + l_chipletPos = l_path[i].instance; + } + else if (l_path[i].type == TARGETING::TYPE_MBS) + { + l_pChipletType = ECMD_CHIPLET_MBS; + l_chipletPos = l_path[i].instance; + } + else if (l_path[i].type == TARGETING::TYPE_MBA) + { + l_pChipletType = ECMD_CHIPLET_MBA; + l_chipletPos = l_path[i].instance; + } + } + + if (l_pChipType == NULL) + { + FAPI_ERR("toString: Physical Path does not contain known chip"); + strcpy(o_ecmdString, "ecmd-no-chip"); + } + else + { + // Construct the ecmd string + char * l_pStr = &o_ecmdString[0]; + + // Chip Type + strcpy(l_pStr, l_pChipType); + l_pStr += strlen(l_pChipType); + + if (l_pChipletType != NULL) + { + // Chiplet Type + *l_pStr = '.'; + l_pStr++; + + strcpy(l_pStr, l_pChipletType); + l_pStr += strlen(l_pChipletType); + } + + // Middle of the string + strcpy(l_pStr, ":k0:n0:s0:p"); + l_pStr += strlen(":k0:n0:s0:p"); + + // Chip Pos (Note that %02d does not appear to work) + if (l_chipPos >= 10) + { + sprintf(l_pStr, "%d", l_chipPos / 10); + } + else + { + *l_pStr = '0'; + } + l_pStr++; + + sprintf(l_pStr, "%d", l_chipPos % 10); + l_pStr++; + + if (l_pChipletType != NULL) + { + // Chiplet Pos + strcpy(l_pStr, ":c"); + l_pStr += strlen(":c"); + sprintf(l_pStr, "%d", l_chipletPos); + } + } + } + else + { + FAPI_ERR("toString: Physical Path Attribute does not exist"); + strcpy(o_ecmdString, "ecmd-no-path"); + } + } } + +} + diff --git a/src/usr/isteps/istep1.C b/src/usr/isteps/istep1.C index 948980fe0..dd97750b5 100644 --- a/src/usr/isteps/istep1.C +++ b/src/usr/isteps/istep1.C @@ -84,8 +84,9 @@ void IStep0sub0( void * io_pArgs ) command, returncode ); // ----- start ISTEP -------------------------------------------------- - // Set processor chip to the master - TARGETING::Target* l_pTarget = MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; + // Get the master processor chip + TARGETING::Target* l_pTarget = NULL; + TARGETING::targetService().masterProcChipTargetHandle(l_pTarget); // Create a FAPI Target and invoke the hwpInitialTest HWP fapi::Target l_fapiTarget(TARGET_TYPE_PROC_CHIP, diff --git a/src/usr/xscom/xscom.C b/src/usr/xscom/xscom.C index c893c5c09..5f90a8beb 100644 --- a/src/usr/xscom/xscom.C +++ b/src/usr/xscom/xscom.C @@ -273,11 +273,32 @@ errlHndl_t getTargetVirtualAddress(const TARGETING::Target* i_target, do { - // Sentinel + // Find out if the target pointer is the master processor chip + bool l_isMasterProcChip = false; + if (i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) { - // If never XSCOM to sentinel before, calculate - // sentinel's virtAddr and store it + // Sentinel pointer representing the master processor chip + l_isMasterProcChip = true; + } + else + { + TARGETING::Target* l_pMasterProcChip = NULL; + TARGETING::targetService(). + masterProcChipTargetHandle(l_pMasterProcChip); + + if (i_target == l_pMasterProcChip) + { + // Target Service reports that this is the master processor chip + l_isMasterProcChip = true; + } + } + + // Figure out the virtual address + if (l_isMasterProcChip) + { + // This is the master processor chip. The virtual address is + // g_masterProcVirtAddr. If this is NULL then initialize it // Use atomic update instructions here to avoid // race condition between different threads. @@ -323,10 +344,10 @@ errlHndl_t getTargetVirtualAddress(const TARGETING::Target* i_target, // Set virtual address to sentinel's value o_virtAddr = g_masterProcVirtAddr; } - - // Non-sentinel else { + // This is not the master processor chip + // @todo: // We (Nick/Patrick/Thi) agree to review the performance cost of // map/unmap calls for each xscom to determine if it's justified @@ -349,45 +370,26 @@ errlHndl_t getTargetVirtualAddress(const TARGETING::Target* i_target, // update it. For Rainer systems the node id of the master chip may // not be 0 if it is on a second node. - // Is this the master proc? - TARGETING::Target* l_masterProcTarget = NULL; + // Get system XSCOM base address + // Note: can't call TARGETING code prior to PNOR being + // brought up. TARGETING::TargetService& l_targetService = - TARGETING::targetService(); - l_targetService.masterProcChipTargetHandle( l_masterProcTarget ); - - // Use sentinel's virtual address for Master processor - if (l_masterProcTarget == i_target) - { - // There's no way g_masterProcVirtAddr is NULL - // at this point. For safety - assert(g_masterProcVirtAddr != NULL); - o_virtAddr = g_masterProcVirtAddr; - } - - // Calculate virtual address for slave processors - else - { - // Get system XSCOM base address - // Note: can't call TARGETING code prior to PNOR being - // brought up. - TARGETING::TargetService& l_targetService = - TARGETING::targetService(); - TARGETING::Target* l_pTopLevel = NULL; - (void) l_targetService.getTopLevelTarget(l_pTopLevel); - assert(l_pTopLevel != NULL); - XSComBase_t l_systemBaseAddr = + TARGETING::targetService(); + TARGETING::Target* l_pTopLevel = NULL; + (void) l_targetService.getTopLevelTarget(l_pTopLevel); + assert(l_pTopLevel != NULL); + XSComBase_t l_systemBaseAddr = l_pTopLevel->getAttr<TARGETING::ATTR_XSCOM_BASE_ADDRESS>(); - // Target's XSCOM Base address - l_XSComBaseAddr = l_systemBaseAddr + - ( ( (g_xscomMaxChipsPerNode * l_xscomChipInfo.nodeId) + - l_xscomChipInfo.chipId ) * THIRTYTWO_GB); + // Target's XSCOM Base address + l_XSComBaseAddr = l_systemBaseAddr + + ( ( (g_xscomMaxChipsPerNode * l_xscomChipInfo.nodeId) + + l_xscomChipInfo.chipId ) * THIRTYTWO_GB); - // Target's virtual address - o_virtAddr = static_cast<uint64_t*> - (mmio_dev_map(reinterpret_cast<void*>(l_XSComBaseAddr), - THIRTYTWO_GB)); - } + // Target's virtual address + o_virtAddr = static_cast<uint64_t*> + (mmio_dev_map(reinterpret_cast<void*>(l_XSComBaseAddr), + THIRTYTWO_GB)); // @todo - Save as an attribute if Virtual address attribute // is implemented, |