From 7344f3b265fe12da99ad0a032e558e7cc7fe1cb2 Mon Sep 17 00:00:00 2001 From: Adam Muhle Date: Thu, 13 Oct 2011 14:44:55 -0500 Subject: 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 Tested-by: Jenkins Server --- src/usr/fsiscom/fsiscom.C | 347 +++++++++++++++++++++++++++++++++++++ src/usr/fsiscom/fsiscom.H | 78 +++++++++ src/usr/fsiscom/makefile | 30 ++++ src/usr/fsiscom/test/fsiscomtest.H | 44 +++++ src/usr/fsiscom/test/makefile | 29 ++++ 5 files changed, 528 insertions(+) create mode 100644 src/usr/fsiscom/fsiscom.C create mode 100644 src/usr/fsiscom/fsiscom.H create mode 100644 src/usr/fsiscom/makefile create mode 100644 src/usr/fsiscom/test/fsiscomtest.H create mode 100644 src/usr/fsiscom/test/makefile (limited to 'src/usr/fsiscom') 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 +#include +#include +#include +#include +#include +#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(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 +#include +#include +#include +#include +#include + + +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 -- cgit v1.2.1