summaryrefslogtreecommitdiffstats
path: root/src/usr/fsi
diff options
context:
space:
mode:
authorElizabeth Liner <eliner@us.ibm.com>2016-09-27 09:51:33 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-02-16 09:27:03 -0500
commit3b69a19abe72dffb47c5d088dc98d963d89f94e8 (patch)
tree1eba860231d445d236b5ea343644751291782b13 /src/usr/fsi
parenta7304a5938ed39e09913ee2b6c085119bc7cb0b0 (diff)
downloadtalos-hostboot-3b69a19abe72dffb47c5d088dc98d963d89f94e8.tar.gz
talos-hostboot-3b69a19abe72dffb47c5d088dc98d963d89f94e8.zip
Adding FSI and PNOR interfaces for PRD FIRDATA in HBRT
Change-Id: I515a328e50536d92f0ab80229cd8d939f89412c7 RTC:127358 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35008 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/fsi')
-rw-r--r--src/usr/fsi/errlud_fsi.C7
-rw-r--r--src/usr/fsi/fsi_common.C65
-rw-r--r--src/usr/fsi/fsi_common.H155
-rw-r--r--src/usr/fsi/fsidd.C167
-rw-r--r--src/usr/fsi/fsidd.H154
-rw-r--r--src/usr/fsi/makefile6
-rw-r--r--src/usr/fsi/runtime/makefile35
-rw-r--r--src/usr/fsi/runtime/rt_fsi.C476
-rw-r--r--src/usr/fsi/runtime/rt_fsi.H118
9 files changed, 944 insertions, 239 deletions
diff --git a/src/usr/fsi/errlud_fsi.C b/src/usr/fsi/errlud_fsi.C
index c9647e444..f00530d22 100644
--- a/src/usr/fsi/errlud_fsi.C
+++ b/src/usr/fsi/errlud_fsi.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2013,2014 */
+/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -29,6 +31,7 @@
#include <fsi/fsi_reasoncodes.H>
#include <string.h>
#include "fsidd.H"
+#include "fsi_common.H"
namespace FSI
{
@@ -44,7 +47,7 @@ UdPresence::UdPresence( TARGETING::Target* i_target )
iv_SubSection = FSI_UDT_PRESENCE;
FsiDD& fsidd = Singleton<FsiDD>::instance();
- FsiDD::FsiChipInfo_t l_chip_info = fsidd.getFsiInfo(i_target);
+ FSI::FsiChipInfo_t l_chip_info = fsidd.getFsiInfo(i_target);
uint64_t l_slaveIndex = fsidd.getSlaveEnableIndex(l_chip_info.master,
l_chip_info.type);
diff --git a/src/usr/fsi/fsi_common.C b/src/usr/fsi/fsi_common.C
new file mode 100644
index 000000000..ca4f5c5a7
--- /dev/null
+++ b/src/usr/fsi/fsi_common.C
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/fsi/fsi_common.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "fsi_common.H"
+#include <fsi/fsiif.H>
+
+/**
+ * @brief Convert a type/port pair into a FSI address offset
+ */
+uint64_t FSI::getPortOffset(TARGETING::FSI_MASTER_TYPE i_type,
+ uint8_t i_port)
+{
+ uint64_t offset = 0;
+ if( TARGETING::FSI_MASTER_TYPE_MFSI == i_type )
+ {
+ switch(i_port)
+ {
+ case(0): offset = FSI::MFSI_PORT_0; break;
+ case(1): offset = FSI::MFSI_PORT_1; break;
+ case(2): offset = FSI::MFSI_PORT_2; break;
+ case(3): offset = FSI::MFSI_PORT_3; break;
+ case(4): offset = FSI::MFSI_PORT_4; break;
+ case(5): offset = FSI::MFSI_PORT_5; break;
+ case(6): offset = FSI::MFSI_PORT_6; break;
+ case(7): offset = FSI::MFSI_PORT_7; break;
+ }
+ }
+ else if( TARGETING::FSI_MASTER_TYPE_CMFSI == i_type )
+ {
+ switch(i_port)
+ {
+ case(0): offset = FSI::CMFSI_PORT_0; break;
+ case(1): offset = FSI::CMFSI_PORT_1; break;
+ case(2): offset = FSI::CMFSI_PORT_2; break;
+ case(3): offset = FSI::CMFSI_PORT_3; break;
+ case(4): offset = FSI::CMFSI_PORT_4; break;
+ case(5): offset = FSI::CMFSI_PORT_5; break;
+ case(6): offset = FSI::CMFSI_PORT_6; break;
+ case(7): offset = FSI::CMFSI_PORT_7; break;
+ }
+ }
+
+ return offset;
+}
diff --git a/src/usr/fsi/fsi_common.H b/src/usr/fsi/fsi_common.H
new file mode 100644
index 000000000..302cea570
--- /dev/null
+++ b/src/usr/fsi/fsi_common.H
@@ -0,0 +1,155 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/fsi/fsi_common.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef FSI_COMMON_H
+#define FSI_COMMON_H
+
+#include <fsi/fsiif.H>
+
+namespace FSI{
+
+ /**
+ * FSI Address Space
+ */
+ enum FsiAddressSpace {
+ // Master control registers
+ CMFSI_CONTROL_REG = 0x003000, /**< cMFSI Control Register */
+ MFSI_CONTROL_REG = 0x003400, /**< MFSI Control Register */
+
+ // cMFSI Ports (32KB each)
+ CMFSI_PORT_0 = 0x040000, /**< cMFSI port 0 */
+ CMFSI_PORT_1 = 0x048000, /**< cMFSI port 1 */
+ CMFSI_PORT_2 = 0x050000, /**< cMFSI port 2 */
+ CMFSI_PORT_3 = 0x058000, /**< cMFSI port 3 */
+ CMFSI_PORT_4 = 0x060000, /**< cMFSI port 4 */
+ CMFSI_PORT_5 = 0x068000, /**< cMFSI port 5 */
+ CMFSI_PORT_6 = 0x070000, /**< cMFSI port 6 */
+ CMFSI_PORT_7 = 0x078000, /**< cMFSI port 7 */
+ CMFSI_PORT_MASK = 0x078000,
+ /**< Mask to look for a valid cMFSI port */
+
+ // Offsets to cascaded slaves within a cMFSI port
+ CMFSI_SLAVE_0 = 0x000000, /**< cMFSI - Slave 0 */
+ CMFSI_SLAVE_1 = 0x002000, /**< cMFSI - Slave 1 */
+ CMFSI_SLAVE_2 = 0x004000, /**< cMFSI - Slave 2 */
+ CMFSI_SLAVE_3 = 0x006000, /**< cMFSI - Slave 3 */
+
+ // MFSI Ports (512KB each)
+ MFSI_PORT_LOCAL = 0x000000, /**< Local master (for local cMFSI) */
+ MFSI_PORT_0 = 0x080000, /**< MFSI port 0 */
+ MFSI_PORT_1 = 0x100000, /**< MFSI port 1 */
+ MFSI_PORT_2 = 0x180000, /**< MFSI port 2 */
+ MFSI_PORT_3 = 0x200000, /**< MFSI port 3 */
+ MFSI_PORT_4 = 0x280000, /**< MFSI port 4 */
+ MFSI_PORT_5 = 0x300000, /**< MFSI port 5 */
+ MFSI_PORT_6 = 0x380000, /**< MFSI port 6 */
+ MFSI_PORT_7 = 0x400000, /**< MFSI port 7 */
+ MFSI_PORT_MASK = 0x780000,
+ /**< Mask to look for a valid MFSI port */
+
+ // Offsets to cascaded slaves within a MFSI port
+ MFSI_SLAVE_0 = 0x000000, /**< MFSI - Slave 0 */
+ MFSI_SLAVE_1 = 0x020000, /**< MFSI - Slave 1 */
+ MFSI_SLAVE_2 = 0x040000, /**< MFSI - Slave 2 */
+ MFSI_SLAVE_3 = 0x060000, /**< MFSI - Slave 3 */
+ };
+
+ /**
+ * Common id to identify a FSI position to use in error logs and traces
+ */
+ union FsiLinkId_t
+ {
+ uint32_t id;
+ struct
+ {
+ uint8_t node; ///< Physical Node of FSI Master processor
+ uint8_t proc; ///< Physical Position of FSI Master processor
+ uint8_t type; ///< FSI Master type (FSI_MASTER_TYPE)
+ uint8_t port; ///< Slave link/port number
+ };
+ };
+
+ /**
+ * @brief Structure which defines info necessary to access a chip via FSI
+ */
+ struct FsiChipInfo_t
+ {
+ TARGETING::Target* slave; //< FSI Slave chip
+ TARGETING::Target* master; ///< FSI Master
+ TARGETING::FSI_MASTER_TYPE type; ///< Master or Cascaded Master
+ uint8_t port; ///< Which port is this chip hanging off of
+ uint8_t cascade; ///< Slave cascade position
+ union {
+ TARGETING::FsiOptionFlags flagbits; ///< Special flags
+ uint16_t flags; ///< Special flags
+ };
+ FsiLinkId_t linkid; ///< Id for traces and error logs
+
+ FsiChipInfo_t() :
+ slave(NULL), master(NULL),
+ type(TARGETING::FSI_MASTER_TYPE_NO_MASTER),
+ port(UINT8_MAX), cascade(0), flags(0)
+ { linkid.id = 0; };
+ };
+
+ /**
+ * @brief Holds a set of addressing information to describe the
+ * current FSI operation
+ */
+ struct FsiAddrInfo_t {
+ TARGETING::Target* fsiTarg; ///< Target of FSI operation
+ TARGETING::Target* opbTarg; ///< OPB control reg target
+ uint32_t relAddr; ///< Input FSI address (relative to fsiTarg)
+ uint32_t absAddr; ///< Absolute FSI address (relative to opbTarg)
+ FsiChipInfo_t accessInfo; ///< FSI Access Info
+
+ /** Input Arg Constructor */
+ FsiAddrInfo_t( TARGETING::Target* i_target,
+ uint64_t i_address ) :
+ fsiTarg(i_target), opbTarg(NULL),
+ relAddr(i_address), absAddr(UINT32_MAX)
+ {};
+
+ private:
+ /** Default Constructor is not allowed */
+ FsiAddrInfo_t() :
+ fsiTarg(NULL), opbTarg(NULL),
+ relAddr(UINT32_MAX),absAddr(UINT32_MAX)
+ {};
+ };
+
+ /**
+ * @brief Convert a type/port pair into a FSI address offset
+ *
+ * @param[in] i_type Type of FSI interface
+ * @param[in] i_port FSI link number
+ * @return uint64_t FSI address offset
+ */
+ uint64_t getPortOffset(TARGETING::FSI_MASTER_TYPE i_type,
+ uint8_t i_port);
+}
+
+
+
+#endif
diff --git a/src/usr/fsi/fsidd.C b/src/usr/fsi/fsidd.C
index db2811f82..9f651f173 100644
--- a/src/usr/fsi/fsidd.C
+++ b/src/usr/fsi/fsidd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2016 */
+/* Contributors Listed Below - COPYRIGHT 2011,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -387,7 +387,7 @@ errlHndl_t FsiDD::read(TARGETING::Target* i_target,
}
// prefix the appropriate MFSI/cMFSI slave port offset
- FsiAddrInfo_t addr_info( i_target, i_address );
+ FSI::FsiAddrInfo_t addr_info( i_target, i_address );
l_err = genFullFsiAddr( addr_info );
if(l_err)
{
@@ -429,7 +429,7 @@ errlHndl_t FsiDD::write(TARGETING::Target* i_target,
}
// prefix the appropriate MFSI/cMFSI slave port offset
- FsiAddrInfo_t addr_info( i_target, i_address );
+ FSI::FsiAddrInfo_t addr_info( i_target, i_address );
l_err = genFullFsiAddr( addr_info );
if(l_err)
{
@@ -503,7 +503,7 @@ errlHndl_t FsiDD::initializeHardware()
typedef struct {
TARGETING::Target* targ;
- FsiDD::FsiChipInfo_t info;
+ FSI::FsiChipInfo_t info;
} target_chipInfo_t ;
// list of ports off of local MFSI
@@ -518,7 +518,7 @@ errlHndl_t FsiDD::initializeHardware()
target_chipInfo_t remote_cmfsi[MAX_SLAVE_PORTS][MAX_SLAVE_PORTS]; // = {};
memset(remote_cmfsi, '\0', sizeof(remote_cmfsi)); // TODO: GCC ICE.
- FsiChipInfo_t info;
+ FSI::FsiChipInfo_t info;
// loop through every CHIP target
TARGETING::PredicateCTM l_chipClass(TARGETING::CLASS_CHIP,
@@ -549,7 +549,7 @@ errlHndl_t FsiDD::initializeHardware()
}
else
{
- FsiChipInfo_t info2 = getFsiInfo(info.master);
+ FSI::FsiChipInfo_t info2 = getFsiInfo(info.master);
if( info2.master == NULL )
{
TRACFCOMP( g_trac_fsi, "Problem with attribute data for master %.8X for slave %.8X", TARGETING::get_huid(info.master), TARGETING::get_huid(*t_itr) );
@@ -771,7 +771,7 @@ void FsiDD::getFsiFFDC(FSI::fsiFFDCType_t i_ffdc_type,
errlHndl_t tmp_err = NULL;
// Use this call to find the OPB Master to read
- FsiAddrInfo_t addr_info( i_target, 0x12345678 );
+ FSI::FsiAddrInfo_t addr_info( i_target, 0x12345678 );
tmp_err = genFullFsiAddr( addr_info );
if( tmp_err )
{
@@ -835,7 +835,7 @@ void FsiDD::getFsiFFDC(FSI::fsiFFDCType_t i_ffdc_type,
else if( FSI::FFDC_PIB_FAIL == i_ffdc_type )
{
errlHndl_t tmp_err = NULL;
- FsiChipInfo_t fsi_info = getFsiInfo( i_target );
+ FSI::FsiChipInfo_t fsi_info = getFsiInfo( i_target );
// Grab the FSI GP regs since they have fencing information
ERRORLOG::ErrlUserDetailsLogRegister regdata2(i_target);
@@ -912,7 +912,7 @@ void FsiDD::getFsiFFDC(FSI::fsiFFDCType_t i_ffdc_type,
{
errlHndl_t tmp_err = NULL;
// Find the OPB Master and then collect FFDC_OPB_FAIL
- FsiAddrInfo_t addr_info( i_target, 0x12345678 );
+ FSI::FsiAddrInfo_t addr_info( i_target, 0x12345678 );
tmp_err = genFullFsiAddr( addr_info );
if( tmp_err )
{
@@ -1036,7 +1036,7 @@ FsiDD::FsiDD()
TRACFCOMP(g_trac_fsi,"Master=%.8X",TARGETING::get_huid(iv_master));
// add a dummy value to catch NULL
- FsiChipInfo_t info;
+ FSI::FsiChipInfo_t info;
iv_fsiInfoMap[NULL] = info;
mutex_init(&iv_dataMutex);
@@ -1063,7 +1063,7 @@ errlHndl_t FsiDD::read(uint64_t i_address,
// generate a set of address info for this manual operation
// note that relAddr==absAddr in this case
- FsiAddrInfo_t addr_info( iv_master, i_address );
+ FSI::FsiAddrInfo_t addr_info( iv_master, i_address );
addr_info.opbTarg = iv_master;
addr_info.absAddr = i_address;
@@ -1086,7 +1086,7 @@ errlHndl_t FsiDD::write(uint64_t i_address,
// generate a set of address info for this manual operation
// note that relAddr==absAddr in this case
- FsiAddrInfo_t addr_info( iv_master, i_address );
+ FSI::FsiAddrInfo_t addr_info( iv_master, i_address );
addr_info.opbTarg = iv_master;
addr_info.absAddr = i_address;
@@ -1100,7 +1100,7 @@ errlHndl_t FsiDD::write(uint64_t i_address,
/**
* @brief Performs an FSI Read Operation
*/
-errlHndl_t FsiDD::read(FsiAddrInfo_t& i_addrInfo,
+errlHndl_t FsiDD::read(FSI::FsiAddrInfo_t& i_addrInfo,
uint32_t* o_buffer,
uint64_t i_buflen )
{
@@ -1202,7 +1202,7 @@ errlHndl_t FsiDD::read(FsiAddrInfo_t& i_addrInfo,
/**
* @brief Write FSI Register
*/
-errlHndl_t FsiDD::write(FsiAddrInfo_t& i_addrInfo,
+errlHndl_t FsiDD::write(FSI::FsiAddrInfo_t& i_addrInfo,
uint32_t* i_buffer,
uint64_t i_buflen )
{
@@ -1308,7 +1308,7 @@ errlHndl_t FsiDD::write(FsiAddrInfo_t& i_addrInfo,
/**
* @brief Analyze error bits and recover hardware as needed
*/
-errlHndl_t FsiDD::handleOpbErrors(FsiAddrInfo_t& i_addrInfo,
+errlHndl_t FsiDD::handleOpbErrors(FSI::FsiAddrInfo_t& i_addrInfo,
uint32_t i_opbStatAddr,
uint32_t i_opbStatData)
{
@@ -1385,10 +1385,10 @@ errlHndl_t FsiDD::handleOpbErrors(FsiAddrInfo_t& i_addrInfo,
if( (l_opb_stat & OPB_STAT_ERRACK)
&& (
((i_addrInfo.relAddr & ~FSI_CTLREG_MASK)
- == MFSI_CONTROL_REG)
+ == FSI::MFSI_CONTROL_REG)
||
((i_addrInfo.relAddr & ~FSI_CTLREG_MASK)
- == CMFSI_CONTROL_REG)
+ == FSI::CMFSI_CONTROL_REG)
)
)
{
@@ -1439,7 +1439,7 @@ errlHndl_t FsiDD::handleOpbErrors(FsiAddrInfo_t& i_addrInfo,
if( !root_cause_found )
{
// read the Status Bridge0 Register
- FsiChipInfo_t fsi_info = getFsiInfo( i_addrInfo.fsiTarg );
+ FSI::FsiChipInfo_t fsi_info = getFsiInfo( i_addrInfo.fsiTarg );
uint64_t ctl_reg = getControlReg(fsi_info.type);
uint32_t mesrb0_data = 0;
@@ -1574,7 +1574,7 @@ errlHndl_t FsiDD::handleOpbErrors(FsiAddrInfo_t& i_addrInfo,
/**
* @brief Poll for completion of a FSI operation, return data on read
*/
-errlHndl_t FsiDD::pollForComplete(FsiAddrInfo_t& i_addrInfo,
+errlHndl_t FsiDD::pollForComplete(FSI::FsiAddrInfo_t& i_addrInfo,
uint32_t* o_readData)
{
errlHndl_t l_err = NULL;
@@ -1790,7 +1790,7 @@ errlHndl_t FsiDD::pollForComplete(FsiAddrInfo_t& i_addrInfo,
* @brief Generate a complete FSI address based on the target and the
* FSI offset within that target
*/
-errlHndl_t FsiDD::genFullFsiAddr(FsiAddrInfo_t& io_addrInfo)
+errlHndl_t FsiDD::genFullFsiAddr(FSI::FsiAddrInfo_t& io_addrInfo)
{
errlHndl_t l_err = NULL;
@@ -1815,7 +1815,7 @@ errlHndl_t FsiDD::genFullFsiAddr(FsiAddrInfo_t& io_addrInfo)
if( io_addrInfo.accessInfo.master == iv_master )
{
//append the appropriate offset
- io_addrInfo.absAddr += getPortOffset(io_addrInfo.accessInfo.type,
+ io_addrInfo.absAddr += FSI::getPortOffset(io_addrInfo.accessInfo.type,
io_addrInfo.accessInfo.port);
}
//verify this target has a valid FSI master
@@ -1848,11 +1848,12 @@ errlHndl_t FsiDD::genFullFsiAddr(FsiAddrInfo_t& io_addrInfo)
else
{
//append the CMFSI portion first
- io_addrInfo.absAddr += getPortOffset(io_addrInfo.accessInfo.type,
+ io_addrInfo.absAddr += FSI::getPortOffset(io_addrInfo.accessInfo.type,
io_addrInfo.accessInfo.port);
//find this port's master and then get its port information
- FsiChipInfo_t mfsi_info = getFsiInfo(io_addrInfo.accessInfo.master);
+ FSI::FsiChipInfo_t mfsi_info =
+ getFsiInfo(io_addrInfo.accessInfo.master);
//check for invalid topology
if( mfsi_info.master != iv_master )
@@ -1937,7 +1938,8 @@ errlHndl_t FsiDD::genFullFsiAddr(FsiAddrInfo_t& io_addrInfo)
// a flipped cmfsi port
//using the master chip so we need to append the MFSI port
- io_addrInfo.absAddr += getPortOffset(mfsi_info.type,mfsi_info.port);
+ io_addrInfo.absAddr += FSI::getPortOffset(mfsi_info.type,
+ mfsi_info.port);
}
else if( (io_addrInfo.accessInfo.master)->
getAttr<TARGETING::ATTR_SCOM_SWITCHES>().useXscom
@@ -1959,7 +1961,8 @@ errlHndl_t FsiDD::genFullFsiAddr(FsiAddrInfo_t& io_addrInfo)
else
{
//using the master chip so we need to append the MFSI port
- io_addrInfo.absAddr += getPortOffset(mfsi_info.type,mfsi_info.port);
+ io_addrInfo.absAddr += FSI::getPortOffset(mfsi_info.type,
+ mfsi_info.port);
}
}
@@ -1970,7 +1973,7 @@ errlHndl_t FsiDD::genFullFsiAddr(FsiAddrInfo_t& io_addrInfo)
* @brief Generate a valid SCOM address to access the OPB, this will
* choose the correct master
*/
-uint64_t FsiDD::genOpbScomAddr(FsiAddrInfo_t& i_addrInfo,
+uint64_t FsiDD::genOpbScomAddr(FSI::FsiAddrInfo_t& i_addrInfo,
uint64_t i_opbOffset)
{
uint64_t opbaddr = FSI2OPB_OFFSET_0;
@@ -1986,7 +1989,7 @@ uint64_t FsiDD::genOpbScomAddr(FsiAddrInfo_t& i_addrInfo,
else if( (TARGETING::FSI_MASTER_TYPE_CMFSI
== i_addrInfo.accessInfo.type) )
{
- FsiChipInfo_t chipinfo = getFsiInfo(i_addrInfo.opbTarg);
+ FSI::FsiChipInfo_t chipinfo = getFsiInfo(i_addrInfo.opbTarg);
if( chipinfo.flagbits.flipPort )
{
opbaddr = FSI2OPB_OFFSET_1;
@@ -2001,7 +2004,7 @@ uint64_t FsiDD::genOpbScomAddr(FsiAddrInfo_t& i_addrInfo,
/**
* @brief Initializes the FSI link to allow slave access
*/
-errlHndl_t FsiDD::initPort(FsiChipInfo_t i_fsiInfo,
+errlHndl_t FsiDD::initPort(FSI::FsiChipInfo_t i_fsiInfo,
bool& o_enabled)
{
errlHndl_t l_err = NULL;
@@ -2019,10 +2022,11 @@ errlHndl_t FsiDD::initPort(FsiChipInfo_t i_fsiInfo,
&& (i_fsiInfo.master != iv_master) )
{
// look up the FSI information for this target's master
- FsiChipInfo_t mfsi_info = getFsiInfo(i_fsiInfo.master);
+ FSI::FsiChipInfo_t mfsi_info = getFsiInfo(i_fsiInfo.master);
// append the master's port offset to the slave's
- master_offset = getPortOffset( TARGETING::FSI_MASTER_TYPE_MFSI, mfsi_info.port );
+ master_offset = FSI::getPortOffset(TARGETING::FSI_MASTER_TYPE_MFSI,
+ mfsi_info.port );
}
// control register is determined by the type of port
@@ -2030,7 +2034,8 @@ errlHndl_t FsiDD::initPort(FsiChipInfo_t i_fsiInfo,
master_ctl_reg += master_offset;
// slave offset is determined by which port it is on
- uint64_t slave_offset = getPortOffset( i_fsiInfo.type, i_fsiInfo.port );
+ uint64_t slave_offset = FSI::getPortOffset( i_fsiInfo.type,
+ i_fsiInfo.port );
slave_offset += master_offset;
// nothing was detected on this port so this is just a NOOP
@@ -2056,7 +2061,7 @@ errlHndl_t FsiDD::initPort(FsiChipInfo_t i_fsiInfo,
//Reset the port to clear up any previous error state
// (using idec reg as arbitrary address for lookups)
- FsiAddrInfo_t addr_info( i_fsiInfo.slave, 0x1028 );
+ FSI::FsiAddrInfo_t addr_info( i_fsiInfo.slave, 0x1028 );
l_err = genFullFsiAddr( addr_info );
if( l_err ) { break; }
l_err = errorCleanup( addr_info, FSI::RC_ERROR_IN_MAEB );
@@ -2076,7 +2081,7 @@ errlHndl_t FsiDD::initPort(FsiChipInfo_t i_fsiInfo,
//Reset the port to clear up any previous error state
// (using idec reg as arbitrary address for lookups)
- FsiAddrInfo_t addr_info( i_fsiInfo.slave, 0x1028 );
+ FSI::FsiAddrInfo_t addr_info( i_fsiInfo.slave, 0x1028 );
l_err = genFullFsiAddr( addr_info );
if( l_err ) { break; }
l_err = errorCleanup( addr_info, FSI::RC_ERROR_IN_MAEB );
@@ -2118,11 +2123,11 @@ errlHndl_t FsiDD::initPort(FsiChipInfo_t i_fsiInfo,
uint32_t tmp_slave_offset = slave_offset;
if( TARGETING::FSI_MASTER_TYPE_CMFSI == i_fsiInfo.type )
{
- slave_offset |= CMFSI_SLAVE_0;
+ slave_offset |= FSI::CMFSI_SLAVE_0;
}
else if( TARGETING::FSI_MASTER_TYPE_MFSI == i_fsiInfo.type )
{
- slave_offset |= MFSI_SLAVE_0;
+ slave_offset |= FSI::MFSI_SLAVE_0;
}
//Setup the FSI slave to enable HW recovery, lbus ratio
@@ -2164,7 +2169,7 @@ errlHndl_t FsiDD::initPort(FsiChipInfo_t i_fsiInfo,
// (using idec reg as arbitrary address for lookups)
//Note, initial cfam reset should have cleaned up everything
// but this makes sure we're in a consistent state
- FsiAddrInfo_t addr_info( i_fsiInfo.slave, 0x1028 );
+ FSI::FsiAddrInfo_t addr_info( i_fsiInfo.slave, 0x1028 );
l_err = genFullFsiAddr( addr_info );
if( l_err ) { break; }
l_err = errorCleanup( addr_info, FSI::RC_ERROR_IN_MAEB );
@@ -2217,12 +2222,13 @@ errlHndl_t FsiDD::initMasterControl(TARGETING::Target* i_master,
// append the master port offset to get to te remote master
if( i_master != iv_master )
{
- FsiChipInfo_t m_info = getFsiInfo(i_master);
- ctl_reg += getPortOffset(TARGETING::FSI_MASTER_TYPE_MFSI,m_info.port);
+ FSI::FsiChipInfo_t m_info = getFsiInfo(i_master);
+ ctl_reg += FSI::getPortOffset(TARGETING::FSI_MASTER_TYPE_MFSI,
+ m_info.port);
}
//Always clear out any pending errors before we start anything
- FsiAddrInfo_t addr_info( i_master, 0 );
+ FSI::FsiAddrInfo_t addr_info( i_master, 0 );
l_err = genFullFsiAddr(addr_info);
if( l_err ) { break; }
@@ -2325,7 +2331,7 @@ errlHndl_t FsiDD::initMasterControl(TARGETING::Target* i_master,
if( i_master != iv_master )
{
// get the data via FSI (scom engine)
- FsiAddrInfo_t addr_info( i_master, 0x1028 );
+ FSI::FsiAddrInfo_t addr_info( i_master, 0x1028 );
l_err = genFullFsiAddr( addr_info );
if( l_err ) { break; }
@@ -2453,45 +2459,6 @@ errlHndl_t FsiDD::initMasterControl(TARGETING::Target* i_master,
/**
- * @brief Convert a type/port pair into a FSI address offset
- */
-uint64_t FsiDD::getPortOffset(TARGETING::FSI_MASTER_TYPE i_type,
- uint8_t i_port)
-{
- uint64_t offset = 0;
- if( TARGETING::FSI_MASTER_TYPE_MFSI == i_type )
- {
- switch(i_port)
- {
- case(0): offset = MFSI_PORT_0; break;
- case(1): offset = MFSI_PORT_1; break;
- case(2): offset = MFSI_PORT_2; break;
- case(3): offset = MFSI_PORT_3; break;
- case(4): offset = MFSI_PORT_4; break;
- case(5): offset = MFSI_PORT_5; break;
- case(6): offset = MFSI_PORT_6; break;
- case(7): offset = MFSI_PORT_7; break;
- }
- }
- else if( TARGETING::FSI_MASTER_TYPE_CMFSI == i_type )
- {
- switch(i_port)
- {
- case(0): offset = CMFSI_PORT_0; break;
- case(1): offset = CMFSI_PORT_1; break;
- case(2): offset = CMFSI_PORT_2; break;
- case(3): offset = CMFSI_PORT_3; break;
- case(4): offset = CMFSI_PORT_4; break;
- case(5): offset = CMFSI_PORT_5; break;
- case(6): offset = CMFSI_PORT_6; break;
- case(7): offset = CMFSI_PORT_7; break;
- }
- }
-
- return offset;
-}
-
-/**
* @brief Retrieve the slave enable index
*/
uint64_t FsiDD::getSlaveEnableIndex( TARGETING::Target* i_master,
@@ -2506,7 +2473,7 @@ uint64_t FsiDD::getSlaveEnableIndex( TARGETING::Target* i_master,
uint64_t slave_index = MAX_SLAVE_PORTS+i_type;
if( i_master != iv_master )
{
- FsiChipInfo_t m_info = getFsiInfo(i_master);
+ FSI::FsiChipInfo_t m_info = getFsiInfo(i_master);
if( m_info.type == TARGETING::FSI_MASTER_TYPE_NO_MASTER )
{
slave_index = INVALID_SLAVE_INDEX;
@@ -2523,9 +2490,9 @@ uint64_t FsiDD::getSlaveEnableIndex( TARGETING::Target* i_master,
* @brief Retrieve the connection information needed to access FSI
* registers within the given chip target
*/
-FsiDD::FsiChipInfo_t FsiDD::getFsiInfoFromAttr( TARGETING::Target* i_target )
+FSI::FsiChipInfo_t FsiDD::getFsiInfoFromAttr( TARGETING::Target* i_target )
{
- FsiChipInfo_t info;
+ FSI::FsiChipInfo_t info;
info.slave = i_target;
using namespace TARGETING;
@@ -2665,14 +2632,14 @@ bool FsiDD::isSlavePresent( TARGETING::Target* i_target,
uint8_t& o_detected )
{
// look up the FSI information for this target
- FsiChipInfo_t info = getFsiInfo(i_target);
+ FSI::FsiChipInfo_t info = getFsiInfo(i_target);
return isSlavePresent( info.master, info.type, info.port, o_detected );
}
/**
* @brief Clear out the error indication so that we can do more FSI ops
*/
-errlHndl_t FsiDD::errorCleanup( FsiAddrInfo_t& i_addrInfo,
+errlHndl_t FsiDD::errorCleanup( FSI::FsiAddrInfo_t& i_addrInfo,
FSI::FSIReasonCode i_errType )
{
errlHndl_t l_err = NULL;
@@ -2736,7 +2703,7 @@ errlHndl_t FsiDD::errorCleanup( FsiAddrInfo_t& i_addrInfo,
{
// 0=Bridge: General reset
data = 0x80000000;
- mesrb0_reg = MFSI_CONTROL_REG | FSI_MESRB0_1D0;
+ mesrb0_reg = FSI::MFSI_CONTROL_REG | FSI_MESRB0_1D0;
l_err = write( iv_master, mesrb0_reg, &data );
if(l_err) break;
}
@@ -2761,17 +2728,17 @@ errlHndl_t FsiDD::errorCleanup( FsiAddrInfo_t& i_addrInfo,
//Trace some values for FFDC in case this cleanup
// didn't really work
uint32_t grabregs[] = {
- MFSI_CONTROL_REG|FSI_MSIEP0_030,
- CMFSI_CONTROL_REG|FSI_MSIEP0_030,
- MFSI_CONTROL_REG|FSI_MAEB_070,
- CMFSI_CONTROL_REG|FSI_MAEB_070
+ FSI::MFSI_CONTROL_REG|FSI_MSIEP0_030,
+ FSI::CMFSI_CONTROL_REG|FSI_MSIEP0_030,
+ FSI::MFSI_CONTROL_REG|FSI_MAEB_070,
+ FSI::CMFSI_CONTROL_REG|FSI_MAEB_070
};
for( size_t r = 0;
r < (sizeof(grabregs)/sizeof(grabregs[0]));
r++ )
{
l_err = read( i_addrInfo.accessInfo.master,
- MFSI_CONTROL_REG|FSI_MSIEP0_030, &data );
+ FSI::MFSI_CONTROL_REG|FSI_MSIEP0_030, &data );
if(l_err) break;
TRACFCOMP( g_trac_fsi, "errorCleanup> %.8X->%.6X = %.8X", TARGETING::get_huid(i_addrInfo.accessInfo.master), grabregs[r], data );
}
@@ -2786,9 +2753,9 @@ errlHndl_t FsiDD::errorCleanup( FsiAddrInfo_t& i_addrInfo,
/**
* @brief Check for FSI errors anywhere in the system
*/
-errlHndl_t FsiDD::checkForErrors( FsiChipInfo_t& i_chipInfo )
+errlHndl_t FsiDD::checkForErrors( FSI::FsiChipInfo_t& i_chipInfo )
{
- FsiAddrInfo_t addr_info( i_chipInfo.slave, 0xFFFFFFFF );
+ FSI::FsiAddrInfo_t addr_info( i_chipInfo.slave, 0xFFFFFFFF );
errlHndl_t errhdl = genFullFsiAddr( addr_info );
if( !errhdl )
{
@@ -2801,7 +2768,7 @@ errlHndl_t FsiDD::checkForErrors( FsiChipInfo_t& i_chipInfo )
/**
* @brief Check for FSI errors anywhere in the system
*/
-errlHndl_t FsiDD::checkForErrors( FsiAddrInfo_t& i_addrInfo )
+errlHndl_t FsiDD::checkForErrors( FSI::FsiAddrInfo_t& i_addrInfo )
{
errlHndl_t l_err = NULL;
@@ -2910,7 +2877,7 @@ errlHndl_t FsiDD::verifyPresent( TARGETING::Target* i_target )
{
TRACFCOMP( g_trac_fsi, "FsiDD::verifyPresent> Requested target was never detected during FSI Init : i_target=%.8X", TARGETING::get_huid(i_target) );
- FsiChipInfo_t chipinfo = getFsiInfo(i_target);
+ FSI::FsiChipInfo_t chipinfo = getFsiInfo(i_target);
/*@
* @errortype
@@ -2973,14 +2940,14 @@ errlHndl_t FsiDD::verifyPresent( TARGETING::Target* i_target )
* @brief Retrieve the connection information needed to access FSI
* registers within the given chip target
*/
-FsiDD::FsiChipInfo_t FsiDD::getFsiInfo( TARGETING::Target* i_target )
+FSI::FsiChipInfo_t FsiDD::getFsiInfo( TARGETING::Target* i_target )
{
- FsiChipInfo_t info;
+ FSI::FsiChipInfo_t info;
mutex_lock(&iv_dataMutex);
// Check if we have a cached version first
- std::map<TARGETING::Target*,FsiChipInfo_t>::iterator itr
+ std::map<TARGETING::Target*,FSI::FsiChipInfo_t>::iterator itr
= iv_fsiInfoMap.find(i_target);
if( itr != iv_fsiInfoMap.end() )
{
@@ -3005,7 +2972,7 @@ FsiDD::FsiChipInfo_t FsiDD::getFsiInfo( TARGETING::Target* i_target )
void FsiDD::getFsiLinkInfo( TARGETING::Target* i_slave,
FSI::FsiLinkInfo_t& o_info )
{
- FsiAddrInfo_t addr_info( i_slave, 0x0 );
+ FSI::FsiAddrInfo_t addr_info( i_slave, 0x0 );
errlHndl_t tmp_err = genFullFsiAddr( addr_info );
if( tmp_err )
{
@@ -3031,8 +2998,8 @@ void FsiDD::getFsiLinkInfo( TARGETING::Target* i_slave,
o_info.baseAddr = addr_info.absAddr;
if( addr_info.opbTarg != iv_master )
{
- FsiChipInfo_t mfsi_info = getFsiInfo(addr_info.accessInfo.master);
- o_info.baseAddr |= getPortOffset(mfsi_info.type,mfsi_info.port);
+ FSI::FsiChipInfo_t mfsi_info = getFsiInfo(addr_info.accessInfo.master);
+ o_info.baseAddr |= FSI::getPortOffset(mfsi_info.type,mfsi_info.port);
}
}
diff --git a/src/usr/fsi/fsidd.H b/src/usr/fsi/fsidd.H
index 999b38d02..b794b4273 100644
--- a/src/usr/fsi/fsidd.H
+++ b/src/usr/fsi/fsidd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -35,6 +35,8 @@
#include <usr/fsi/fsiif.H>
#include <usr/fsi/fsi_reasoncodes.H>
#include <map>
+#include "fsi_common.H"
+
namespace FSI { class UdPresence; }
/** @file fsidd.H
@@ -190,70 +192,6 @@ class FsiDD
size_t i_buflen = 4);
/**
- * Common id to identify a FSI position to use in error logs and traces
- */
- union FsiLinkId_t
- {
- uint32_t id;
- struct
- {
- uint8_t node; ///< Physical Node of FSI Master processor
- uint8_t proc; ///< Physical Position of FSI Master processor
- uint8_t type; ///< FSI Master type (FSI_MASTER_TYPE)
- uint8_t port; ///< Slave link/port number
- };
- };
-
- /**
- * @brief Structure which defines info necessary to access a chip via FSI
- */
- struct FsiChipInfo_t
- {
- TARGETING::Target* slave; //< FSI Slave chip
- TARGETING::Target* master; ///< FSI Master
- TARGETING::FSI_MASTER_TYPE type; ///< Master or Cascaded Master
- uint8_t port; ///< Which port is this chip hanging off of
- uint8_t cascade; ///< Slave cascade position
- union {
- TARGETING::FsiOptionFlags flagbits; ///< Special flags
- uint16_t flags; ///< Special flags
- };
- FsiLinkId_t linkid; ///< Id for traces and error logs
-
- FsiChipInfo_t() :
- slave(NULL), master(NULL),
- type(TARGETING::FSI_MASTER_TYPE_NO_MASTER),
- port(UINT8_MAX), cascade(0), flags(0)
- { linkid.id = 0; };
- };
-
- /**
- * @brief Holds a set of addressing information to describe the
- * current FSI operation
- */
- struct FsiAddrInfo_t {
- TARGETING::Target* fsiTarg; ///< Target of FSI operation
- TARGETING::Target* opbTarg; ///< OPB control reg target
- uint32_t relAddr; ///< Input FSI address (relative to fsiTarg)
- uint32_t absAddr; ///< Absolute FSI address (relative to opbTarg)
- FsiChipInfo_t accessInfo; ///< FSI Access Info
-
- /** Input Arg Constructor */
- FsiAddrInfo_t( TARGETING::Target* i_target,
- uint64_t i_address ) :
- fsiTarg(i_target), opbTarg(NULL),
- relAddr(i_address), absAddr(UINT32_MAX)
- {};
-
- private:
- /** Default Constructor is not allowed */
- FsiAddrInfo_t() :
- fsiTarg(NULL), opbTarg(NULL),
- relAddr(UINT32_MAX),absAddr(UINT32_MAX)
- {};
- };
-
- /**
* @brief Performs an FSI Read Operation
*
* @param[in] i_addrInfo Addressing information
@@ -262,7 +200,7 @@ class FsiDD
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t read(FsiAddrInfo_t& i_addrInfo,
+ errlHndl_t read(FSI::FsiAddrInfo_t& i_addrInfo,
uint32_t* o_buffer,
size_t i_buflen = 4);
@@ -275,7 +213,7 @@ class FsiDD
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t write(FsiAddrInfo_t& i_addrInfo,
+ errlHndl_t write(FSI::FsiAddrInfo_t& i_addrInfo,
uint32_t* i_buffer,
size_t i_buflen = 4);
@@ -298,7 +236,7 @@ class FsiDD
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t initPort(FsiChipInfo_t i_fsiInfo,
+ errlHndl_t initPort(FSI::FsiChipInfo_t i_fsiInfo,
bool& o_enabled);
/**
@@ -310,7 +248,7 @@ class FsiDD
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t handleOpbErrors(FsiAddrInfo_t& i_addrInfo,
+ errlHndl_t handleOpbErrors(FSI::FsiAddrInfo_t& i_addrInfo,
uint32_t i_opbStatAddr,
uint32_t i_opbStatData);
@@ -323,7 +261,7 @@ class FsiDD
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t pollForComplete(FsiAddrInfo_t& i_addrInfo,
+ errlHndl_t pollForComplete(FSI::FsiAddrInfo_t& i_addrInfo,
uint32_t* o_readData);
/**
@@ -336,7 +274,7 @@ class FsiDD
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t genFullFsiAddr(FsiAddrInfo_t& io_addrInfo);
+ errlHndl_t genFullFsiAddr(FSI::FsiAddrInfo_t& io_addrInfo);
/**
* @brief Generate a valid SCOM address to access the OPB, this will
@@ -349,67 +287,11 @@ class FsiDD
*
* @return uint64_t Fully qualified OPB SCOM address
*/
- uint64_t genOpbScomAddr(FsiAddrInfo_t& i_addrInfo,
+ uint64_t genOpbScomAddr(FSI::FsiAddrInfo_t& i_addrInfo,
uint64_t i_opbOffset);
/**
- * @brief Convert a type/port pair into a FSI address offset
- *
- * @param[in] i_type Type of FSI interface
- * @param[in] i_port FSI link number
- * @return uint64_t FSI address offset
- */
- uint64_t getPortOffset(TARGETING::FSI_MASTER_TYPE i_type,
- uint8_t i_port);
-
-
- /**
- * FSI Address Space
- */
- enum FsiAddressSpace {
- // Master control registers
- CMFSI_CONTROL_REG = 0x003000, /**< cMFSI Control Register */
- MFSI_CONTROL_REG = 0x003400, /**< MFSI Control Register */
-
- // cMFSI Ports (32KB each)
- CMFSI_PORT_0 = 0x040000, /**< cMFSI port 0 */
- CMFSI_PORT_1 = 0x048000, /**< cMFSI port 1 */
- CMFSI_PORT_2 = 0x050000, /**< cMFSI port 2 */
- CMFSI_PORT_3 = 0x058000, /**< cMFSI port 3 */
- CMFSI_PORT_4 = 0x060000, /**< cMFSI port 4 */
- CMFSI_PORT_5 = 0x068000, /**< cMFSI port 5 */
- CMFSI_PORT_6 = 0x070000, /**< cMFSI port 6 */
- CMFSI_PORT_7 = 0x078000, /**< cMFSI port 7 */
- CMFSI_PORT_MASK = 0x078000, /**< Mask to look for a valid cMFSI port */
-
- // Offsets to cascaded slaves within a cMFSI port
- CMFSI_SLAVE_0 = 0x000000, /**< cMFSI - Slave 0 */
- CMFSI_SLAVE_1 = 0x002000, /**< cMFSI - Slave 1 */
- CMFSI_SLAVE_2 = 0x004000, /**< cMFSI - Slave 2 */
- CMFSI_SLAVE_3 = 0x006000, /**< cMFSI - Slave 3 */
-
- // MFSI Ports (512KB each)
- MFSI_PORT_LOCAL = 0x000000, /**< Local master (used for local cMFSI) */
- MFSI_PORT_0 = 0x080000, /**< MFSI port 0 */
- MFSI_PORT_1 = 0x100000, /**< MFSI port 1 */
- MFSI_PORT_2 = 0x180000, /**< MFSI port 2 */
- MFSI_PORT_3 = 0x200000, /**< MFSI port 3 */
- MFSI_PORT_4 = 0x280000, /**< MFSI port 4 */
- MFSI_PORT_5 = 0x300000, /**< MFSI port 5 */
- MFSI_PORT_6 = 0x380000, /**< MFSI port 6 */
- MFSI_PORT_7 = 0x400000, /**< MFSI port 7 */
- MFSI_PORT_MASK = 0x780000, /**< Mask to look for a valid MFSI port */
-
- // Offsets to cascaded slaves within a MFSI port
- MFSI_SLAVE_0 = 0x000000, /**< MFSI - Slave 0 */
- MFSI_SLAVE_1 = 0x020000, /**< MFSI - Slave 1 */
- MFSI_SLAVE_2 = 0x040000, /**< MFSI - Slave 2 */
- MFSI_SLAVE_3 = 0x060000, /**< MFSI - Slave 3 */
- };
-
-
- /**
* PIB2OPB Registers
*/
enum Pib2OpbRegisters {
@@ -501,10 +383,10 @@ class FsiDD
*/
uint64_t getControlReg(TARGETING::FSI_MASTER_TYPE i_type)
{
- uint64_t ctl_reg = MFSI_CONTROL_REG;
+ uint64_t ctl_reg = FSI::MFSI_CONTROL_REG;
if( TARGETING::FSI_MASTER_TYPE_CMFSI == i_type )
{
- ctl_reg = CMFSI_CONTROL_REG;
+ ctl_reg = FSI::CMFSI_CONTROL_REG;
}
return ctl_reg;
};
@@ -526,7 +408,7 @@ class FsiDD
*
* @return FsiChipInfo_t FSI Chip Information
*/
- FsiChipInfo_t getFsiInfo( TARGETING::Target* i_target );
+ FSI::FsiChipInfo_t getFsiInfo( TARGETING::Target* i_target );
/**
* @brief Clear out the error indication so that we can do more FSI ops
@@ -536,7 +418,7 @@ class FsiDD
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t errorCleanup( FsiAddrInfo_t& i_addrInfo,
+ errlHndl_t errorCleanup( FSI::FsiAddrInfo_t& i_addrInfo,
FSI::FSIReasonCode i_errType );
/**
@@ -546,7 +428,7 @@ class FsiDD
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t checkForErrors( FsiChipInfo_t& i_chipInfo );
+ errlHndl_t checkForErrors( FSI::FsiChipInfo_t& i_chipInfo );
/**
* @brief Check for FSI errors anywhere in the system
@@ -555,7 +437,7 @@ class FsiDD
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t checkForErrors( FsiAddrInfo_t& i_addrInfo );
+ errlHndl_t checkForErrors( FSI::FsiAddrInfo_t& i_addrInfo );
/**
* @brief Verify that the slave target was detected
@@ -574,7 +456,7 @@ class FsiDD
*
* @return FsiChipInfo_t FSI Chip Information
*/
- FsiChipInfo_t getFsiInfoFromAttr( TARGETING::Target* i_target );
+ FSI::FsiChipInfo_t getFsiInfoFromAttr( TARGETING::Target* i_target );
/********************************************
@@ -616,7 +498,7 @@ class FsiDD
* Cache of FSI connection information gleaned from attributes
* Indexed by Target*, returns FsiChipInfo_t
*/
- std::map<TARGETING::Target*,FsiChipInfo_t> iv_fsiInfoMap;
+ std::map<TARGETING::Target*,FSI::FsiChipInfo_t> iv_fsiInfoMap;
/**
* Mutex to protect the internal maps
diff --git a/src/usr/fsi/makefile b/src/usr/fsi/makefile
index 437d99f35..df88c4fb5 100644
--- a/src/usr/fsi/makefile
+++ b/src/usr/fsi/makefile
@@ -5,7 +5,9 @@
#
# OpenPOWER HostBoot Project
#
-# COPYRIGHT International Business Machines Corp. 2011,2014
+# Contributors Listed Below - COPYRIGHT 2011,2017
+# [+] International Business Machines Corp.
+#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -26,7 +28,9 @@ MODULE = fsi
OBJS += fsidd.o
OBJS += fsipres.o
OBJS += errlud_fsi.o
+OBJS += fsi_common.o
SUBDIRS += test.d
+SUBDIRS += runtime.d
include ${ROOTPATH}/config.mk
diff --git a/src/usr/fsi/runtime/makefile b/src/usr/fsi/runtime/makefile
new file mode 100644
index 000000000..10d4d5ae3
--- /dev/null
+++ b/src/usr/fsi/runtime/makefile
@@ -0,0 +1,35 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/fsi/runtime/makefile $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2016,2017
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+HOSTBOOT_RUNTIME = 1
+ROOTPATH = ../../../..
+MODULE = fsi_rt
+
+OBJS += rt_fsi.o
+OBJS += fsi_common.o
+
+EXTRAINCDIR += ${ROOTPATH}/src/usr/fsi
+
+VPATH += ../
+include $(ROOTPATH)/config.mk
diff --git a/src/usr/fsi/runtime/rt_fsi.C b/src/usr/fsi/runtime/rt_fsi.C
new file mode 100644
index 000000000..75103cc4b
--- /dev/null
+++ b/src/usr/fsi/runtime/rt_fsi.C
@@ -0,0 +1,476 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/fsi/runtime/rt_fsi.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include <stdlib.h>
+#include <runtime/rt_targeting.H>
+#include <runtime/interface.h>
+
+#include <targeting/common/targetservice.H>
+
+#include <fsi/fsiif.H>
+#include "rt_fsi.H"
+#include <util/misc.H>
+#include <fsi/fsi_reasoncodes.H>
+
+// Trace definition
+trace_desc_t* g_trac_fsi = NULL;
+TRAC_INIT(&g_trac_fsi, FSI_COMP_NAME, KILOBYTE); // 1K
+
+
+/**
+ * @brief Retrieve some FSI attribute information
+ */
+void FSI::getFsiLinkInfo( TARGETING::Target* i_slave,
+ FSI::FsiLinkInfo_t& o_info )
+{
+ Singleton<RtFsi>::instance().getFsiLinkInfo( i_slave,o_info );
+}
+
+/* Protected Methods */
+
+/**
+ * @brief Constructor
+ */
+RtFsi::RtFsi()
+:iv_master(NULL)
+,iv_useAlt(0)
+{
+ TRACFCOMP(g_trac_fsi, "RtFsi::RtFsi()>");
+
+ // save away the master processor target
+ TARGETING::TargetService& targetService = TARGETING::targetService();
+ iv_master = NULL;
+ targetService.masterProcChipTargetHandle( iv_master );
+ TRACFCOMP(g_trac_fsi, "Master=%.8X",TARGETING::get_huid(iv_master));
+
+}
+
+/**
+ * @brief Destructor
+ */
+RtFsi::~RtFsi()
+{
+
+}
+
+/* Public Methods */
+
+/**
+ * @brief Retrieve the connection information needed to access FSI
+ * registers within the given chip target
+ */
+FSI::FsiChipInfo_t RtFsi::getFsiInfo( TARGETING::Target* i_target )
+{
+ FSI::FsiChipInfo_t info;
+
+ mutex_lock(&iv_dataMutex);
+
+ // Check if we have a cached version first
+ std::map<TARGETING::Target*,FSI::FsiChipInfo_t>::iterator itr
+ = iv_fsiInfoMap.find(i_target);
+ if( itr != iv_fsiInfoMap.end() )
+ {
+ info = itr->second;
+ }
+ else
+ {
+ // fetch the data from the attributes
+ info = getFsiInfoFromAttr( i_target );
+ // then cache it for next time
+ iv_fsiInfoMap[i_target] = info;
+ }
+
+ mutex_unlock(&iv_dataMutex);
+
+ return info;
+}
+
+/**
+ * @brief Retrieve some FSI attribute information
+ */
+void RtFsi::getFsiLinkInfo( TARGETING::Target* i_slave,
+ FSI::FsiLinkInfo_t& o_info )
+{
+ FSI::FsiAddrInfo_t addr_info( i_slave, 0x0 );
+ errlHndl_t tmp_err = RtFsi::genFullFsiAddr( addr_info );
+ if( tmp_err )
+ {
+ TRACFCOMP( g_trac_fsi, "Error getting FsiLinkInfo fo %.8X",
+ TARGETING::get_huid(i_slave));
+ delete tmp_err;
+ return;
+ }
+
+ o_info.master = addr_info.accessInfo.master;
+ o_info.type = addr_info.accessInfo.type;
+ o_info.link = addr_info.accessInfo.port;
+ o_info.cascade = addr_info.accessInfo.cascade;
+ o_info.mPort = 0;
+ if( addr_info.accessInfo.master &&
+ (addr_info.accessInfo.master != iv_master) &&
+ (getFsiInfo(addr_info.accessInfo.master).flagbits.flipPort) )
+ {
+ o_info.mPort = 1;
+ }
+
+ // if this chip is not off the master, need to include its
+ // master's offset oo
+ o_info.baseAddr = addr_info.absAddr;
+ if( addr_info.opbTarg != iv_master )
+ {
+ FSI::FsiChipInfo_t mfsi_info = getFsiInfo(addr_info.accessInfo.master);
+ o_info.baseAddr |= FSI::getPortOffset(mfsi_info.type,mfsi_info.port);
+ }
+}
+
+/**
+ * @brief Generate a complete FSI address based on the target and the
+ * FSI offset within that target
+ */
+errlHndl_t RtFsi::genFullFsiAddr(FSI::FsiAddrInfo_t& io_addrInfo)
+{
+ errlHndl_t l_err = NULL;
+
+ //default to using the master chip for OPB XSCOM ops
+ io_addrInfo.opbTarg = iv_master;
+
+ //start off with the addresses being the same
+ io_addrInfo.absAddr = io_addrInfo.relAddr;
+
+ //pull the FSI info out for this target
+ io_addrInfo.accessInfo = getFsiInfo( io_addrInfo.fsiTarg );
+
+ //target matches master so the address is correct as-is
+ if( io_addrInfo.fsiTarg == iv_master )
+ {
+ return NULL;
+ }
+
+ TRACFCOMP( g_trac_fsi, "target=%.8X : Link Id=%.8X",
+ TARGETING::get_huid(io_addrInfo.fsiTarg),
+ io_addrInfo.accessInfo.linkid.id );
+
+ //FSI master is the master proc, find the port
+ if( io_addrInfo.accessInfo.master == iv_master )
+ {
+ //append the appropriate offset
+ io_addrInfo.absAddr += FSI::getPortOffset(io_addrInfo.accessInfo.type,
+ io_addrInfo.accessInfo.port);
+ }
+ //verify this target has a valid FSI master
+ else if( TARGETING::FSI_MASTER_TYPE_CMFSI != io_addrInfo.accessInfo.type )
+ {
+ TRACFCOMP( g_trac_fsi,"target=%.8X : Master Type isn't supported = %d",
+ TARGETING::get_huid(io_addrInfo.fsiTarg),
+ io_addrInfo.accessInfo.type );
+ /*@
+ * @errortype
+ * @moduleid FSI::MOD_RTFSI_GENFULLFSIADDR
+ * @reasoncode FSI::RC_FSI_NOT_SUPPORTED
+ * @userdata1 Target of FSI Operation
+ * @userdata2[32:39] Physical Node of FSI Master processor
+ * @userdata2[40:47] Physical Position of FSI Master processor
+ * @userdata2[48:55] FSI Master type (0=MFSI,1=CMFSI,2=NO_MASTER)
+ * @userdata2[56:63] Slave link/port number
+ * @devdesc FsiDD::genFullFsiAddr> Master Type is not supported
+ * @custdesc A problem occurred during the
+ * IPL of the system.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ FSI::MOD_RTFSI_GENFULLFSIADDR,
+ FSI::RC_FSI_NOT_SUPPORTED,
+ TARGETING::get_huid(io_addrInfo.fsiTarg),
+ io_addrInfo.accessInfo.linkid.id,
+ true /*SW error*/);
+ l_err->collectTrace(FSI_COMP_NAME);
+ return l_err;
+ }
+ //target is behind another proc
+ else
+ {
+ //append the CMFSI portion first
+ io_addrInfo.absAddr += FSI::getPortOffset(io_addrInfo.accessInfo.type,
+ io_addrInfo.accessInfo.port);
+
+ //find this port's master and then get its port information
+ FSI::FsiChipInfo_t mfsi_info =
+ getFsiInfo(io_addrInfo.accessInfo.master);
+
+ //check for invalid topology
+ if( mfsi_info.master != iv_master )
+ {
+ TRACFCOMP( g_trac_fsi,
+ "target=%.8X : master=%.8X : master's master=%.8X :"
+ " Cannot chain 2 masters",
+ TARGETING::get_huid(io_addrInfo.fsiTarg),
+ TARGETING::get_huid(io_addrInfo.accessInfo.master),
+ TARGETING::get_huid(mfsi_info.master),
+ io_addrInfo.accessInfo.type );
+ /*@
+ * @errortype
+ * @moduleid FSI::MOD_RTFSI_GENFULLFSIADDR
+ * @reasoncode FSI::RC_INVALID_FSI_PATH_1
+ * @userdata1[0:31] Target of FSI Operation
+ * @userdata1[32:63] Target's FSI Master Chip
+ * @userdata2[0:7] Physical Node of FSI Master processor
+ * [target's master]
+ * @userdata2[8:15] Physical Position of FSI Master processor
+ * [target's master]
+ * @userdata2[16:23] FSI Master type (0=MFSI,1=CMFSI,2=NO_MASTER)
+ * [target's master]
+ * @userdata2[24:31] Slave link/port number [target's master]
+ * @userdata2[32:39] Physical Node of FSI Master processor
+ * [master's master]
+ * @userdata2[40:47] Physical Position of FSI Master processor
+ * [master's master]
+ * @userdata2[48:55] FSI Master type (0=MFSI,1=CMFSI,2=NO_MASTER)
+ * [master's master]
+ * @userdata2[56:63] Slave link/port number [master's master]
+ * @devdesc FsiDD::genFullFsiAddr> Cannot chain 2 masters
+ * @custdesc A problem occurred during the
+ * IPL of the system.
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ FSI::MOD_RTFSI_GENFULLFSIADDR,
+ FSI::RC_INVALID_FSI_PATH_1,
+ TWO_UINT32_TO_UINT64(
+ TARGETING::get_huid(io_addrInfo.fsiTarg),
+ TARGETING::get_huid(io_addrInfo.accessInfo.master)),
+ TWO_UINT32_TO_UINT64(
+ io_addrInfo.accessInfo.linkid.id,
+ mfsi_info.linkid.id),
+ true /*SW error*/);
+ l_err->collectTrace(FSI_COMP_NAME);
+ return l_err;
+ }
+ else if( TARGETING::FSI_MASTER_TYPE_MFSI != mfsi_info.type )
+ {
+ TRACFCOMP( g_trac_fsi, "target=%.8X:master=%.8X, type=%d, port=%d",
+ TARGETING::get_huid(io_addrInfo.fsiTarg),
+ TARGETING::get_huid(io_addrInfo.accessInfo.master),
+ io_addrInfo.accessInfo.type,
+ io_addrInfo.accessInfo.port );
+ TRACFCOMP( g_trac_fsi,
+ "Master: target=%.8X : master=%.8X, type=%d, port=%d",
+ TARGETING::get_huid(io_addrInfo.accessInfo.master),
+ TARGETING::get_huid(mfsi_info.master),
+ mfsi_info.type, mfsi_info.port );
+ /*@
+ * @errortype
+ * @moduleid FSI::MOD_RTFSI_GENFULLFSIADDR
+ * @reasoncode FSI::RC_INVALID_FSI_PATH_2
+ * @userdata1[0:31] Target of FSI Operation
+ * @userdata1[32:63] Target's FSI Master Chip
+ * @userdata2[0:7] Physical Node of FSI Master processor
+ * [target's master]
+ * @userdata2[8:15] Physical Position of FSI Master processor
+ * [target's master]
+ * @userdata2[16:23] FSI Master type (0=MFSI,1=CMFSI,2=NO_MASTER)
+ * [target's master]
+ * @userdata2[24:31] Slave link/port number [target's master]
+ * @userdata2[32:39] Physical Node of FSI Master processor
+ * [master's master]
+ * @userdata2[40:47] Physical Position of FSI Master processor
+ * [master's master]
+ * @userdata2[48:55] FSI Master type (0=MFSI,1=CMFSI,2=NO_MASTER)
+ * [master's master]
+ * @userdata2[56:63] Slave link/port number [master's master]
+ * @devdesc FsiDD::genFullFsiAddr> Invalid master type for the
+ * target's master
+ * @custdesc A problem occurred during the
+ * IPL of the system.
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ FSI::MOD_RTFSI_GENFULLFSIADDR,
+ FSI::RC_INVALID_FSI_PATH_2,
+ TWO_UINT32_TO_UINT64(
+ TARGETING::get_huid(io_addrInfo.fsiTarg),
+ TARGETING::get_huid(io_addrInfo.accessInfo.master)),
+ TWO_UINT32_TO_UINT64(
+ io_addrInfo.accessInfo.linkid.id,
+ mfsi_info.linkid.id),
+ true /*SW error*/);
+ l_err->collectTrace(FSI_COMP_NAME);
+ return l_err;
+ }
+
+ // If powerbus is alive, we can use the local master
+ //
+ if( Util::isSimicsRunning()
+ && (mfsi_info.flagbits.flipPort) )
+ {
+ //@fixme - RTC:99928 : Simics is wired wrong on Brazos
+ // so always use indirect path when talking through
+ // a flipped cmfsi port
+
+ //using the master chip so we need to append the MFSI port
+ io_addrInfo.absAddr += FSI::getPortOffset(mfsi_info.type,
+ mfsi_info.port);
+ }
+ else if( (io_addrInfo.accessInfo.master)->
+ getAttr<TARGETING::ATTR_SCOM_SWITCHES>().useXscom
+ )
+ {
+ //use the local proc to drive the operation instead of
+ // going through the master proc indirectly
+ io_addrInfo.opbTarg = io_addrInfo.accessInfo.master;
+ // Note: no need to append the MFSI port since it is now local
+
+ // set a flag to flip the OPB port if this slave's master
+ // is reversed and it isn't the acting master
+ if( io_addrInfo.accessInfo.master != iv_master )
+ {
+ io_addrInfo.accessInfo.flagbits.flipPort
+ = mfsi_info.flagbits.flipPort;
+ }
+ }
+ else
+ {
+ //using the master chip so we need to append the MFSI port
+ io_addrInfo.absAddr += FSI::getPortOffset(mfsi_info.type,
+ mfsi_info.port);
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * @brief Retrieve the connection information needed to access FSI
+ * registers within the given chip target
+ */
+FSI::FsiChipInfo_t RtFsi::getFsiInfoFromAttr( TARGETING::Target* i_target )
+{
+ FSI::FsiChipInfo_t info;
+ info.slave = i_target;
+
+ using namespace TARGETING;
+
+ EntityPath epath;
+
+ if( (i_target != NULL) &&
+ i_target->tryGetAttr<ATTR_FSI_MASTER_TYPE>(info.type) )
+ {
+ if( info.type != FSI_MASTER_TYPE_NO_MASTER )
+ {
+ if( !iv_useAlt
+ && i_target->tryGetAttr<ATTR_FSI_MASTER_CHIP>(epath) )
+ {
+ info.master = targetService().toTarget(epath);
+
+ if( i_target->tryGetAttr<ATTR_FSI_MASTER_PORT>(info.port) )
+ {
+ if( i_target->tryGetAttr<ATTR_FSI_SLAVE_CASCADE>
+ (info.cascade) )
+ {
+ if( !i_target->tryGetAttr<ATTR_FSI_OPTION_FLAGS>
+ (info.flagbits) )
+ {
+ info.master = NULL;
+ }
+ }
+ else
+ {
+ info.master = NULL;
+ }
+ }
+ else
+ {
+ info.master = NULL;
+ }
+ }
+ else if( iv_useAlt
+ && i_target->tryGetAttr<ATTR_ALTFSI_MASTER_CHIP>(epath) )
+ {
+ TRACFCOMP(g_trac_fsi,"Using alt path for %.8X",i_target);
+ info.master = targetService().toTarget(epath);
+
+ if( i_target->tryGetAttr<ATTR_ALTFSI_MASTER_PORT>(info.port) )
+ {
+ if( i_target->tryGetAttr<ATTR_FSI_SLAVE_CASCADE>
+ (info.cascade) )
+ {
+ if( !i_target->tryGetAttr<ATTR_FSI_OPTION_FLAGS>
+ (info.flagbits) )
+ {
+ info.master = NULL;
+ }
+ }
+ else
+ {
+ info.master = NULL;
+ }
+ }
+ else
+ {
+ info.master = NULL;
+ }
+ }
+ else
+ {
+ info.master = NULL;
+ }
+ }
+ }
+
+
+ if( (info.master == NULL)
+ || (info.type == FSI_MASTER_TYPE_NO_MASTER)
+ || (info.port == UINT8_MAX) )
+ {
+ info.master = NULL;
+ info.type = FSI_MASTER_TYPE_NO_MASTER;
+ info.port = UINT8_MAX;
+ info.cascade = 0;
+ info.flags = 0;
+ info.linkid.id = 0;
+ }
+ else
+ {
+ TARGETING::EntityPath master_phys;
+ if( info.master->tryGetAttr<TARGETING::ATTR_PHYS_PATH>(master_phys) )
+ {
+ info.linkid.node =
+ master_phys.pathElementOfType(TARGETING::TYPE_NODE).instance;
+ info.linkid.proc =
+ master_phys.pathElementOfType(TARGETING::TYPE_PROC).instance;
+ info.linkid.type = static_cast<uint8_t>(info.type);
+ info.linkid.port = info.port;
+ }
+ }
+
+ TRACDCOMP( g_trac_fsi,
+ "getFsiInfoFromAttr> i_target=%.8X : master=%.8X, type=%X",
+ TARGETING::get_huid(i_target),
+ TARGETING::get_huid(info.master), info.type );
+ TRACDCOMP( g_trac_fsi,
+ "getFsiInfoFromAttr> port=%X, cascade=%X, flags=%X, linkid=%.8X",
+ info.port, info.cascade, info.flags, info.port );
+ return info;
+}
+
+
diff --git a/src/usr/fsi/runtime/rt_fsi.H b/src/usr/fsi/runtime/rt_fsi.H
new file mode 100644
index 000000000..d8efa6f56
--- /dev/null
+++ b/src/usr/fsi/runtime/rt_fsi.H
@@ -0,0 +1,118 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/fsi/runtime/rt_fsi.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef _RT_FSI_H_
+#define _RT_FSI_H_
+
+#include <fsi/fsiif.H>
+#include <map>
+#include "fsi_common.H"
+
+class RtFsi
+{
+
+ public:
+ /**
+ * @brief Retrieve some FSI attribute information
+ *
+ * @param[in] i_slave Slave Chip Target to query
+ * @param[out] o_info FSI Link Information
+ *
+ */
+ void getFsiLinkInfo( TARGETING::Target* i_slave,
+ FSI::FsiLinkInfo_t& o_info);
+
+ protected:
+ /**
+ * @brief Constructor
+ */
+ RtFsi();
+
+ /**
+ * @brief Destructor
+ */
+ ~RtFsi();
+
+ /**
+ * @brief Figure out the optimal OPB Master to use and generate a
+ * complete FSI address relative to that master based on the target
+ * and the FSI offset within that target
+ *
+ * @param[inout] io_addrInfo FSI addressing information,
+ * expects fsiTarg and relAddr to be populated as input
+ *
+ * @return errlHndl_t NULL on success
+ */
+ errlHndl_t genFullFsiAddr(FSI::FsiAddrInfo_t& io_addrInfo);
+
+
+ /**
+ * @brief Retrieve the connection information needed to access FSI
+ * registers within the given chip target
+ *
+ * @param[in] i_target Target of FSI Slave to access
+ *
+ * @return FsiChipInfo_t FSI Chip Information
+ */
+ FSI::FsiChipInfo_t getFsiInfo( TARGETING::Target* i_target );
+
+ /**
+ * @brief Retrieve the connection information needed to access FSI
+ * registers within the given chip target from attributes
+ *
+ * @param[in] i_target Target of FSI Slave to access
+ *
+ * @return FsiChipInfo_t FSI Chip Information
+ */
+ FSI::FsiChipInfo_t getFsiInfoFromAttr( TARGETING::Target* i_target );
+
+
+ /************************
+ * VARIABLES
+ ************************/
+
+ /**
+ * Master processor target
+ */
+ TARGETING::Target* iv_master;
+
+ /**
+ * Cache of FSI connection information gleaned from attributes
+ * Indexed by Target*, returns FsiChipInfo_t
+ */
+ std::map<TARGETING::Target*,FSI::FsiChipInfo_t> iv_fsiInfoMap;
+
+ /**
+ * Mutex to protect the internal maps
+ */
+ mutex_t iv_dataMutex;
+
+ /**
+ * Using alternate master
+ */
+ uint8_t iv_useAlt;
+
+};
+
+#endif
OpenPOWER on IntegriCloud