summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorAdam Muhle <armuhle@us.ibm.com>2011-10-13 14:44:55 -0500
committerADAM R. MUHLE <armuhle@us.ibm.com>2011-10-25 15:17:19 -0500
commit7344f3b265fe12da99ad0a032e558e7cc7fe1cb2 (patch)
treeff7bd2d0d9ac139e63a0f8bda778e3dac1b290f8 /src/usr
parent0ad20184aec21ef0560a9eee7e7c26a36ace07e1 (diff)
downloadtalos-hostboot-7344f3b265fe12da99ad0a032e558e7cc7fe1cb2.tar.gz
talos-hostboot-7344f3b265fe12da99ad0a032e558e7cc7fe1cb2.zip
Base FSISCOM Support and test Cases. (Story 3880)
Change-Id: Ia65187cd475da725250a17cec59b1aa6ff805f84 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/453 Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> Tested-by: Jenkins Server
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/fsiscom/fsiscom.C347
-rw-r--r--src/usr/fsiscom/fsiscom.H78
-rw-r--r--src/usr/fsiscom/makefile30
-rw-r--r--src/usr/fsiscom/test/fsiscomtest.H44
-rw-r--r--src/usr/fsiscom/test/makefile29
-rw-r--r--src/usr/initservice/extinitsvc/extinitsvctasks.H26
-rw-r--r--src/usr/makefile4
-rw-r--r--src/usr/scom/scom.C46
-rw-r--r--src/usr/scom/scom.H6
-rw-r--r--src/usr/scom/test/scomtest.H114
10 files changed, 711 insertions, 13 deletions
diff --git a/src/usr/fsiscom/fsiscom.C b/src/usr/fsiscom/fsiscom.C
new file mode 100644
index 000000000..2788614ed
--- /dev/null
+++ b/src/usr/fsiscom/fsiscom.C
@@ -0,0 +1,347 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/fsiscom/fsiscom.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
+/*****************************************************************************/
+// I n c l u d e s
+/*****************************************************************************/
+#include <string.h>
+#include <devicefw/driverif.H>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <fsiscom/fsiscom_reasoncodes.H>
+#include "fsiscom.H"
+
+//Globals/Constants
+// @todo - change to target-specific MUTEX so devices can be accessed in parallel.
+static mutex_t g_fsiScomMutex = MUTEX_INITIALIZER;
+
+// Trace definition
+trace_desc_t* g_trac_fsiscom = NULL;
+TRAC_INIT(&g_trac_fsiscom, "FSISCOM", 4096); //4K
+
+// Easy macro replace for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+
+
+namespace FSISCOM
+{
+
+union ioData6432
+{
+ uint64_t data64;
+ struct {
+ uint32_t data32_0;
+ uint32_t data32_1;
+ };
+};
+
+//@fixme - not full tested due to simics instability. Will full test when
+// enabling the scom test cases.
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+errlHndl_t fsiScomPerformOp(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;
+
+ uint64_t l_scomAddr = va_arg(i_args,uint64_t);
+ ioData6432 scratchData;
+ uint32_t l_command = 0;
+ uint32_t l_status = 0;
+ bool need_unlock = false;
+ size_t op_size = sizeof(uint32_t);
+
+ do{
+
+ if( io_buflen != sizeof(uint64_t) )
+ {
+ TRACFCOMP( g_trac_fsiscom, ERR_MRK "fsiScomPerformOp> Invalid data length : io_buflen=%d", io_buflen );
+ /*@
+ * @errortype
+ * @moduleid FSISCOM::MOD_FSISCOM_PERFORMOP
+ * @reasoncode FSISCOM::RC_INVALID_LENGTH
+ * @userdata1 SCOM Address
+ * @userdata2 Data Length
+ * @devdesc FSISCOM: fsiScomPerformOp> Invalid data length (!= 8 bytes)
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ FSISCOM::MOD_FSISCOM_PERFORMOP,
+ FSISCOM::RC_INVALID_LENGTH,
+ l_scomAddr,
+ TO_UINT64(io_buflen));
+ //@fixme: Need to callout target somehow. Need to decide how to callout target and where
+ // it should be done (this layer or somewhere higher in the call stack?)
+ break;
+ }
+
+ if( (l_scomAddr & 0xFFFFFFFF80000000) != 0)
+ {
+ TRACFCOMP( g_trac_fsiscom, ERR_MRK "fsiScomPerformOp> Address contains more than 31 bits : l_scomAddr=0x%.8x", l_scomAddr );
+ /*@
+ * @errortype
+ * @moduleid FSISCOM::MOD_FSISCOM_PERFORMOP
+ * @reasoncode FSISCOM::RC_INVALID_ADDRESS
+ * @userdata1 SCOM Address
+ * @userdata2 0
+ * @devdesc FSISCOM: fsiScomPerformOp> Address contains more than 31 bits.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ FSISCOM::MOD_FSISCOM_PERFORMOP,
+ FSISCOM::RC_INVALID_ADDRESS,
+ l_scomAddr,
+ 0);
+ //@fixme: Need to callout target somehow. Need to decide how to callout target and where
+ // it should be done (this layer or somewhere higher in the call stack?)
+ break;
+ }
+
+ l_command = static_cast<uint32_t>(l_scomAddr & 0x000000007FFFFFFF);
+
+
+ if(i_opType == DeviceFW::WRITE)
+ {
+ memcpy(&(scratchData.data64), io_buffer, 8);
+
+ TRACUCOMP( g_trac_fsiscom, "fsiScomPerformOp> Write(l_scomAddr=0x%X, l_data0=0x%X, l_data1=0x%X)", l_scomAddr, scratchData.data32_0, scratchData.data32_1);
+
+
+ // atomic section >>
+ mutex_lock(&g_fsiScomMutex);
+ need_unlock = true;
+
+
+ //write bits 0-31 to data0
+ l_err = DeviceFW::deviceOp( DeviceFW::WRITE,
+ i_target,
+ &scratchData.data32_0,
+ op_size,
+ DEVICE_FSI_ADDRESS(DATA0_REG));
+ if(l_err)
+ {
+ break;
+ }
+
+ //write bits 32-63 to data1
+ l_err = DeviceFW::deviceOp( DeviceFW::WRITE,
+ i_target,
+ &scratchData.data32_1,
+ op_size,
+ DEVICE_FSI_ADDRESS(DATA1_REG));
+ if(l_err)
+ {
+ break;
+ }
+
+ //write to FSI2PIB command reg starts write operation
+ //bit 0 high => write command
+ l_command = 0x80000000 | l_command;
+ l_err = DeviceFW::deviceOp( DeviceFW::WRITE,
+ i_target,
+ &l_command,
+ op_size,
+ DEVICE_FSI_ADDRESS(COMMAND_REG));
+ if(l_err)
+ {
+ break;
+ }
+
+ //check status reg to see result
+ l_err = DeviceFW::deviceOp( DeviceFW::READ,
+ i_target,
+ &l_status,
+ op_size,
+ DEVICE_FSI_ADDRESS(STATUS_REG));
+ if(l_err)
+ {
+ break;
+ }
+
+ // atomic section <<
+ need_unlock = false;
+ mutex_unlock(&g_fsiScomMutex);
+
+ //bits 17-19 indicates PCB/PIB error
+ if(l_status & 0x00007000)
+ {
+ TRACFCOMP( g_trac_fsiscom, ERR_MRK"fsiScomPerformOp:Write: PCB/PIB error received: l_status=0x%X)", l_status);
+ /*@
+ * @errortype
+ * @moduleid FSISCOM::MOD_FSISCOM_PERFORMOP
+ * @reasoncode FSISCOM::RC_WRITE_ERROR
+ * @userdata1 SCOM Addr
+ * @userdata2 SCOM Status Reg
+ * @devdesc fsiScomPerformOp> Error returned from SCOM Engine after write
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ FSISCOM::MOD_FSISCOM_PERFORMOP,
+ FSISCOM::RC_WRITE_ERROR,
+ l_scomAddr,
+ TO_UINT64(l_status));
+
+ //@fixme: Need to callout target somehow. Need to decide how to callout target and where
+ // it should be done (this layer or somewhere higher in the call stack?)
+ //@todo: May add recover actions later. Currently undefined
+
+ break;
+ }
+
+
+
+ }
+ else if(i_opType == DeviceFW::READ)
+ {
+ TRACUCOMP( g_trac_fsiscom, "fsiScomPerformOp: Read(l_scomAddr=0x%.8X)", l_scomAddr);
+
+ // atomic section >>
+ mutex_lock(&g_fsiScomMutex);
+ need_unlock = true;
+
+
+ //write to FSI2PIB command reg starts read operation
+ // bit 0 low -> read command
+ l_err = DeviceFW::deviceOp( DeviceFW::WRITE,
+ i_target,
+ &l_command,
+ op_size,
+ DEVICE_FSI_ADDRESS(COMMAND_REG));
+ if(l_err)
+ {
+ break;
+ }
+
+ //check ststus reg to see result
+ l_err = DeviceFW::deviceOp( DeviceFW::READ,
+ i_target,
+ &l_status,
+ op_size,
+ DEVICE_FSI_ADDRESS(STATUS_REG));
+ if(l_err)
+ {
+ break;
+ }
+
+ //bits 17-19 indicates PCB/PIB error
+ if((l_status & 0x00007000) != 0)
+ {
+ TRACFCOMP( g_trac_fsiscom, ERR_MRK"fsiScomPerformOp:Read: PCB/PIB error received: l_status=0x%.8X)", l_status);
+
+ /*@
+ * @errortype
+ * @moduleid FSISCOM::MOD_FSISCOM_PERFORMOP
+ * @reasoncode FSISCOM::RC_READ_ERROR
+ * @userdata1 SCOM Addr
+ * @userdata2 SCOM Status Reg
+ * @devdesc fsiScomPerformOp> Error returned from SCOM Engine after read.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ FSISCOM::MOD_FSISCOM_PERFORMOP,
+ FSISCOM::RC_READ_ERROR,
+ l_scomAddr,
+ TO_UINT64(l_status));
+
+ //@fixme: Need to callout target somehow. Need to decide how to callout target and where
+ // it should be done (this layer or somewhere higher in the call stack?)
+ //@todo: May add recover actions later. Currently undefined
+ break;
+ }
+
+ //read bits 0-31 to data0
+ l_err = DeviceFW::deviceOp( DeviceFW::READ,
+ i_target,
+ &scratchData.data32_0,
+ op_size,
+ DEVICE_FSI_ADDRESS(DATA0_REG));
+ if(l_err)
+ {
+ break;
+ }
+
+ //read bits 32-63 to data1
+ l_err = DeviceFW::deviceOp( DeviceFW::READ,
+ i_target,
+ &scratchData.data32_1,
+ op_size,
+ DEVICE_FSI_ADDRESS(DATA1_REG));
+ if(l_err)
+ {
+ break;
+ }
+
+ // atomic section <<
+ need_unlock = false;
+ mutex_unlock(&g_fsiScomMutex);
+
+ TRACUCOMP( g_trac_fsiscom, "fsiScomPerformOp: Read: l_scomAddr=0x%X, l_data0=0x%X, l_data1=0x%X", l_scomAddr, scratchData.data32_0, scratchData.data32_1);
+
+ memcpy(io_buffer, &(scratchData.data64), 8);
+ }
+ else
+ {
+ TRACFCOMP( g_trac_fsiscom, ERR_MRK"fsiScomPerformOp:Read: PCB/PIB error received: l_status=0x%.8X)", l_status);
+
+ /*@
+ * @errortype
+ * @moduleid FSISCOM::MOD_FSISCOM_PERFORMOP
+ * @reasoncode FSISCOM::RC_READ_ERROR
+ * @userdata1 Operation Type (i_opType) : 0=READ, 1=WRITE
+ * @userdata2 0
+ * @devdesc fsiScomPerformOp> Unsupported Operation Type specified
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ FSISCOM::MOD_FSISCOM_PERFORMOP,
+ FSISCOM::RC_READ_ERROR,
+ TO_UINT64(i_opType),
+ 0);
+
+ //@fixme: Need to callout target somehow. Need to decide how to callout target and where
+ // it should be done (this layer or somewhere higher in the call stack?)
+ break;
+
+ }
+
+ }while(0);
+
+ if( need_unlock )
+ {
+ mutex_unlock(&g_fsiScomMutex);
+ }
+
+
+ return l_err;
+
+}
+
+// Register SCom access functions to DD framework
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::FSISCOM,
+ TARGETING::TYPE_PROC,
+ fsiScomPerformOp);
+
+
+} // end namespace
diff --git a/src/usr/fsiscom/fsiscom.H b/src/usr/fsiscom/fsiscom.H
new file mode 100644
index 000000000..62ed12f27
--- /dev/null
+++ b/src/usr/fsiscom/fsiscom.H
@@ -0,0 +1,78 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/fsiscom/fsiscom.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 __FSISCOM_H
+#define __FSISCOM_H
+
+/** @file fsiscom.H
+ * @brief Provides the interfaces to perform a FSI SCOM
+ */
+
+namespace FSISCOM
+{
+
+ enum {
+ //FSI addresses are byte offsets, so need to multiply by 4 since each register is 4 bytes long.
+ //prefix with 0x10xx for engine offset
+ DATA0_REG = 0x1000, /* SCOM Data Register 0 (0x00) */
+ DATA1_REG = 0x1004, /* SCOM Data Register 1 (0x01) */
+ COMMAND_REG = 0x1008, /* SCOM Command Register (0x02) */
+ STATUS_REG = 0x101C, /* STATUS Register (0x07) */
+ };
+
+/**
+ * @brief Performs an FSI SCOM operation
+ * This function performs an SCom Read/Write operation. It follows a
+ * pre-defined prototype functions in order to be registered with the
+ * device-driver framework.
+ *
+ * @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.
+ *
+ * @return errlHndl_t
+ */
+errlHndl_t fsiScomPerformOp(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args);
+
+
+
+
+
+
+}; // End namespace
+
+#endif
diff --git a/src/usr/fsiscom/makefile b/src/usr/fsiscom/makefile
new file mode 100644
index 000000000..56402b30f
--- /dev/null
+++ b/src/usr/fsiscom/makefile
@@ -0,0 +1,30 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/fsiscom/makefile $
+#
+# 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
+ROOTPATH = ../../..
+MODULE = fsiscom
+
+OBJS = fsiscom.o
+
+SUBDIRS = test.d
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/fsiscom/test/fsiscomtest.H b/src/usr/fsiscom/test/fsiscomtest.H
new file mode 100644
index 000000000..76afb9a18
--- /dev/null
+++ b/src/usr/fsiscom/test/fsiscomtest.H
@@ -0,0 +1,44 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/fsiscom/test/fsiscomtest.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
+#include <cxxtest/TestSuite.H>
+#include <errl/errlmanager.H>
+#include <errl/errlentry.H>
+#include <errl/errltypes.H>
+#include <limits.h>
+#include <devicefw/driverif.H>
+
+
+class FsiScomTest : public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief test1
+ */
+ void test_fsiScom(void)
+ {
+
+ //FSISCOM testing driving by SCOM device driver. This allows for testing FSISCOM <-> XSCOM
+ //coherency.
+ };
+};
diff --git a/src/usr/fsiscom/test/makefile b/src/usr/fsiscom/test/makefile
new file mode 100644
index 000000000..b6c001ea8
--- /dev/null
+++ b/src/usr/fsiscom/test/makefile
@@ -0,0 +1,29 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/fsiscom/test/makefile $
+#
+# 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
+ROOTPATH = ../../../..
+
+#MODULE = testfsiscom Disabled as we don't currently have any tests defined.
+#TESTS = *.H
+
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/initservice/extinitsvc/extinitsvctasks.H b/src/usr/initservice/extinitsvc/extinitsvctasks.H
index 859e3caee..761295319 100644
--- a/src/usr/initservice/extinitsvc/extinitsvctasks.H
+++ b/src/usr/initservice/extinitsvc/extinitsvctasks.H
@@ -133,6 +133,32 @@ const TaskInfo g_exttaskinfolist[] = {
}
},
+ /**
+ * @brief FSI Device Driver
+ */
+ {
+ "libfsi.so" , // taskname
+ NULL, // no pointer to fn
+ {
+ INIT_TASK, // task type
+ EXT_IMAGE, // Extended Module
+ START_FSIDD_ERRL_ID, // module id
+ }
+ },
+
+ /**
+ * @brief FSI Device Driver
+ */
+ {
+ "libfsiscom.so" , // taskname
+ NULL, // no pointer to fn
+ {
+ INIT_TASK, // task type
+ EXT_IMAGE, // Extended Module
+ START_FSISCOM_ERRL_ID, // module id
+ }
+ },
+
// ---------------------------------------------------------------
// ----- END OF LIST!!! ---------------------------------------
diff --git a/src/usr/makefile b/src/usr/makefile
index 47e8e2d69..10c88e94f 100644
--- a/src/usr/makefile
+++ b/src/usr/makefile
@@ -25,7 +25,7 @@ ROOTPATH = ../..
OBJS = module_init.o
SUBDIRS = example.d trace.d cxxtest.d testcore.d errl.d devicefw.d \
- scom.d xscom.d targeting.d initservice.d hwpf.d \
- ecmddatabuffer.d pnor.d i2c.d vfs.d fsi.d hwas.d
+ scom.d xscom.d targeting.d initservice.d hwpf.d \
+ ecmddatabuffer.d pnor.d i2c.d vfs.d fsi.d hwas.d fsiscom.d
include ${ROOTPATH}/config.mk
diff --git a/src/usr/scom/scom.C b/src/usr/scom/scom.C
index 9e67a40af..895724d4d 100644
--- a/src/usr/scom/scom.C
+++ b/src/usr/scom/scom.C
@@ -29,16 +29,22 @@
/*****************************************************************************/
// 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"
+// Trace definition
+trace_desc_t* g_trac_scom = NULL;
+TRAC_INIT(&g_trac_scom, "SCOM", 1024); //1K
+
+
namespace SCOM
{
-// Register SCom access functions to DD framework
+// Register Scom access functions to DD framework
DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
DeviceFW::SCOM,
TARGETING::TYPE_PROC,
@@ -55,14 +61,40 @@ errlHndl_t scomPerformOp(DeviceFW::OperationType i_opType,
{
errlHndl_t l_err = NULL;
- //@todo - For now, just call XSCOM
- l_err = deviceOp(i_opType,
- i_target,
- io_buffer,
- io_buflen,
- DEVICE_XSCOM_ADDRESS(va_arg(i_args,uint64_t)));
+ do{
+ //Always XSCOM the Master Sentinel
+ if((TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL == i_target) ||
+ (i_target->getAttr<TARGETING::ATTR_SCOM_SWITCHES>().useXscom))
+ { //do XSCOM
+
+ l_err = deviceOp(i_opType,
+ i_target,
+ io_buffer,
+ io_buflen,
+ DEVICE_XSCOM_ADDRESS(va_arg(i_args,uint64_t)));
+ break;
+ }
+ else if(i_target->getAttr<TARGETING::ATTR_SCOM_SWITCHES>().useFsiScom)
+ { //do FSISCOM
+ l_err = deviceOp(i_opType,
+ i_target,
+ io_buffer,
+ io_buflen,
+ DEVICE_FSISCOM_ADDRESS(va_arg(i_args,uint64_t)));
+ if( l_err ) { break; }
+ }
+ else
+ {
+ //@todo - add target info to assert trace
+ assert(0,"SCOM::scomPerformOp> ATTR_SCOM_SWITCHES does not indicate Xscom or FSISCOM is supported");
+ break;
+ }
+
+ }while(0);
return l_err;
}
+
+
} // end namespace
diff --git a/src/usr/scom/scom.H b/src/usr/scom/scom.H
index ba04cb9d4..d91eb41ee 100644
--- a/src/usr/scom/scom.H
+++ b/src/usr/scom/scom.H
@@ -23,6 +23,8 @@
#ifndef __SCOM_H
#define __SCOM_H
+#include <devicefw/driverif.H>
+
/** @file scom.H
* @brief Provides the interfaces to perform a SCom
*/
@@ -30,6 +32,7 @@
namespace SCOM
{
+
/**
* @brief Performs an SCom operation
* This function performs an SCom Read/Write operation. It follows a
@@ -58,6 +61,9 @@ errlHndl_t scomPerformOp(DeviceFW::OperationType i_opType,
size_t& io_buflen,
int64_t i_accessType,
va_list i_args);
+
+
+
}; // End namespace
#endif
diff --git a/src/usr/scom/test/scomtest.H b/src/usr/scom/test/scomtest.H
index 418e2cf72..46000c136 100644
--- a/src/usr/scom/test/scomtest.H
+++ b/src/usr/scom/test/scomtest.H
@@ -34,19 +34,125 @@
#include <errl/errlentry.H>
#include <errl/errltypes.H>
#include <devicefw/userif.H>
+#include <fsi/fsiif.H>
+
+
+
+extern trace_desc_t* g_trac_scom;
+
class ScomTest: public CxxTest::TestSuite
{
public:
/**
- * @brief SCOM test #1
- * TBD
+ * @brief SCOM test via FSISCOM
+ *
*/
- void testScom1(void)
+ void test_FSISCOMreadWrite(void)
{
- return;
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test_FSISCOMreadWrite> Start" );
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test_FSISCOMreadWrite> Disabled due to simics stability issues" );
+ return; //@todo - enable when simics is stable
+
+ uint64_t fails = 0;
+ uint64_t total = 0;
+ errlHndl_t l_err = NULL;
+
+ //make sure the FSI hardware is initailized (ordering of test cases is not currently guaranteed)
+ l_err = FSI::initializeHardware();
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_FSISCOMreadWrite> FSI::initializeHardware failed, RC=0x%X", l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_FSISCOMreadWrite> FsiDD::initializeHardware failed, aborting test case." );
+ errlCommit(l_err);
+ return;
+ }
+
+
+ TARGETING::Target* fsi_target = NULL;
+
+ // Target Proc 1 - the FSI wrap-back connection in simics
+ 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);
+ fsi_target = 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 {
+ uint64_t addr;
+ uint64_t data;
+ } test_data[] = {
+ { 0x120F0000 ,0xFEEDB0B000001234},
+ { 0x120F0166, 0xFEDCBA9876543210},
+ { 0x00040005, 0x0000000000000000},
+ { 0x02040004, 0xFFFFFFFFFFFFFFFF},
+
+ };
+ 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++ )
+ {
+ op_size = sizeof(uint64_t);
+
+ total++;
+ l_err = deviceWrite( fsi_target,
+ &(test_data[x].data),
+ op_size,
+ DEVICE_SCOM_ADDRESS(test_data[x].addr) );
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_FSISCOMreadWrite> Write: Error from device : addr=0x%X, RC=%X", test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_FSISCOMreadWrite> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err);
+ delete l_err;
+ }
+ }
+
+ // read all the test registers
+ for( uint64_t x = 0; x < NUM_ADDRS; x++ )
+ {
+ op_size = sizeof(uint64_t);
+
+ total++;
+ l_err = deviceRead( fsi_target,
+ &(read_data[x]),
+ op_size,
+ DEVICE_SCOM_ADDRESS(test_data[x].addr) );
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_FSISCOMreadWrite> read: Error from device : addr=0x%X, RC=%X", test_data[x].addr, l_err->reasonCode() );
+ TS_FAIL( "ScomTest::test_FSISCOMreadWrite> ERROR : Unexpected error log from write1" );
+ fails++;
+ errlCommit(l_err);
+ delete l_err;
+ }
+ else if(read_data[x] != test_data[x].data)
+ {
+ TRACFCOMP(g_trac_scom, "ScomTest::test_FSISCOMreadWrite> read: Data miss-match : addr=0x%X, read_data=0x%llx, write_data=0x%llx", test_data[x].addr, read_data[x], test_data[x].data);
+ TS_FAIL( "ScomTest::test_FSISCOMreadWrite> ERROR : Data miss-match between read and expected data" );
+ fails++;
+ }
+ }
+
+ TRACFCOMP( g_trac_scom, "ScomTest::test_FSISCOMreadWrite> %d/%d fails", fails, total );
+
}
+
+
+ //@todo - write tests to verify connection between XSCOM and FSISCOM
+
};
#endif
OpenPOWER on IntegriCloud