summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Jones <mjjones@us.ibm.com>2011-09-06 08:52:17 -0500
committerMIKE J. JONES <mjjones@us.ibm.com>2011-09-07 08:52:29 -0500
commitdd8d92217c8cebd6aa5408ad7fd4fa50ea248c84 (patch)
treee407bbb12cc5e6e12546154e6ac9cbe8a4ccc99c
parent11ea7375f50c8e426e85ebdb4c2d9b67b8ecbb27 (diff)
downloadblackbird-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.H20
-rw-r--r--src/usr/hwpf/hwp/fapiTestHwp.C6
-rw-r--r--src/usr/hwpf/plat/fapiPlatTarget.C162
-rw-r--r--src/usr/isteps/istep1.C5
-rw-r--r--src/usr/xscom/xscom.C82
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,
OpenPOWER on IntegriCloud