Skip to content

Commit

Permalink
HBBL LPC Error Checking
Browse files Browse the repository at this point in the history
  - To avoid IPL delays, the LPC status register should be
    checked prior to loading the entire PNOR image
    (done via LPC). If an error condition occurs, HBBL
    should fail out.

Change-Id: I5d716213f468e28191db794bf3e5480af547b26e
CQ: SW446254
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/68442
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>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
wghoffa authored and dcrowell77 committed Feb 8, 2019
1 parent dc1efdb commit e36e001
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 27 deletions.
44 changes: 39 additions & 5 deletions src/bootloader/bl_pnorAccess.C
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -190,9 +190,13 @@ void bl_pnorAccess::readTOC(uint8_t i_tocBuffer[PNOR::TOC_SIZE],
} while(0);
}

void bl_pnorAccess::findTOC(uint64_t i_pnorEnd, PNOR::SectionData_t * o_TOC,
void bl_pnorAccess::findTOC(uint64_t i_lpcBar, PNOR::SectionData_t * o_TOC,
uint32_t& o_errCode, uint64_t& o_pnorStart)
{
//pnorEnd is the end of flash, which is base of lpc, plus
//the offset of the FW space, plus the TOP memory address in FW space
uint64_t i_pnorEnd = i_lpcBar + LPC::LPCHC_FW_SPACE + PNOR::LPC_TOP_OF_FLASH_OFFSET;

uint8_t *l_tocBuffer = g_blScratchSpace;

//The first TOC is 1 TOC size + 1 page back from the end of the flash (+ 1)
Expand All @@ -204,6 +208,35 @@ void bl_pnorAccess::findTOC(uint64_t i_pnorEnd, PNOR::SectionData_t * o_TOC,
//@TODO RTC:138268 Set up multiple side of PNOR for bootloader
o_errCode = 0;

uint64_t l_mmioStatusAddr = LPC::LPCHC_ERR_SPACE + i_lpcBar;

// First do a dummy LPC access (if an LPC error condition exists,
// an access can be necessary to get the error indicated in the
// status register. This read will force the error condition to
// properly be shown in the LPC error status reg
Bootloader::handleMMIO(l_mmioAddr,
reinterpret_cast<uint64_t>(l_tocBuffer),
Bootloader::WORDSIZE,
Bootloader::WORDSIZE);

// Now Read OPB Master Status Reg offset (LPC Addr 0xC0010000)
Bootloader::handleMMIO(l_mmioStatusAddr,
reinterpret_cast<uint64_t>(l_tocBuffer),
Bootloader::WORDSIZE,
Bootloader::WORDSIZE);

uint32_t *l_val = reinterpret_cast<uint32_t *>(l_tocBuffer);

// Check Error Condition
if (*l_val & LPC::OPB_ERROR_MASK)
{
//PNOR error found
o_errCode = PNOR::LPC_ERR;
BOOTLOADER_TRACE(BTLDR_TRC_PA_FINDTOC_TOC1_LPC_ERR);
//@TODO RTC:203989 Add LPC Error/Status Reg as part of FFDC
terminateExecuteTI();
}

//Copy Table of Contents from PNOR flash to a local buffer
Bootloader::handleMMIO(l_mmioAddr,
reinterpret_cast<uint64_t>(l_tocBuffer),
Expand Down Expand Up @@ -273,17 +306,19 @@ void bl_pnorAccess::findTOC(uint64_t i_pnorEnd, PNOR::SectionData_t * o_TOC,
/**
* @brief Get the hostboot base image
*/
void bl_pnorAccess::getHBBSection(uint64_t i_pnorEnd,
void bl_pnorAccess::getHBBSection(uint64_t i_lpcBar,
PNOR::SectionData_t& o_hbbSection,
uint32_t& o_errCode,
uint64_t& o_pnorStart)
{
BOOTLOADER_TRACE(BTLDR_TRC_PA_GETHBBSECTION_START);
do
{

o_errCode = 0;
PNOR::SectionData_t l_TOC[PNOR::NUM_SECTIONS+1];

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

if(o_errCode != PNOR::NO_ERROR)
{
Expand Down Expand Up @@ -318,6 +353,5 @@ void bl_pnorAccess::getHBBSection(uint64_t i_pnorEnd,
}
} while(0);
BOOTLOADER_TRACE(BTLDR_TRC_PA_GETHBBSECTION_FINDTOC_RTN);

}

8 changes: 2 additions & 6 deletions src/bootloader/bootloader.C
Original file line number Diff line number Diff line change
Expand Up @@ -431,11 +431,6 @@ namespace Bootloader{
? l_blConfigData->lpcBAR
: MMIO_GROUP0_CHIP0_LPC_BASE_ADDR;

//pnorEnd is the end of flash, which is base of lpc, plus
//the offset of the FW space, plus the TOP memory address in FW space
uint64_t l_pnorEnd = g_blData->blToHbData.lpcBAR + LPC::LPCHC_FW_SPACE
+ PNOR::LPC_TOP_OF_FLASH_OFFSET;

//We dont know what the start of pnor is because we dont know the size
uint64_t l_pnorStart = 0;

Expand All @@ -444,10 +439,11 @@ namespace Bootloader{

// Get location of HB base code in PNOR from TOC
// @TODO RTC:138268 Support multiple sides of PNOR in bootloader
bl_pnorAccess::getHBBSection(l_pnorEnd,
bl_pnorAccess::getHBBSection(g_blData->blToHbData.lpcBAR,
g_blData->bl_hbbSection,
l_errCode,
l_pnorStart);

BOOTLOADER_TRACE(BTLDR_TRC_MAIN_GETHBBSECTION_RTN );

if(PNOR::NO_ERROR == l_errCode)
Expand Down
13 changes: 7 additions & 6 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,2017 */
/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -49,7 +49,7 @@ class bl_pnorAccess
/**
* @brief Get the hostboot base image
*
* @param[in] i_pnorEnd MMIO address to access the end of pnor flash
* @param[in] i_lpcBar MMIO address to base LPC space
*
* @param[out] o_hbbSection Struct that holds information about the
* Hostboot Base Image Section
Expand All @@ -60,12 +60,13 @@ class bl_pnorAccess
*
* @return void
*/
static void getHBBSection(uint64_t i_pnorEnd,
static void getHBBSection(uint64_t i_lpcBar,
PNOR::SectionData_t& o_hbbSection,
uint32_t& o_errCode,
uint64_t& o_pnorStart);

private:

/**
* @brief Read in the toc and get information about each section
*
Expand All @@ -89,7 +90,7 @@ static void readTOC(uint8_t i_tocBuffer[PNOR::TOC_SIZE], uint32_t & o_errCode,
* @brief Find a valid TOC within specified side of pnor flash
side is determined by the base mmio address passed in
*
* @param[in] i_pnorEnd MMIO address to access the end of pnor flash
* @param[in] i_lpcBar MMIO address to base LPC space
*
* @param[out] o_TOC Array of section data describing contents of pnor
*
Expand All @@ -99,9 +100,9 @@ static void readTOC(uint8_t i_tocBuffer[PNOR::TOC_SIZE], uint32_t & o_errCode,
*
* @return void
*/
static void findTOC(uint64_t i_pnorEnd, PNOR::SectionData_t * o_TOC,
static void findTOC(uint64_t i_lpcBar, PNOR::SectionData_t * o_TOC,
uint32_t& o_errCode, uint64_t& o_pnorStart);

};

#endif
#endif
15 changes: 14 additions & 1 deletion src/include/bootloader/bootloader_trace.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,2017 */
/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -85,6 +85,13 @@ enum BootloaderTraces
/** Bootloader PNOR Access getHBBSection started */
BTLDR_TRC_PA_GETHBBSECTION_START = 0x30,

/** Technically the below value falls here in the IPL flow between
* BTLDR_TRC_PA_GETHBBSECTION_START + BTLDR_TRC_PA_FINDTOC_TOC1_HANDLEMMIO_RTN,
* but the value is defined below in numerical order to help guarantee
* it won't be re-used.
BTLDR_TRC_PA_FINDTOC_TOC1_LPC_RTN = 0x36,
**/

/** Bootloader PNOR Access findTOC handleMMIO to copy TOC ONE returned */
BTLDR_TRC_PA_FINDTOC_TOC1_HANDLEMMIO_RTN = 0x31,

Expand All @@ -100,6 +107,9 @@ enum BootloaderTraces
/** Bootloader PNOR Access getHBBSection findTOC returned */
BTLDR_TRC_PA_GETHBBSECTION_FINDTOC_RTN = 0x35,

/** Bootloader PNOR Access findTOC handleMMIO LPC Error Check returned */
BTLDR_TRC_PA_FINDTOC_TOC1_LPC_RTN = 0x36,

/** Bootloader PNOR Access readTOC zeroSection returned */
BTLDR_TRC_PA_READTOC_ZEROSECTION_RTN = 0x41,

Expand Down Expand Up @@ -186,6 +196,9 @@ enum BootloaderTraces

/** Bootloader main verifyContainer secure rom invalid */
BTLDR_TRC_MAIN_VERIFY_INVALID_SECROM = 0xFC,

/** Bootloader PNOR Access findTOC handleMMIO LPC ERR returned */
BTLDR_TRC_PA_FINDTOC_TOC1_LPC_ERR = 0xFD,
};

#ifndef BOOTLOADER_TRACE
Expand Down
5 changes: 4 additions & 1 deletion src/include/usr/lpc/lpc_const.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,2017 */
/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -45,6 +45,9 @@ namespace LPC
LPC_PHYS_BASE = 0x6030000000000,

FW_WINDOW_SIZE = 0x10000000, //Size of FW Window

OPB_ERROR_MASK = 0x20000FC3, /**< OPBM Error Bits MASK */

};
}

Expand Down
8 changes: 4 additions & 4 deletions src/usr/lpc/lpcdd.C
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2014,2018 */
/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
Expand Down Expand Up @@ -523,7 +523,7 @@ errlHndl_t LpcDD::hwReset( ResetLevels i_resetLevel )
uint32_t * l_status_ptr
= reinterpret_cast<uint32_t*>(l_addr);
//Clear under mask - aka write 1 clears
*l_status_ptr = OPB_ERROR_MASK;
*l_status_ptr = LPC::OPB_ERROR_MASK;
eieio();

//Clear related bits in the LPCM OPB Master Accumulated
Expand All @@ -534,7 +534,7 @@ errlHndl_t LpcDD::hwReset( ResetLevels i_resetLevel )
uint32_t * l_accum_status_ptr
= reinterpret_cast<uint32_t*>(l_addr);
//Clear under mask - aka write 1 clears
*l_accum_status_ptr = OPB_ERROR_MASK;
*l_accum_status_ptr = LPC::OPB_ERROR_MASK;
eieio();

//Reset LPCHC Logic
Expand Down Expand Up @@ -1116,7 +1116,7 @@ errlHndl_t LpcDD::checkForLpcErrors()
eieio();

// Mask error bits
opbm_err_union.data32 = (opbm_buffer & OPB_ERROR_MASK);
opbm_err_union.data32 = (opbm_buffer & LPC::OPB_ERROR_MASK);
lpchc_err_union.data32 = (lpchc_buffer & LPCHC_ERROR_MASK);

// First look for errors in the OPBM bit mask
Expand Down
4 changes: 1 addition & 3 deletions src/usr/lpc/lpcdd.H
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2014,2017 */
/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
Expand Down Expand Up @@ -214,8 +214,6 @@ class LpcDD
/** LPC Host Controller Reset Register */
LPCHC_RESET_REG = 0x20FC,

OPB_ERROR_MASK = 0x20000FC3, /**< OPBM Error Bits MASK */

LPCHC_ERROR_MASK = 0x000004FC /**< LPCHC Error Bits MASK */

};
Expand Down
3 changes: 2 additions & 1 deletion src/usr/pnor/pnor_utils.H
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2011,2017 */
/* Contributors Listed Below - COPYRIGHT 2011,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -85,6 +85,7 @@ enum pnorUtilErrorCodes
HEADER_ERR = 0x00000800,
ENTRY_ERR = 0x00001000,
NO_HBB_SECTION = 0x00002000,
LPC_ERR = 0x00004000,
};

enum
Expand Down

0 comments on commit e36e001

Please sign in to comment.