summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMissy Connell <missyc@us.ibm.com>2012-01-30 10:14:46 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-02-07 16:46:25 -0600
commit914b46ba52822c63799ebf60ebcc4df200d3371b (patch)
tree023e96a996671a2907c7fc962088fcd14884475c
parente457b5df08897236374bd8851d8169188e9dc1f8 (diff)
downloadtalos-hostboot-914b46ba52822c63799ebf60ebcc4df200d3371b.tar.gz
talos-hostboot-914b46ba52822c63799ebf60ebcc4df200d3371b.zip
Scom Translate for EX, MCS, MBA/MBS
Change-Id: Iff47274d72c3994923234c998894671db6e833ba Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/632 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/build/citest/etc/bbuild2
-rw-r--r--src/include/usr/scom/scomreasoncodes.H48
-rw-r--r--src/usr/scom/makefile2
-rw-r--r--src/usr/scom/scom.C44
-rw-r--r--src/usr/scom/scom.H36
-rw-r--r--src/usr/scom/scomtrans.C496
-rw-r--r--src/usr/scom/scomtrans.H120
-rw-r--r--src/usr/scom/test/scomtest.H550
8 files changed, 1281 insertions, 17 deletions
diff --git a/src/build/citest/etc/bbuild b/src/build/citest/etc/bbuild
index cb4953f9f..06eeabac1 100644
--- a/src/build/citest/etc/bbuild
+++ b/src/build/citest/etc/bbuild
@@ -1 +1 @@
-/esw/fips760/Builds/b1129a_1149.760
+/esw/fips760/Builds/b0131a_1205.760
diff --git a/src/include/usr/scom/scomreasoncodes.H b/src/include/usr/scom/scomreasoncodes.H
new file mode 100644
index 000000000..d2ffa7e79
--- /dev/null
+++ b/src/include/usr/scom/scomreasoncodes.H
@@ -0,0 +1,48 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/include/usr/xscom/scomreasoncodes.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+#ifndef __SCOM_REASONCODES_H
+#define __SCOM_REASONCODES_H
+
+#include <hbotcompid.H>
+
+namespace SCOM
+{
+ enum scomModuleId
+ {
+ SCOM_PERFORM_OP = 0x00,
+ SCOM_TRANSLATE = 0x01,
+ SCOM_PERFORM_TRANSLATE = 0x02,
+ SCOM_FIND_PARENT_TARGET = 0x03,
+
+ };
+
+ enum scomReasonCode
+ {
+ SCOM_INVALID_ADDR = SCOM_COMP_ID | 0x01,
+ SCOM_NO_MATCHING_PARENT = SCOM_COMP_ID | 0x02,
+ SCOM_TRANS_INVALID_TYPE = SCOM_COMP_ID | 0x03,
+ SCOM_TRANS_UNSUPPORTED = SCOM_COMP_ID | 0x04,
+ };
+};
+
+#endif
diff --git a/src/usr/scom/makefile b/src/usr/scom/makefile
index a7b4a6403..451ed17de 100644
--- a/src/usr/scom/makefile
+++ b/src/usr/scom/makefile
@@ -23,7 +23,7 @@
ROOTPATH = ../../..
MODULE = scom
-OBJS = scom.o
+OBJS = scom.o scomtrans.o
SUBDIRS = test.d
diff --git a/src/usr/scom/scom.C b/src/usr/scom/scom.C
index 8bfdbf004..07a5754db 100644
--- a/src/usr/scom/scom.C
+++ b/src/usr/scom/scom.C
@@ -35,6 +35,7 @@
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include "scom.H"
+#include <scom/scomreasoncodes.H>
// Trace definition
trace_desc_t* g_trac_scom = NULL;
@@ -56,7 +57,6 @@ DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
scomPerformOp);
-
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
errlHndl_t scomPerformOp(DeviceFW::OperationType i_opType,
@@ -67,19 +67,45 @@ errlHndl_t scomPerformOp(DeviceFW::OperationType i_opType,
va_list i_args)
{
errlHndl_t l_err = NULL;
- mutex_t* l_mutex = NULL;
+
uint64_t l_scomAddr = va_arg(i_args,uint64_t);
+
+
+ l_err = checkIndirectAndDoScom(i_opType,
+ i_target,
+ io_buffer,
+ io_buflen,
+ i_accessType,
+ l_scomAddr);
+
+ return l_err;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+errlHndl_t checkIndirectAndDoScom(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ uint64_t i_addr)
+{
+
+ errlHndl_t l_err = NULL;
+ mutex_t* l_mutex = NULL;
+
// If the indirect scom bit is 0, then doing a regular scom
- if( (l_scomAddr & 0x8000000000000000) == 0)
+ if( (i_addr & 0x8000000000000000) == 0)
{
l_err = doScomOp(i_opType,
i_target,
io_buffer,
io_buflen,
i_accessType,
- l_scomAddr);
+ i_addr);
}
// We are performing an indirect scom.
else
@@ -88,7 +114,7 @@ errlHndl_t scomPerformOp(DeviceFW::OperationType i_opType,
uint64_t temp_scomAddr;
memcpy(&l_io_buffer, io_buffer, 8);
- memcpy(&temp_scomAddr, &l_scomAddr, 8);
+ memcpy(&temp_scomAddr, &i_addr, 8);
// Get the 20bit indirect scom address
temp_scomAddr = temp_scomAddr & 0x001FFFFF00000000;
@@ -100,7 +126,7 @@ errlHndl_t scomPerformOp(DeviceFW::OperationType i_opType,
l_io_buffer = l_io_buffer | temp_scomAddr;
// zero out the indirect address from the buffer..
- l_scomAddr = l_scomAddr & 0x00000000EFFFFFFFF;
+ i_addr = i_addr & 0x00000000EFFFFFFFF;
// If we are doing a read. We need to do a write first..
if(i_opType == DeviceFW::READ)
@@ -121,7 +147,7 @@ errlHndl_t scomPerformOp(DeviceFW::OperationType i_opType,
& l_io_buffer,
io_buflen,
i_accessType,
- l_scomAddr);
+ i_addr);
if (l_err != NULL)
{
@@ -136,7 +162,7 @@ errlHndl_t scomPerformOp(DeviceFW::OperationType i_opType,
io_buffer,
io_buflen,
i_accessType,
- l_scomAddr);
+ i_addr);
mutex_unlock(l_mutex);
@@ -154,7 +180,7 @@ errlHndl_t scomPerformOp(DeviceFW::OperationType i_opType,
& l_io_buffer,
io_buflen,
i_accessType,
- l_scomAddr);
+ i_addr);
}
}
diff --git a/src/usr/scom/scom.H b/src/usr/scom/scom.H
index f39720aae..d4b76a165 100644
--- a/src/usr/scom/scom.H
+++ b/src/usr/scom/scom.H
@@ -35,8 +35,9 @@ namespace SCOM
/**
* @brief Performs a SCom operation
- * This function performs a SCOM operation by calling doScomOP. It
- * handles whether the address a regular or an indirect SCOM address
+ * This function performs a SCOM operation by calling
+ * checkIndirectScomOP. It handles whether the address
+ * a regular or an indirect SCOM address
*
* @param[in] i_opType Operation type, see DeviceFW::OperationType
* in driverif.H
@@ -78,9 +79,7 @@ errlHndl_t scomPerformOp(DeviceFW::OperationType i_opType,
* Write: size of data written
* @param[in] i_accessType Select from DeviceFW::AccessType enum
* (usrif.H)
- * @param[in] i_args This is an argument list for DD framework.
- * In this function, there's only one argument,
- * which is the SCom address value.
+ * @param[in] i_addr scom Address Value
*
* @return errlHndl_t
*/
@@ -92,6 +91,33 @@ errlHndl_t doScomOp(DeviceFW::OperationType i_opType,
uint64_t i_addr);
+/**
+ * @brief Performs a SCom operation
+ * This function performs a SCOM operation by calling doScomOP after
+ * It handles whether the address is a regular or an indirect SCOM
+ * address
+ *
+ * @param[in] i_opType Operation type
+ * @param[in] i_target SCom target
+ * @param[in/out] io_buffer Read: pointer to output data storage
+ * Write: pointer to data to be written
+ * @param[in/out] io_buflen Input: size of io_buffer (in bytes)
+ * Output: Read: size of output data
+ * Write: size of data written
+ * @param[in] i_accessType Select from DeviceFW::AccessType enum
+ * (usrif.H)
+ * @param[in] i_addr Scom Address Value.
+ *
+ * @return errlHndl_t
+ */
+errlHndl_t checkIndirectAndDoScom(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ uint64_t i_addr);
+
+
}; // End namespace
#endif
diff --git a/src/usr/scom/scomtrans.C b/src/usr/scom/scomtrans.C
new file mode 100644
index 000000000..eaf42b98b
--- /dev/null
+++ b/src/usr/scom/scomtrans.C
@@ -0,0 +1,496 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/scom/scomtrans.C $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+/**
+ * @file scomtrans.C
+ *
+ * @brief Implementation of SCOM operations
+ */
+
+/*****************************************************************************/
+// I n c l u d e s
+/*****************************************************************************/
+#include <assert.h>
+#include <devicefw/driverif.H>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include "scom.H"
+#include "scomtrans.H"
+#include <scom/scomreasoncodes.H>
+
+// Trace definition
+extern trace_desc_t* g_trac_scom;
+
+namespace SCOM
+{
+
+
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::SCOM,
+ TARGETING::TYPE_EX,
+ scomTranslate);
+
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::SCOM,
+ TARGETING::TYPE_MBS,
+ scomTranslate);
+
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::SCOM,
+ TARGETING::TYPE_MBA,
+ scomTranslate);
+
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::SCOM,
+ TARGETING::TYPE_MCS,
+ scomTranslate);
+
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::SCOM,
+ TARGETING::TYPE_XBUS,
+ scomTranslate);
+
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::SCOM,
+ TARGETING::TYPE_ABUS,
+ scomTranslate);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+errlHndl_t scomTranslate(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args)
+
+{
+ errlHndl_t l_err = NULL;
+
+ bool l_invalidAddr = false;
+
+ uint64_t i_addr = va_arg(i_args,uint64_t);
+
+ // Get the attribute type.
+ TARGETING::TYPE l_type = i_target->getAttr<TARGETING::ATTR_TYPE>();
+
+ // get the specific entry to determine the address.
+ TARGETING::EntityPath epath;
+
+ if (i_target->tryGetAttr<TARGETING::ATTR_PHYS_PATH>(epath))
+ {
+ if (l_type == TARGETING::TYPE_EX)
+ {
+
+ // Below are the assumptions used for the EX translate
+ /*EX
+ Mask : 0x1F00_0000
+ Range 1 : 0x1000_0000 - 0x10FF_FFFF
+ ...
+ ...
+ bits 3:7 correspond to what EX chiplet is targeted.
+ where 0x10XXXXXX is for EX0
+ ...
+ where 0x13XXXXXX is for EX3
+ where 0x14XXXXXX is for EX4
+ ...
+ where 0x1CXXXXXX is for EX12
+
+
+ original mask = 0x000000001F000000
+ change that to be 0x7F000000 to catch other chiplets.*/
+
+ // check to see that the Address is in the correct range
+ if ((i_addr & SCOM_TRANS_EX_MASK) == SCOM_TRANS_EX_BASEADDR)
+ {
+ // Call the function that performs the translate
+ l_err = scomPerformTranslate(epath,
+ TARGETING::TYPE_EX,
+ TARGETING::TYPE_PROC,
+ 24,
+ SCOM_TRANS_EX_MASK,
+ i_target,
+ i_addr );
+ }
+ else
+ {
+ // set invalid addr to true.. and create errorlog below.
+ l_invalidAddr = true;
+ }
+ }
+ else if (l_type == TARGETING::TYPE_MCS)
+ {
+ /* ring 6 = MCL
+ MC0 MCS0 = 0x02011800 MCS-0 range 0
+ MC0 MCS1 = 0x02011880 MCS-1 range 0 + remainder
+ MC1 MCS0 = 0x02011900 MCS-2 range 1
+ MC1 MCS0 = 0x02011980 MCS-3 range 1 + remainder
+ IOMC0 = 0x02011A00 -NOT targeting this range..
+ ring 7 = MCR
+ MC2 MCS0 = 0x02011C00 MCS-4 range 2
+ MC2 MCS1 = 0x02011C80 MCS-5 range 2 + remainder
+ MC3 MCS0 = 0x02011D00 MCS-6 range 3
+ MC3 MCS1 = 0x02011D80 MCS-7 range 3 + remainder
+
+ original mask = 0x0000000002011D80
+ Need the mask to be 0x7FFFFF80*/
+
+
+ uint64_t l_instance;
+
+ // Check that we are working with the correct address range
+ if ((i_addr & SCOM_TRANS_MCS_MASK) == SCOM_TRANS_MCS_BASEADDR )
+ {
+
+ // Need to extract what instance of the entity we are at
+ l_instance =
+ epath.pathElementOfType(TARGETING::TYPE_MCS).instance;
+
+ // based on the instance, update the address
+
+ // range 1 - add 0x100 to the addr
+ if( (l_instance / 2) == 1)
+ {
+ i_addr += 0x100;
+ }
+ // range 2 - add 0x400 to the addr
+ else if( (l_instance / 2) == 2)
+ {
+ i_addr += 0x400;
+ }
+ // range 3 - add 0x500 to the addr
+ else if( (l_instance / 2) == 3)
+ {
+ i_addr += 0x500;
+ }
+
+ // add 0x80 if the instance%2 is nonzero.
+ if (l_instance % 2)
+ {
+ i_addr += 0x80;
+ }
+
+ // Call to set the target to the parent target type
+ l_err = scomfindParentTarget(epath,
+ TARGETING::TYPE_PROC,
+ i_target);
+ }
+ else
+ {
+ l_invalidAddr = true;
+ }
+ }
+ else if (l_type == TARGETING::TYPE_XBUS)
+ {
+ //*** temporarily put an error log indicating not supported until we
+ // have info from the hardware team
+
+ TRACFCOMP(g_trac_scom, "SCOM_TRANSLATE-unsupported target type=0x%X", l_type);
+
+ /*@
+ * @errortype
+ * @moduleid SCOM::SCOM_TRANSLATE
+ * @reasoncode SCOM::SCOM_TRANS_UNSUPPORTED
+ * @userdata1 Address
+ * @userdata2 Target Type that failed
+ * @devdesc Scom Translate not supported for this type
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SCOM_TRANSLATE,
+ SCOM_TRANS_UNSUPPORTED,
+ i_addr,
+ l_type);
+
+ }
+ else if (l_type == TARGETING::TYPE_ABUS)
+ {
+ //*** temporarily put an error log indicating not supported until we have info
+ // from the hardware team
+ TRACFCOMP(g_trac_scom, "SCOM_TRANSLATE-unsupported target type=0x%X", l_type);
+
+ /*@
+ * @errortype
+ * @moduleid SCOM::SCOM_TRANSLATE
+ * @reasoncode SCOM::SCOM_TRANS_UNSUPPORTED
+ * @userdata1 Address
+ * @userdata2 Target Type that failed
+ * @devdesc Scom Translate not supported for this type
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SCOM_TRANSLATE,
+ SCOM_TRANS_UNSUPPORTED,
+ i_addr,
+ l_type);
+
+
+ }
+ else if (l_type == TARGETING::TYPE_MBS)
+ {
+ /*
+ MBS
+ Mask : NA
+ Range 1 : 0x02010000 - 0x0201FFFF
+
+ default>physical:sys-0/node-0/membuf-10/mbs-0</default>
+
+ */
+ // NO address shifting required.. no mask..
+ // just get parent.
+ l_err = scomfindParentTarget(epath,
+ TARGETING::TYPE_MEMBUF,
+ i_target);
+
+ }
+ else if (l_type == TARGETING::TYPE_MBA)
+ {
+ /*
+ MBA
+ Mask : 0x03010800
+ Range 1 : 0x03010400 - 0301043F # MBA01
+ Range 2 : 0x03010600 - 030106FF # MBA01 MCBIST
+ Range 4 : 0x03010C00 - 03010C3F # MBA23
+ Range 5 : 0x03010E00 - 03010EFF # MBA23 MCBIST
+
+ Original mask from hdw team is: 03010800
+ The mask needs to be 0x7FFFF800 in order make sure we
+ don't have any other valid address bits on for another
+ chiplet.
+
+ bits 20 correspond to what MBA chiplet is targeted.
+ where 0x03010000 is for MBA01
+ where 0x03010800 is for MBA23
+
+ In the XML.. the
+ <default>physical:sys-0/node-0/membuf-10/mbs-0/mba-1</default>
+
+ Assuming the MBA we are accessing is under the Centaur
+ not the processor.. for now.
+ */
+ // check to see that the Address is in the correct range
+ if ((i_addr & SCOM_TRANS_MBA_MASK) == SCOM_TRANS_MBA_BASEADDR)
+ {
+
+ l_err = scomPerformTranslate(epath,
+ TARGETING::TYPE_MBA,
+ TARGETING::TYPE_MEMBUF,
+ 11,
+ SCOM_TRANS_MBA_MASK,
+ i_target,
+ i_addr );
+ }
+ else
+ {
+ // got and error.. bad address.. write an errorlog..
+ l_invalidAddr = true;
+ }
+ }
+ else
+ {
+ //*** temporarily put an error log indicating not supported until we have info
+ // from the hardware team
+ TRACFCOMP(g_trac_scom, "SCOM_TRANSLATE.. Invalid target type=0x%X", l_type);
+
+ /*@
+ * @errortype
+ * @moduleid SCOM::SCOM_TRANSLATE
+ * @reasoncode SCOM::SCOM_TRANS_INVALID_TYPE
+ * @userdata1 Address
+ * @userdata2 Target Type that failed
+ * @devdesc Scom Translate not supported for this type
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SCOM_TRANSLATE,
+ SCOM_TRANS_INVALID_TYPE,
+ i_addr,
+ l_type);
+
+
+ }
+ }
+
+ if (l_invalidAddr)
+ {
+
+ TRACFCOMP(g_trac_scom, "scomTranslate-Invalid Address i_addr=0x%X", i_addr);
+
+ /*@
+ * @errortype
+ * @moduleid SCOM::SCOM_TRANSLATE
+ * @reasoncode SCOM::SCOM_INVALID_ADDR
+ * @userdata1 Address
+ * @userdata2 Unit type that failed
+ * @devdesc Invalid address for that unit
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SCOM_TRANSLATE,
+ SCOM_INVALID_ADDR,
+ i_addr,
+ l_type);
+ l_err->collectTrace("SCOM",1024);
+
+ }
+
+ if (l_err == NULL)
+ {
+
+ // call the routine that will do the indirect scom
+ // and then call the correct device driver.
+ l_err = SCOM::checkIndirectAndDoScom(i_opType,
+ i_target,
+ io_buffer,
+ io_buflen,
+ i_accessType,
+ i_addr);
+ }
+ return l_err;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+errlHndl_t scomPerformTranslate(TARGETING::EntityPath i_epath,
+ TARGETING::TYPE i_ctype,
+ TARGETING::TYPE i_ptype,
+ int i_shift,
+ int i_mask,
+ TARGETING::Target * &o_target,
+ uint64_t &i_addr )
+{
+
+ errlHndl_t l_err = NULL;
+
+ uint64_t l_instance;
+
+ // Need to extract what instance of the entity we are at we are
+ // for this target.
+ l_instance = i_epath.pathElementOfType(i_ctype).instance;
+
+ // shift the instance variable over specificed number of
+ // bits with the chiplet area
+ l_instance = l_instance << i_shift;
+
+ // Check the address against the mask
+ if (i_addr & i_mask)
+ {
+ // add the instance of this target to the address
+ i_addr = i_addr | l_instance;
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @moduleid SCOM::SCOM_PERFORM_TRANSLATE
+ * @reasoncode SCOM::SCOM_INVALID_ADDR
+ * @userdata1 Address
+ * @userdata2 Unit type that failed
+ * @devdesc Invalid Address for the mask passed in.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SCOM_PERFORM_TRANSLATE,
+ SCOM_INVALID_ADDR,
+ i_addr,
+ o_target->getAttr<TARGETING::ATTR_TYPE>());
+
+ l_err->collectTrace("SCOM",1024);
+
+ TRACFCOMP(g_trac_scom,"SCOMPERFORMTRANSLATE Invalid Address.i_addr =0x%X for mask = 0x%X", i_addr, i_mask);
+
+ return (l_err);
+ }
+
+
+ l_err = scomfindParentTarget(i_epath,
+ i_ptype,
+ o_target);
+
+ return l_err;
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+errlHndl_t scomfindParentTarget( TARGETING::EntityPath i_epath,
+ TARGETING::TYPE i_ptype,
+ TARGETING::Target * &o_target)
+{
+
+ errlHndl_t l_err = NULL;
+
+ bool foundParent = false;
+
+ // This routine passes in a given target.. the goal is to find its parent
+ // target that matches the passed in parent type.
+
+ // This loop takes the last item off the entity path and
+ // checks to see if it matches the parent type.. If it does
+ // we exit.. it continues to loop until it either finds
+ // a match, or runs out of elements.
+ do
+ {
+ // remove the last entry from the entity path..
+ i_epath.removeLast();
+
+ int lastEntry = i_epath.size() - 1;
+
+ // if the type equals the type passed in. then create the target
+ if (i_epath[lastEntry].type == i_ptype)
+ {
+ // return the target to be the parent type.
+ o_target = TARGETING::targetService().toTarget(i_epath);
+
+ foundParent = true;
+
+ break;
+ }
+ }
+ while (i_epath.size() != 0);
+
+ if (!foundParent)
+ {
+ // got and error.. bad address.. write an errorlog..
+ /*@
+ * @errortype
+ * @moduleid SCOM::SCOM_PERFORM_TRANSLATE
+ * @reasoncode SCOM::SCOM_NO_MATCHING_PARENT
+ * @userdata1 Parent type requested
+ * @userdata2 Unit type that failed
+ * @devdesc Did not find parent type requested
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SCOM_FIND_PARENT_TARGET,
+ SCOM_NO_MATCHING_PARENT,
+ i_ptype,
+ o_target->getAttr<TARGETING::ATTR_TYPE>());
+
+ l_err->collectTrace("SCOM",1024);
+
+ // Need to write and errorlog and return..
+ TRACFCOMP(g_trac_scom, "TRANSLATE..Did not find parent type=0x%X ", i_ptype);
+ }
+
+ return l_err;
+}
+
+
+} // end namespace
diff --git a/src/usr/scom/scomtrans.H b/src/usr/scom/scomtrans.H
new file mode 100644
index 000000000..e65cc3511
--- /dev/null
+++ b/src/usr/scom/scomtrans.H
@@ -0,0 +1,120 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/scom/scomtrans.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+#ifndef __SCOMTRANS_H
+#define __SCOMTRANS_H
+
+#include <devicefw/driverif.H>
+
+/** @file scomtrans.H
+ * @brief Provides the interfaces to perform a SCom
+ */
+
+namespace SCOM
+{
+
+
+ enum ScomTransMask
+ {
+ SCOM_TRANS_EX_MASK = 0x000000007F000000,
+ SCOM_TRANS_MCS_MASK = 0x000000007FFFFF80,
+ SCOM_TRANS_MBA_MASK = 0x000000007FFFF800,
+ };
+
+ enum ScomTransBaseAddr
+ {
+ SCOM_TRANS_EX_BASEADDR = 0x0000000010000000,
+ SCOM_TRANS_MCS_BASEADDR = 0x0000000002011800,
+ SCOM_TRANS_MBA_BASEADDR = 0x0000000003010000,
+ };
+
+
+
+/**
+ * @brief Performs a SCom Translation of the scom address
+ * This function performs the translation and get the
+ * correct target and continues the scom Operation.
+ *
+ * @param[in] i_opType Operation type, see DeviceFW::OperationType
+ * in driverif.H
+ * @param[in] i_target SCom target
+ * @param[in/out] io_buffer Read: pointer to output data storage
+ * Write: pointer to data to be written
+ * @param[in/out] io_buflen Input: size of io_buffer (in bytes)
+ * Output: Read: size of output data
+ * Write: size of data written
+ * @param[in] i_accessType Select from DeviceFW::AccessType enum
+ * (usrif.H)
+ * @param[in] i_args This is an argument list for DD framework.
+ * In this function, there's only one argument,
+ * which is the SCom address value.
+ */
+errlHndl_t scomTranslate(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args);
+
+
+/**
+ * @brief Utility function does the address translation for
+ * unit types that have similar unit identifying strategy
+ *
+ * @param[in] i_epath entity path is passed in
+ * @param[in] i_ctype Current targets target type
+ * @param[in] i_ptype Target type of the parent
+ * @param[in] i_shift Number of bits the instance needs to shift
+ * @param[in] i_mask Mask value
+ * @param[in|out] o_target SCom target is passed in and after
+ * translation return a scomable target
+ * @param[in|out} i_addr Address passed in and return as a
+ * translated address
+ * @return errlHndl_t
+ */
+errlHndl_t scomPerformTranslate(TARGETING::EntityPath i_epath,
+ TARGETING::TYPE i_ctype,
+ TARGETING::TYPE i_ptype,
+ int i_shift,
+ int i_mask,
+ TARGETING::Target * &o_target,
+ uint64_t &i_addr );
+
+/**
+ * @brief This function finds the parent target type and returns
+ * that as the new target
+ *
+ * @param[in] i_epath SCom target is passed in and return
+ * the parent type requested
+ * @param[in] i_ptype Target type needed for the parent requested
+ * @param[in|out] o_target SCom target is passed in and after
+ * translation return a parent target
+ * @return errlHndl_t
+ */
+errlHndl_t scomfindParentTarget( TARGETING::EntityPath i_epath,
+ TARGETING::TYPE i_ptype,
+ TARGETING::Target * &o_target);
+
+
+}; // End namespace
+
+#endif
diff --git a/src/usr/scom/test/scomtest.H b/src/usr/scom/test/scomtest.H
index 183ac0ebc..543c589cc 100644
--- a/src/usr/scom/test/scomtest.H
+++ b/src/usr/scom/test/scomtest.H
@@ -260,7 +260,6 @@ public:
uint64_t addr;
uint64_t data;
} test_data[] = {
- { scom_targets[CENTAUR0], 0x00012345 , 0x1111222233334444 },
//@fixme - address should be 0x02011403 but simics is adding parity...
{ scom_targets[CENTAUR0], 0x02011402 , 0x123456789ABCDEF0 },
{ scom_targets[CENTAUR0], 0x02011672 , 0x1122334455667788 },
@@ -348,6 +347,20 @@ public:
uint64_t total = 0;
errlHndl_t l_err = NULL;
+ //@VBU workaround - Disable Indirect SCOM test case o
+ //Test case read/writes to valid addresses and is
+ //potentially destructive on VBU
+ TARGETING::EntityPath syspath(TARGETING::EntityPath::PATH_PHYSICAL);
+ syspath.addLast(TARGETING::TYPE_SYS,0);
+ TARGETING::Target* sys = TARGETING::targetService().toTarget(syspath);
+ uint8_t vpo_mode = 0;
+ if( sys
+ && sys->tryGetAttr<TARGETING::ATTR_IS_SIMULATION>(vpo_mode)
+ && (vpo_mode == 1) )
+ {
+ return;
+ }
+
// Setup some targets to use
enum {
@@ -473,6 +486,541 @@ public:
}
+
+
+
+
+ void test_TranslateScom_EX(void)
+ {
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test_TranslateScom> Start" );
+
+ uint64_t fails = 0;
+ uint64_t total = 0;
+ errlHndl_t l_err = NULL;
+
+
+ //@VBU workaround - Disable Indirect SCOM test case o
+ //Test case read/writes to valid addresses and is
+ //potentially destructive on VBU
+ TARGETING::EntityPath syspath(TARGETING::EntityPath::PATH_PHYSICAL);
+ syspath.addLast(TARGETING::TYPE_SYS,0);
+ TARGETING::Target* sys = TARGETING::targetService().toTarget(syspath);
+ uint8_t vpo_mode = 0;
+ if( sys
+ && sys->tryGetAttr<TARGETING::ATTR_IS_SIMULATION>(vpo_mode)
+ && (vpo_mode == 1) )
+ {
+ return;
+ }
+
+ // Setup some targets to use
+ enum {
+ myProc0,
+ myEX1,
+ myEX5,
+ NUM_TARGETS
+ };
+
+ TARGETING::Target* scom_targets[NUM_TARGETS];
+ for( uint64_t x = 0; x < NUM_TARGETS; x++ )
+ {
+ scom_targets[x] = NULL;
+ }
+
+ // Target Proc 0 - to make sure we have XSCOM and FSISCOM attributes
+ TARGETING::EntityPath epath(TARGETING::EntityPath::PATH_PHYSICAL);
+ epath.addLast(TARGETING::TYPE_SYS,0);
+ epath.addLast(TARGETING::TYPE_NODE,0);
+ epath.addLast(TARGETING::TYPE_PROC,0);
+
+ scom_targets[myProc0] = TARGETING::targetService().toTarget(epath);
+
+ // Only check the Proc or Membuf targets to look at the SCOM attributes
+ if ((scom_targets[myProc0] != NULL) &&
+ (scom_targets[myProc0]->getAttr<TARGETING::ATTR_SCOM_SWITCHES>().useXscom == 0) &&
+ (scom_targets[myProc0]->getAttr<TARGETING::ATTR_SCOM_SWITCHES>().useFsiScom == 0))
+ {
+ // If both FSI and XSCOM are not enabled.. then ignore..
+ TRACFCOMP(g_trac_scom, "TRANSLATE SCOM>> SKIPPING ");
+ scom_targets[myProc0] = NULL; //remove from our list
+ }
+
+
+ if (scom_targets[myProc0] != NULL)
+ {
+ // Add the Ex1 to the path and create new target
+ epath.addLast(TARGETING::TYPE_EX,1);
+ scom_targets[myEX1] = TARGETING::targetService().toTarget(epath);
+
+ // remote EX1 target (off of sys-0/node-0/proc-0/EX1)
+ epath.removeLast();
+
+ // add EX5 target.
+ epath.addLast(TARGETING::TYPE_EX,5);
+ scom_targets[myEX5] = TARGETING::targetService().toTarget(epath);
+ }
+ // scratch data to use
+ //@fixme: Need to either fabricate some fake registers to use or save off data before modifying SCOMs to avoid
+ // corrupting the HW.
+
+ struct {
+ TARGETING::Target* target;
+ uint64_t addr;
+ uint64_t data;
+ } test_data[] = {
+ { scom_targets[myEX1], 0x100F0120 ,0x7676767676767676},
+ { scom_targets[myEX5], 0x100F0166, 0x9191919191919191},
+ { scom_targets[myEX5], 0x130F0166, 0xabcdabcdabcdabcd}, // invalid unit 0 address
+ { scom_targets[myEX1], 0x000F0166, 0xabcdabcdabcdabcd}, // invalid address range for target
+ };
+ const uint64_t NUM_ADDRS = sizeof(test_data)/sizeof(test_data[0]);
+
+ size_t op_size = sizeof(uint32_t);
+
+ // write all the test registers
+ for( uint64_t x = 0; x < NUM_ADDRS; x++ )
+ {
+ //only run if the target exists
+ if(test_data[x].target == NULL)
+ {
+ continue;
+ }
+
+ op_size = sizeof(uint64_t);
+
+ total++;
+ l_err = deviceWrite( test_data[x].target,
+ &(test_data[x].data),
+ op_size,
+ DEVICE_SCOM_ADDRESS(test_data[x].addr) );
+ if( l_err )
+ {
+ // last 2 writes have expected failure conditions.
+ if ((x == NUM_ADDRS-1) || (x == NUM_ADDRS-2))
+ {
+ TRACDCOMP( g_trac_scom, "ScomTest::test_translate_EX.. Expected Error log returned> " );
+ }
+ else
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_translate_scom_EX> [%d] Write: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_translate_EX> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ }
+
+ delete l_err;
+ }
+ }
+
+ // allocate space for read data
+ uint64_t read_data[NUM_ADDRS];
+
+ memset(read_data, 0, sizeof (read_data));
+
+
+ // read all the test registers
+ for( uint64_t x = 0; x < NUM_ADDRS-2; x++ )
+ {
+ //only run if the target exists
+ if(test_data[x].target == NULL)
+ {
+ continue;
+ }
+
+ op_size = sizeof(uint64_t);
+
+ total++;
+ l_err = deviceRead( test_data[x].target,
+ &(read_data[x]),
+ op_size,
+ DEVICE_SCOM_ADDRESS(test_data[x].addr) );
+
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_translate_scom_EX> [%d] Read: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_translate_scom_EX> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ delete l_err;
+ }
+ else if((read_data[x]) != (test_data[x].data))
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_translate_scom_EX> [%d] Read: Data miss-match : addr=0x%X, read_data=0x%llx, write_data=0x%llx", x, test_data[x].addr, read_data[x], test_data[x].data);
+ TS_FAIL( "ScomTest::test_translate_scom_EX> ERROR : Data miss-match between read and expected data" );
+ fails++;
+ }
+
+ }
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test_translateScom_EX> %d/%d fails", fails, total );
+
+ }
+
+
+ void test_TranslateScom_MCS(void)
+ {
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test_TranslateScom_MCS Start" );
+ errlHndl_t l_err = NULL;
+
+ uint64_t fails = 0;
+ uint64_t total = 0;
+
+
+
+ //@VBU workaround - Disable Indirect SCOM test case o
+ //Test case read/writes to valid addresses and is
+ //potentially destructive on VBU
+ TARGETING::EntityPath syspath(TARGETING::EntityPath::PATH_PHYSICAL);
+ syspath.addLast(TARGETING::TYPE_SYS,0);
+ TARGETING::Target* sys = TARGETING::targetService().toTarget(syspath);
+ uint8_t vpo_mode = 0;
+ if( sys
+ && sys->tryGetAttr<TARGETING::ATTR_IS_SIMULATION>(vpo_mode)
+ && (vpo_mode == 1) )
+ {
+ return;
+ }
+
+ // Setup some targets to use
+ enum {
+ myProc0,
+ myMCS1,
+ myMCS2,
+ myMCS7,
+ myMCS4,
+ NUM_TARGETS
+ };
+
+ TARGETING::Target* scom_targets[NUM_TARGETS];
+ for( uint64_t x = 0; x < NUM_TARGETS; x++ )
+ {
+ scom_targets[x] = NULL;
+ }
+
+ // Target Proc 0 - to make sure we have XSCOM and FSISCOM attributes
+ TARGETING::EntityPath epath(TARGETING::EntityPath::PATH_PHYSICAL);
+ epath.addLast(TARGETING::TYPE_SYS,0);
+ epath.addLast(TARGETING::TYPE_NODE,0);
+ epath.addLast(TARGETING::TYPE_PROC,0);
+
+ scom_targets[myProc0] = TARGETING::targetService().toTarget(epath);
+
+ // Only check the Proc or Membuf targets to look at the SCOM attributes
+ if ((scom_targets[myProc0] != NULL) &&
+ (scom_targets[myProc0]->getAttr<TARGETING::ATTR_SCOM_SWITCHES>().useXscom == 0) &&
+ (scom_targets[myProc0]->getAttr<TARGETING::ATTR_SCOM_SWITCHES>().useFsiScom == 0))
+ {
+ // If both FSI and XSCOM are not enabled.. then ignore..
+ TRACFCOMP(g_trac_scom, "TRANSLATE_SCOM_MCS>> SKIPPING ");
+ scom_targets[myProc0] = NULL; //remove from our list
+ }
+
+
+ if (scom_targets[myProc0] != NULL)
+ {
+ // Add the MCS(1) to the path and create new target
+ epath.addLast(TARGETING::TYPE_MCS,1);
+ scom_targets[myMCS1] = TARGETING::targetService().toTarget(epath);
+
+ // remote MCS(1) (off of sys-0/node-0/proc-0/MCS1)
+ epath.removeLast();
+
+ // add MCS4 target.
+ epath.addLast(TARGETING::TYPE_MCS,4);
+ scom_targets[myMCS4] = TARGETING::targetService().toTarget(epath);
+
+ // remote MCS4 target (off of sys-0/node-0/proc-0/MCS4)
+ epath.removeLast();
+
+ // add MCS2 target.
+ epath.addLast(TARGETING::TYPE_MCS,2);
+ scom_targets[myMCS2] = TARGETING::targetService().toTarget(epath);
+
+ // remove MCS2 target (off of sys-0/node-0/proc-0/MCS4)
+ epath.removeLast();
+
+ // add MCS7 target.
+ epath.addLast(TARGETING::TYPE_MCS,7);
+ scom_targets[myMCS7] = TARGETING::targetService().toTarget(epath);
+ }
+
+ // scratch data to use
+ //@fixme: Need to either fabricate some fake registers to use or save off data before modifying SCOMs to avoid
+ // corrupting the HW.
+ struct {
+ TARGETING::Target* target;
+ uint64_t addr;
+ uint64_t data;
+ } test_data[] = {
+ { scom_targets[myMCS1], 0x0201184A ,0x1111111122222222},
+ { scom_targets[myMCS4], 0x0201184A, 0x3333333344444444},
+ { scom_targets[myMCS2], 0x0201184A, 0x5555555566666666},
+ { scom_targets[myMCS7], 0x0201184A, 0x7777777788888888},
+// { scom_targets[myMCS4], 0x02011C4A, 0x0101010101010101}, // invalid
+ // Unit for
+ // the
+ // target
+ { scom_targets[myMCS4], 0x0601184A, 0x0101010101010101}, // invalid address range
+ { scom_targets[myMCS4], 0x0200184A, 0x2323232323232323}, // Invalid address range for target
+ };
+ const uint64_t NUM_ADDRS = sizeof(test_data)/sizeof(test_data[0]);
+
+ size_t op_size = sizeof(uint32_t);
+
+ // write all the test registers
+ for( uint64_t x = 0; x < NUM_ADDRS; x++ )
+ {
+ //only run if the target exists
+ if(test_data[x].target == NULL)
+ {
+ continue;
+ }
+
+ op_size = sizeof(uint64_t);
+
+ total++;
+ l_err = deviceWrite( test_data[x].target,
+ &(test_data[x].data),
+ op_size,
+ DEVICE_SCOM_ADDRESS(test_data[x].addr) );
+ if( l_err )
+ {
+ if ((x == NUM_ADDRS-1) || (x==NUM_ADDRS-2))
+ {
+ TRACDCOMP( g_trac_scom, "ScomTest::test_translate MCS.. Expected Error log returned> x = %d", x );
+ }
+ else
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_translate_Scom_MCS> [%d] Write: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_Translate_SCOM_mcs> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ }
+
+ delete l_err;
+ }
+ }
+
+ // allocate space for read data
+ uint64_t read_data[NUM_ADDRS];
+
+ memset(read_data, 0, sizeof read_data);
+
+ // read all the test registers
+ for( uint64_t x = 0; x < NUM_ADDRS-2; x++ )
+ {
+ //only run if the target exists
+ if(test_data[x].target == NULL)
+ {
+ continue;
+ }
+
+ op_size = sizeof(uint64_t);
+
+ total++;
+ l_err = deviceRead( test_data[x].target,
+ &(read_data[x]),
+ op_size,
+ DEVICE_SCOM_ADDRESS(test_data[x].addr) );
+
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_TranslateScom_MCS> [%d] Read: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_TranslateScom_MCS> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ delete l_err;
+ }
+ else if((read_data[x]) != (test_data[x].data))
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_TranslateScom_MCS> [%d] Read: Data miss-match : addr=0x%X, read_data=0x%llx, write_data=0x%llx", x, test_data[x].addr, read_data[x], test_data[x].data);
+ TS_FAIL( "ScomTest::test_TranslateScom_MCS> ERROR : Data miss-match between read and expected data" );
+ fails++;
+ }
+
+ }
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test_translateScom_MCS> %d/%d fails", fails, total );
+
+ }
+
+
+
+ void test_TranslateScom_MBA_MBS(void)
+ {
+ TRACFCOMP( g_trac_scom, "ScomTest::test_TranslateScom_MBA_MBS Start" );
+
+ uint64_t fails = 0;
+ uint64_t total = 0;
+ errlHndl_t l_err = NULL;
+
+ //@VBU workaround - Disable Indirect SCOM test case o
+ //Test case read/writes to valid addresses and is
+ //potentially destructive on VBU
+ TARGETING::EntityPath syspath(TARGETING::EntityPath::PATH_PHYSICAL);
+ syspath.addLast(TARGETING::TYPE_SYS,0);
+ TARGETING::Target* sys = TARGETING::targetService().toTarget(syspath);
+ uint8_t vpo_mode = 0;
+ if( sys
+ && sys->tryGetAttr<TARGETING::ATTR_IS_SIMULATION>(vpo_mode)
+ && (vpo_mode == 1) )
+ {
+ return;
+ }
+
+ // Setup some targets to use
+ enum {
+ myMembuf0,
+ myMBS,
+ myMBA0,
+ myMBA1,
+ NUM_TARGETS
+ };
+
+
+ TARGETING::Target* scom_targets[NUM_TARGETS];
+ for( uint64_t x = 0; x < NUM_TARGETS; x++ )
+ {
+ scom_targets[x] = NULL;
+ }
+
+ // Target Proc 0 - to make sure we have XSCOM and FSISCOM attributes
+ TARGETING::EntityPath epath(TARGETING::EntityPath::PATH_PHYSICAL);
+ epath.addLast(TARGETING::TYPE_SYS,0);
+ epath.addLast(TARGETING::TYPE_NODE,0);
+ epath.addLast(TARGETING::TYPE_MEMBUF,0);
+
+ scom_targets[myMembuf0] = TARGETING::targetService().toTarget(epath);
+
+ if ( (scom_targets[myMembuf0] != NULL) &&
+ (scom_targets[myMembuf0]->getAttr<TARGETING::ATTR_SCOM_SWITCHES>().useXscom == 0) &&
+ (scom_targets[myMembuf0]->getAttr<TARGETING::ATTR_SCOM_SWITCHES>().useFsiScom == 0))
+ {
+ // If both FSI and XSCOM are not enabled.. then ignore..
+ TRACFCOMP(g_trac_scom, "TRANSLATE_SCOM_MBA_MBS>> SKIPPING ");
+ scom_targets[myMembuf0] = NULL; //remove from our list
+ }
+
+ if(scom_targets[myMembuf0] != NULL)
+ {
+ // add MBS target.
+ epath.addLast(TARGETING::TYPE_MBS,0);
+ scom_targets[myMBS] = TARGETING::targetService().toTarget(epath);
+
+ // add MBA0 target.
+ epath.addLast(TARGETING::TYPE_MBA,0);
+ scom_targets[myMBA0] = TARGETING::targetService().toTarget(epath);
+
+ // remote MBA0 target (off of sys-0/node-0/membuf-0/MBS-0/MBA0)
+ epath.removeLast();
+
+ // Add MBA1 to the path and create new target
+ epath.addLast(TARGETING::TYPE_MBA,1);
+ scom_targets[myMBA1] = TARGETING::targetService().toTarget(epath);
+ }
+ // scratch data to use
+ //@fixme: Need to either fabricate some fake registers to use or save off data before modifying SCOMs to avoid
+ // corrupting the HW.
+ struct {
+ TARGETING::Target* target;
+ uint64_t addr;
+ uint64_t data;
+ } test_data[] = {
+ { scom_targets[myMBA0], 0x03010655 ,0x1111111122222222},
+ { scom_targets[myMBA1], 0x03010655, 0x3333333344444444},
+ { scom_targets[myMBS], 0x02011417, 0x1231231231231231},
+ { scom_targets[myMBA0], 0x03010E55, 0x0101010101010101}, // invalid passing in a non-0 unit address
+ };
+ const uint64_t NUM_ADDRS = sizeof(test_data)/sizeof(test_data[0]);
+
+ size_t op_size = sizeof(uint32_t);
+
+ // write all the test registers
+ for( uint64_t x = 0; x < NUM_ADDRS; x++ )
+ {
+ //only run if the target exists
+ if(test_data[x].target == NULL)
+ {
+ TRACFCOMP( g_trac_scom, "MBA_MBS ScomTest before device write- TARGET = NULL x = %d", x);
+
+ continue;
+ }
+
+ op_size = sizeof(uint64_t);
+
+ total++;
+ l_err = deviceWrite( test_data[x].target,
+ &(test_data[x].data),
+ op_size,
+ DEVICE_SCOM_ADDRESS(test_data[x].addr) );
+ if( l_err )
+ {
+ // checking the read of NUM_ADDRs - 1 because the last entry written above failed as expected.
+ if (x == (NUM_ADDRS-1))
+ {
+ TRACDCOMP( g_trac_scom, "ScomTest::test_translate MCS.. Expected Errorlog Returned> x = %d", x );
+ }
+ else
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_translate_Scom_MBA_MBS> [%d] Write: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_Translate_SCOM_MBA_MBS> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ }
+
+ delete l_err;
+ }
+ }
+
+ // allocate space for read data
+ uint64_t read_data[NUM_ADDRS];
+
+ // read all the test registers
+ for( uint64_t x = 0; x < NUM_ADDRS-1; x++ )
+ {
+ memset(read_data, 0, sizeof read_data);
+
+ //only run if the target exists
+ if(test_data[x].target == NULL)
+ {
+ continue;
+ }
+
+ op_size = sizeof(uint64_t);
+
+ total++;
+ l_err = deviceRead( test_data[x].target,
+ &(read_data[x]),
+ op_size,
+ DEVICE_SCOM_ADDRESS(test_data[x].addr) );
+
+
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_TranslateScom_MBA_MBS> [%d] Read: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_TranslateScom_MBA_MBS> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ delete l_err;
+ }
+ else if((read_data[x]) != (test_data[x].data))
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_TranslateScom_MBA_MBS> [%d] Read: Data miss-match : addr=0x%X, read_data=0x%llx, write_data=0x%llx", x, test_data[x].addr, read_data[x], test_data[x].data);
+ TS_FAIL( "ScomTest::test_TranslateScom_MBA_MBS> ERROR : Data miss-match between read and expected data" );
+ fails++;
+ }
+
+ }
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test_translateScom_MBA_MBS> %d/%d fails", fails, total );
+
+ }
+
+
+
+
//@todo - write tests to verify connection between XSCOM and FSISCOM
//@todo - write error path testcase for FSI scom using bad address
OpenPOWER on IntegriCloud