summaryrefslogtreecommitdiffstats
path: root/src/usr/pnor
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/pnor')
-rw-r--r--src/usr/pnor/pnorrp.C88
-rw-r--r--src/usr/pnor/pnorrp.H15
-rw-r--r--src/usr/pnor/test/pnorrptest.H7
3 files changed, 73 insertions, 37 deletions
diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C
index 0d4915ed0..c3deb16ed 100644
--- a/src/usr/pnor/pnorrp.C
+++ b/src/usr/pnor/pnorrp.C
@@ -345,7 +345,10 @@ void PnorRP::initDaemon()
//Find and read the TOC in the PNOR to compute the sections and set
//their correct permissions
- l_errhdl = findTOC();
+
+ size_t l_sizeOfToc = 0;
+
+ l_errhdl = findTOC(l_sizeOfToc);
if( l_errhdl )
{
TRACFCOMP(g_trac_pnor, ERR_MRK"PnorRP::initDaemon: Failed to findTOC");
@@ -353,13 +356,13 @@ void PnorRP::initDaemon()
INITSERVICE::doShutdown(PNOR::RC_FINDTOC_FAILED);
}
- l_errhdl = readTOC();
+ l_errhdl = readTOC(l_sizeOfToc);
if( l_errhdl )
{
TRACFCOMP(g_trac_pnor, ERR_MRK"PnorRP::initDaemon: Failed to readTOC");
break;
}
- l_errhdl = setSideInfo ();
+ l_errhdl = setSideInfo (l_sizeOfToc);
if(l_errhdl)
{
TRACFCOMP(g_trac_pnor, "PnorRP::initDaemon> setSideInfo failed");
@@ -671,10 +674,11 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
/*
* @brief Finds the toc locations based on hostboot base address
*/
-errlHndl_t PnorRP::findTOC()
+errlHndl_t PnorRP::findTOC(size_t & o_tocSize)
{
TRACDCOMP(g_trac_pnor, ENTER_MRK"PnorRP::findTOC...");
errlHndl_t l_err = NULL;
+ uint8_t *realTocBuffer = nullptr;
do {
const uint32_t l_shiftAmount = 32;
uint64_t l_chip = 0;
@@ -683,7 +687,7 @@ errlHndl_t PnorRP::findTOC()
uint64_t l_toc = PNOR::PNOR_SIZE - 1;
ffs_hdr* l_ffs_hdr = 0;
uint64_t l_hbbAddr = 0;
- uint8_t l_tocBuffer [PAGESIZE];
+ uint8_t l_tmpTocBuffer [PAGESIZE];
//get the HBB Address we booted from
l_err = PNOR::mmioToPhysicalOffset(l_hbbAddr);
@@ -703,7 +707,7 @@ errlHndl_t PnorRP::findTOC()
{
//Align HBB down -- looking at 0x0 or 0x2000000
l_toc = ALIGN_DOWN_X(l_tempHBB, l_shiftAmount*MEGABYTE);
- l_err = readFromDevice(l_toc, l_chip, false, l_tocBuffer,
+ l_err = readFromDevice(l_toc, l_chip, false, l_tmpTocBuffer,
l_fatalError);
if(l_err)
{
@@ -712,7 +716,7 @@ errlHndl_t PnorRP::findTOC()
break;
}
- l_ffs_hdr = (ffs_hdr*)l_tocBuffer;
+ l_ffs_hdr = (ffs_hdr*)l_tmpTocBuffer;
l_foundTOC = ((l_ffs_hdr->magic == FFS_MAGIC) &&
(PNOR::pnor_ffs_checksum(l_ffs_hdr,FFS_HDR_SIZE) == 0));
if (!l_foundTOC)
@@ -720,7 +724,7 @@ errlHndl_t PnorRP::findTOC()
//If TOC not found at 0x0 or 0x2000000
//Align HBB down + 8000 -- looking at 0x8000 or 0x2008000
l_toc += TOC_SIZE;
- l_err = readFromDevice(l_toc, l_chip, false, l_tocBuffer,
+ l_err = readFromDevice(l_toc, l_chip, false, l_tmpTocBuffer,
l_fatalError);
if(l_err)
{
@@ -729,7 +733,7 @@ errlHndl_t PnorRP::findTOC()
break;
}
- l_ffs_hdr = (ffs_hdr*)l_tocBuffer;
+ l_ffs_hdr = (ffs_hdr*)l_tmpTocBuffer;
l_foundTOC =
((l_ffs_hdr->magic == FFS_MAGIC) &&
(PNOR::pnor_ffs_checksum(l_ffs_hdr, FFS_HDR_SIZE) == 0));
@@ -742,7 +746,7 @@ errlHndl_t PnorRP::findTOC()
// -- looking at 0x1FF8000 or 0x3FF8000
l_toc = ALIGN_X(l_tempHBB, l_shiftAmount*MEGABYTE);
l_toc -= TOC_SIZE;
- l_err = readFromDevice(l_toc, l_chip, false, l_tocBuffer,
+ l_err = readFromDevice(l_toc, l_chip, false, l_tmpTocBuffer,
l_fatalError);
if(l_err)
{
@@ -751,7 +755,7 @@ errlHndl_t PnorRP::findTOC()
break;
}
- l_ffs_hdr = (ffs_hdr*)l_tocBuffer;
+ l_ffs_hdr = (ffs_hdr*)l_tmpTocBuffer;
l_foundTOC =
((l_ffs_hdr->magic == FFS_MAGIC) &&
(PNOR::pnor_ffs_checksum(l_ffs_hdr, FFS_HDR_SIZE) == 0));
@@ -772,6 +776,21 @@ errlHndl_t PnorRP::findTOC()
{
TRACDCOMP(g_trac_pnor, "findTOC> found at least one toc at 0x%X", l_toc);
+ //TOC might be greater than one page (4k), so need to check hdr if we need
+ //to increase the size of the buffer
+ o_tocSize = l_ffs_hdr->block_size * l_ffs_hdr->size;
+ realTocBuffer = new uint8_t[o_tocSize];
+ TARGETING::Target* pnor_target = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL;
+ l_err = DeviceFW::deviceRead(pnor_target, realTocBuffer, o_tocSize,
+ DEVICE_PNOR_ADDRESS(0,l_toc));
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_pnor,"findTOC:failed trying to copy TOC from the device into a buffer");
+ break;
+ }
+
+ l_ffs_hdr = (ffs_hdr*)realTocBuffer;
+
//look for BACKUP_PART and read it
uint64_t l_backupTOC = INVALID_OFFSET;
PNOR::findPhysicalOffset(l_ffs_hdr,"BACKUP_PART",l_backupTOC);
@@ -914,8 +933,8 @@ errlHndl_t PnorRP::findTOC()
}
else
{
- printk("no valid toc - l_foundTOC=%d, l_toc=%lX, l_tocBuffer=%p\n",
- l_foundTOC, l_toc, l_tocBuffer);
+ printk("no valid toc - l_foundTOC=%d, l_toc=%lX, l_tmpTocBuffer=%p\n",
+ l_foundTOC, l_toc, l_tmpTocBuffer);
sync();
//no valid TOC found
TRACFCOMP(g_trac_pnor, "No valid TOC found");
@@ -927,6 +946,11 @@ errlHndl_t PnorRP::findTOC()
}
} while (0);
+ if(realTocBuffer != nullptr)
+ {
+ delete[] realTocBuffer;
+ }
+
TRACDCOMP(g_trac_pnor, EXIT_MRK"findTOC");
return l_err;
}
@@ -934,28 +958,30 @@ errlHndl_t PnorRP::findTOC()
/**
* @brief Read the TOC and store section information
*/
-errlHndl_t PnorRP::readTOC()
+errlHndl_t PnorRP::readTOC(size_t i_tocSize)
{
TRACUCOMP(g_trac_pnor, "PnorRP::readTOC>" );
errlHndl_t l_errhdl = nullptr;
errlHndl_t l_primary_errhdl = nullptr;
errlHndl_t l_secondary_errhdl = nullptr;
+ TARGETING::Target* pnor_target = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL;
+
+ uint8_t* toc0Buffer = new uint8_t[i_tocSize];
+ uint8_t* toc1Buffer = new uint8_t[i_tocSize];
- uint8_t* toc0Buffer = new uint8_t[PAGESIZE];
- uint8_t* toc1Buffer = new uint8_t[PAGESIZE];
PNOR::SectionData_t l_secondary_TOC[PNOR::NUM_SECTIONS+1];
- uint64_t fatal_error = 0;
+
do {
- //Initialize toc bufferes to invalid value
+ //Initialize toc buffers to invalid value
//If these buffers are not read from device,
//then parseTOC will see invalid data
- memset(toc0Buffer, 0xFF, PAGESIZE);
- memset(toc1Buffer, 0xFF, PAGESIZE);
+ memset(toc0Buffer, 0xFF, i_tocSize);
+ memset(toc1Buffer, 0xFF, i_tocSize);
//If the first toc is at a valid offset try to read and parse it
if (iv_TocOffset[WORKING].first != INVALID_OFFSET)
{
- l_errhdl = readFromDevice(iv_TocOffset[WORKING].first, 0, false,
- toc0Buffer, fatal_error );
+ l_errhdl = DeviceFW::deviceRead(pnor_target, toc0Buffer, i_tocSize,
+ DEVICE_PNOR_ADDRESS(0,iv_TocOffset[WORKING].first));
if (l_errhdl)
{
TRACFCOMP(g_trac_pnor,"readTOC:readFromDevice failed for TOC0");
@@ -969,8 +995,8 @@ errlHndl_t PnorRP::readTOC()
//If the second toc is at a valid offset try to read and parse it
if (iv_TocOffset[WORKING].second != INVALID_OFFSET)
{
- l_errhdl = readFromDevice(iv_TocOffset[WORKING].second, 0, false,
- toc1Buffer, fatal_error );
+ l_errhdl = DeviceFW::deviceRead(pnor_target, toc1Buffer, i_tocSize,
+ DEVICE_PNOR_ADDRESS(0,iv_TocOffset[WORKING].second));
if (l_errhdl)
{
TRACFCOMP(g_trac_pnor,"readTOC:readFromDevice failed for TOC1");
@@ -1041,13 +1067,12 @@ errlHndl_t PnorRP::readTOC()
return l_errhdl;
}
-errlHndl_t PnorRP::setSideInfo ()
+errlHndl_t PnorRP::setSideInfo (size_t i_tocSize)
{
- uint64_t l_chip = 0;
- uint64_t l_fatalError = 0;
- uint8_t* l_tocBuffer = new uint8_t [PAGESIZE];
+ uint8_t* l_tocBuffer = new uint8_t [i_tocSize];
ffs_hdr* l_ffs_hdr = 0;
errlHndl_t l_err = NULL;
+ TARGETING::Target* pnor_target = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL;
for (SideId i = FIRST_SIDE; i < NUM_SIDES; i = (SideId)(i+1))
{
//id
@@ -1102,8 +1127,9 @@ errlHndl_t PnorRP::setSideInfo ()
iv_side[i].primaryTOC = l_primaryTOC;
iv_side[i].backupTOC = l_backupTOC;
- l_err = readFromDevice(l_validTOC,l_chip,
- false, l_tocBuffer,l_fatalError);
+
+ l_err = DeviceFW::deviceRead(pnor_target, l_tocBuffer, i_tocSize,
+ DEVICE_PNOR_ADDRESS(0,l_validTOC));
if(l_err)
{
TRACFCOMP(g_trac_pnor, "setSideInfo: readFromDevice failed"
@@ -1146,7 +1172,7 @@ errlHndl_t PnorRP::setSideInfo ()
//char side
iv_side[i].side =(ALIGN_DOWN_X(l_secOffset,32*MEGABYTE) == 0) ? 'A':'B';
- TRACDCOMP(g_trac_pnor, "setSideInfo: sideId:%d, isGolden:%d, "
+ TRACFCOMP(g_trac_pnor, "setSideInfo: sideId:%d, isGolden:%d, "
"isGuardPresent:%d, hasOtherSide:%d, primaryTOC: 0x%x, backupTOC"
":0x%X, HBB:0x%X, MMIO:0x%X",i, iv_side[i].isGolden,
iv_side[i].isGuardPresent,iv_side[i].hasOtherSide,
diff --git a/src/usr/pnor/pnorrp.H b/src/usr/pnor/pnorrp.H
index 868ba4ece..f3519b576 100644
--- a/src/usr/pnor/pnorrp.H
+++ b/src/usr/pnor/pnorrp.H
@@ -188,25 +188,34 @@ class PnorRP
/**
* @brief Determine the TOC offsets based on the HBB address
* System does a shutdown if any errors detected
+ *
+ * @param[out] o_tocSize The size of the table of content of PNOR in bytes
+ *
* @return Error from device
*/
- errlHndl_t findTOC();
+ errlHndl_t findTOC(size_t & o_tocSize);
/*
* @brief determines the sides information and fills the class variable
* iv_side
+ *
+ * @param[in] i_tocSize The size of the table of content of PNOR in bytes
+ *
* @return Error
*/
- errlHndl_t setSideInfo();
+ errlHndl_t setSideInfo(size_t i_tocSize);
/**
* @brief Verify both TOC's and store section information from one of the
* verified TOC's. Additionally set each section permissions
* (e.g. readOnly)
*
+ * @param[in] i_tocSize The size of the table of content of PNOR in bytes
+ *
+ *
* @return Error from device
*/
- errlHndl_t readTOC();
+ errlHndl_t readTOC(size_t i_tocSize);
/**
* @brief Message receiver
diff --git a/src/usr/pnor/test/pnorrptest.H b/src/usr/pnor/test/pnorrptest.H
index a8701e140..942eff9ab 100644
--- a/src/usr/pnor/test/pnorrptest.H
+++ b/src/usr/pnor/test/pnorrptest.H
@@ -563,8 +563,9 @@ class PnorRpTest : public CxxTest::TestSuite
PnorRP::getInstance().writeToDevice( offset, 0, false,
corruptBuffer );
+ size_t tocSize = PAGESIZE;
// Check if cur_TOC failed that other TOC is used
- PnorRP::getInstance().readTOC();
+ PnorRP::getInstance().readTOC(tocSize);
TOC_used = PnorRP::getInstance().iv_TOC_used;
TRACFCOMP(g_trac_pnor, "PnorRpTest::test_TOC : TOC %d Corrupt Header, Toc_used = %d", cur_TOC, TOC_used);
@@ -598,7 +599,7 @@ class PnorRpTest : public CxxTest::TestSuite
// Check if cur_TOC failed that other TOC is used
TOC_used = cur_TOC;
- PnorRP::getInstance().readTOC();
+ PnorRP::getInstance().readTOC(tocSize);
TOC_used = PnorRP::getInstance().iv_TOC_used;
TRACFCOMP(g_trac_pnor, "PnorRpTest::test_TOC : TOC %d Corrupt Entry, Toc_used = %d", cur_TOC, TOC_used);
@@ -612,7 +613,7 @@ class PnorRpTest : public CxxTest::TestSuite
PnorRP::getInstance().writeToDevice( offset + FFS_HDR_SIZE, 0,
false, tocEntry );
//Read the corrected entry into iv_TOC
- PnorRP::getInstance().readTOC();
+ PnorRP::getInstance().readTOC(tocSize);
}
OpenPOWER on IntegriCloud