diff options
-rw-r--r-- | src/include/usr/fsi/fsiif.H | 7 | ||||
-rw-r--r-- | src/include/usr/pnor/pnorif.H | 16 | ||||
-rw-r--r-- | src/usr/fsi/fsidd.C | 31 | ||||
-rw-r--r-- | src/usr/fsi/test/fsiddtest.H | 92 | ||||
-rw-r--r-- | src/usr/pnor/pnordd.C | 33 | ||||
-rw-r--r-- | src/usr/pnor/pnordd.H | 16 | ||||
-rw-r--r-- | src/usr/pnor/sfcdd.H | 11 |
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(); |