summaryrefslogtreecommitdiffstats
path: root/src/usr/fsiscom
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/fsiscom
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/fsiscom')
-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
5 files changed, 528 insertions, 0 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
OpenPOWER on IntegriCloud