summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/sbe/sbe_update.H23
-rw-r--r--src/include/usr/sbeio/sbe_psudd.H33
-rw-r--r--src/include/usr/sbeio/sbeioif.H22
-rw-r--r--src/usr/sbe/sbe_update.C383
-rw-r--r--src/usr/sbeio/makefile1
-rw-r--r--src/usr/sbeio/sbe_psuReadSeeprom.C108
6 files changed, 467 insertions, 103 deletions
diff --git a/src/include/usr/sbe/sbe_update.H b/src/include/usr/sbe/sbe_update.H
index 25d7448af..45e295c2d 100644
--- a/src/include/usr/sbe/sbe_update.H
+++ b/src/include/usr/sbe/sbe_update.H
@@ -77,12 +77,17 @@ namespace SBE
const uint64_t SBE_VERSION_SPACE_WITH_ECC = (256 * 9) / 8; // 256B + ECC
const uint64_t SBE_SEEPROM_SIZE = 64*KILOBYTE; // 64KB
const uint64_t SBE_SEEPROM_ECC_PAD = SBE_SEEPROM_SIZE % 9;
+ const uint64_t SBE_SEEPROM_SIZE_WO_ECC = ((64*KILOBYTE - SBE_SEEPROM_ECC_PAD) / 9) * 8 ;
// SBE Version (with ECC) kept at end of fourth 64KB memory
// Adjust end of usable memory with ECC to be a multiple of 9 bytes
const uint64_t SBE_VERSION_SEEPROM_ADDRESS = 4*SBE_SEEPROM_SIZE
- SBE_SEEPROM_ECC_PAD
- SBE_VERSION_SPACE_WITH_ECC;
+ const uint64_t SBE_SEEPROM_VERSION_READ_SIZE = 0x100; // 128 Bytes * 2 (256 decimal)
+ const uint64_t END_OF_SEEPROM_MINUS_READ_SIZE = 4*SBE_SEEPROM_SIZE_WO_ECC
+ - SBE_SEEPROM_VERSION_READ_SIZE;
+
// Used to read SBE Boot Side from processor
// (PERV_SB_CS_SCOM 0x00050008 or PERV_SB_CS_FSI 0x2808)
const uint64_t SBE_BOOT_SELECT_MASK = 0x0000400000000000;
@@ -478,7 +483,7 @@ namespace SBE
sbeSeepromSide_t& o_bootSide);
/**
- * @brief Collects Version information from a specific SEEPROM
+ * @brief Collects Version information from a specific SEEPROM using I2C
*
* @param[in] i_target Target processor to customize
*
@@ -492,10 +497,24 @@ namespace SBE
*
* @return errlHndl_t Error log handle on failure.
*/
- errlHndl_t getSeepromSideVersion(TARGETING::Target* i_target,
+ errlHndl_t getSeepromSideVersionViaI2c(TARGETING::Target* i_target,
EEPROM::eeprom_chip_types_t i_seepromSide,
sbeSeepromVersionInfo_t& o_info,
bool& o_seeprom_ver_ECC_fail);
+ /**
+ * @brief Collects Version information from a specific SEEPROM using PSU ChipOp
+ *
+ * @param[in] i_target Target processor to customize
+ *
+ * @param[out] o_info Struct containing the SBE Version Information
+ *
+ * @param[out] o_opSupported output if sbe supports seeprom read chip op or not
+ *
+ * @return errlHndl_t Error log handle on failure.
+ */
+ errlHndl_t getSeepromSideVersionViaChipOp(TARGETING::Target* i_target,
+ sbeSeepromVersionInfo_t& o_info,
+ bool& o_opSupported);
/**
* @brief Updates a specific SEEPROM
diff --git a/src/include/usr/sbeio/sbe_psudd.H b/src/include/usr/sbeio/sbe_psudd.H
index 5b2983c39..76603859f 100644
--- a/src/include/usr/sbeio/sbe_psudd.H
+++ b/src/include/usr/sbeio/sbe_psudd.H
@@ -102,6 +102,7 @@ class SbePsu
//BYTE 7 options
enum psuGenericMessageCommands
{
+ SBE_PSU_READ_SEEPROM = 0x03,
SBE_PSU_SET_FFDC_ADDRESS = 0x04,
SBE_PSU_GENERIC_MSG_QUIESCE = 0x05,
SBE_CMD_CONTROL_SYSTEM_CONFIG = 0x06,
@@ -226,6 +227,25 @@ class SbePsu
* 0x4 - Reg 2 is non-reserved (read or write this reg)
* 0x8 - Reg 3 is non-reserved (read or write this reg)
*/
+ enum psuReadSeepromMsgs
+ {
+ SBE_READ_SEEPROM_REQ_USED_REGS = 0x07,
+ SBE_READ_SEEPROM_RSP_USED_REGS = 0x01,
+ };
+
+ /**
+ * @brief non reserved word enums
+ *
+ * Shows which of the request and response msg registers are
+ * not reserved. Reserved registers do not need to be written
+ * or read.
+ *
+ * This is a 4 bit field:
+ * 0x1 - Reg 0 is non-reserved (read or write this reg)
+ * 0x2 - Reg 1 is non-reserved (read or write this reg)
+ * 0x4 - Reg 2 is non-reserved (read or write this reg)
+ * 0x8 - Reg 3 is non-reserved (read or write this reg)
+ */
enum psuStashKeyAddrNonReservedMsgs
{
SBE_STASH_KEY_ADDR_REQ_USED_REGS = 0x07,
@@ -413,6 +433,19 @@ class SbePsu
uint64_t cd7_setFFDCAddr_CommAddr; // mbxReg3
} PACKED;
+ struct //readSeeprom
+ {
+ uint16_t cd7_readSeeprom_Reserved;
+ uint16_t cd7_readSeeprom_ControlFlags;
+ uint16_t cd7_readSeeprom_SeqId;
+ uint8_t cd7_readSeeprom_CommandClass;
+ uint8_t cd7_readSeeprom_Command;
+ uint32_t cd7_readSeeprom_SeepromOffset; // mbxReg1
+ uint32_t cd7_readSeeprom_ReadSize; // mbxReg1
+ uint64_t cd7_readSeeprom_DestinationAddr; // mbxReg2
+ uint64_t cd7_readSeeprom_MbxReg3Reserved; // mbxReg3
+ } PACKED;
+
psuCommand(uint16_t i_controlFlags, //Mbx Reg 0 input
uint8_t i_commandClass, //Mbx Reg 0 input
uint8_t i_command) : //Mbx Reg 0 input
diff --git a/src/include/usr/sbeio/sbeioif.H b/src/include/usr/sbeio/sbeioif.H
index a951fe4a4..12881c939 100644
--- a/src/include/usr/sbeio/sbeioif.H
+++ b/src/include/usr/sbeio/sbeioif.H
@@ -285,6 +285,28 @@ namespace SBEIO
uint64_t i_dataSize,
const char * i_hwpName);
+ /**
+ * @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
+ *
+ * @return errlHndl_t Error log handle on failure.
+ *
+ */
+ errlHndl_t sendPsuReadSeeprom(TARGETING::Target * i_target,
+ uint32_t i_seepromOffset,
+ uint32_t i_readSize,
+ uint64_t i_destAddr,
+ bool & o_opSupported);
+
+
} //end namespace SBEIO
diff --git a/src/usr/sbe/sbe_update.C b/src/usr/sbe/sbe_update.C
index 822a6912f..c22d84f08 100644
--- a/src/usr/sbe/sbe_update.C
+++ b/src/usr/sbe/sbe_update.C
@@ -1804,8 +1804,11 @@ namespace SBE
TARGETING::get_huid(io_sbeState.target));
- errlHndl_t err = NULL;
- void *sbeHbblImgPtr = NULL;
+ errlHndl_t err = nullptr;
+ void *sbeHbblImgPtr = nullptr;
+ bool l_sideZeroIsActive = true;
+ bool l_sbeSupportedSeepromReadOp = true;
+ bool l_errFoundDuringChipOp = false;
// Clear build information
io_sbeState.new_imageBuild.buildDate = 0;
@@ -1816,6 +1819,62 @@ namespace SBE
do{
+ /***********************************************/
+ /* Determine which SEEPROM System Booted On */
+ /***********************************************/
+ //Get Current (boot) Side
+ sbeSeepromSide_t tmp_cur_side = SBE_SEEPROM_INVALID;
+ err = getSbeBootSeeprom(io_sbeState.target, tmp_cur_side);
+ if(err)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - "
+ "Error returned from getSbeBootSeeprom(), "
+ "RC=0x%X, PLID=0x%lX",
+ ERRL_GETRC_SAFE(err),
+ ERRL_GETPLID_SAFE(err));
+ break;
+ }
+
+ io_sbeState.cur_seeprom_side = tmp_cur_side;
+ if (io_sbeState.cur_seeprom_side == SBE_SEEPROM0)
+ {
+ io_sbeState.alt_seeprom_side = SBE_SEEPROM1;
+ }
+ else if ( io_sbeState.cur_seeprom_side == SBE_SEEPROM1)
+ {
+ io_sbeState.alt_seeprom_side = SBE_SEEPROM0;
+ l_sideZeroIsActive = false;
+ }
+ else
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error: "
+ "Unexpected cur_seeprom_side value = 0x%X, ",
+ io_sbeState.cur_seeprom_side);
+
+ /*@
+ * @errortype
+ * @moduleid SBE_GET_TARGET_INFO_STATE
+ * @reasoncode SBE_INVALID_SEEPROM_SIDE
+ * @userdata1 Temporary Current Side
+ * @userdata2 SBE State Current Side
+ * @devdesc Invalid Boot SEEPROM Side Found
+ */
+ err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ SBE_GET_TARGET_INFO_STATE,
+ SBE_INVALID_SEEPROM_SIDE,
+ tmp_cur_side,
+ io_sbeState.cur_seeprom_side);
+ err->collectTrace(SBE_COMP_NAME);
+ err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH );
+
+ break;
+ }
+
+ TRACUCOMP( g_trac_sbe,"getSbeInfoState() - cur=0x%X, alt=0x%X",
+ io_sbeState.cur_seeprom_side,
+ io_sbeState.alt_seeprom_side);
+
/************************************************************/
/* Set Target Properties (target_is_master previously set) */
/************************************************************/
@@ -1823,51 +1882,138 @@ namespace SBE
/*******************************************/
- /* Get SEEPROM A SBE Version Information */
+ /* Get SEEPROM 0 SBE Version Information */
/*******************************************/
- err = getSeepromSideVersion(io_sbeState.target,
- EEPROM::SBE_PRIMARY,
- io_sbeState.seeprom_0_ver,
- io_sbeState.seeprom_0_ver_ECC_fail);
- if(err)
+ // If the current seeprom is side 0 and is on master proc,
+ // then attempt read via chipOp
+ if (l_sideZeroIsActive && io_sbeState.target_is_master)
{
- TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error "
- "getting SBE Information from SEEPROM A (0x%X), "
- "RC=0x%X, PLID=0x%lX",
- EEPROM::SBE_PRIMARY,
- ERRL_GETRC_SAFE(err),
- ERRL_GETPLID_SAFE(err));
- break;
+ err = getSeepromSideVersionViaChipOp(io_sbeState.target,
+ io_sbeState.seeprom_0_ver,
+ l_sbeSupportedSeepromReadOp);
+
+ if(err)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error "
+ "getting SBE Information from SEEPROM 0 (Primary) via ChipOp "
+ "RC=0x%X, PLID=0x%lX, will attempt I2C read instead",
+ ERRL_GETRC_SAFE(err),
+ ERRL_GETPLID_SAFE(err));
+ //Commit error as informational and attempt reading via i2c
+ l_errFoundDuringChipOp = true;
+ err->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ err->collectTrace(SBE_COMP_NAME, 256);
+ err->collectTrace(SBEIO_COMP_NAME, 256);
+ errlCommit( err, SBEIO_COMP_ID );
+ }
+ else if(!l_sbeSupportedSeepromReadOp)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error "
+ "getting SBE Information from SEEPROM 0 (Primary) via ChipOp. The "
+ "SBE firmware level does not support readSeeprom Op, will attempt I2C read instead");
+ }
+ else
+ {
+ TRACDBIN(g_trac_sbe, "getSbeInfoState found via ChipOp -spA",
+ &(io_sbeState.seeprom_0_ver),
+ sizeof(sbeSeepromVersionInfo_t));
+ }
}
- TRACDBIN(g_trac_sbe, "getSbeInfoState-spA",
- &(io_sbeState.seeprom_0_ver),
- sizeof(sbeSeepromVersionInfo_t));
+ //If side 0 is not active, or this is a slave proc, or there was
+ //an error trying to read the primary via chipOp, then try reading via I2C
+ if(!l_sideZeroIsActive || !l_sbeSupportedSeepromReadOp ||
+ l_errFoundDuringChipOp|| !io_sbeState.target_is_master)
+ {
+
+ err = getSeepromSideVersionViaI2c(io_sbeState.target,
+ EEPROM::SBE_PRIMARY,
+ io_sbeState.seeprom_0_ver,
+ io_sbeState.seeprom_0_ver_ECC_fail);
+
+ if(err)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error "
+ "getting SBE Information from SEEPROM 0 (Primary) via I2C, "
+ "RC=0x%X, PLID=0x%lX",
+ ERRL_GETRC_SAFE(err),
+ ERRL_GETPLID_SAFE(err));
+ break;
+ }
+
+ TRACDBIN(g_trac_sbe, "getSbeInfoState found via I2C -spA",
+ &(io_sbeState.seeprom_0_ver),
+ sizeof(sbeSeepromVersionInfo_t));
+ }
/*******************************************/
- /* Get SEEPROM B SBE Version Information */
+ /* Get SEEPROM 1 SBE Version Information */
/*******************************************/
- err = getSeepromSideVersion(io_sbeState.target,
- EEPROM::SBE_BACKUP,
- io_sbeState.seeprom_1_ver,
- io_sbeState.seeprom_1_ver_ECC_fail);
- if(err)
+ //If side 1 is active and this is master, then attempt read via chipOp
+ //Note that there is no reason to attempt chipOp on backup if it failed
+ //on the primary.
+ if (!l_sideZeroIsActive && l_sbeSupportedSeepromReadOp &&
+ !l_errFoundDuringChipOp && io_sbeState.target_is_master)
{
- TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error "
- "getting SBE Information from SEEPROM B (0x%X), "
- "RC=0x%X, PLID=0x%lX",
- EEPROM::SBE_BACKUP,
- ERRL_GETRC_SAFE(err),
- ERRL_GETPLID_SAFE(err));
- break;
+ err = getSeepromSideVersionViaChipOp(io_sbeState.target,
+ io_sbeState.seeprom_1_ver,
+ l_sbeSupportedSeepromReadOp);
+
+ if(err)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error "
+ "getting SBE Information from SEEPROM 1 (Backup) via Chipop, "
+ "RC=0x%X, PLID=0x%lX, will attempt I2C read instead",
+ ERRL_GETRC_SAFE(err),
+ ERRL_GETPLID_SAFE(err));
+ //Commit error as informational and attempt reading via i2c
+ l_errFoundDuringChipOp = true;
+ err->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ err->collectTrace(SBE_COMP_NAME, 256);
+ err->collectTrace(SBEIO_COMP_NAME, 256);
+ errlCommit( err, SBEIO_COMP_ID );
+ }
+ else if(!l_sbeSupportedSeepromReadOp)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error "
+ "getting SBE Information from SEEPROM 1 (Backup) via ChipOp. The "
+ "SBE firmware level does not support readSeeprom Op, will attempt I2C read instead");
+ }
+ else
+ {
+ TRACDBIN(g_trac_sbe, "getSbeInfoState found via Chipop -spB",
+ &(io_sbeState.seeprom_1_ver),
+ sizeof(sbeSeepromVersionInfo_t));
+ }
}
- TRACDBIN(g_trac_sbe, "getSbeInfoState-spB",
- &(io_sbeState.seeprom_1_ver),
- sizeof(sbeSeepromVersionInfo_t));
+ //If side 1 is not active, or this is a slave proc, or there was
+ //an error trying to read the primary via chipOp, then try reading via I2C
+ if(l_sideZeroIsActive || !l_sbeSupportedSeepromReadOp ||
+ l_errFoundDuringChipOp || !io_sbeState.target_is_master)
+ {
+ err = getSeepromSideVersionViaI2c(io_sbeState.target,
+ EEPROM::SBE_BACKUP,
+ io_sbeState.seeprom_1_ver,
+ io_sbeState.seeprom_1_ver_ECC_fail);
+
+ if(err)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error "
+ "getting SBE Information from SEEPROM 1 (Backup) via I2C, "
+ "RC=0x%X, PLID=0x%lX",
+ ERRL_GETRC_SAFE(err),
+ ERRL_GETPLID_SAFE(err));
+ break;
+ }
+
+ TRACDBIN(g_trac_sbe, "getSbeInfoState-spB found via I2C",
+ &(io_sbeState.seeprom_1_ver),
+ sizeof(sbeSeepromVersionInfo_t));
+ }
/*******************************************/
@@ -2201,62 +2347,6 @@ namespace SBE
io_sbeState.permanent_seeprom_side = SBE_SEEPROM1;
}
-
- /***********************************************/
- /* Determine which SEEPROM System Booted On */
- /***********************************************/
- //Get Current (boot) Side
- sbeSeepromSide_t tmp_cur_side = SBE_SEEPROM_INVALID;
- err = getSbeBootSeeprom(io_sbeState.target, tmp_cur_side);
- if(err)
- {
- TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - "
- "Error returned from getSbeBootSeeprom(), "
- "RC=0x%X, PLID=0x%lX",
- ERRL_GETRC_SAFE(err),
- ERRL_GETPLID_SAFE(err));
- break;
- }
-
- io_sbeState.cur_seeprom_side = tmp_cur_side;
- if (io_sbeState.cur_seeprom_side == SBE_SEEPROM0)
- {
- io_sbeState.alt_seeprom_side = SBE_SEEPROM1;
- }
- else if ( io_sbeState.cur_seeprom_side == SBE_SEEPROM1)
- {
- io_sbeState.alt_seeprom_side = SBE_SEEPROM0;
- }
- else
- {
- TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error: "
- "Unexpected cur_seeprom_side value = 0x%X, ",
- io_sbeState.cur_seeprom_side);
-
- /*@
- * @errortype
- * @moduleid SBE_GET_TARGET_INFO_STATE
- * @reasoncode SBE_INVALID_SEEPROM_SIDE
- * @userdata1 Temporary Current Side
- * @userdata2 SBE State Current Side
- * @devdesc Invalid Boot SEEPROM Side Found
- */
- err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
- SBE_GET_TARGET_INFO_STATE,
- SBE_INVALID_SEEPROM_SIDE,
- tmp_cur_side,
- io_sbeState.cur_seeprom_side);
- err->collectTrace(SBE_COMP_NAME);
- err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH );
-
- break;
- }
-
- TRACUCOMP( g_trac_sbe,"getSbeInfoState() - cur=0x%X, alt=0x%X",
- io_sbeState.cur_seeprom_side,
- io_sbeState.alt_seeprom_side);
-
}while(0);
if(err && (io_sbeState.new_imageBuild.buildDate != 0) &&
@@ -2276,13 +2366,13 @@ namespace SBE
/////////////////////////////////////////////////////////////////////
- errlHndl_t getSeepromSideVersion(TARGETING::Target* i_target,
+ errlHndl_t getSeepromSideVersionViaI2c(TARGETING::Target* i_target,
EEPROM::eeprom_chip_types_t i_seepromSide,
sbeSeepromVersionInfo_t& o_info,
bool& o_seeprom_ver_ECC_fail)
{
TRACUCOMP( g_trac_sbe,
- ENTER_MRK"getSeepromSideVersion(): HUID=0x%.8X, side:%d",
+ ENTER_MRK"getSeepromSideVersionViaI2c(): HUID=0x%.8X, side:%d",
TARGETING::get_huid(i_target), i_seepromSide);
errlHndl_t err = NULL;
@@ -2314,7 +2404,7 @@ namespace SBE
if(err)
{
- TRACFCOMP( g_trac_sbe, ERR_MRK"getSeepromSideVersion() - "
+ TRACFCOMP( g_trac_sbe, ERR_MRK"getSeepromSideVersionViaI2c() - "
"Error reading SBE Version from Seeprom 0x%X, "
"HUID=0x%.8X, RC=0x%X, PLID=0x%lX",
i_seepromSide, TARGETING::get_huid(i_target),
@@ -2324,7 +2414,7 @@ namespace SBE
}
TRACDBIN(g_trac_sbe,
- "getSeepromSideVersion() - tmp_data_ECC",
+ "getSeepromSideVersionViaI2c() - tmp_data_ECC",
tmp_data_ECC,
sbeInfoSize_ECC);
@@ -2342,7 +2432,7 @@ namespace SBE
SBE_VERSION_SEEPROM_ADDRESS,
SBE_SEEPROM_SIZE);
- TRACUCOMP( g_trac_sbe, "getSeepromSideVersion(): First 8-Bytes: "
+ TRACUCOMP( g_trac_sbe, "getSeepromSideVersionViaI2c(): First 8-Bytes: "
"eccStatus=%d, version=0x%X, data_crc=0x%X",
eccStatus, o_info.struct_version, o_info.data_crc);
@@ -2357,7 +2447,7 @@ namespace SBE
else
{
// Unsupported versions - ignoring any ECC errors
- TRACFCOMP( g_trac_sbe, "getSeepromSideVersion(): Unsupported "
+ TRACFCOMP( g_trac_sbe, "getSeepromSideVersionViaI2c(): Unsupported "
"Struct Version=0x%X, ignoring any eccStatus=%d",
o_info.struct_version, eccStatus);
@@ -2372,7 +2462,7 @@ namespace SBE
SBE_VERSION_SEEPROM_ADDRESS,
SBE_SEEPROM_SIZE);
- TRACFCOMP( g_trac_sbe, "getSeepromSideVersion(): eccStatus=%d, "
+ TRACFCOMP( g_trac_sbe, "getSeepromSideVersionViaI2c(): eccStatus=%d, "
"sizeof o_info/sI=%d, sI_ECC=%d, origin golden=%i",
eccStatus, sbeInfoSize, sbeInfoSize_ECC, o_info.origin);
@@ -2380,7 +2470,7 @@ namespace SBE
// clear data and set o_seeprom_ver_ECC_fail=true
if ( eccStatus == PNOR::ECC::UNCORRECTABLE )
{
- TRACFCOMP( g_trac_sbe, ERR_MRK"getSeepromSideVersion() - ECC "
+ TRACFCOMP( g_trac_sbe, ERR_MRK"getSeepromSideVersionViaI2c() - ECC "
"ERROR: Handled. eccStatus=%d, side=%d, sizeof "
"o_info/sI=%d, sI_ECC=%d",
eccStatus, i_seepromSide, sbeInfoSize,
@@ -2389,14 +2479,14 @@ namespace SBE
memset( &o_info, 0, sizeof(o_info));
o_seeprom_ver_ECC_fail = true;
- TRACUCOMP( g_trac_sbe, "getSeepromSideVersion(): clearing out "
+ TRACUCOMP( g_trac_sbe, "getSeepromSideVersionViaI2c(): clearing out "
"version data (o_info) for side %d and returning "
"o_seeprom_ver_ECC_fail as true (%d)",
i_seepromSide, o_seeprom_ver_ECC_fail);
}
TRACDBIN(g_trac_sbe,
- "getSeepromSideVersion: data (no ECC)",
+ "getSeepromSideVersionViaI2c: data (no ECC)",
&o_info,
sizeof(o_info));
@@ -2407,12 +2497,103 @@ namespace SBE
TRACUCOMP( g_trac_sbe,
- EXIT_MRK"getSeepromSideVersion: o_seeprom_ver_ECC_fail=%d",
+ EXIT_MRK"getSeepromSideVersionViaI2c: o_seeprom_ver_ECC_fail=%d",
o_seeprom_ver_ECC_fail );
return err;
}
+errlHndl_t getSeepromSideVersionViaChipOp(TARGETING::Target* i_target,
+ sbeSeepromVersionInfo_t& o_info,
+ bool& o_opSupported)
+ {
+ errlHndl_t l_err = nullptr;
+
+ // Set these variables to the read out the max struct size
+ // Supported version 1 is a subset of supported version 2
+ size_t sbeInfoSize = sizeof(sbeSeepromVersionInfo_t);
+
+ //Set up the buffer which the SBE will copy the version info to
+ //Add 127 bytes to the buffer length so we can guarantee a 128 byte aligned addr
+ //Note that the SBE_SEEPROM_VERSION_READ_SIZE is 3 * 128 Bytes to be cacheline aligned
+ uint8_t * l_seepromReadBuffer = static_cast<uint8_t*>(
+ malloc(SBE_SEEPROM_VERSION_READ_SIZE + 127 ));
+
+ uint64_t l_seepromReadBufferAligned = ALIGN_X(reinterpret_cast<uint64_t>(l_seepromReadBuffer),
+ 128);
+
+ do{
+
+ /***********************************************/
+ /* Read SBE Version SBE Version Information */
+ /***********************************************/
+ // Clear Buffer
+ memset( reinterpret_cast<uint8_t*>(l_seepromReadBufferAligned),
+ 0,
+ SBE_SEEPROM_VERSION_READ_SIZE );
+
+ // Clear destination
+ memset( &o_info, 0, sizeof(o_info) );
+
+ l_err = SBEIO::sendPsuReadSeeprom(i_target,
+ END_OF_SEEPROM_MINUS_READ_SIZE,
+ SBE_SEEPROM_VERSION_READ_SIZE,
+ mm_virt_to_phys(reinterpret_cast<void*>(l_seepromReadBufferAligned)),
+ o_opSupported);
+
+ if(!l_err && o_opSupported)
+ {
+
+ TRACDBIN(g_trac_sbe,
+ "getSeepromSideVersionViaChipOp() - l_seepromReadBufferAligned",
+ reinterpret_cast<uint8_t*>(l_seepromReadBufferAligned),
+ SBE_SEEPROM_VERSION_READ_SIZE);
+
+ // Initially only look at the first 8-Bytes which should include
+ // the struct version value
+ memcpy ( &o_info, reinterpret_cast<void*>(l_seepromReadBufferAligned), 8);
+
+ if ( STRUCT_VERSION_CHECK(o_info.struct_version) )
+ {
+ // Supported Versions - set size variable
+ sbeInfoSize = SBE_SEEPROM_STRUCT_SIZES[o_info.struct_version];
+ }
+ else
+ {
+ // Unsupported versions
+ TRACFCOMP( g_trac_sbe, "getSeepromSideVersion(): Unsupported "
+ "Struct Version=0x%X",
+ o_info.struct_version);
+
+ break;
+ }
+
+ //Copy the sbeInfo data into the struct that was passed into the function
+ memcpy ( &o_info, reinterpret_cast<void*>(l_seepromReadBufferAligned), sbeInfoSize);
+
+ TRACDBIN(g_trac_sbe,
+ "getSeepromSideVersionViaChipOp: data (no ECC)",
+ &o_info,
+ sizeof(o_info));
+ }
+ else
+ {
+ TRACFCOMP( g_trac_sbe,
+ "Error reading seeprom via chipOp, either the Op isnt supported by SBE or"
+ " something else went wrong, not going to attempt to parse results");
+ }
+
+ }while(0);
+
+ //Free up the buffer before returning no matter what
+ free(l_seepromReadBuffer);
+ l_seepromReadBuffer = nullptr;
+
+ TRACUCOMP( g_trac_sbe,
+ EXIT_MRK"getSeepromSideVersionViaChipOp" );
+ return l_err;
+ }
+
/////////////////////////////////////////////////////////////////////
errlHndl_t updateSeepromSide(sbeTargetState_t& io_sbeState)
diff --git a/src/usr/sbeio/makefile b/src/usr/sbeio/makefile
index 9d5710c7c..5f8af1adc 100644
--- a/src/usr/sbeio/makefile
+++ b/src/usr/sbeio/makefile
@@ -40,6 +40,7 @@ OBJS += sbe_psudd.o
OBJS += sbe_utils.o
OBJS += sbe_secureHwp.o
OBJS += sbe_coreStateControl.o
+OBJS += sbe_psuReadSeeprom.o
OBJS += sbe_psuQuiesce.o
OBJS += sbe_stashKeyAddr.o
OBJS += sbe_continueMpipl.o
diff --git a/src/usr/sbeio/sbe_psuReadSeeprom.C b/src/usr/sbeio/sbe_psuReadSeeprom.C
new file mode 100644
index 000000000..9550b0cdd
--- /dev/null
+++ b/src/usr/sbeio/sbe_psuReadSeeprom.C
@@ -0,0 +1,108 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/sbeio/sbe_psuReadSeeprom.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+* @file sbe_psuReadSeeprom.C
+* @brief Send command to request Seeprom read on SBE
+*/
+
+#include <config.h>
+#include <trace/interface.H>
+#include <errl/errlmanager.H>
+#include <sbeio/sbeioif.H>
+#include <sbeio/sbe_psudd.H>
+
+extern trace_desc_t* g_trac_sbeio;
+
+#define SBE_TRACD(printf_string,args...) \
+TRACDCOMP(g_trac_sbeio,"psuReadSeeprom: " printf_string,##args)
+
+#define SBE_TRACF(printf_string,args...) \
+TRACFCOMP(g_trac_sbeio,"psuReadSeeprom: " printf_string,##args)
+
+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
+ *
+ * @return errlHndl_t Error log handle on failure.
+ *
+ */
+ errlHndl_t sendPsuReadSeeprom(TARGETING::Target * i_target,
+ uint32_t i_seepromOffset,
+ uint32_t i_readSize,
+ uint64_t i_destAddr,
+ bool & o_opSupported)
+ {
+ errlHndl_t errl = nullptr;
+
+ SBE_TRACD(ENTER_MRK "sending psu seeprom read request command from HB -> SBE");
+
+ // set up PSU command message
+ SbePsu::psuCommand l_psuCommand(
+ SbePsu::SBE_REQUIRE_RESPONSE |
+ SbePsu::SBE_REQUIRE_ACK, //control flags
+ SbePsu::SBE_PSU_GENERIC_MESSAGE, //command class
+ SbePsu::SBE_PSU_READ_SEEPROM); //command
+ SbePsu::psuResponse l_psuResponse;
+
+ l_psuCommand.cd7_readSeeprom_SeepromOffset = i_seepromOffset;
+ l_psuCommand.cd7_readSeeprom_ReadSize = i_readSize;
+ l_psuCommand.cd7_readSeeprom_DestinationAddr = i_destAddr;
+
+
+ errl = SBEIO::SbePsu::getTheInstance().performPsuChipOp(i_target,
+ &l_psuCommand,
+ &l_psuResponse,
+ SbePsu::MAX_PSU_SHORT_TIMEOUT_NS,
+ SbePsu::SBE_READ_SEEPROM_REQ_USED_REGS,
+ SbePsu::SBE_READ_SEEPROM_RSP_USED_REGS);
+
+ if(l_psuResponse.primaryStatus == SBE_PRI_INVALID_COMMAND &&
+ l_psuResponse.secondaryStatus == SBE_SEC_COMMAND_NOT_SUPPORTED)
+ {
+ SBE_TRACF(ENTER_MRK "SBE firmware level does not support PSU Seeprom Read Requests");
+ //Make sure we aren't passing out any errors if the command isn't supported
+ delete errl;
+ errl = nullptr;
+ o_opSupported = false;
+ }
+
+ SBE_TRACD(EXIT_MRK "sendPsuReadSeeprom");
+
+ return errl;
+ };
+
+} //end namespace SBEIO
+
OpenPOWER on IntegriCloud