summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/fsi/fsiif.H7
-rw-r--r--src/include/usr/pnor/pnorif.H16
-rw-r--r--src/usr/fsi/fsidd.C31
-rw-r--r--src/usr/fsi/test/fsiddtest.H92
-rw-r--r--src/usr/pnor/pnordd.C33
-rw-r--r--src/usr/pnor/pnordd.H16
-rw-r--r--src/usr/pnor/sfcdd.H11
7 files changed, 190 insertions, 16 deletions
diff --git a/src/include/usr/fsi/fsiif.H b/src/include/usr/fsi/fsiif.H
index 756dbb7b0..5ab2e449e 100644
--- a/src/include/usr/fsi/fsiif.H
+++ b/src/include/usr/fsi/fsiif.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* [+] 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. */
@@ -109,10 +111,11 @@ struct FsiLinkInfo_t
uint8_t link; ///< Which link is this chip hanging off of
uint8_t cascade; ///< Slave cascade position
uint8_t mPort; ///< FSI Master port (0=A,1=B)
+ uint32_t baseAddr; ///< Base FSI Address for this chip
FsiLinkInfo_t() :
master(NULL), type(TARGETING::FSI_MASTER_TYPE_NO_MASTER),
- link(0xFF), cascade(0), mPort(0)
+ link(0xFF), cascade(0), mPort(0), baseAddr(UINT32_MAX)
{};
};
diff --git a/src/include/usr/pnor/pnorif.H b/src/include/usr/pnor/pnorif.H
index 26890771a..00f80f421 100644
--- a/src/include/usr/pnor/pnorif.H
+++ b/src/include/usr/pnor/pnorif.H
@@ -183,6 +183,22 @@ enum sbeSeepromSide_t
errlHndl_t getSbeBootSeeprom(TARGETING::Target* i_target,
sbeSeepromSide_t& o_bootSide);
+
+/** Information about PNOR Layout */
+struct PnorInfo_t
+{
+ uint32_t mmioOffset; //< Address of MMIO access
+ uint32_t norWorkarounds; //< NOR flash workarounds
+ uint32_t flashSize; //< Size of PNOR in bytes
+};
+
+/**
+ * @brief Retrieve some information about the PNOR/SFC hardware
+ *
+ * @param[out] o_pnorInfo Information about PNOR
+ */
+void getPnorInfo( PnorInfo_t& o_pnorInfo );
+
}
#endif
diff --git a/src/usr/fsi/fsidd.C b/src/usr/fsi/fsidd.C
index 7f313aa7d..6e7ae8aea 100644
--- a/src/usr/fsi/fsidd.C
+++ b/src/usr/fsi/fsidd.C
@@ -1806,15 +1806,15 @@ errlHndl_t FsiDD::genFullFsiAddr(FsiAddrInfo_t& io_addrInfo)
//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;
}
- //pull the FSI info out for this target
- io_addrInfo.accessInfo = getFsiInfo( io_addrInfo.fsiTarg );
-
TRACU1COMP( 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
@@ -3011,17 +3011,26 @@ FsiDD::FsiChipInfo_t FsiDD::getFsiInfo( TARGETING::Target* i_target )
void FsiDD::getFsiLinkInfo( TARGETING::Target* i_slave,
FSI::FsiLinkInfo_t& o_info )
{
- FsiChipInfo_t info = getFsiInfo( i_slave );
- o_info.master = info.master;
- o_info.type = info.type;
- o_info.link = info.port;
- o_info.cascade = info.cascade;
+ FsiAddrInfo_t addr_info( i_slave, 0x0 );
+ errlHndl_t tmp_err = genFullFsiAddr( addr_info );
+ if( tmp_err )
+ {
+ TRACFCOMP( g_trac_fsi, "Error getting FsiLinkInfo for %.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( info.master
- && (info.master != iv_master )
- && (getFsiInfo(info.master).flagbits.flipPort) )
+ if( addr_info.accessInfo.master
+ && (addr_info.accessInfo.master != iv_master )
+ && (getFsiInfo(addr_info.accessInfo.master).flagbits.flipPort) )
{
o_info.mPort = 1;
}
+ o_info.baseAddr = addr_info.absAddr;
}
diff --git a/src/usr/fsi/test/fsiddtest.H b/src/usr/fsi/test/fsiddtest.H
index 5d6eaaabc..ab409bc78 100644
--- a/src/usr/fsi/test/fsiddtest.H
+++ b/src/usr/fsi/test/fsiddtest.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* [+] 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. */
@@ -445,6 +447,94 @@ class FsiDDTest : public CxxTest::TestSuite
TRACFCOMP( g_trac_fsi, "FsiDDTest::test_FFDC> Finish" );
};
+
+ /**
+ * @brief FSI DD test - FSI Link Info
+ * Spot check getFsiLinkInfo results
+ */
+ void test_getFsiLinkInfo(void)
+ {
+ TRACFCOMP( g_trac_fsi, "FsiDDTest::test_getFsiLinkInfo> Start" );
+
+ enum {
+ PROC0,
+ CENTAUR4,
+ NUM_TARGETS
+ };
+ TARGETING::Target* fsi_targets[NUM_TARGETS];
+ for( size_t x = 0; x < NUM_TARGETS; x++ )
+ {
+ fsi_targets[x] = NULL;
+ }
+
+ TARGETING::Target* fsi_target = NULL;
+
+ // master processor target
+ TARGETING::EntityPath epath(TARGETING::EntityPath::PATH_PHYSICAL);
+ epath.addLast(TARGETING::TYPE_SYS,0);
+ epath.addLast(TARGETING::TYPE_NODE,0);
+ epath.addLast(TARGETING::TYPE_PROC,0);
+ fsi_target = TARGETING::targetService().toTarget(epath);
+ fsi_targets[PROC0] = fsi_target;
+
+ // local centaur target (physical:sys-0/node-0/membuf-4)
+ epath.removeLast();
+ epath.addLast(TARGETING::TYPE_MEMBUF,4);
+ fsi_target = TARGETING::targetService().toTarget(epath);
+ fsi_targets[CENTAUR4] = fsi_target;
+
+
+
+ // loop through all of the targets we defined to
+ // check the data
+ for( size_t x = 0; x < NUM_TARGETS; x++ )
+ {
+ if( fsi_targets[x] == NULL )
+ {
+ continue;
+ }
+
+ // Get the FSI port info for this target
+ TARGETING::FSI_MASTER_TYPE type =
+ fsi_targets[x]->getAttr<TARGETING::ATTR_FSI_MASTER_TYPE>();
+ uint8_t slave_port =
+ fsi_targets[x]->getAttr<TARGETING::ATTR_FSI_MASTER_PORT>();
+ TARGETING::EntityPath masterpath =
+ fsi_targets[x]->getAttr<TARGETING::ATTR_FSI_MASTER_CHIP>();
+ TARGETING::Target* master =
+ TARGETING::targetService().toTarget(masterpath);
+ uint8_t master_port = 0;
+ if( type != TARGETING::FSI_MASTER_TYPE_NO_MASTER )
+ {
+ master_port =
+ master->getAttr<TARGETING::ATTR_FSI_MASTER_PORT>()+1;
+ }
+
+ TRACFCOMP( g_trac_fsi, "sport=%d, mport=%d, master=%.8X, type=%d",slave_port,master_port, TARGETING::get_huid(master), master_port);
+ // Compute the offset
+ // CMFSI ports start at 0x040000 and increment by 0x008000
+ // MFSI ports start at 0x080000 and increment by 0x080000
+ // (local CMFSI ports have no MFSI offset)
+ uint32_t offset = (master_port * 0x080000);
+ if( type == TARGETING::FSI_MASTER_TYPE_CMFSI )
+ {
+ offset += ((slave_port * 0x008000) + 0x040000);
+ }
+
+ // Now call the interface we want to test
+ FSI::FsiLinkInfo_t linkinfo;
+ FSI::getFsiLinkInfo( fsi_targets[x], linkinfo );
+
+ // Compare the results
+ TRACFCOMP( g_trac_fsi, "FsiDDTest::test_getFsiLinkInfo> Data for %.8X: exp=%.6X, act=%.6X", TARGETING::get_huid(fsi_targets[x]), offset, linkinfo.baseAddr );
+ if( linkinfo.baseAddr != offset )
+ {
+ TS_FAIL( "FsiDDTest::test_getFsiLinkInfo> Mismatch for %.8X: exp=%.6X, act=%.6X", TARGETING::get_huid(fsi_targets[x]), offset, linkinfo.baseAddr );
+ }
+ }
+
+ TRACFCOMP( g_trac_fsi, "FsiDDTest::test_getFsiLinkInfo> End" );
+ }
};
diff --git a/src/usr/pnor/pnordd.C b/src/usr/pnor/pnordd.C
index 0d4789869..13667ce3a 100644
--- a/src/usr/pnor/pnordd.C
+++ b/src/usr/pnor/pnordd.C
@@ -191,6 +191,19 @@ bool usingL3Cache()
return Singleton<PnorDD>::instance().usingL3Cache();
}
+/**
+ * @brief Retrieve some information about the PNOR/SFC hardware
+ */
+void getPnorInfo( PnorInfo_t& o_pnorInfo )
+{
+ o_pnorInfo.mmioOffset = 0; //LPC_SFC_MMIO_OFFSET;//@fixme-need Prachi's code for this
+ o_pnorInfo.norWorkarounds =
+ Singleton<PnorDD>::instance().getNorWorkarounds();
+ o_pnorInfo.flashSize =
+ Singleton<PnorDD>::instance().getNorSize();
+}
+
+
// Register PNORDD access functions to DD framework
DEVICE_REGISTER_ROUTE(DeviceFW::READ,
@@ -865,3 +878,23 @@ errlHndl_t PnorDD::_eraseFlash( uint32_t i_addr )
return l_err;
}
+
+/**
+ * @brief Retrieve bitstring of NOR workarounds
+ */
+uint32_t PnorDD::getNorWorkarounds( void )
+{
+ return iv_sfc->getNorWorkarounds();
+}
+
+/**
+ * @brief Retrieve size of NOR flash
+ */
+uint32_t PnorDD::getNorSize( void )
+{
+#ifdef CONFIG_PNOR_IS_32MB
+ return (32*MEGABYTE);
+#else //default to 64MB
+ return (64*MEGABYTE);
+#endif
+}
diff --git a/src/usr/pnor/pnordd.H b/src/usr/pnor/pnordd.H
index 589f60e27..94c393b76 100644
--- a/src/usr/pnor/pnordd.H
+++ b/src/usr/pnor/pnordd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2015 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -82,6 +82,19 @@ class PnorDD
bool usingL3Cache( );
+ /**
+ * @brief Retrieve bitstring of NOR workarounds
+ * @return NOR workarounds (see VendorWorkarounds in norflash.H)
+ */
+ uint32_t getNorWorkarounds( void );
+
+ /**
+ * @brief Retrieve size of NOR flash
+ * @return Size of PNOR in bytes
+ */
+ uint32_t getNorSize( void );
+
+
// Enumeration values must match those in debug framework.
enum PnorMode_t {
MODEL_UNKNOWN, /**< Invalid */
@@ -340,6 +353,7 @@ class PnorDD
*/
errlHndl_t _eraseFlash( uint32_t i_address );
+
private: // Variables
/**
diff --git a/src/usr/pnor/sfcdd.H b/src/usr/pnor/sfcdd.H
index 7c27a1e00..72285f5e0 100644
--- a/src/usr/pnor/sfcdd.H
+++ b/src/usr/pnor/sfcdd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2015 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -149,6 +149,15 @@ class SfcDD
};
/**
+ * @brief Retrieve bitstring of NOR workarounds
+ * @return NOR workarounds (see VendorWorkarounds in norflash.H)
+ */
+ uint32_t getNorWorkarounds( void )
+ {
+ return iv_flashWorkarounds;
+ };
+
+ /**
* @brief Destructor
*/
virtual ~SfcDD();
OpenPOWER on IntegriCloud