Skip to content

Commit

Permalink
Bootloader hangs if it can't find first TOC
Browse files Browse the repository at this point in the history
Revise logic in Bootloader for locating the PNOR TOC if it cannot find
the TOC at the end of PNOR or if the TOC there fails verification
checks.  Use the start of PNOR if it was determined, else search back
through PNOR by PAGESIZE decrements.

Change-Id: I51d0c0f0319bce12ec40d41df2b03f787a3964fd
RTC: 164445
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/40638
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Reviewed-by: Corey V. Swenson <cswenson@us.ibm.com>
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
  • Loading branch information
mgloff authored and wghoffa committed May 26, 2017
1 parent 5e1b4a6 commit 52ff15c
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 53 deletions.
73 changes: 36 additions & 37 deletions src/bootloader/bl_pnorAccess.C
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <bootloader/hbblreasoncodes.H>
#include <util/singleton.H>
#include <bootloader/bootloader.H>
#include <lpc_const.H>
#ifdef PNORUTILSTEST_H
#define BOOTLOADER_TRACE(args) TRACFCOMP(g_trac_pnor,"##args")
#define BOOTLOADER_TRACE_W_BRK(args) TRACFCOMP(g_trac_pnor,"##args")
Expand Down Expand Up @@ -61,7 +62,7 @@ void bl_pnorAccess::readTOC(uint8_t i_tocBuffer[PNOR::TOC_SIZE],
if(o_errCode != PNOR::NO_ERROR)
{
BOOTLOADER_TRACE_W_BRK(BTLDR_TRC_PA_READTOC_CHKNULLBUFFER_NULL);
// Set TI information but caller decides to TI or not
// Always TI if NULL pointer is passed in
/*@
* @errortype
* @moduleid Bootloader::MOD_PNORACC_READTOC
Expand All @@ -78,17 +79,12 @@ void bl_pnorAccess::readTOC(uint8_t i_tocBuffer[PNOR::TOC_SIZE],
bl_terminate(Bootloader::MOD_PNORACC_READTOC,
Bootloader::RC_CHK_NULL_BUFFER,
reinterpret_cast<uint64_t>(i_tocBuffer),
o_errCode,
false);
o_errCode);
break;
}

BOOTLOADER_TRACE(BTLDR_TRC_PA_READTOC_CHECKNULLBUFFER_RTN);

//Subtract the size of the pnor from the end address to find the start
o_pnorStart = i_pnorEnd -
(l_ffs_hdr->block_size * l_ffs_hdr->block_count) + 1;

//Do a checksum on the header
if(PNOR::pnor_ffs_checksum(l_ffs_hdr, FFS_HDR_SIZE) != 0)
{
Expand Down Expand Up @@ -149,8 +145,12 @@ void bl_pnorAccess::readTOC(uint8_t i_tocBuffer[PNOR::TOC_SIZE],
false);
break;
}

BOOTLOADER_TRACE(BTLDR_TRC_PA_READTOC_CHECKHEADER_RTN);

//Subtract the size of the pnor from the end address to find the start
o_pnorStart = i_pnorEnd -
(l_ffs_hdr->block_size * l_ffs_hdr->block_count) + 1;

//if an error is found with an entry we use this variable to hold
//the value of the entry. That way we can record which entry is causing
Expand Down Expand Up @@ -184,25 +184,25 @@ void bl_pnorAccess::readTOC(uint8_t i_tocBuffer[PNOR::TOC_SIZE],
false);
break;
}
BOOTLOADER_TRACE(BTLDR_TRC_PA_READTOC_PARSEENTRIES_RTN);


BOOTLOADER_TRACE(BTLDR_TRC_PA_READTOC_PARSEENTRIES_RTN);
} while(0);
}

void bl_pnorAccess::findTOC(uint64_t i_pnorEnd, PNOR::SectionData_t * o_TOC,
uint32_t& o_errCode, uint8_t& o_tocUsed,
uint64_t& o_pnorStart)
uint32_t& o_errCode, uint64_t& o_pnorStart)
{
uint8_t *l_tocBuffer = Bootloader::g_blScratchSpace;

//The first TOC is 1 TOC size + 1 page back from the end of the flash (+ 1)
uint64_t l_mmioAddr = i_pnorEnd - PNOR::TOC_OFFSET_FROM_TOP_OF_FLASH;

do
{
//@TODO RTC:138268 Set up multiple side of PNOR for bootloader
o_errCode = 0;
o_tocUsed = 0;
//Copy Table of Contents from PNOR flash to a local buffer
//The first TOC is 2 TOC sizes back from the end of the flash (+ 1)
Bootloader::handleMMIO(i_pnorEnd - PNOR::TOC_OFFSET_FROM_TOP_OF_FLASH,
Bootloader::handleMMIO(l_mmioAddr,
reinterpret_cast<uint64_t>(l_tocBuffer),
(PNOR::TOC_SIZE),
Bootloader::WORDSIZE);
Expand All @@ -214,35 +214,35 @@ void bl_pnorAccess::findTOC(uint64_t i_pnorEnd, PNOR::SectionData_t * o_TOC,
if(o_errCode == PNOR::NO_ERROR)
{
BOOTLOADER_TRACE(BTLDR_TRC_PA_FINDTOC_TOC1_READTOC_RTN);
o_tocUsed = 0;
break;
}
else
{
// @TODO RTC:164445 Can remove if there is a way to find another TOC
// TI with data from readTOC
terminateExecuteTI();

//If the first toc was invalid, look for the backup in the start
Bootloader::handleMMIO(o_pnorStart,
reinterpret_cast<uint64_t>(l_tocBuffer),
(PNOR::TOC_SIZE),
Bootloader::WORDSIZE);

o_errCode = 0;
readTOC(l_tocBuffer, o_errCode, o_TOC, o_pnorStart, i_pnorEnd);
if(o_errCode == PNOR::NO_ERROR)
if(o_pnorStart != NULL)
{
// Use PNOR start address for next MMIO
BOOTLOADER_TRACE(BTLDR_TRC_PA_FINDTOC_USE_PNOR_START);
l_mmioAddr = o_pnorStart;
}
else
{
o_tocUsed = 1;
// Adjust to new location in PNOR flash for next MMIO
BOOTLOADER_TRACE(BTLDR_TRC_PA_FINDTOC_ADJUST_PNOR_ADDR);
l_mmioAddr -= PAGESIZE;
}

// Check that address is still in FW space
if(l_mmioAddr < (LPC::LPC_PHYS_BASE + LPC::LPCHC_FW_SPACE))
{
BOOTLOADER_TRACE_W_BRK(BTLDR_TRC_PA_FINDTOC_READTOC_ERR);

// TI with data from readTOC
terminateExecuteTI();

break;
}
BOOTLOADER_TRACE_W_BRK(BTLDR_TRC_PA_FINDTOC_READTOC_ERR);
// TI with data from readTOC
terminateExecuteTI();
}

break;
}while(0);
}while(1);
}

/**
Expand All @@ -251,15 +251,14 @@ void bl_pnorAccess::findTOC(uint64_t i_pnorEnd, PNOR::SectionData_t * o_TOC,
void bl_pnorAccess::getHBBSection(uint64_t i_pnorEnd,
PNOR::SectionData_t& o_hbbSection,
uint32_t& o_errCode,
uint8_t& o_tocUsed,
uint64_t& o_pnorStart)
{
BOOTLOADER_TRACE(BTLDR_TRC_PA_GETHBBSECTION_START);
do
{
PNOR::SectionData_t l_TOC[PNOR::NUM_SECTIONS+1];

findTOC(i_pnorEnd, l_TOC, o_errCode, o_tocUsed, o_pnorStart);
findTOC(i_pnorEnd, l_TOC, o_errCode, o_pnorStart);

if(o_errCode != PNOR::NO_ERROR)
{
Expand Down
2 changes: 0 additions & 2 deletions src/bootloader/bootloader.C
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ namespace Bootloader{
uint64_t l_pnorStart = 0;

uint32_t l_errCode = PNOR::NO_ERROR;
uint8_t l_tocUsed = 0;
g_blScratchSpace = reinterpret_cast<uint8_t*>(HBBL_SCRATCH_SPACE_ADDR);
g_blData->secureRomValid = false;

Expand All @@ -306,7 +305,6 @@ namespace Bootloader{
bl_pnorAccess::getHBBSection(l_pnorEnd,
g_blData->bl_hbbSection,
l_errCode,
l_tocUsed,
l_pnorStart);
BOOTLOADER_TRACE(BTLDR_TRC_MAIN_GETHBBSECTION_RTN );

Expand Down
4 changes: 2 additions & 2 deletions src/build/debug/Hostboot/BlTrace.pm
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ my %traceText = (
"30" => "PNOR Access getHBBSection started",
"31" => "PNOR Access findTOC handleMMIO to copy TOC ONE returned",
"32" => "PNOR Access findTOC readTOC for TOC ONE returned",
"33" => "PNOR Access findTOC handleMMIO to copy TOC TWO returned",
"34" => "PNOR Access findTOC readTOC for TOC TWO returned",
"33" => "PNOR Access findTOC use PNOR start address",
"34" => "PNOR Access findTOC adjust PNOR address",
"35" => "PNOR Access getHBBSection findTOC returned",
"41" => "PNOR Access readTOC zeroSection returned",
"42" => "PNOR Access readTOC checkForNullBuffer returned",
Expand Down
12 changes: 4 additions & 8 deletions src/include/bootloader/bl_pnorAccess.H
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,2016 */
/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -56,16 +56,13 @@ class bl_pnorAccess
*
* @param[out] o_errCode Anything besides PNOR:NO_ERROR is an error
*
* @param[out] o_tocUsed Tells you which table of contents was used
*
* @param[out] o_pnorStart The MMIO address of the start of PNOR
*
* @return void
*/
static void getHBBSection(uint64_t i_pnorEnd,
PNOR::SectionData_t& o_hbbSection,
uint32_t& o_errCode,
uint8_t& o_tocUsed,
uint64_t& o_pnorStart);

private:
Expand All @@ -85,7 +82,8 @@ static void getHBBSection(uint64_t i_pnorEnd,
* @return void
*/
static void readTOC(uint8_t i_tocBuffer[PNOR::TOC_SIZE], uint32_t & o_errCode,
PNOR::SectionData_t * o_TOC, uint64_t& o_pnorStart, uint64_t i_pnorEnd);
PNOR::SectionData_t * o_TOC, uint64_t& o_pnorStart,
uint64_t i_pnorEnd);

/**
* @brief Find a valid TOC within specified side of pnor flash
Expand All @@ -97,14 +95,12 @@ static void readTOC(uint8_t i_tocBuffer[PNOR::TOC_SIZE], uint32_t & o_errCode,
*
* @param[out] o_errCode Anything besides PNOR:NO_ERROR is an error
*
* @param[out] o_tocUsed Tells you which table of contents was used
*
* @param[out] o_pnorStart The MMIO address of the start of PNOR
*
* @return void
*/
static void findTOC(uint64_t i_pnorEnd, PNOR::SectionData_t * o_TOC,
uint32_t& o_errCode, uint8_t& o_tocUsed, uint64_t& o_pnorStart);
uint32_t& o_errCode, uint64_t& o_pnorStart);

};

Expand Down
8 changes: 4 additions & 4 deletions src/include/bootloader/bootloader_trace.H
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ enum BootloaderTraces
/** Bootloader PNOR Access findTOC readTOC for TOC ONE returned */
BTLDR_TRC_PA_FINDTOC_TOC1_READTOC_RTN = 0x32,

/** Bootloader PNOR Access findTOC handleMMIO to copy TOC TWO returned */
BTLDR_TRC_PA_FINDTOC_TOC2_HANDLEMMIO_RTN = 0x33,
/** Bootloader PNOR Access findTOC use PNOR start address */
BTLDR_TRC_PA_FINDTOC_USE_PNOR_START = 0x33,

/** Bootloader PNOR Access findTOC readTOC for TOC TWO returned */
BTLDR_TRC_PA_FINDTOC_TOC2_READTOC_RTN = 0x34,
/** Bootloader PNOR Access findTOC adjust PNOR address */
BTLDR_TRC_PA_FINDTOC_ADJUST_PNOR_ADDR = 0x34,

/** Bootloader PNOR Access getHBBSection findTOC returned */
BTLDR_TRC_PA_GETHBBSECTION_FINDTOC_RTN = 0x35,
Expand Down

0 comments on commit 52ff15c

Please sign in to comment.