summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/runtime/interface.h16
-rw-r--r--src/include/usr/xscom/xscomreasoncodes.H7
-rw-r--r--src/makefile7
-rw-r--r--src/usr/devicefw/devicefw.mk25
-rw-r--r--src/usr/devicefw/makefile35
-rw-r--r--src/usr/devicefw/runtime/makefile36
-rw-r--r--src/usr/devicefw/runtime/test/makefile30
-rw-r--r--src/usr/scom/makefile36
-rw-r--r--src/usr/scom/runtime/makefile36
-rw-r--r--src/usr/scom/runtime/test/makefile30
-rw-r--r--src/usr/scom/runtime/test/testscom_rt.H1011
-rw-r--r--src/usr/scom/scom.mk24
-rw-r--r--src/usr/testcore/rtloader/loader.H72
-rw-r--r--src/usr/xscom/makefile2
-rw-r--r--src/usr/xscom/runtime/makefile32
-rw-r--r--src/usr/xscom/runtime/rt_xscom.C411
-rw-r--r--src/usr/xscom/runtime/test/makefile29
-rw-r--r--src/usr/xscom/runtime/test/testxscom_rt.H159
18 files changed, 1962 insertions, 36 deletions
diff --git a/src/include/runtime/interface.h b/src/include/runtime/interface.h
index 082f2440c..7dd49d202 100644
--- a/src/include/runtime/interface.h
+++ b/src/include/runtime/interface.h
@@ -67,6 +67,22 @@ typedef struct hostInterfaces
*/
int (*sendErrorLog)(uint32_t,uint32_t,void *);
+ /** Scan communication read
+ * @param[in] chip_id (based on devtree defn)
+ * @param[in] address
+ * @param[in] pointer to 8-byte data buffer
+ * @return 0 on success else return code
+ */
+ int (*scom_read)(uint32_t, uint32_t, void*);
+
+ /** Scan communication write
+ * @param[in] chip_id (based on devtree defn)
+ * @param[in] address
+ * @param[in] pointer to 8-byte data buffer
+ * @return 0 on success else return code
+ */
+ int (*scom_write)(uint32_t, uint32_t, void* );
+
} hostInterfaces_t;
typedef struct runtimeInterfaces
diff --git a/src/include/usr/xscom/xscomreasoncodes.H b/src/include/usr/xscom/xscomreasoncodes.H
index facc7657d..c3af7a186 100644
--- a/src/include/usr/xscom/xscomreasoncodes.H
+++ b/src/include/usr/xscom/xscomreasoncodes.H
@@ -37,6 +37,9 @@ namespace XSCOM
XSCOM_COLLECT_FFDC = 0x05,
XSCOM_RESET = 0x06,
XSCOM_DO_OP = 0x07,
+ XSCOM_RT_DO_OP = 0x08,
+ XSCOM_RT_SANITY_CHECK = 0x09,
+ XSCOM_RT_GET_TARGET = 0x0A,
};
enum xscomReasonCode
@@ -46,6 +49,10 @@ namespace XSCOM
XSCOM_INVALID_OP_TYPE = XSCOM_COMP_ID | 0x03,
XSCOM_DATA_UNMATCHED = XSCOM_COMP_ID | 0x04,
XSCOM_MMIO_UNMAP_ERR = XSCOM_COMP_ID | 0x05,
+ XSCOM_RUNTIME_ERR = XSCOM_COMP_ID | 0x06,
+ XSCOM_RUNTIME_INTERFACE_ERR = XSCOM_COMP_ID | 0x07,
+ XSCOM_RT_NO_MCS_TARGET = XSCOM_COMP_ID | 0x08,
+ XSCOM_RT_NO_PROC_TARGET = XSCOM_COMP_ID | 0x09,
};
};
diff --git a/src/makefile b/src/makefile
index b03e08b04..7f71f9b5b 100644
--- a/src/makefile
+++ b/src/makefile
@@ -71,9 +71,12 @@ TESTCASE_MODULES = cxxtest testtrace testerrl testdevicefw testsyslib \
RUNTIME_OBJECTS = rt_start.o rt_main.o rt_console.o rt_stdlib.o rt_sync.o \
rt_assert.o rt_vfs.o
-RUNTIME_MODULES = trace_rt targeting_rt errl_rt
+
+RUNTIME_MODULES = trace_rt errl_rt targeting_rt devicefw_rt xscom_rt scom_rt
+
RUNTIME_DATA_MODULES =
-RUNTIME_TESTCASE_MODULES = cxxtest_rt testsyslib_rt testtargeting_rt testerrl_rt
+RUNTIME_TESTCASE_MODULES = cxxtest_rt testsyslib_rt testtargeting_rt \
+ testxscom_rt testerrl_rt testdevicefw_rt testscom_rt
RELOCATABLE_IMAGE_LDFLAGS = -pie --export-dynamic
diff --git a/src/usr/devicefw/devicefw.mk b/src/usr/devicefw/devicefw.mk
new file mode 100644
index 000000000..e8a8003c0
--- /dev/null
+++ b/src/usr/devicefw/devicefw.mk
@@ -0,0 +1,25 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/devicefw/devicefw.mk $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2013
+#
+# 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 otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+# common objects used in both runtime and standard hostboot envrionment
+OBJS = driverif.o userif.o assoccontain.o associator.o
+
diff --git a/src/usr/devicefw/makefile b/src/usr/devicefw/makefile
index 6ef2afcf9..95a4a9024 100644
--- a/src/usr/devicefw/makefile
+++ b/src/usr/devicefw/makefile
@@ -1,30 +1,33 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
#
-# $Source: src/usr/devicefw/makefile $
+# $Source: src/usr/devicefw/makefile $
#
-# IBM CONFIDENTIAL
+# IBM CONFIDENTIAL
#
-# COPYRIGHT International Business Machines Corp. 2011
+# COPYRIGHT International Business Machines Corp. 2011,2013
#
-# p1
+# p1
#
-# Object Code Only (OCO) source materials
-# Licensed Internal Code Source Materials
-# IBM HostBoot Licensed Internal Code
+# 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.
+# The source code for this program is not published or otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
#
-# Origin: 30
+# Origin: 30
#
-# IBM_PROLOG_END
+# IBM_PROLOG_END_TAG
ROOTPATH = ../../..
MODULE = devicefw
-OBJS = driverif.o userif.o assoccontain.o associator.o
+# common ojects for devicefw
+include devicefw.mk
-SUBDIRS = test.d
+# add objectcs unique to standard hostboot - currently none
+
+SUBDIRS = test.d runtime.d
include ${ROOTPATH}/config.mk
diff --git a/src/usr/devicefw/runtime/makefile b/src/usr/devicefw/runtime/makefile
new file mode 100644
index 000000000..efe063d7b
--- /dev/null
+++ b/src/usr/devicefw/runtime/makefile
@@ -0,0 +1,36 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/devicefw/runtime/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2013
+#
+# 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 otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+HOSTBOOT_RUNTIME = 1
+ROOTPATH = ../../../..
+MODULE = devicefw_rt
+
+# Include common objects
+include ../devicefw.mk
+
+# add unique objects - currently none
+# OBJS +=
+
+SUBDIRS = test.d
+
+VPATH += ..
+include $(ROOTPATH)/config.mk
diff --git a/src/usr/devicefw/runtime/test/makefile b/src/usr/devicefw/runtime/test/makefile
new file mode 100644
index 000000000..5c83cbfb8
--- /dev/null
+++ b/src/usr/devicefw/runtime/test/makefile
@@ -0,0 +1,30 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/devicefw/runtime/test/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2013
+#
+# 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 otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+HOSTBOOT_RUNTIME = 1
+ROOTPATH = ../../../../..
+
+MODULE = testdevicefw_rt
+
+TESTS = ../../test/*.H
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/scom/makefile b/src/usr/scom/makefile
index 451ed17de..3579acbcc 100644
--- a/src/usr/scom/makefile
+++ b/src/usr/scom/makefile
@@ -1,30 +1,34 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
#
-# $Source: src/usr/scom/makefile $
+# $Source: src/usr/scom/makefile $
#
-# IBM CONFIDENTIAL
+# IBM CONFIDENTIAL
#
-# COPYRIGHT International Business Machines Corp. 2011
+# COPYRIGHT International Business Machines Corp. 2011,2013
#
-# p1
+# p1
#
-# Object Code Only (OCO) source materials
-# Licensed Internal Code Source Materials
-# IBM HostBoot Licensed Internal Code
+# 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.
+# The source code for this program is not published or otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
#
-# Origin: 30
+# Origin: 30
#
-# IBM_PROLOG_END
+# IBM_PROLOG_END_TAG
ROOTPATH = ../../..
MODULE = scom
-OBJS = scom.o scomtrans.o
+#include common ojects between hostboot and runtime hostboot
+include scom.mk
-SUBDIRS = test.d
+#include unique object modules - currently none
+# OBJS +=
+
+SUBDIRS = test.d runtime.d
include ${ROOTPATH}/config.mk
diff --git a/src/usr/scom/runtime/makefile b/src/usr/scom/runtime/makefile
new file mode 100644
index 000000000..f31b0def5
--- /dev/null
+++ b/src/usr/scom/runtime/makefile
@@ -0,0 +1,36 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/scom/runtime/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2013
+#
+# 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 otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+HOSTBOOT_RUNTIME = 1
+ROOTPATH = ../../../..
+MODULE = scom_rt
+
+#include common ojects between hostboot and runtime hostboot
+include ../scom.mk
+
+#include unique object modules - currently none
+# OBJS +=
+
+SUBDIRS = test.d
+
+VPATH += ..
+include $(ROOTPATH)/config.mk
diff --git a/src/usr/scom/runtime/test/makefile b/src/usr/scom/runtime/test/makefile
new file mode 100644
index 000000000..0d10880c8
--- /dev/null
+++ b/src/usr/scom/runtime/test/makefile
@@ -0,0 +1,30 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/scom/runtime/test/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2013
+#
+# 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 otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+HOSTBOOT_RUNTIME = 1
+ROOTPATH = ../../../../..
+
+MODULE = testscom_rt
+
+TESTS = *.H
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/scom/runtime/test/testscom_rt.H b/src/usr/scom/runtime/test/testscom_rt.H
new file mode 100644
index 000000000..ede6715d2
--- /dev/null
+++ b/src/usr/scom/runtime/test/testscom_rt.H
@@ -0,0 +1,1011 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/scom/runtime/test/testscom_rt.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* 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 otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SCOMTEST_H
+#define __SCOMTEST_H
+
+/**
+ * @file scomtest.H
+ *
+ * @brief Test case for SCOM code
+*/
+
+#include <cxxtest/TestSuite.H>
+#include <errl/errlmanager.H>
+#include <errl/errlentry.H>
+#include <devicefw/userif.H>
+#include <fsi/fsiif.H>
+#include <targeting/common/util.H>
+
+#include <devicefw/driverif.H>
+
+
+extern trace_desc_t* g_trac_scom;
+
+
+class ScomTestRt: public CxxTest::TestSuite
+{
+public:
+
+ /**
+ * @brief runtime SCOM test
+ *
+ */
+ void test_SCOMreadWrite_proc(void)
+ {
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test_SCOMreadWrite_proc> Start" );
+
+ uint64_t fails = 0;
+ uint64_t total = 0;
+ errlHndl_t l_err = NULL;
+
+ // Setup some targets to use
+ enum {
+ PROC0,
+ PROC1,
+ NUM_TARGETS
+ };
+ TARGETING::Target* scom_targets[NUM_TARGETS];
+ for( uint64_t x = 0; x < NUM_TARGETS; x++ )
+ {
+ scom_targets[x] = NULL;
+ }
+
+ // Target Proc 0
+ 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[PROC0] = TARGETING::targetService().toTarget(epath);
+
+ // Target Proc 1
+ epath.removeLast();
+ epath.addLast(TARGETING::TYPE_PROC,1);
+ scom_targets[PROC1] = TARGETING::targetService().toTarget(epath);
+
+ for( uint64_t x = 0; x < NUM_TARGETS; x++ )
+ {
+ //only run if the target exists
+ if(scom_targets[x] == NULL)
+ {
+ continue;
+ }
+ else if (scom_targets[x]->getAttr<TARGETING::ATTR_HWAS_STATE>().functional != true)
+ {
+ TRACDCOMP( g_trac_scom, "ScomTest::test_SCOMreadWrite_proc> Target %d is not functional", x );
+ scom_targets[x] = NULL; //remove from our list
+ }
+ }
+
+ // scratch data to use
+ struct {
+ TARGETING::Target* target;
+ uint64_t addr;
+ uint64_t data;
+ } test_data[] = {
+ { scom_targets[PROC0], 0x120F0000 ,0xFEEDB0B000001234},
+ { scom_targets[PROC0], 0x120F0166, 0xFEDCBA9876543210},
+ { scom_targets[PROC0], 0x01010803, 0x0000000000000000},
+ { scom_targets[PROC0], 0x02040004, 0xFFFFFFFFFFFFFFFF},
+ { scom_targets[PROC1], 0x01010803, 0x1234567887654321},
+ { scom_targets[PROC1], 0x02040004, 0x1122334455667788},
+ };
+ const uint64_t NUM_ADDRS = sizeof(test_data)/sizeof(test_data[0]);
+
+ // allocate space for read data
+ uint64_t read_data[NUM_ADDRS];
+ 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 )
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_SCOMreadWrite_proc> [%d] Write: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_SCOMreadWrite_proc> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ }
+ }
+
+ // read 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 = 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_SCOMreadWrite_proc> [%d] Read: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_SCOMreadWrite_proc> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ }
+ else if(read_data[x] != test_data[x].data)
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_SCOMreadWrite_proc> [%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_SCOMreadWrite_proc> ERROR : Data miss-match between read and expected data" );
+ fails++;
+ }
+ }
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test_SCOMreadWrite_proc> %d/%d fails", fails, total );
+
+ }
+
+ /**
+ * @brief SCOM test via FSISCOM to Centaur
+ *
+ */
+ void test_FSISCOMreadWrite_centaur(void)
+ {
+ TRACFCOMP( g_trac_scom, "ScomTest::test_FSISCOMreadWrite_centaur> Start" );
+ uint64_t fails = 0;
+ uint64_t total = 0;
+ errlHndl_t l_err = NULL;
+
+ // Setup some targets to use
+ enum {
+ CENTAUR0, //local
+ CENTAUR1, //local
+ CENTAUR2, //local
+ CENTAUR3, //local
+ CENTAUR4, //local
+ CENTAUR5, //local
+ CENTAUR6, //local
+ CENTAUR7, //local
+ CENTAUR8, //remote (off PROC1)
+ CENTAUR9, //remote (off PROC1)
+ NUM_TARGETS
+ };
+ TARGETING::Target* scom_targets[NUM_TARGETS];
+ for( uint64_t x = 0; x < NUM_TARGETS; x++ )
+ {
+ scom_targets[x] = NULL;
+ }
+
+ // Target Centaur0 - the local centaur
+ 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[CENTAUR0] = TARGETING::targetService().toTarget(epath);
+
+ // remote centaur target (off of sys-0/node-0/proc-1)
+ epath.removeLast();
+ epath.addLast(TARGETING::TYPE_MEMBUF,8);
+ scom_targets[CENTAUR8] = TARGETING::targetService().toTarget(epath);
+
+ epath.removeLast();
+ epath.addLast(TARGETING::TYPE_MEMBUF,1);
+ scom_targets[CENTAUR1] = TARGETING::targetService().toTarget(epath);
+ epath.removeLast();
+ epath.addLast(TARGETING::TYPE_MEMBUF,2);
+ scom_targets[CENTAUR2] = TARGETING::targetService().toTarget(epath);
+ epath.removeLast();
+ epath.addLast(TARGETING::TYPE_MEMBUF,3);
+ scom_targets[CENTAUR3] = TARGETING::targetService().toTarget(epath);
+ epath.removeLast();
+ epath.addLast(TARGETING::TYPE_MEMBUF,4);
+ scom_targets[CENTAUR4] = TARGETING::targetService().toTarget(epath);
+ epath.removeLast();
+ epath.addLast(TARGETING::TYPE_MEMBUF,5);
+ scom_targets[CENTAUR5] = TARGETING::targetService().toTarget(epath);
+ epath.removeLast();
+ epath.addLast(TARGETING::TYPE_MEMBUF,6);
+ scom_targets[CENTAUR6] = TARGETING::targetService().toTarget(epath);
+ epath.removeLast();
+ epath.addLast(TARGETING::TYPE_MEMBUF,7);
+ scom_targets[CENTAUR7] = TARGETING::targetService().toTarget(epath);
+ epath.removeLast();
+ epath.addLast(TARGETING::TYPE_MEMBUF,9);
+ scom_targets[CENTAUR9] = TARGETING::targetService().toTarget(epath);
+
+ for( uint64_t x = 0; x < NUM_TARGETS; x++ )
+ {
+ //only run if the target exists and has FSI enabled.
+ if(scom_targets[x] == NULL)
+ {
+ continue;
+ }
+ else if (scom_targets[x]->getAttr<TARGETING::ATTR_HWAS_STATE>().functional != true)
+ {
+ TRACDCOMP( g_trac_scom, "ScomTest::test_FSISCOMreadWrite_centaur> Target %d is not functional", x );
+ scom_targets[x] = NULL; //remove from our list
+ }
+ }
+
+ // scratch data to use
+ struct {
+ TARGETING::Target* target;
+ uint64_t addr;
+ uint64_t data;
+ } test_data[] = {
+ { scom_targets[CENTAUR0], 0x02011403 , 0x1234567800000000 },
+ { scom_targets[CENTAUR0], 0x02011672 , 0x1122334455667788 },
+ { scom_targets[CENTAUR8], 0x02011672 , 0x9E9E9E9E9E9E9E9E },
+
+ { scom_targets[CENTAUR0], 0x030104E0 , 0x00000000f0f0f0f0 },
+ { scom_targets[CENTAUR1], 0x030104E1 , 0x1111111100000000 },
+ { scom_targets[CENTAUR2], 0x030104E2 , 0x2222222200000000 },
+ { scom_targets[CENTAUR3], 0x030104E3 , 0x3333333300000000 },
+ { scom_targets[CENTAUR4], 0x030104E4 , 0x4444444400000000 },
+ { scom_targets[CENTAUR5], 0x030104E5 , 0x5555555500000000 },
+ { scom_targets[CENTAUR6], 0x030104E6 , 0x6666666600000000 },
+ { scom_targets[CENTAUR7], 0x030104E7 , 0x7777777700000000 },
+ { scom_targets[CENTAUR8], 0x030104E8 , 0x8888888800000000 },
+ { scom_targets[CENTAUR9], 0x030104E9 , 0x9999999900000000 },
+ };
+ const uint64_t NUM_ADDRS = sizeof(test_data)/sizeof(test_data[0]);
+
+ // allocate space for read data
+ uint64_t read_data[NUM_ADDRS];
+ size_t op_size = sizeof(uint32_t);
+
+ // write all the test registers
+ for( uint64_t x = 0; x < NUM_ADDRS; x++ )
+ {
+ TRACDCOMP(g_trac_scom, "ScomTest::test_FSISCOMreadWrite_centaur> x=%d, addr=%.8X, target=%p", x, test_data[x].addr, test_data[x].target );
+
+ //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 )
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_FSISCOMreadWrite_centaur> [%d] Write: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_FSISCOMreadWrite_centaur> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ }
+ }
+
+ // read all the test registers
+ for( uint64_t x = 0; x < NUM_ADDRS; x++ )
+ {
+ TRACDCOMP(g_trac_scom, "ScomTest::test_FSISCOMreadWrite_centaur> x=%d, addr=%.8X, target=%p", x, test_data[x].addr, test_data[x].target );
+
+ //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_FSISCOMreadWrite_centaur> [%d] Read: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_FSISCOMreadWrite_centaur> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ }
+ else if(read_data[x] != test_data[x].data)
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_FSISCOMreadWrite_centaur> [%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_FSISCOMreadWrite_centaur> ERROR : Data miss-match between read and expected data" );
+ fails++;
+ }
+ }
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test_FSISCOMreadWrite_centaur> %d/%d fails", fails, total );
+
+ }
+
+
+
+
+ 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;
+
+
+ // 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);
+
+
+ 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
+
+ struct {
+ TARGETING::Target* target;
+ uint64_t addr;
+ uint64_t data;
+ } test_data[] = {
+ { scom_targets[myEX1], 0x10040000 ,0x7676767676767676},
+ { scom_targets[myEX5], 0x10040002, 0x9191919191919191},
+ { scom_targets[myEX5], 0x13040002, 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;
+ }
+ // check to see if the target is functional.. if not.. skip this target
+ else if (test_data[x].target->getAttr<TARGETING::ATTR_HWAS_STATE>().functional != true)
+ {
+ TRACDCOMP( g_trac_scom, "ScomTest::test_translate_scom_EX> Target %d is not functional", 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 )
+ {
+ // 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);
+ }
+ 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
+ if (TARGETING::is_vpo())
+ {
+ 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);
+
+ 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
+ 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], 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;
+ }
+ // check to see if the target is functional.. if not.. skip this target
+ else if (test_data[x].target->getAttr<TARGETING::ATTR_HWAS_STATE>().functional != true)
+ {
+ TRACDCOMP( g_trac_scom, "ScomTest::test_translate_scom_MCS> Target %d is not functional", 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 )
+ {
+ 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);
+ }
+ 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);
+
+ //temp workaround for MCSs that have been turned off (RTC Issue 84907)
+ if (read_data[x] != 0x0)
+ {
+ 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
+ if (TARGETING::is_vpo())
+ {
+ return;
+ }
+
+ // Setup some targets to use
+ enum {
+ myMembuf0,
+ 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)
+ {
+
+ // 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/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
+ struct {
+ TARGETING::Target* target;
+ uint64_t addr;
+ uint64_t data;
+ } test_data[] = {
+ { scom_targets[myMBA0], 0x03010655 ,0x111111111111DDDD},
+ { scom_targets[myMBA1], 0x03010655, 0x333333334444EEEE},
+ { scom_targets[myMBA0], 0x8000C0140301143F,0x1111111111111212},
+ { scom_targets[myMBA1], 0x8000C0140301143F, 0x333333334444abcd},
+ { scom_targets[myMBA0], 0x8000C0140301183F,0x111111111111ccee}, // invalid non zero indirect address
+ { scom_targets[myMBA0], 0x03010E55, 0x010101010101CCCC}, // 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)
+ {
+ continue;
+ }
+
+ // check to see if the target is functional.. if not.. skip this target
+ else if (test_data[x].target->getAttr<TARGETING::ATTR_HWAS_STATE>().functional != true)
+ {
+ TRACDCOMP( g_trac_scom, "ScomTest::test_translate_scom_MBA_MBS> Target %d is not functional", 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) || (x==NUM_ADDRS-2))
+ {
+ TRACDCOMP( g_trac_scom, "ScomTest::test_translate MBA_MBS.. 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-2; x++ )
+ {
+ memset(read_data, 0, sizeof read_data);
+
+ //only run if the target exists
+ if(test_data[x].target == NULL)
+ {
+ continue;
+ }
+ // check to see if the target is functional.. if not.. skip this target
+ else if (test_data[x].target->getAttr<TARGETING::ATTR_HWAS_STATE>().functional != true)
+ {
+ TRACDCOMP( g_trac_scom, "ScomTest::test_translate_scom_MBA_MBS> Target %d is not functional", x );
+ 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);
+ }
+ else if ((x == 2) || (x==3))
+ {
+ if((read_data[x] & 0x000000000000FFFF) != (test_data[x].data & 0x000000000000FFFF))
+
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_TranslateScom_ABUS> [%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_ABUS> ERROR : Data miss-match between read and expected data" );
+ fails++;
+ }
+ }
+ 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
+
+
+
+
+
+ /**
+ * @brief multi chip SCOM test
+ *
+ */
+ void test_MultiChipSCOMreadWrite_proc(void)
+ {
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test_MultiChipSCOMreadWrite_proc> Start" );
+
+ uint64_t fails = 0;
+ uint64_t total = 0;
+ errlHndl_t l_err = NULL;
+
+ // Setup some targets to use
+ enum {
+ PROC1,
+ NUM_TARGETS
+ };
+ TARGETING::Target* scom_targets[NUM_TARGETS];
+ for( uint64_t x = 0; x < NUM_TARGETS; x++ )
+ {
+ scom_targets[x] = NULL;
+ }
+
+ TARGETING::EntityPath epath(TARGETING::EntityPath::PATH_PHYSICAL);
+ epath.addLast(TARGETING::TYPE_SYS,0);
+ epath.addLast(TARGETING::TYPE_NODE,0);
+ epath.addLast(TARGETING::TYPE_PROC,1);
+ scom_targets[PROC1] = TARGETING::targetService().toTarget(epath);
+
+ for( uint64_t x = 0; x < NUM_TARGETS; x++ )
+ {
+ //only run if the target exists
+ if(scom_targets[x] == NULL)
+ {
+ continue;
+ }
+ else if (scom_targets[x]->getAttr<TARGETING::ATTR_HWAS_STATE>().functional != true)
+ {
+ TRACDCOMP( g_trac_scom, "ScomTest::test_SCOMreadWrite_proc> Target %d is not functional", x );
+ scom_targets[x] = NULL; //remove from our list
+ }
+ }
+ // scratch data to use
+ struct {
+ TARGETING::Target* target;
+ uint64_t addr;
+ uint64_t data;
+ } test_data[] = {
+ { scom_targets[PROC1], 0x01010803, 0x1234567887654321},
+ { scom_targets[PROC1], 0x02040004, 0x1122334455667788},
+ };
+ const uint64_t NUM_ADDRS = sizeof(test_data)/sizeof(test_data[0]);
+
+ // allocate space for read data
+ uint64_t read_data[NUM_ADDRS];
+ 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 = deviceOp( DeviceFW::WRITE,
+ test_data[x].target,
+ &(test_data[x].data),
+ op_size,
+ DEVICE_XSCOM_ADDRESS(test_data[x].addr) );
+
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_MultiChipScomWrite_proc> [%d] Write: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test__MultiChipScomWrite_proc> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ }
+ }
+
+ // read 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++;
+
+ // read the data back using XSCOM
+ l_err = deviceOp( DeviceFW::READ,
+ test_data[x].target,
+ &(read_data[x]),
+ op_size,
+ DEVICE_XSCOM_ADDRESS(test_data[x].addr) );
+
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test__MultiChipScomWrite_proc> [%d] XSCOM Read: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test__MultiChipScomWrite_proc> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ }
+ else if(read_data[x] != test_data[x].data)
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test__MultiChipScomWrite_proc> [%d] XSCOM 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__MultiChipScomWrite_proc> ERROR : Data miss-match between read and expected data" );
+ fails++;
+ }
+
+ // Read the data back using FSIscom to make sure the data is the same.
+ l_err = deviceOp( DeviceFW::READ,
+ test_data[x].target,
+ &(read_data[x]),
+ op_size,
+ DEVICE_FSISCOM_ADDRESS(test_data[x].addr) );
+
+
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test__MultiChipScomWrite_proc> [%d] FSISCOM Read: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test__MultiChipScomWrite_proc> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err,SCOM_COMP_ID);
+ }
+ else if(read_data[x] != test_data[x].data)
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test__MultiChipScomWrite_proc> [%d] FSISCOM 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__MultiChipScomWrite_proc> ERROR : Data miss-match between read and expected data" );
+ fails++;
+ }
+
+ }
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test__MultiChipScomWrite_proc> %d/%d fails", fails, total );
+
+ }
+
+};
+
+
+
+#endif
diff --git a/src/usr/scom/scom.mk b/src/usr/scom/scom.mk
new file mode 100644
index 000000000..44ae2fc45
--- /dev/null
+++ b/src/usr/scom/scom.mk
@@ -0,0 +1,24 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/scom/scom.mk $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2013
+#
+# 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 otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+# common objects between hostboot and runtime hostboot
+OBJS = scom.o scomtrans.o
diff --git a/src/usr/testcore/rtloader/loader.H b/src/usr/testcore/rtloader/loader.H
index 205522536..60272aa63 100644
--- a/src/usr/testcore/rtloader/loader.H
+++ b/src/usr/testcore/rtloader/loader.H
@@ -26,8 +26,11 @@
#include <pnor/pnorif.H>
#include <util/align.H>
#include <sys/mm.h>
-#include <errl/errlentry.H>
+#include <targeting/common/targetservice.H>
+#include <targeting/common/attributes.H>
+#include <targeting/common/utilFilter.H>
#include <errl/errlmanager.H>
+#include <map>
#include <runtime/interface.h>
@@ -100,6 +103,8 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
intf->realloc = realloc;
intf->assert = rt_assert;
intf->sendErrorLog = rt_logErr;
+ intf->scom_read = rt_scom_read;
+ intf->scom_write = rt_scom_write;
// Call init.
runtimeInterfaces_t* rtInterface =
@@ -163,6 +168,62 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
assert(false);
}
+
+
+
+ static int rt_scom_read(uint32_t chipid,
+ uint32_t addr,
+ void* data)
+ {
+ int rc = 0;
+
+ TRACFCOMP(g_trac_test,
+ "RUNTIME MSG: Scom read chipid: 0x%08x Address: 0x%08x",
+ chipid,
+ addr);
+
+ uint64_t * data64 = static_cast<uint64_t *>(data);
+
+ SCOM_KEY scomKey(chipid,addr);
+ SCOM_MAP::iterator it = cv_scomMap.find(scomKey);
+
+ if(it != cv_scomMap.end())
+ {
+ *data64 = it->second;
+ }
+ else
+ {
+ *data64 = 0;
+ }
+
+ return rc;
+ }
+
+
+
+
+ static int rt_scom_write(uint32_t chipid,
+ uint32_t addr,
+ void* data)
+ {
+ int rc = 0;
+
+ TRACFCOMP(g_trac_test,
+ "RUNTIME MSG: Scom write chipid: 0x%08x Address: 0x%08x",
+ chipid,
+ addr);
+
+ uint64_t * data64 = static_cast<uint64_t *>(data);
+
+ SCOM_KEY scomKey(chipid,addr);
+ cv_scomMap[scomKey] = *data64;
+
+ return rc;
+ }
+
+
+
+
static int rt_logErr(uint32_t plid,
uint32_t data_len,
void * data)
@@ -185,5 +246,14 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
return rc;
}
+
+
+ typedef std::pair<uint32_t,uint32_t> SCOM_KEY;
+ typedef std::map<SCOM_KEY,uint64_t> SCOM_MAP;
+ static SCOM_MAP cv_scomMap;
};
+
+
+RuntimeLoaderTest::SCOM_MAP RuntimeLoaderTest::cv_scomMap;
+
#endif
diff --git a/src/usr/xscom/makefile b/src/usr/xscom/makefile
index f879c70ec..89ead1946 100644
--- a/src/usr/xscom/makefile
+++ b/src/usr/xscom/makefile
@@ -25,6 +25,6 @@ MODULE = xscom
OBJS = xscom.o piberror.o
-SUBDIRS = test.d
+SUBDIRS = test.d runtime.d
include ${ROOTPATH}/config.mk
diff --git a/src/usr/xscom/runtime/makefile b/src/usr/xscom/runtime/makefile
new file mode 100644
index 000000000..b49e707b5
--- /dev/null
+++ b/src/usr/xscom/runtime/makefile
@@ -0,0 +1,32 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/xscom/runtime/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2013
+#
+# 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 otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+HOSTBOOT_RUNTIME = 1
+ROOTPATH = ../../../..
+MODULE = xscom_rt
+
+OBJS = rt_xscom.o
+
+SUBDIRS = test.d
+
+VPATH += ..
+include $(ROOTPATH)/config.mk
diff --git a/src/usr/xscom/runtime/rt_xscom.C b/src/usr/xscom/runtime/rt_xscom.C
new file mode 100644
index 000000000..7aa8669cb
--- /dev/null
+++ b/src/usr/xscom/runtime/rt_xscom.C
@@ -0,0 +1,411 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/xscom/runtime/rt_xscom.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* 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 otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <devicefw/driverif.H>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <targeting/common/targetservice.H>
+#include <targeting/common/utilFilter.H>
+#include <xscom/xscomreasoncodes.H>
+#include "../xscom.H"
+#include <assert.h>
+#include <errl/errludlogregister.H>
+#include <runtime/interface.h>
+#include <errl/errludtarget.H>
+
+// Trace definition
+trace_desc_t* g_trac_xscom = NULL;
+TRAC_INIT(&g_trac_xscom, "XSCOM", 2*KILOBYTE, TRACE::BUFFER_SLOW);
+
+namespace XSCOM
+{
+
+enum
+{
+ CHIPID_NODE_SHIFT = 3, // CHIPID is 'NNNCCC'b, shift 3
+ MEMBUF_ID_SHIFT = 4, // CHIPID for MEMBUF is 'NNNCCCMMMM'b
+ MEMBUF_ID_FLAG = 0x80000000, // MEMBUF chip id has MSbit on
+};
+
+
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::XSCOM,
+ TARGETING::TYPE_PROC,
+ xscomPerformOp);
+
+// Direct all scom calls though this interface at runtime
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::FSISCOM,
+ TARGETING::TYPE_PROC,
+ xscomPerformOp);
+
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::FSISCOM,
+ TARGETING::TYPE_MEMBUF,
+ xscomPerformOp);
+
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::IBSCOM,
+ TARGETING::TYPE_MEMBUF,
+ xscomPerformOp);
+/**
+ * @brief Convert target into chipId that the hypervisor uses
+ * @param[in] i_target The HB TARGETING target
+ * @param[out] o_chipId 32-bit chipid
+ * @return errlHndl_t Error handle if there was an error
+ */
+errlHndl_t get_rt_target(TARGETING::Target* i_target,
+ uint32_t & o_chipId);
+
+/**
+ * @brief Internal routine that verifies the validity of input parameters
+ * for an XSCOM access.
+ *
+ * @param[in] i_opType Operation type, see DeviceFW::OperationType
+ * in driverif.H
+ * @param[in] i_target XSCom target
+ * @param[in/out] i_buffer Read: Pointer to output data storage
+ * Write: Pointer to input data storage
+ * @param[in/out] i_buflen Input: size of io_buffer (in bytes)
+ * Output:
+ * Read: Size of output data
+ * Write: Size of data written
+ * @param[in] i_args This is an argument list for DD framework.
+ * In this function, there's only one argument,
+ * which is the MMIO XSCom address
+ * @return errlHndl_t
+ */
+errlHndl_t xscomOpSanityCheck(const DeviceFW::OperationType i_opType,
+ const TARGETING::Target* i_target,
+ const void* i_buffer,
+ const size_t& i_buflen,
+ const va_list i_args);
+
+
+
+errlHndl_t xscomOpSanityCheck(const DeviceFW::OperationType i_opType,
+ const TARGETING::Target* i_target,
+ const void* i_buffer,
+ const size_t& i_buflen,
+ const va_list i_args){
+ errlHndl_t l_err = NULL;
+
+ do
+ {
+ // Verify data buffer
+ if ( (i_buflen < XSCOM_BUFFER_SIZE) ||
+ (i_buffer == NULL) )
+ {
+ /*@
+ * @errortype
+ * @moduleid XSCOM_RT_SANITY_CHECK
+ * @reasoncode XSCOM_INVALID_DATA_BUFFER
+ * @userdata1 Buffer size
+ * @userdata2 XSCom address
+ * @devdesc XSCOM buffer size < 8 bytes or NULL data buff
+ */
+ l_err =
+ new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ XSCOM_RT_SANITY_CHECK,
+ XSCOM_INVALID_DATA_BUFFER,
+ i_buflen,
+ va_arg(i_args,uint64_t));
+ break;
+ }
+
+ // Verify OP type
+ if ( (i_opType != DeviceFW::READ) &&
+ (i_opType != DeviceFW::WRITE) )
+ {
+ /*@
+ * @errortype
+ * @moduleid XSCOM_RT_SANITY_CHECK
+ * @reasoncode XSCOM_INVALID_OP_TYPE
+ * @userdata1 Operation type
+ * @userdata2 XSCom address
+ * @devdesc XSCOM invalid operation type
+ */
+ l_err =
+ new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ XSCOM_RT_SANITY_CHECK,
+ XSCOM_INVALID_OP_TYPE,
+ i_opType,
+ va_arg(i_args,uint64_t));
+ break;
+ }
+
+
+ } while(0);
+
+ return l_err;
+}
+
+
+errlHndl_t get_rt_target(TARGETING::Target* i_target,
+ uint32_t &o_chipId)
+{
+ errlHndl_t l_err = NULL;
+
+ do
+ {
+ if(i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL)
+ {
+ TARGETING::Target* masterProcChip = NULL;
+ TARGETING::targetService().
+ masterProcChipTargetHandle(masterProcChip);
+
+ i_target = masterProcChip;
+ }
+
+ uint32_t target_type = i_target->getAttr<TARGETING::ATTR_TYPE>();
+
+ if(target_type == TARGETING::TYPE_MEMBUF)
+ {
+ TARGETING::TargetHandleList targetList;
+
+ // need to get assoicated MC for this MEMBUF
+ getParentAffinityTargets(targetList,
+ i_target,
+ TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MCS);
+ if( targetList.empty() )
+ {
+ uint32_t huid = get_huid(i_target);
+ TRACFCOMP(g_trac_xscom,ERR_MRK
+ "No MSC target found for MEMBUF. MEMBUF huid: %08x",
+ huid);
+ /*@
+ * @errortype
+ * @moduleid XSCOM_RT_GET_TARGET
+ * @reasoncode XSCOM_RT_NO_MCS_TARGET
+ * @userdata1 HUID of MEMBUF target
+ * @devdesc No memory controller target found for the
+ * given Memory data controller
+ */
+ l_err =
+ new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ XSCOM_RT_GET_TARGET,
+ XSCOM_RT_NO_MCS_TARGET,
+ huid,
+ 0);
+
+ l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target").
+ addToLog(l_err);
+
+ break;
+ }
+
+ TARGETING::Target * mcs_target = targetList[0];
+ uint32_t mcpos = mcs_target->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+
+ // Get associated proc chip
+ targetList.clear();
+ getParentAffinityTargets(targetList,
+ mcs_target,
+ TARGETING::CLASS_CHIP,
+ TARGETING::TYPE_PROC);
+
+ if(targetList.empty())
+ {
+ uint32_t huid = get_huid(mcs_target);
+ TRACFCOMP(g_trac_xscom,ERR_MRK
+ "No proc target found for MSC. MSC huid: %08x",
+ huid);
+ /*@
+ * @errortype
+ * @moduleid XSCOM_RT_GET_TARGET
+ * @reasoncode XSCOM_RT_NO_PROC_TARGET
+ * @userdata1 HUID of the MSC target
+ * @devdesc No processor target found for the Memory
+ * controller.
+ */
+ l_err =
+ new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ XSCOM_RT_GET_TARGET,
+ XSCOM_RT_NO_PROC_TARGET,
+ huid,
+ 0);
+
+ l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ ERRORLOG::ErrlUserDetailsTarget(mcs_target,"SCOM Target").
+ addToLog(l_err);
+
+ break;
+ }
+
+ TARGETING::Target * proc_target = targetList[0];
+ uint32_t fabId =
+ proc_target->getAttr<TARGETING::ATTR_FABRIC_NODE_ID>();
+ uint32_t procPos =
+ proc_target->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();
+
+ o_chipId = (fabId << CHIPID_NODE_SHIFT) + procPos;
+ o_chipId = (o_chipId << MEMBUF_ID_SHIFT) | MEMBUF_ID_FLAG;
+ o_chipId += mcpos;
+ }
+ else // must be proc
+ {
+ uint32_t fabId = i_target->getAttr<TARGETING::ATTR_FABRIC_NODE_ID>();
+ uint32_t procPos = i_target->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();
+
+ o_chipId = (fabId << CHIPID_NODE_SHIFT) + procPos;
+ }
+ } while(0);
+
+ return l_err;
+}
+
+
+/**
+ * @brief Do the scom operation
+ */
+errlHndl_t xScomDoOp(DeviceFW::OperationType i_ioType,
+ TARGETING::Target * i_target,
+ uint32_t i_scomAddr,
+ void * io_buffer)
+{
+ errlHndl_t l_err = NULL;
+ int rc = 0;
+ uint32_t proc_id = 0;
+
+ // Convert target to something Sapphire understands
+ l_err = get_rt_target(i_target,
+ proc_id);
+
+ if(l_err)
+ {
+ return l_err;
+ }
+
+ if(g_hostInterfaces != NULL &&
+ g_hostInterfaces->scom_read != NULL &&
+ g_hostInterfaces->scom_write != NULL)
+ {
+
+ if(i_ioType == DeviceFW::READ)
+ {
+ rc =
+ g_hostInterfaces->scom_read(proc_id,
+ i_scomAddr,
+ io_buffer
+ );
+ }
+ else if (i_ioType == DeviceFW::WRITE)
+ {
+ rc =
+ g_hostInterfaces->scom_write(proc_id,
+ i_scomAddr,
+ io_buffer
+ );
+ }
+
+ if(rc)
+ {
+ // convert rc to error log
+ /*@
+ * @errortype
+ * @moduleid XSCOM_RT_DO_OP
+ * @reasoncode XSCOM_RUNTIME_ERR
+ * @userdata1 Hypervisor return code
+ * @userdata2 SCOM address
+ * @devdesc XSCOM access error
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ XSCOM_RT_DO_OP,
+ XSCOM_RUNTIME_ERR,
+ rc,
+ i_scomAddr);
+
+ // TODO - RTC 86782 need to know what kind of errors Sapphire can
+ // return - could effect callout.
+ l_err->addHwCallout(i_target,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Note: no trace buffer available at runtime
+ }
+ }
+ else // Hypervisor interface not initialized
+ {
+ TRACFCOMP(g_trac_xscom,ERR_MRK"Hypervisor scom interface not linked");
+ /*@
+ * @errortype
+ * @moduleid XSCOM_RT_DO_OP
+ * @reasoncode XSCOM_RUNTIME_INTERFACE_ERR
+ * @userdata1 0
+ * @userdata2 SCOM address
+ * @devdesc XSCOM runtime interface not linked.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ XSCOM_RT_DO_OP,
+ XSCOM_RUNTIME_INTERFACE_ERR,
+ 0,
+ i_scomAddr);
+
+ l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ }
+
+ return l_err;
+}
+
+
+errlHndl_t xscomPerformOp(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args)
+{
+ TRACDCOMP(g_trac_xscom,ENTER_MRK"xscomPerformOp");
+ errlHndl_t l_err = NULL;
+ uint64_t l_addr = va_arg(i_args,uint64_t);
+
+ l_err = xscomOpSanityCheck(i_opType,
+ i_target,
+ io_buffer,
+ io_buflen,
+ i_args);
+
+ if (!l_err)
+ {
+
+ l_err = xScomDoOp(i_opType,
+ i_target,
+ (uint32_t)l_addr,
+ io_buffer);
+ }
+
+ TRACDCOMP(g_trac_xscom,EXIT_MRK"xscomPerformOp");
+
+ return l_err;
+}
+
+}; // end namespace XSCOM
+
diff --git a/src/usr/xscom/runtime/test/makefile b/src/usr/xscom/runtime/test/makefile
new file mode 100644
index 000000000..23939761e
--- /dev/null
+++ b/src/usr/xscom/runtime/test/makefile
@@ -0,0 +1,29 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/xscom/runtime/test/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2013
+#
+# 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 otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+HOSTBOOT_RUNTIME = 1
+ROOTPATH = ../../../../..
+
+MODULE = testxscom_rt
+TESTS = *.H
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/xscom/runtime/test/testxscom_rt.H b/src/usr/xscom/runtime/test/testxscom_rt.H
new file mode 100644
index 000000000..943d6381e
--- /dev/null
+++ b/src/usr/xscom/runtime/test/testxscom_rt.H
@@ -0,0 +1,159 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/xscom/runtime/test/testxscom_rt.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* 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 otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <cxxtest/TestSuite.H>
+#include <errl/errlmanager.H>
+#include <errl/errlentry.H>
+#include <devicefw/userif.H>
+#include <xscom/xscomreasoncodes.H>
+
+extern trace_desc_t* g_trac_xscom;
+
+using namespace TARGETING;
+
+// Address and data to read/write
+struct testXscomAddrData
+{
+ uint32_t addr;
+ uint64_t data;
+};
+
+// Test table values
+const testXscomAddrData g_xscomAddrTable[] =
+{
+ // Write data to be ORed with read value
+ {0x15013288, 0x0000040000000000},
+ {0x15010002, 0xC000000000000000},
+ {0x00040001, 0xE000000000000000}, //TP Chiplet
+ // TODO - more tests
+};
+const uint32_t g_xscomAddrTableSz =
+ sizeof(g_xscomAddrTable)/sizeof(testXscomAddrData);
+
+class XscomTestSuite : public CxxTest::TestSuite
+{
+ public:
+ /**
+ * @brief XSCOM test #1
+ * Write value and read back to verify
+ */
+ void testXscom1(void)
+ {
+
+ TARGETING::TargetService& l_targetService = TARGETING::targetService();
+ TARGETING::Target* l_testTarget = NULL;
+ l_targetService.masterProcChipTargetHandle( l_testTarget );
+ assert(l_testTarget != NULL);
+
+ size_t l_size = sizeof(uint64_t);
+
+ // Loop thru table
+ errlHndl_t l_err = NULL;
+ for( uint32_t l_num=0; l_num < g_xscomAddrTableSz; l_num++)
+ {
+ testXscomAddrData l_testEntry = g_xscomAddrTable[l_num];
+
+ // Perform XSComOM read
+ uint64_t l_readData = 0;
+ uint64_t l_writeData = 0;
+ uint64_t l_savedData = 0;
+ l_err = deviceRead(l_testTarget,
+ &l_readData,
+ l_size,
+ DEVICE_SCOM_ADDRESS(l_testEntry.addr));
+ if (l_err)
+ {
+ TS_FAIL("testXscom1: XSCom read: deviceRead() fails! Error committed.");
+ break;
+ }
+ else
+ {
+ TS_TRACE("testXscom1: XSCom read, Address 0x%.8X, Data %llx",
+ l_testEntry.addr,
+ (long long unsigned)l_readData);
+ }
+
+ // Perform an XSCom write
+ l_savedData = l_readData;
+ l_writeData = (l_readData | l_testEntry.data);
+ l_err = deviceWrite(l_testTarget,
+ &l_writeData,
+ l_size,
+ DeviceFW::SCOM,
+ l_testEntry.addr);
+
+ if (l_err)
+ {
+ TS_FAIL("testXscom1: XSCom write: deviceWrite() fails!");
+ break;
+ }
+ else
+ {
+ TS_TRACE("testXscom1: XSCom write, Address 0x%.8X, Data %llx",
+ l_testEntry.addr,
+ (long long unsigned)l_writeData);
+ }
+
+ // Read back
+ l_readData = 0;
+ l_err = deviceRead(l_testTarget,
+ &l_readData,
+ l_size,
+ DEVICE_SCOM_ADDRESS(l_testEntry.addr));
+ if (l_err)
+ {
+ TS_FAIL("testXscom1: XSCom read back: deviceRead() fails!");
+ break;
+ }
+
+ if( l_readData != l_writeData )
+ {
+ TS_FAIL("testXscom1: XSCom read back doesn't match write!");
+ break;
+ }
+
+ // Write back original value
+ l_err = deviceWrite(l_testTarget,
+ &l_savedData,
+ l_size,
+ DeviceFW::SCOM,
+ l_testEntry.addr);
+
+ if (l_err)
+ {
+ TS_FAIL("testXscom1: XSCom write back original fails!");
+ break;
+ }
+ }
+
+ if (l_err)
+ {
+ TS_FAIL("testXscom1 failed! Error committed.");
+ errlCommit(l_err,XSCOM_COMP_ID);
+ }
+ else
+ {
+ TS_TRACE("testXscom1 runs successfully!");
+ }
+ return;
+ }
+};
OpenPOWER on IntegriCloud