summaryrefslogtreecommitdiffstats
path: root/src/usr/pnor/pnorrp.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/pnor/pnorrp.C')
-rw-r--r--src/usr/pnor/pnorrp.C152
1 files changed, 94 insertions, 58 deletions
diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C
index 299a063f4..aeaeb222a 100644
--- a/src/usr/pnor/pnorrp.C
+++ b/src/usr/pnor/pnorrp.C
@@ -44,6 +44,7 @@
#include <endian.h>
#include <util/align.H>
#include <config.h>
+#include "pnor_common.H"
extern trace_desc_t* g_trac_pnor;
@@ -192,7 +193,9 @@ void* wait_for_message( void* unused )
* @brief Constructor
*/
PnorRP::PnorRP()
-: iv_TOC_used(0)
+: iv_activeTocOffsets(SIDE_A_TOC_0_OFFSET,SIDE_A_TOC_1_OFFSET)
+,iv_altTocOffsets(SIDE_B_TOC_0_OFFSET,SIDE_B_TOC_1_OFFSET)
+,iv_TOC_used(TOC_0)
,iv_msgQ(NULL)
,iv_startupRC(0)
{
@@ -231,12 +234,28 @@ void PnorRP::initDaemon()
do
{
- // read the TOC in the PNOR to compute the sections
- l_errhdl = readTOC();
- if( l_errhdl )
+ // @TODO RTC: 120062 - Determine which side is Golden
+ // Default TOC offsets set to side A. If two side support is enabled,
+ // check which SEEPROM hostboot booted from
+#ifdef CONFIG_TWO_SIDE_SUPPORT
+ TARGETING::Target* pnor_target = TARGETING::
+ MASTER_PROCESSOR_CHIP_TARGET_SENTINEL;
+ // Get correct TOC
+ PNOR::sbeSeepromSide_t l_bootSide;
+ PNOR::getSbeBootSeeprom(pnor_target, l_bootSide);
+ if (l_bootSide == PNOR::SBE_SEEPROM1)
{
- break;
+ TRACFCOMP( g_trac_pnor, "PnorRP::initDaemon> Booting from Side B");
+ iv_activeTocOffsets.first = SIDE_B_TOC_0_OFFSET;
+ iv_activeTocOffsets.second = SIDE_B_TOC_1_OFFSET;
+ iv_altTocOffsets.first = SIDE_A_TOC_0_OFFSET;
+ iv_altTocOffsets.second = SIDE_A_TOC_0_OFFSET;
}
+ else
+ {
+ TRACFCOMP( g_trac_pnor, "PnorRP::initDaemon> Booting from Side A");
+ }
+#endif
// create a message queue
iv_msgQ = msg_q_create();
@@ -253,7 +272,7 @@ void PnorRP::initDaemon()
* @userdata1 Requested Address
* @userdata2 rc from mm_alloc_block
* @devdesc PnorRP::initDaemon> Error from mm_alloc_block
- * @custdesc A problem occurred while accessing the boot flash.
+ * @custdesc A problem occurred while accessing the boot flash.
*/
l_errhdl = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
@@ -270,9 +289,14 @@ void PnorRP::initDaemon()
INITSERVICE::registerBlock(reinterpret_cast<void*>(BASE_VADDR),
TOTAL_SIZE,PNOR_PRIORITY);
- // Need to set permissions to R/W
- rc = mm_set_permission((void*) BASE_VADDR,TOTAL_SIZE,
- WRITABLE | WRITE_TRACKED);
+ // Read the TOC in the PNOR to compute the sections and set their
+ // correct permissions
+ l_errhdl = readTOC();
+ if( l_errhdl )
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"PnorRP::initDaemon: Failed to readTOC");
+ break;
+ }
// start task to wait on the queue
task_create( wait_for_message, NULL );
@@ -319,7 +343,7 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
* @userdata1 Requested Section
* @userdata2 Startup RC
* @devdesc PnorRP::getSectionInfo> RP not properly initialized
- * @custdesc A problem occurred while accessing the boot flash.
+ * @custdesc A problem occurred while accessing the boot flash.
*/
l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORRP_GETSECTIONINFO,
@@ -346,7 +370,7 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
* @userdata1 Requested Section
* @userdata2 TOC used
* @devdesc PnorRP::getSectionInfo> Invalid Address for read/write
- * @custdesc A problem occurred while accessing the boot flash.
+ * @custdesc A problem occurred while accessing the boot flash.
*/
l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORRP_GETSECTIONINFO,
@@ -378,12 +402,13 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
!= 0) ? true : false;
o_info.sha512perEC = ((iv_TOC[id].version & FFS_VERS_SHA512_PER_EC)
!= 0) ? true : false;
+ o_info.readOnly = ((iv_TOC[id].misc & FFS_MISC_READ_ONLY)
+ != 0) ? true : false;
}
return l_errhdl;
}
-
/**
* @brief Read the TOC and store section information
*/
@@ -395,7 +420,7 @@ errlHndl_t PnorRP::readTOC()
uint8_t* toc1Buffer = new uint8_t[PAGESIZE];
uint64_t fatal_error = 0;
do {
- l_errhdl = readFromDevice( TOC_0_OFFSET, 0, false,
+ l_errhdl = readFromDevice( iv_activeTocOffsets.first, 0, false,
toc0Buffer, fatal_error );
if (l_errhdl)
{
@@ -403,7 +428,7 @@ errlHndl_t PnorRP::readTOC()
break;
}
- l_errhdl = readFromDevice( TOC_1_OFFSET, 0, false,
+ l_errhdl = readFromDevice( iv_activeTocOffsets.second, 0, false,
toc1Buffer, fatal_error );
if (l_errhdl)
{
@@ -412,7 +437,7 @@ errlHndl_t PnorRP::readTOC()
}
l_errhdl = PNOR::parseTOC(toc0Buffer, toc1Buffer, iv_TOC_used, iv_TOC,
- BASE_VADDR);
+ BASE_VADDR);
if (l_errhdl)
{
TRACFCOMP(g_trac_pnor, "readTOC: parseTOC failed");
@@ -737,59 +762,63 @@ errlHndl_t PnorRP::computeDeviceAddr( void* i_vaddr,
o_chip = 99;
uint64_t l_vaddr = (uint64_t)i_vaddr;
- // make sure this is one of our addresses
- if( !((l_vaddr >= BASE_VADDR)
- && (l_vaddr < LAST_VADDR)) )
+ do
{
- TRACFCOMP( g_trac_pnor, "PnorRP::computeDeviceAddr> Virtual Address outside known PNOR range : i_vaddr=%p", i_vaddr );
- /*@
- * @errortype
- * @moduleid PNOR::MOD_PNORRP_WAITFORMESSAGE
- * @reasoncode PNOR::RC_INVALID_ADDRESS
- * @userdata1 Virtual Address
- * @userdata2 Base PNOR Address
- * @devdesc PnorRP::computeDeviceAddr> Virtual Address outside
- * known PNOR range
- * @custdesc A problem occurred while accessing the boot flash.
- */
- l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- PNOR::MOD_PNORRP_COMPUTEDEVICEADDR,
- PNOR::RC_INVALID_ADDRESS,
- l_vaddr,
- BASE_VADDR,
- true /*Add HB SW Callout*/);
- l_errhdl->collectTrace(PNOR_COMP_NAME);
- return l_errhdl;
- }
+ // make sure this is one of our addresses
+ if( !((l_vaddr >= BASE_VADDR)
+ && (l_vaddr < LAST_VADDR)) )
+ {
+ TRACFCOMP( g_trac_pnor, "PnorRP::computeDeviceAddr> Virtual Address outside known PNOR range : i_vaddr=%p", i_vaddr );
+ /*@
+ * @errortype
+ * @moduleid PNOR::MOD_PNORRP_WAITFORMESSAGE
+ * @reasoncode PNOR::RC_INVALID_ADDRESS
+ * @userdata1 Virtual Address
+ * @userdata2 Base PNOR Address
+ * @devdesc PnorRP::computeDeviceAddr> Virtual Address outside
+ * known PNOR range
+ * @custdesc A problem occurred while accessing the boot flash.
+ */
+ l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ PNOR::MOD_PNORRP_COMPUTEDEVICEADDR,
+ PNOR::RC_INVALID_ADDRESS,
+ l_vaddr,
+ BASE_VADDR,
+ true /*Add HB SW Callout*/);
+ l_errhdl->collectTrace(PNOR_COMP_NAME);
+ break;
+ }
- // find the matching section
- PNOR::SectionId id = PNOR::INVALID_SECTION;
- l_errhdl = computeSection( l_vaddr, id );
- if( l_errhdl )
- {
- return l_errhdl;
- }
+ // find the matching section
+ PNOR::SectionId id = PNOR::INVALID_SECTION;
+ l_errhdl = computeSection( l_vaddr, id );
+ if( l_errhdl )
+ {
+ TRACFCOMP( g_trac_pnor, "PnorRP::computeDeviceAddr> Virtual address does not match any pnor sections : i_vaddr=%p", i_vaddr );
+ break;
+ }
- // pull out the information we need to return from our global copy
- o_chip = iv_TOC[id].chip;
- o_ecc = (bool)(iv_TOC[id].integrity & FFS_INTEG_ECC_PROTECT);
- o_offset = l_vaddr - iv_TOC[id].virtAddr; //offset into section
+ // pull out the information we need to return from our global copy
+ o_chip = iv_TOC[id].chip;
+ o_ecc = (bool)(iv_TOC[id].integrity & FFS_INTEG_ECC_PROTECT);
+ o_offset = l_vaddr - iv_TOC[id].virtAddr; //offset into section
- // for ECC we need to figure out where the ECC-enhanced offset is
- // before tacking on the offset to the section
- if( o_ecc )
- {
- o_offset = (o_offset * 9) / 8;
- }
- // add on the offset of the section itself
- o_offset += iv_TOC[id].flashAddr;
+ // for ECC we need to figure out where the ECC-enhanced offset is
+ // before tacking on the offset to the section
+ if( o_ecc )
+ {
+ o_offset = (o_offset * 9) / 8;
+ }
+ // add on the offset of the section itself
+ o_offset += iv_TOC[id].flashAddr;
+ } while(0);
TRACUCOMP( g_trac_pnor, "< PnorRP::computeDeviceAddr: i_vaddr=%X, o_offset=0x%X, o_chip=%d", l_vaddr, o_offset, o_chip );
return l_errhdl;
}
/**
- * @brief Static instance function for testcase only
+ * @brief Static instance function
*/
PnorRP& PnorRP::getInstance()
{
@@ -987,3 +1016,10 @@ errlHndl_t PnorRP::fixECC (PNOR::SectionId i_section)
TRACFCOMP(g_trac_pnor, EXIT_MRK"PnorRP::fixECC");
return l_err;
}
+
+uint64_t PnorRP::getTocOffset(TOCS i_toc) const
+{
+ // Can use a ternary operator because there are only 2 TOCs per side
+ return (i_toc == TOC_0) ? iv_activeTocOffsets.first :
+ iv_activeTocOffsets.second;
+}
OpenPOWER on IntegriCloud