diff options
author | Adam Muhle <armuhle@us.ibm.com> | 2011-10-13 14:44:55 -0500 |
---|---|---|
committer | ADAM R. MUHLE <armuhle@us.ibm.com> | 2011-10-25 15:17:19 -0500 |
commit | 7344f3b265fe12da99ad0a032e558e7cc7fe1cb2 (patch) | |
tree | ff7bd2d0d9ac139e63a0f8bda778e3dac1b290f8 /src/usr | |
parent | 0ad20184aec21ef0560a9eee7e7c26a36ace07e1 (diff) | |
download | talos-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.C | 347 | ||||
-rw-r--r-- | src/usr/fsiscom/fsiscom.H | 78 | ||||
-rw-r--r-- | src/usr/fsiscom/makefile | 30 | ||||
-rw-r--r-- | src/usr/fsiscom/test/fsiscomtest.H | 44 | ||||
-rw-r--r-- | src/usr/fsiscom/test/makefile | 29 | ||||
-rw-r--r-- | src/usr/initservice/extinitsvc/extinitsvctasks.H | 26 | ||||
-rw-r--r-- | src/usr/makefile | 4 | ||||
-rw-r--r-- | src/usr/scom/scom.C | 46 | ||||
-rw-r--r-- | src/usr/scom/scom.H | 6 | ||||
-rw-r--r-- | src/usr/scom/test/scomtest.H | 114 |
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 |