Skip to content

Commit

Permalink
Read HW Key Hash From SBE Seeprom via ChipOp when applicable
Browse files Browse the repository at this point in the history
This commit uses SBEIO ChipOps to read the HW Key Hash from the
SBE Seeprom when reading from the Seeprom that booted the processor.
This will help avoid I2C collisions when both Hostboot and the SBE
try to access the same SBE Seeprom at the same time.

Change-Id: I5693cc59aa2a7259f07363328bd8513c943f0a06
CQ:SW435288
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/61958
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
  • Loading branch information
mabaiocchi authored and wghoffa committed Jul 7, 2018
1 parent ea5c84f commit a76fe8f
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/include/usr/sbe/sbe_common.H
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ namespace SBE
static_assert(0 == (sizeof(sbeSeepromVersionInfo_t) % 8),
"sbeSeepromVersionInfo_t is not 8-byte-aligned");

typedef uint8_t sbe_image_version_t[SBE_IMAGE_VERSION_SIZE];

/**
* @brief Struct of individual SBE entry in SBE
Expand Down
1 change: 0 additions & 1 deletion src/include/usr/sbe/sbe_update.H
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#define __SBE_SBE_UPDATE_H

#include <sbe/sbe_common.H> // sbeSeepromVersionInfo_t
#include <sbe/sbeif.H> // sbe_image_version_t

#include <stdint.h> // uint32_t, etc
#include <errl/errlentry.H> // errlHndl_t
Expand Down
10 changes: 8 additions & 2 deletions src/include/usr/sbe/sbeif.H
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,14 @@
#define _SBEIF_H

#include <sbe/sbe_common.H>
#include <sbe/sbe_update.H>
#include <errl/errlentry.H>
#include <pnor/pnorif.H>
#include <secureboot/service.H>
#include <i2c/eepromif.H>

namespace SBE
{
typedef uint8_t sbe_image_version_t[SBE_IMAGE_VERSION_SIZE];

/**
* @brief Gets a pointer to the proper SBE image in PNOR
*
Expand Down Expand Up @@ -115,6 +114,12 @@ namespace SBE
* NOTE: Ignored if i_image_ptr specifies an image
* (ie, != nullptr).
*
*
* @param[in] i_bootSide Designates which Seeprom the processor booted on.
* If i_bootSide and i_seeprom match then ChipOps
* will be used to read the Seeprom to avoid I2C
* collisions.
*
* @param[out] o_hash HW Key Hash returned from the Processor SEEPROM
*
* @param[in] i_image_ptr Defaults to nullptr.
Expand All @@ -127,6 +132,7 @@ namespace SBE
*/
errlHndl_t getHwKeyHashFromSbeImage(TARGETING::Target* i_target,
EEPROM::eeprom_chip_types_t i_seeprom,
sbeSeepromSide_t i_bootSide,
SHA512_t o_hash,
const void * i_image_ptr = nullptr);

Expand Down
9 changes: 9 additions & 0 deletions src/include/usr/sbeio/sbeioif.H
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@

#include <errl/errlentry.H>


/* Associated defines for sendPsuReadSeeprom() function below */
#define CHIPOP_READ_SEEPROM_SIZE_ALIGNMENT_BYTES 128
#define CHIPOP_READ_SEEPROM_DEST_ADDR_ALIGNMENT_BYTES 8


namespace SBEIO
{
enum KeyAddrStashKeys
Expand Down Expand Up @@ -310,11 +316,14 @@ namespace SBEIO
* @brief Sends a PSU chipOp to request Seeprom read from SBE
*
* @param[in] i_target Target with SBE to send read request to
* Assert if i_target == nullptr
* @param[in] i_seepromOffset Offset in the seeprom image where we want
* to start copying from (ignores ECC)
* @param[in] i_readSize Amount of bytes we want to copy (ignores ECC)
* Assert if i_readSize is not 128-byte-aligned
* @param[in] i_destAddr Address that hostboot has prepared which the
* sbe will write too
* Assert if i_destAddr is not 8-byte aligned
* @param[out] o_opSupported Bool which tells us if the sbe supports the
* chipOp or not
*
Expand Down
4 changes: 4 additions & 0 deletions src/usr/isteps/istep10/call_proc_cen_ref_clk_enable.C
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,7 @@ void validateSecuritySettings()
err = SBE::getHwKeyHashFromSbeImage(
mProc,
EEPROM::SBE_PRIMARY,
bootSide,
l_masterHash);

if (err)
Expand Down Expand Up @@ -610,6 +611,7 @@ void validateSecuritySettings()
err = SBE::getHwKeyHashFromSbeImage(
mProc,
EEPROM::SBE_BACKUP,
bootSide,
l_backupHash);

if (err)
Expand Down Expand Up @@ -752,6 +754,7 @@ void validateSecuritySettings()
err = SBE::getHwKeyHashFromSbeImage(
pProc,
EEPROM::SBE_PRIMARY,
bootSide,
l_slaveHashPri);

if (err)
Expand Down Expand Up @@ -793,6 +796,7 @@ void validateSecuritySettings()
err = SBE::getHwKeyHashFromSbeImage(
pProc,
EEPROM::SBE_BACKUP,
bootSide,
l_slaveHashBac);
if (err)
{
Expand Down
120 changes: 113 additions & 7 deletions src/usr/sbe/sbe_update.C
Original file line number Diff line number Diff line change
Expand Up @@ -2330,6 +2330,7 @@ namespace SBE
SHA512_t hash = {0};
err = getHwKeyHashFromSbeImage(io_sbeState.target, // ignored
EEPROM::SBE_PRIMARY, // ignored
SBE_SEEPROM_INVALID, // ignored
hash,
pCustomizedBfr);

Expand Down Expand Up @@ -5578,18 +5579,35 @@ errlHndl_t sbeDoReboot( void )
errlHndl_t getHwKeyHashFromSbeImage(
TARGETING::Target* const i_target,
const EEPROM::eeprom_chip_types_t i_seeprom,
const sbeSeepromSide_t i_bootSide,
SHA512_t o_hash,
const void * i_image_ptr) // defaults to nullptr
{
errlHndl_t err = nullptr;

// if i_image_ptr == nullptr, then read from SBE Seeprom;
// if i_seepom matches i_bootSide then read from SEEPROM via ChipOp
// else read from SEEPROM via I2C
// if i_image_ptr != nullptr, then read from memory at i_image_ptr
// TODO RTC:186269 Remove check forcing down I2C path when simics issue
// is resolved
bool l_useChipOp = (((i_bootSide == SBE_SEEPROM0) &&
(i_seeprom == EEPROM::SBE_PRIMARY)) ||
((i_bootSide == SBE_SEEPROM1) &&
(i_seeprom == EEPROM::SBE_BACKUP)))
&& !Util::isSimicsRunning();

// reading via ChipOp should be supported, but this parameter is still used
// for the call
bool l_chipOpSupported = false;

TRACFCOMP( g_trac_sbe, ENTER_MRK"getHwKeyHashFromSbeImage: "
"i_target=0x%X, i_seeprom=%d, i_image_ptr=%p: "
"reading from %s",
get_huid(i_target), i_seeprom, i_image_ptr,
(i_image_ptr) ? "memory" : "seeprom");
(i_image_ptr) ? "memory" :
(l_useChipOp) ? "seeprom via ChipOp" :
"seeprom via I2C");

// Check Input Parameters
if ( i_image_ptr == nullptr )
Expand Down Expand Up @@ -5617,17 +5635,34 @@ errlHndl_t getHwKeyHashFromSbeImage(
// Create buffers for read operations and removing ECC
const size_t max_buffer_size = PNOR::ECC::sizeWithEcc(
(std::max(sizeof(P9XipHeader), sizeof(SHA512_t))));

uint8_t tmp_data[max_buffer_size] = {0};
uint8_t tmp_data_ECC[max_buffer_size] = {0};


// For reading via ChipOp we need buffer on a 128 byte boundary, so get
// the right size for that boundary and then add 127 bytes to the buffer
// length so we can guarantee a 128 byte aligned addr
const size_t max_buffer_size_chipOp =
ALIGN_X(max_buffer_size,
CHIPOP_READ_SEEPROM_SIZE_ALIGNMENT_BYTES);
uint8_t * l_chipOpBuffer = static_cast<uint8_t*>(
malloc(max_buffer_size_chipOp + 127 ));

uint64_t l_chipOpBufferAligned =
ALIGN_X(reinterpret_cast<uint64_t>(l_chipOpBuffer),
128);
// Clear Buffer
memset( reinterpret_cast<uint8_t*>(l_chipOpBufferAligned),
0,
max_buffer_size);
do{
// Get P9XipHeader, which is at the start of the SBE Image
seeprom_offset = 0;

if ( i_image_ptr == nullptr )
if ( ( i_image_ptr == nullptr ) &&
( l_useChipOp == false ) )
{
// Read Seeprom via I2C
// Calculate amount of data to read from SEEPROM
size = PNOR::ECC::sizeWithEcc(sizeof(P9XipHeader));
expected_size = size;
Expand Down Expand Up @@ -5677,6 +5712,36 @@ errlHndl_t getHwKeyHashFromSbeImage(
tmp_data_ECC,
PNOR::ECC::sizeWithEcc(sizeof(P9XipHeader().iv_magic) ) );

}
else if ( ( i_image_ptr == nullptr ) &&
( l_useChipOp == true ) )
{
// Read Seeprom via ChipOp
err = SBEIO::sendPsuReadSeeprom(
i_target,
seeprom_offset,
ALIGN_X(sizeof(P9XipHeader),
CHIPOP_READ_SEEPROM_SIZE_ALIGNMENT_BYTES),
mm_virt_to_phys(reinterpret_cast
<void*>(l_chipOpBufferAligned)),
l_chipOpSupported);

if(err || !l_chipOpSupported)
{
TRACFCOMP( g_trac_sbe,
"getHwKeyHashFromSbeImage: Error reading P9XipHeader "
"from seeprom via chipOp: either the Op is not "
"supported by SBE (%d) or something else went wrong "
"(err_rc=0x%X, err_plid=0x%X)",
l_chipOpSupported, ERRL_GETRC_SAFE(err),
ERRL_GETPLID_SAFE(err));
break;
}
// Copy P9XipHeader to local membuf
memcpy (tmp_data,
reinterpret_cast<void*>(l_chipOpBufferAligned),
sizeof(P9XipHeader));

}
else
{
Expand Down Expand Up @@ -5755,19 +5820,23 @@ errlHndl_t getHwKeyHashFromSbeImage(
// Calculate Seeprom offset
// -- Raw Image Offset -- HW Key Hash is at end of HBBL section
seeprom_offset = l_xipSection.iv_offset + HBBL_HW_KEY_HASH_LOCATION;
if ( i_image_ptr == nullptr )
if ( ( i_image_ptr == nullptr ) &&
( l_useChipOp == false ) )
{
// Math to convert Image offset to Seeprom(with ECC) Offset
// when reading Seeprom via I2C
seeprom_offset = setECCSize(seeprom_offset);
}

TRACUCOMP( g_trac_sbe, "getHwKeyHashFromSbeImage: seeprom_offset "
"= 0x%X, size = 0x%X",
seeprom_offset, size);
seeprom_offset, l_xipSection.iv_size);

// Read HW Key Hash from SBE Image
if ( i_image_ptr == nullptr)
if ( ( i_image_ptr == nullptr ) &&
( l_useChipOp == false ) )
{
// Read HW Key Hash from SBE Image via I2C

// Clear buffers and set size to SHA512_t+ECC
memset( tmp_data_ECC, 0, max_buffer_size );
memset( tmp_data, 0, max_buffer_size );
Expand Down Expand Up @@ -5828,6 +5897,37 @@ errlHndl_t getHwKeyHashFromSbeImage(
"found successfully from SBE Seeprom- setting o_hash");
memcpy(o_hash, tmp_data, sizeof(SHA512_t));
}
else if ( ( i_image_ptr == nullptr ) &&
( l_useChipOp == true ) )
{

// Read Seeprom via ChipOp
err = SBEIO::sendPsuReadSeeprom(
i_target,
seeprom_offset,
ALIGN_X(sizeof(SHA512_t),
CHIPOP_READ_SEEPROM_SIZE_ALIGNMENT_BYTES),
mm_virt_to_phys(reinterpret_cast
<void*>(l_chipOpBufferAligned)),
l_chipOpSupported);

if(err || !l_chipOpSupported)
{
TRACFCOMP( g_trac_sbe,
"getHwKeyHashFromSbeImage: Error reading Hash from "
"seeprom via chipOp: either the Op is not supported "
"by SBE (%d) or something else went wrong: (err_rc="
"0x%X, err_plid=0x%X): offset=0x%X",
l_chipOpSupported, ERRL_GETRC_SAFE(err),
ERRL_GETPLID_SAFE(err), seeprom_offset);
break;
}
// Copy P9XipHeader to local membuf
memcpy (o_hash,
reinterpret_cast<void*>(l_chipOpBufferAligned),
sizeof(SHA512_t));

}
else
{
// Copy HW Key Hash from system memory
Expand Down Expand Up @@ -5879,6 +5979,12 @@ errlHndl_t getHwKeyHashFromSbeImage(
err->collectTrace(SBE_COMP_NAME);
}

//Free up the buffer before returning no matter what
if (l_chipOpBuffer)
{
free(l_chipOpBuffer);
l_chipOpBuffer = nullptr;
}

TRACFCOMP( g_trac_sbe, EXIT_MRK"getHwKeyHashFromSbeImage: "
"err rc=0x%X, plid=0x%X, o_hash=0x%.8X",
Expand Down
24 changes: 15 additions & 9 deletions src/usr/sbeio/sbe_psuReadSeeprom.C
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2012,2017 */
/* Contributors Listed Below - COPYRIGHT 2012,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -41,20 +41,17 @@ TRACDCOMP(g_trac_sbeio,"psuReadSeeprom: " printf_string,##args)
#define SBE_TRACF(printf_string,args...) \
TRACFCOMP(g_trac_sbeio,"psuReadSeeprom: " printf_string,##args)

#define READ_SEEPROM_SIZE_ALIGNMENT_BYTES 128
#define READ_SEEPROM_DEST_ADDR_ALIGNMENT_BYTES 8


namespace SBEIO
{

/**
* @brief Sends a PSU chipOp to request Seeprom read from SBE
*
* @param[in] i_target Target with SBE to send read request to
* @param[in] i_seepromOffset Offset in the seeprom image where we want
* to start copying from (ignores ECC)
* @param[in] i_readSize Amount of bytes we want to copy (ignores ECC)
* @param[in] i_destAddr Address that hostboot has prepared which the
* sbe will write too
* @param[out] o_opSupported Bool which tells us if the sbe supports the
* chipOp or not
* @note - details in sbeioif.H
*
* @return errlHndl_t Error log handle on failure.
*
Expand All @@ -69,6 +66,11 @@ namespace SBEIO

SBE_TRACD(ENTER_MRK "sending psu seeprom read request command from HB -> SBE");

// Verify input parameters meet restrictions
assert(i_target!=nullptr,"sendPsuReadSeeprom: i_target was nullptr");
assert((i_readSize % CHIPOP_READ_SEEPROM_SIZE_ALIGNMENT_BYTES) == 0,"sendPsuReadSeeprom: i_readSize 0x%X is not 128B aligned", i_readSize);
assert((i_destAddr % CHIPOP_READ_SEEPROM_DEST_ADDR_ALIGNMENT_BYTES) == 0,"sendPsuReadSeeprom: i_destAddr 0x%X is not 8B aligned", i_destAddr);

// set up PSU command message
SbePsu::psuCommand l_psuCommand(
SbePsu::SBE_REQUIRE_RESPONSE |
Expand Down Expand Up @@ -98,6 +100,10 @@ namespace SBEIO
errl = nullptr;
o_opSupported = false;
}
else
{
o_opSupported = true;
}

SBE_TRACD(EXIT_MRK "sendPsuReadSeeprom");

Expand Down

0 comments on commit a76fe8f

Please sign in to comment.