summaryrefslogtreecommitdiffstats
path: root/src/usr/pnor
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2014-05-13 16:45:45 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-09-22 13:31:04 -0500
commitd001febf0b5594120dd422bcbe5736221471e0ca (patch)
tree227678a8341e96ef6bf9fe385e1215cffe613b97 /src/usr/pnor
parente7d14e42caf28c421dfaa4b3b15bda7cf5a77e43 (diff)
downloadtalos-hostboot-d001febf0b5594120dd422bcbe5736221471e0ca.tar.gz
talos-hostboot-d001febf0b5594120dd422bcbe5736221471e0ca.zip
Create LPC Device Driver
Split LPC function out from PNOR DD and incorporate Stradale changes Change-Id: I4162db1a9f52ba3c0c973438b7b70baeae00aee2 Origin: Google Shared Technology RTC: 97494 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/11198 Tested-by: Jenkins Server Reviewed-by: Michael Baiocchi <baiocchi@us.ibm.com> Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/pnor')
-rw-r--r--src/usr/pnor/pnordd.C533
-rw-r--r--src/usr/pnor/pnordd.H105
-rw-r--r--src/usr/pnor/pnorvalid.C47
3 files changed, 82 insertions, 603 deletions
diff --git a/src/usr/pnor/pnordd.C b/src/usr/pnor/pnordd.C
index 52ebe997b..2d9bc1854 100644
--- a/src/usr/pnor/pnordd.C
+++ b/src/usr/pnor/pnordd.C
@@ -51,6 +51,7 @@
#include <sys/time.h>
#include <initservice/initserviceif.H>
#include <util/align.H>
+#include <lpc/lpcif.H>
#include <config.h>
@@ -59,6 +60,7 @@
/*****************************************************************************/
#define PNORDD_MAX_RETRIES 1
+// Initialized in pnorrp.C
extern trace_desc_t* g_trac_pnor;
namespace PNOR
@@ -429,7 +431,6 @@ PnorDD::PnorDD( PnorMode_t i_mode,
iv_mutex_ptr = &iv_mutex;
mutex_init(iv_mutex_ptr);
TRACFCOMP(g_trac_pnor, "PnorDD::PnorDD()> Using i_target=0x%X (non-master) and iv_mutex_ptr", TARGETING::get_huid(i_target));
-
}
else
{
@@ -740,17 +741,17 @@ errlHndl_t PnorDD::pollSfcOpComplete(uint64_t i_pollTime)
/*@
* @errortype
* @moduleid PNOR::MOD_PNORDD_POLLSFCOPCOMPLETE
- * @reasoncode PNOR::RC_LPC_ERROR
+ * @reasoncode PNOR::RC_SFC_ERROR
* @userdata1[0:31] NOR Flash Chip ID
* @userdata1[32:63] Total poll time (ns)
* @userdata2[0:31] ECCB Status Register
* @devdesc PnorDD::pollSfcOpComplete> Error or timeout from
* SFC Status Register
- * @custdesc A problem occurred while accessing the boot flash.
+ * @custdesc Hardware error accessing flash during IPL
*/
l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORDD_POLLSFCOPCOMPLETE,
- PNOR::RC_LPC_ERROR,
+ PNOR::RC_SFC_ERROR,
TWO_UINT32_TO_UINT64(iv_nor_chipid,
poll_time),
TWO_UINT32_TO_UINT64(sfc_stat.data32,0));
@@ -970,7 +971,7 @@ errlHndl_t PnorDD::checkForSfcErrors( ResetLevels &o_pnorResetLevel )
* @userdata2 Reset Level
* @devdesc PnorDD::checkForSfcErrors> Error(s) found in SFC
* and/or LPC Slave Status Registers
- * @custdesc A problem occurred while accessing the boot flash.
+ * @custdesc Hardware error accessing flash during IPL
*/
l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORDD_CHECKFORSFCERRORS,
@@ -996,163 +997,6 @@ errlHndl_t PnorDD::checkForSfcErrors( ResetLevels &o_pnorResetLevel )
}
/**
- * @brief Check For Errors in OPB and LPCHC Status Registers
- */
-errlHndl_t PnorDD::checkForOpbErrors( ResetLevels &o_pnorResetLevel )
-{
- errlHndl_t l_err = NULL;
- bool errorFound = false;
-
- // Used to set Reset Levels, if necessary
- o_pnorResetLevel = RESET_CLEAR;
-
- // Default status values in case we fail in reading the registers
- OpbLpcmFirReg_t fir_reg;
- fir_reg.data64 = 0xDEADBEEFDEADBEEF;
- uint64_t fir_data = 0x0;
-
- // always read/write 64 bits to SCOM
- size_t scom_size = sizeof(uint64_t);
-
- do {
- // Read FIR Register
- l_err = deviceOp( DeviceFW::READ,
- iv_target,
- &(fir_data),
- scom_size,
- DEVICE_SCOM_ADDRESS(OPB_LPCM_FIR_REG) );
- if( l_err ) { break; }
-
- // Mask data to just the FIR bits we care about
- fir_reg.data64 = fir_data & OPB_LPCM_FIR_ERROR_MASK;
-
- // First look for SOFT errors
- if( 1 == fir_reg.rxits )
- {
- errorFound = true;
- o_pnorResetLevel = RESET_OPB_LPCHC_SOFT;
- TRACFCOMP( g_trac_pnor, ERR_MRK"PnorDD::checkForOpbErrors> Invalid Transfer Size: OPB_LPCM_FIR_REG=0x%.16X, ResetLevel=%d",
- fir_reg.data64, o_pnorResetLevel);
- }
-
- if( 1 == fir_reg.rxicmd )
- {
- errorFound = true;
- o_pnorResetLevel = RESET_OPB_LPCHC_SOFT;
- TRACFCOMP( g_trac_pnor, ERR_MRK"PnorDD::checkForOpbErrors> Invalid Command: OPB_LPCM_FIR_REG=0x%.16X, ResetLevel=%d",
- fir_reg.data64, o_pnorResetLevel);
- }
-
- if( 1 == fir_reg.rxiaa )
- {
- errorFound = true;
- o_pnorResetLevel = RESET_OPB_LPCHC_SOFT;
- TRACFCOMP( g_trac_pnor, ERR_MRK"PnorDD::checkForOpbErrors> Invalid Address Alignment: OPB_LPCM_FIR_REG=0x%.16X, ResetLevel=%d",
- fir_reg.data64, o_pnorResetLevel);
- }
-
- if( 1 == fir_reg.rxcbpe )
- {
- errorFound = true;
- o_pnorResetLevel = RESET_OPB_LPCHC_SOFT;
- TRACFCOMP( g_trac_pnor, ERR_MRK"PnorDD::checkForOpbErrors> Command Buffer Parity Error: OPB_LPCM_FIR_REG=0x%.16X, ResetLevel=%d",
- fir_reg.data64, o_pnorResetLevel);
- }
-
- if( 1 == fir_reg.rxdbpe )
- {
- errorFound = true;
- o_pnorResetLevel = RESET_OPB_LPCHC_SOFT;
- TRACFCOMP( g_trac_pnor, ERR_MRK"PnorDD::checkForOpbErrors> Data Buffer Parity Error: OPB_LPCM_FIR_REG=0x%.16X, ResetLevel=%d",
- fir_reg.data64, o_pnorResetLevel);
- }
-
-
- // Now look for HARD errors that will override SOFT errors reset Level
- if( 1 == fir_reg.rxhopbe )
- {
- errorFound = true;
- o_pnorResetLevel = RESET_OPB_LPCHC_HARD;
- TRACFCOMP( g_trac_pnor, ERR_MRK"PnorDD::checkForOpbErrors> OPB Bus Error: OPB_LPCM_FIR_REG=0x%.16X, ResetLevel=%d",
- fir_reg.data64, o_pnorResetLevel);
- }
-
- if( 1 == fir_reg.rxhopbt )
- {
- errorFound = true;
- o_pnorResetLevel = RESET_OPB_LPCHC_HARD;
- TRACFCOMP( g_trac_pnor, ERR_MRK"PnorDD::checkForOpbErrors> OPB Bus Timeout: OPB_LPCM_FIR_REG=0x%.16X, ResetLevel=%d",
- fir_reg.data64, o_pnorResetLevel);
- }
-
- if( 1 == fir_reg.rxctgtel )
- {
- errorFound = true;
- o_pnorResetLevel = RESET_OPB_LPCHC_HARD;
- TRACFCOMP( g_trac_pnor, ERR_MRK"PnorDD::checkForOpbErrors> CI Load/CI Store/OPB Master Hang Timeout: OPB_LPCM_FIR_REG=0x%.16X, ResetLevel=%d",
- fir_reg.data64, o_pnorResetLevel);
- }
-
-
- }while(0);
-
-
- // If there is any error create an error log
- if ( errorFound )
- {
- // If we failed on a register read above, but still found an error,
- // delete register read error log and create an original error log
- // for the found error
- if ( l_err )
- {
- TRACFCOMP( g_trac_pnor, ERR_MRK"PnorDD::checkForOpbErrors> Deleting register read error. Returning error created for the found error");
- delete l_err;
- }
-
- /*@
- * @errortype
- * @moduleid PNOR::MOD_PNORDD_CHECKFOROPBERRORS
- * @reasoncode PNOR::RC_ERROR_IN_STATUS_REG
- * @userdata1 OPB FIR Register Data
- * @userdata2 Reset Level
- * @devdesc PnorDD::checkForOpbErrors> Error(s) found in OPB
- * and/or LPCHC Status Register
- */
- l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- PNOR::MOD_PNORDD_CHECKFOROPBERRORS,
- PNOR::RC_ERROR_IN_STATUS_REG,
- fir_reg.data64,
- o_pnorResetLevel );
-
- // Limited in callout: no PNOR target, so calling out processor
- l_err->addHwCallout(
- iv_target,
- HWAS::SRCI_PRIORITY_HIGH,
- HWAS::NO_DECONFIG,
- HWAS::GARD_NULL );
-
-
- // Log FIR Register Data
- ERRORLOG::ErrlUserDetailsLogRegister
- l_eud(iv_target);
-
- l_eud.addDataBuffer(&fir_data, scom_size,
- DEVICE_SCOM_ADDRESS(OPB_LPCM_FIR_REG));
-
- l_eud.addToLog(l_err);
-
- addFFDCRegisters(l_err);
- l_err->collectTrace(PNOR_COMP_NAME);
-
- }
-
- return l_err;
-
-}
-
-
-
-/**
* @brief Add Error Registers to an existing Error Log
*/
void PnorDD::addFFDCRegisters(errlHndl_t & io_errl)
@@ -1176,7 +1020,9 @@ void PnorDD::addFFDCRegisters(errlHndl_t & io_errl)
l_eud(iv_target);
do {
-
+ //@fixme - RTC:107788 Seems like this might not belong here,
+ // instead only in the LPC layer...
+ // Add ECCB Status Register
tmp_err = deviceOp( DeviceFW::READ,
iv_target,
&(data64),
@@ -1410,7 +1256,7 @@ errlHndl_t PnorDD::micronFlagStatus(uint64_t i_pollTime)
* @userdata2[0:31] Micron Flag status register
* @devdesc PnorDD::micronFlagStatus> Error or timeout from
* Micron Flag Status Register
- * @custdesc A problem occurred while accessing the boot flash.
+ * @custdesc Hardware error accessing flash during IPL
*/
l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORDD_MICRONFLAGSTATUS,
@@ -1929,125 +1775,12 @@ errlHndl_t PnorDD::writeSfcBuffer(size_t i_size,
errlHndl_t PnorDD::readLPC(uint32_t i_addr,
uint32_t& o_data)
{
- errlHndl_t l_err = NULL;
- ResetLevels pnorResetLevel = RESET_CLEAR;
-
- do {
-
- // always read/write 64 bits to SCOM
- size_t scom_size = sizeof(uint64_t);
-
- // write command register with LPC address to read
- EccbControlReg_t eccb_cmd;
- eccb_cmd.read_op = 1;
- eccb_cmd.address = i_addr;
- l_err = deviceOp( DeviceFW::WRITE,
+ size_t reg_size = sizeof(uint32_t);
+ errlHndl_t l_err = deviceOp( DeviceFW::READ,
iv_target,
- &(eccb_cmd.data64),
- scom_size,
- DEVICE_SCOM_ADDRESS(ECCB_CTL_REG) );
- if( l_err ) { break; }
-
- // poll for complete and get the data back
- EccbStatusReg_t eccb_stat;
- uint64_t poll_time = 0;
- uint64_t loop = 0;
-
- while( poll_time < ECCB_POLL_TIME_NS )
- {
- l_err = deviceOp( DeviceFW::READ,
- iv_target,
- &(eccb_stat.data64),
- scom_size,
- DEVICE_SCOM_ADDRESS(ECCB_STAT_REG) );
- if( l_err ) { break; }
-
- if( eccb_stat.op_done == 1 )
- {
- break;
- }
-
-
- // want to start out incrementing by small numbers then get bigger
- // to avoid a really tight loop in an error case so we'll increase
- // the wait each time through
- //TODO tmp remove for VPO, need better polling strategy -- RTC43738
- //nanosleep( 0, ECCB_POLL_INCR_NS*(++loop) );
- poll_time += ECCB_POLL_INCR_NS*++loop;
- }
- if( l_err ) { break; }
-
- // check for errors or timeout at ECCB level
- if( (eccb_stat.data64 & ECCB_LPC_STAT_REG_ERROR_MASK)
- || (eccb_stat.op_done == 0) )
- {
- TRACFCOMP(g_trac_pnor, "PnorDD::readLPC> Error or timeout from LPC Status Register : i_addr=0x%.8X, status=0x%.16X", i_addr, eccb_stat.data64 );
-
- /*@
- * @errortype
- * @moduleid PNOR::MOD_PNORDD_READLPC
- * @reasoncode PNOR::RC_LPC_ERROR
- * @userdata1[0:31] LPC Address
- * @userdata1[32:63] Total poll time (ns)
- * @userdata2 ECCB Status Register
- * @devdesc PnorDD::readLPC> Error or timeout from
- * LPC Status Register
- * @custdesc A problem occurred while accessing the boot flash.
- */
- l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- PNOR::MOD_PNORDD_READLPC,
- PNOR::RC_LPC_ERROR,
- TWO_UINT32_TO_UINT64(i_addr,poll_time),
- eccb_stat.data64);
-
- // Limited in callout: no PNOR target, so calling out processor
- l_err->addHwCallout(
- iv_target,
- HWAS::SRCI_PRIORITY_HIGH,
- HWAS::NO_DECONFIG,
- HWAS::GARD_NULL );
-
- addFFDCRegisters(l_err);
- l_err->collectTrace(PNOR_COMP_NAME);
- l_err->collectTrace(XSCOM_COMP_NAME);
-
- // Reset ECCB - handled below
- pnorResetLevel = RESET_ECCB;
-
- break;
- }
-
- // check for errors at OPB level
- l_err = checkForOpbErrors( pnorResetLevel );
-
- if( l_err ) { break; }
-
- // copy data out to caller's buffer
- o_data = eccb_stat.read_data;
-
- } while(0);
-
-
- // If we have an error that requires a reset, do that here
- if ( l_err && ( pnorResetLevel != RESET_CLEAR ) )
- {
- errlHndl_t tmp_err = NULL;
- tmp_err = resetPnor(pnorResetLevel);
-
- if ( tmp_err )
- {
- // Commit reset error since we have original error l_err
- TRACFCOMP(g_trac_pnor, "PnorDD::readLPC Error from resetPnor() after previous error eid=0x%X. Committing resetPnor() error log eid=0x%X.",
- l_err->eid(), tmp_err->eid());
-
- tmp_err->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
- tmp_err->collectTrace(PNOR_COMP_NAME);
- tmp_err->plid(l_err->plid());
- errlCommit(tmp_err, PNOR_COMP_ID);
- }
- }
-
-
+ &o_data,
+ reg_size,
+ DEVICE_LPC_ADDRESS(LPC::TRANS_ABS,i_addr) );
return l_err;
}
@@ -2057,136 +1790,14 @@ errlHndl_t PnorDD::readLPC(uint32_t i_addr,
errlHndl_t PnorDD::writeLPC(uint32_t i_addr,
uint32_t i_data)
{
- errlHndl_t l_err = NULL;
- ResetLevels pnorResetLevel = RESET_CLEAR;
-
-
+ size_t reg_size = sizeof(uint32_t);
+ errlHndl_t l_err = deviceOp( DeviceFW::WRITE,
+ iv_target,
+ &i_data,
+ reg_size,
+ DEVICE_LPC_ADDRESS(LPC::TRANS_ABS,i_addr) );
TRACDCOMP(g_trac_pnor, "writeLPC> %.8X = %.8X", i_addr, i_data );
- do {
-
- // always read/write 64 bits to SCOM
- size_t scom_size = sizeof(uint64_t);
-
- // write data register
- TRACDCOMP(g_trac_pnor, "writeLPC> Write ECCB data register");
-
- uint64_t eccb_data = static_cast<uint64_t>(i_data);
- eccb_data = eccb_data << 32; //left-justify my data
- l_err = deviceOp( DeviceFW::WRITE,
- iv_target,
- &eccb_data,
- scom_size,
- DEVICE_SCOM_ADDRESS(ECCB_DATA_REG) );
- if( l_err ) { break; }
-
- // write command register with LPC address to write
- EccbControlReg_t eccb_cmd;
- eccb_cmd.read_op = 0;
- eccb_cmd.address = i_addr;
- TRACDCOMP(g_trac_pnor, "writeLPC> Write ECCB command register, cmd=0x%.16x", eccb_cmd.data64 );
- l_err = deviceOp( DeviceFW::WRITE,
- iv_target,
- &(eccb_cmd.data64),
- scom_size,
- DEVICE_SCOM_ADDRESS(ECCB_CTL_REG) );
- if( l_err ) { break; }
-
-
- // poll for complete
- EccbStatusReg_t eccb_stat;
- uint64_t poll_time = 0;
- uint64_t loop = 0;
- while( poll_time < ECCB_POLL_TIME_NS )
- {
- l_err = deviceOp( DeviceFW::READ,
- iv_target,
- &(eccb_stat.data64),
- scom_size,
- DEVICE_SCOM_ADDRESS(ECCB_STAT_REG) );
- TRACDCOMP(g_trac_pnor, "writeLPC> Poll on ECCB Status, poll_time=0x%.16x, stat=0x%.16x", eccb_stat.data64, poll_time );
-
- if( l_err ) { break; }
-
- if( eccb_stat.op_done == 1 )
- {
- break;
- }
-
- // want to start out incrementing by small numbers then get bigger
- // to avoid a really tight loop in an error case so we'll increase
- // the wait each time through
- //TODO tmp remove for VPO, need better polling strategy -- RTC43738
- //nanosleep( 0, ECCB_POLL_INCR_NS*(++loop) );
- poll_time += ECCB_POLL_INCR_NS*++loop;
- }
- if( l_err ) { break; }
-
- // check for errors at ECCB level
- if( (eccb_stat.data64 & ECCB_LPC_STAT_REG_ERROR_MASK)
- || (eccb_stat.op_done == 0) )
- {
- TRACFCOMP(g_trac_pnor, "PnorDD::writeLPC> Error or timeout from LPC Status Register : i_addr=0x%.8X, status=0x%.16X", i_addr, eccb_stat.data64 );
-
- /*@
- * @errortype
- * @moduleid PNOR::MOD_PNORDD_WRITELPC
- * @reasoncode PNOR::RC_LPC_ERROR
- * @userdata1 LPC Address
- * @userdata2 ECCB Status Register
- * @devdesc PnorDD::writeLPC> Error or timeout from
- * LPC Status Register
- * @custdesc A problem occurred while accessing the boot flash.
- */
- l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- PNOR::MOD_PNORDD_WRITELPC,
- PNOR::RC_LPC_ERROR,
- TWO_UINT32_TO_UINT64(0,i_addr),
- eccb_stat.data64);
- // Limited in callout: no PNOR target, so calling out processor
- l_err->addHwCallout(
- iv_target,
- HWAS::SRCI_PRIORITY_HIGH,
- HWAS::NO_DECONFIG,
- HWAS::GARD_NULL );
-
- addFFDCRegisters(l_err);
- l_err->collectTrace(PNOR_COMP_NAME);
- l_err->collectTrace(XSCOM_COMP_NAME);
-
- // Reset ECCB - handled below
- pnorResetLevel = RESET_ECCB;
-
- break;
- }
-
- // check for errors at OPB level
- l_err = checkForOpbErrors( pnorResetLevel );
-
- if( l_err ) { break; }
-
- } while(0);
-
- // If we have an error that requires a reset, do that here
- if ( l_err && ( pnorResetLevel != RESET_CLEAR ) )
- {
- errlHndl_t tmp_err = NULL;
- tmp_err = resetPnor(pnorResetLevel);
-
- if ( tmp_err )
- {
- // Commit reset error since we have original error l_err
- TRACFCOMP(g_trac_pnor, "PnorDD::writeLPC Error from resetPnor() after previous error eid=0x%X. Committing resetPnor() error log eid=0x%X.",
- l_err->eid(), tmp_err->eid());
-
- tmp_err->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
- tmp_err->collectTrace(PNOR_COMP_NAME);
- tmp_err->plid(l_err->plid());
- errlCommit(tmp_err, PNOR_COMP_ID);
- }
- }
-
-
return l_err;
}
@@ -2246,7 +1857,7 @@ errlHndl_t PnorDD::compareAndWriteBlock(uint32_t i_blockStart,
if(need_write == false)
{
//No write actually needed, break out here
- TRACFCOMP(g_trac_pnor,"compareAndWriteBlock> NO Write Needed! Exiting FUnction");
+ TRACDCOMP(g_trac_pnor,"compareAndWriteBlock> NO Write Needed! Exiting Function");
break;
}
@@ -2347,7 +1958,7 @@ errlHndl_t PnorDD::compareAndWriteBlock(uint32_t i_blockStart,
delete[] read_data;
}
- TRACFCOMP(g_trac_pnor,"<<compareAndWriteBlock() Exit");
+ TRACDCOMP(g_trac_pnor,"<<compareAndWriteBlock() Exit");
return l_err;
@@ -2370,15 +1981,15 @@ errlHndl_t PnorDD::eraseFlash(uint32_t i_address)
/*@
* @errortype
* @moduleid PNOR::MOD_PNORDD_ERASEFLASH
- * @reasoncode PNOR::RC_LPC_ERROR
+ * @reasoncode PNOR::RC_INVALID_ADDRESS
* @userdata1 LPC Address
* @userdata2 Nearest Erase Boundary
* @devdesc PnorDD::eraseFlash> Address not on erase boundary
- * @custdesc A problem occurred while accessing the boot flash.
+ * @custdesc Firmware error accessing flash during IPL
*/
l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORDD_ERASEFLASH,
- PNOR::RC_LPC_ERROR,
+ PNOR::RC_INVALID_ADDRESS,
TWO_UINT32_TO_UINT64(0,i_address),
findEraseBlock(i_address),
true /*Add HB SW Callout*/ );
@@ -2652,15 +2263,11 @@ errlHndl_t PnorDD::resetPnor( ResetLevels i_pnorResetLevel )
TRACFCOMP(g_trac_pnor, "PnorDD::resetPnor> i_pnorResetLevel=0x%.8X", i_pnorResetLevel);
do {
-
- // always read/write 64 bits to SCOM
- uint64_t scom_data_64 = 0x0;
- size_t scom_size = sizeof(uint64_t);
-
+#if 0
// 32 bits for address and data for LPC operations
uint32_t lpc_addr=0;
uint32_t lpc_data=0;
-
+#endif
// To Avoid Infinite Loop - skip recovery if it already failed
if ( iv_error_recovery_failed == true )
@@ -2679,85 +2286,7 @@ errlHndl_t PnorDD::resetPnor( ResetLevels i_pnorResetLevel )
break;
}
- case RESET_ECCB:
- {
- // Write Reset Register to reset FW Logic registers
- TRACFCOMP(g_trac_pnor, "PnorDD::resetPnor> Writing ECCB_RESET_REG to reset ECCB FW Logic");
- scom_data_64 = 0x0;
- l_err = deviceOp( DeviceFW::WRITE,
- iv_target,
- &(scom_data_64),
- scom_size,
- DEVICE_SCOM_ADDRESS(ECCB_RESET_REG) );
-
- break;
- }
-
- case RESET_OPB_LPCHC_SOFT:
- {
- TRACFCOMP(g_trac_pnor, "PnorDD::resetPnor> Writing OPB_MASTER_LS_CONTROL_REG to disable then enable First Error Data Capture");
-
- // First read OPB_MASTER_LS_CONTROL_REG
- lpc_addr = OPB_MASTER_LS_CONTROL_REG;
- lpc_data = 0x0;
-
- l_err = readLPC(lpc_addr, lpc_data);
-
- if (l_err) { break; }
-
- // Disable 'First Error Data Capture' - set bit 29 to 0b1
- lpc_data |= 0x00000004;
-
- l_err = writeLPC(lpc_addr, lpc_data);
-
- if (l_err) { break; }
-
-
- // Enable 'First Error Data Capture' - set bit 29 to 0b0
- // No wait-time needed
- lpc_data &= 0xFFFFFFFB;
-
- l_err = writeLPC(lpc_addr, lpc_data);
-
- if (l_err) { break; }
-
- // Clear FIR register
- scom_data_64 = ~(OPB_LPCM_FIR_ERROR_MASK);
- l_err = deviceOp(
- DeviceFW::WRITE,
- iv_target,
- &(scom_data_64),
- scom_size,
- DEVICE_SCOM_ADDRESS(OPB_LPCM_FIR_WOX_AND_REG) );
- break;
- }
-
- case RESET_OPB_LPCHC_HARD:
- {
- TRACFCOMP(g_trac_pnor, "PnorDD::resetPnor> Writing LPCHC_RESET_REG to reset LPCHC Logic");
- lpc_addr = LPCHC_RESET_REG;
- lpc_data = 0x0;
-
- l_err = writeLPC(lpc_addr, lpc_data);
-
- // sleep 1ms for LPCHC to execute internal
- // reset+init sequence
- nanosleep( 0, NS_PER_MSEC );
-
- if (l_err) { break; }
-
- // Clear FIR register
- scom_data_64 = ~(OPB_LPCM_FIR_ERROR_MASK);
- l_err = deviceOp(
- DeviceFW::WRITE,
- iv_target,
- &(scom_data_64),
- scom_size,
- DEVICE_SCOM_ADDRESS(OPB_LPCM_FIR_WOX_AND_REG) );
-
- break;
- }
-
+ //@fixme RTC:109859 -- All SFC recovery should move into SFC classes
case RESET_LPC_SLAVE:
{
// @todo RTC 109999 - Skipping because SFC resets can
@@ -2774,6 +2303,7 @@ errlHndl_t PnorDD::resetPnor( ResetLevels i_pnorResetLevel )
break;
}
+ //@fixme RTC:109859 -- All SFC recovery should move into SFC classes
case RESET_LPC_SLAVE_ERRS:
{
// @todo RTC 109999 - Skipping because SFC resets can
@@ -2790,6 +2320,7 @@ errlHndl_t PnorDD::resetPnor( ResetLevels i_pnorResetLevel )
}
+ //@fixme RTC:109859 -- All SFC recovery should move into SFC classes
case RESET_SFC_LOCAL_BUS:
{
// @todo RTC 109999 - Skipping because SFC resets can
@@ -2809,6 +2340,7 @@ errlHndl_t PnorDD::resetPnor( ResetLevels i_pnorResetLevel )
break;
}
+ //@fixme RTC:109859 -- All SFC recovery should move into SFC classes
case RESET_SFCBUS_LPCSLAVE_ERRS:
{
// @todo RTC 109999 - Skipping because SFC resets can
@@ -2883,6 +2415,7 @@ errlHndl_t PnorDD::resetPnor( ResetLevels i_pnorResetLevel )
+//@fixme RTC:109859 -- All SFC recovery should move into SFC classes
errlHndl_t PnorDD::reinitializeSfc( void )
{
TRACFCOMP(g_trac_pnor, "PnorDD::reinitializeSfc>");
diff --git a/src/usr/pnor/pnordd.H b/src/usr/pnor/pnordd.H
index 25915b294..31b3d8d7d 100644
--- a/src/usr/pnor/pnordd.H
+++ b/src/usr/pnor/pnordd.H
@@ -36,7 +36,7 @@ namespace PNOR { class UdPnorDDParms; }
/**
* @brief PNOR Device Driver Class
- * Provides access to the PNOR flash via the ECCB/LPC/SPI hardware
+ * Provides access to the PNOR flash via the ECCB/LPC hardware
*/
class PnorDD
{
@@ -126,17 +126,6 @@ class PnorDD
};
/**
- * @brief LPC HC Registers
- * These are offsets within the LPC Host Controller Register Space
- */
- enum LpcRegAddr {
- LPC_REG_BAR0 = 0x00, /**< BAR0 : OPB register */
- LPC_REG_BAR1 = 0x04, /**< BAR1 : LPC I/O space */
- LPC_REG_BAR2 = 0x08, /**< BAR2 : LPC Memory space */
- LPC_REG_BAR3 = 0x0C, /**< BAR3 : LPC Firmware space */
- };
-
- /**
* @brief SPI Config Info
* OP Codes and other MISC info for configuring SFC
*/
@@ -282,9 +271,6 @@ class PnorDD
*/
enum ResetLevels {
RESET_CLEAR = 0x00000000, /**< Clear Reset Level */
- RESET_ECCB = 0x00000001, /**< ECCB FW Logic */
- RESET_OPB_LPCHC_SOFT = 0x00000002, /**< OPB LPCHC Clear Errors */
- RESET_OPB_LPCHC_HARD = 0x00000004, /**< OPB LPCHC Reset Logic */
RESET_LPC_SLAVE = 0x00000008, /**< LPC Slave Logic on SFC */
RESET_LPC_SLAVE_ERRS = 0x00000010, /**< LPC Slave Errors on SFC */
RESET_SFC_LOCAL_BUS = 0x00000020, /**< SFC Local Bus */
@@ -416,36 +402,6 @@ class PnorDD
};
/**
- * @brief OPB-LPCM FIR Register Layout
- */
- union OpbLpcmFirReg_t
- {
- uint64_t data64;
- struct
- {
- uint64_t rxits : 1; // Invalid Transfer Size
- uint64_t rxicmd : 1; // Invalid Command
- uint64_t rxiaa : 1; // Invalid Address Alignment
- uint64_t rxhopbe : 1; // OPB Bus Error
- uint64_t rxhopbt : 1; // OPB Bus Timeout
- uint64_t rxctgtel : 1; // CI Load/CI Store/OPB Master Hang Timeout
- uint64_t rxcbpe : 1; // Command Buffer Parity Error
- uint64_t rxdbpe : 1; // Data Buffer Parity Error
- uint64_t reserved : 56;
- };
- OpbLpcmFirReg_t() : data64(0) {};
- };
-
- /**
- * @brief LPCHC Registers
- * These are offsets within the LPCHC Register Space
- */
- enum LpcHcRegAddr {
- LPCHC_REG_RESET = 0xFC, /**< RESET : write-only */
- };
-
-
- /**
* @brief Write a SFC Register
*
* @parm i_range SFC Address Range
@@ -610,17 +566,7 @@ class PnorDD
#endif
LPC_TOP_OF_FLASH_OFFSET = 0xFFFFFFFF,
- ECCB_CTL_REG = 0x000B0020, /**< ECCB Control Reg (FW) */
- ECCB_RESET_REG = 0x000B0021, /**< ECCB Reset Reg (FW) */
- ECCB_STAT_REG = 0x000B0022, /**< ECCB Status Reg (FW) */
- ECCB_DATA_REG = 0x000B0023, /**< ECCB Data Reg (FW) */
-
- // Default Values to set for all operations
- // 1101.0100.0000.000x.0000.0001.0000.0000.<address>
- ECCB_LPC_CTL_REG_DEFAULT = 0xD400010000000000,
-
- // Error bits: 41-43, 56 (52=cmd complete) (not 57: only non-fw use)
- ECCB_LPC_STAT_REG_ERROR_MASK = 0x0000000000700080, /**< Error Bits */
+ ECCB_STAT_REG = 0x000B0022, /**< ECCB Status Reg (FW) */
/**< OPB LPCM Sync FIR Reg - used to read the FIR*/
OPB_LPCM_FIR_REG = 0x01010C00,
@@ -639,8 +585,6 @@ class PnorDD
ERASE_COUNT_MAX = 64, /**<Max number of tracked erase blocks */
ERASESIZE_BYTES_DEFAULT = 4 * KILOBYTE, /**< Min Erase Block (bytes) */
- ECCB_POLL_TIME_NS = 400000, /**< max time from Manfred Walz is 400ms */
- ECCB_POLL_INCR_NS = 10, /**< minimum increment during poll */
};
/**
@@ -784,51 +728,6 @@ class PnorDD
void addFFDCRegisters(errlHndl_t & io_errl);
/**
- * @brief ECCB Control Register Layout
- */
- union EccbControlReg_t
- {
- uint64_t data64;
- struct
- {
- // unused sections should be set to zero
- uint64_t magic1 : 8; /**< 0:7 = b11010100 per spec */
- uint64_t unused1 : 7; /**< 8:14 */
- uint64_t read_op : 1; /**< 15 = set for read operation */
- uint64_t unused2 : 7; /**< 16:22 */
- uint64_t addr_len : 3; /**< 23:25 = 100 means 4 byte */
- uint64_t unused3 : 6; /**< 26:31 */
- uint64_t address : 32; /**< 32:63 = LPC Address */
- };
-
- EccbControlReg_t() : data64(ECCB_LPC_CTL_REG_DEFAULT) {};
- };
-
- /**
- * @brief ECCB Status Register Layout
- */
- union EccbStatusReg_t
- {
- uint64_t data64;
- struct
- {
- uint64_t unused : 6; /**< 0:5 */
- uint64_t read_data : 32; /**< 6:37 */
- uint64_t unused1 : 3; /**< 38:40 */
- uint64_t eccb_err : 3; /**< 41:43 = ECCB_Error_Info */
- uint64_t busy : 1; /**< 44 = Operation Busy */
- uint64_t unused2 : 7; /**< 45:51 */
- uint64_t op_done : 1; /**< 52 = Command Complete */
- uint64_t unused3 : 3; /**< 53:55 */
- uint64_t addr_parity_err : 1; /**< 56 = ECC Address Register
- Parity Error */
- uint64_t unused4 : 7; /**< 57:63 */
- };
- EccbStatusReg_t() : data64(0) {};
- };
-
-
- /**
* @brief Reset PNOR Logic At The Specified Level
*
* @parm i_pnorResetLevel Level of PNOR to Reset
diff --git a/src/usr/pnor/pnorvalid.C b/src/usr/pnor/pnorvalid.C
index 22232729d..b690fd5fc 100644
--- a/src/usr/pnor/pnorvalid.C
+++ b/src/usr/pnor/pnorvalid.C
@@ -6,6 +6,7 @@
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -46,6 +47,7 @@
#include "pnordd.H"
#include <pnor/pnorif.H>
#include <pnor/pnor_reasoncodes.H>
+#include <lpc/lpcif.H>
// Used for creating an Invalid TOC ("PNOR")
@@ -139,7 +141,38 @@ errlHndl_t validateAltMaster( void )
{
delete pnordd;
pnordd = NULL;
+
+ // Delete the LPC objects we already used
+ l_err = LPC::create_altmaster_objects( false, NULL );
+ if ( l_err )
+ {
+ // Commit Error Log, but continue the test
+ TRACFCOMP( g_trac_pnor, INFO_MRK"PNOR::validateAltMaster> Could not delete LPC objects. eid=0x%X, rc=0x%X. Committing log and Continuing", l_err->eid(), l_err->reasonCode());
+
+ l_err->collectTrace(PNOR_COMP_NAME);
+
+ // if there was an error, commit here and then proceed to
+ // the next processor
+ errlCommit(l_err,PNOR_COMP_ID);
+ continue;
+ }
+ }
+
+ // Create the LPC objects we're going to use
+ l_err = LPC::create_altmaster_objects( true, procList[i] );
+ if ( l_err )
+ {
+ // Commit Error Log, but continue the test
+ TRACFCOMP( g_trac_pnor, INFO_MRK"PNOR::validateAltMaster> Could not create LPC objects for %.8X. eid=0x%X, rc=0x%X. Committing log and Continuing", TARGETING::get_huid(procList[i]), l_err->eid(), l_err->reasonCode());
+
+ l_err->collectTrace(PNOR_COMP_NAME);
+
+ // if there was an error, commit here and then proceed to
+ // the next processor
+ errlCommit(l_err,PNOR_COMP_ID);
+ continue;
}
+
pnordd = new PnorDD(PnorDD::MODEL_REAL_MMIO, 0, 0, procList[i]);
// Read Flash
@@ -248,6 +281,20 @@ errlHndl_t validateAltMaster( void )
{
delete pnordd;
pnordd = NULL;
+
+ // Delete the LPC objects we used
+ l_err = LPC::create_altmaster_objects( false, NULL );
+ if ( l_err )
+ {
+ // Commit Error Log, but continue the test
+ TRACFCOMP( g_trac_pnor, INFO_MRK"PNOR::validateAltMaster> Could not delete LPC objects. eid=0x%X, rc=0x%X. Committing log and Continuing", l_err->eid(), l_err->reasonCode());
+
+ l_err->collectTrace(PNOR_COMP_NAME);
+
+ // if there was an error, commit here and then proceed to
+ // the next processor
+ errlCommit(l_err,PNOR_COMP_ID);
+ }
}
if(tocBuffer != NULL)
OpenPOWER on IntegriCloud