summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/build/citest/etc/bbuild2
-rwxr-xr-xsrc/build/citest/etc/workarounds.postsimsetup11
-rwxr-xr-xsrc/build/citest/etc/workarounds.presimsetup33
-rwxr-xr-xsrc/build/simics/standalone.simics4
-rw-r--r--src/include/usr/pnor/pnor_reasoncodes.H46
-rw-r--r--src/usr/pnor/pnordd.C283
-rw-r--r--src/usr/pnor/pnordd.H44
7 files changed, 350 insertions, 73 deletions
diff --git a/src/build/citest/etc/bbuild b/src/build/citest/etc/bbuild
index 28472dc7b..36a548773 100644
--- a/src/build/citest/etc/bbuild
+++ b/src/build/citest/etc/bbuild
@@ -1 +1 @@
-/esw/fips810/Builds/b1106a_1245.810
+/esw/fips810/Builds/b1201b_1249.810
diff --git a/src/build/citest/etc/workarounds.postsimsetup b/src/build/citest/etc/workarounds.postsimsetup
index e56c08ef5..0b7a91941 100755
--- a/src/build/citest/etc/workarounds.postsimsetup
+++ b/src/build/citest/etc/workarounds.postsimsetup
@@ -32,3 +32,14 @@ mkdir -p $sb/simu/data/cec-chip/
cp $bb/src/simu/data/cec-chip/centaur.act $sb/simu/data/cec-chip/centaur.act
patch -p0 $sb/simu/data/cec-chip/centaur.act $HOSTBOOTROOT/src/build/citest/etc/patches/centaur.act.patch
###
+
+#### Update config file with new variables (Remove with RTC: 59984) ####
+echo "+++ Forcing SBE header usage till Fips defaults to OFF"
+mkdir -p $sb/simu/configs
+mkdir -p $sb/simu/data/cec-chip
+egrep -v "SETENV GFW_P8_MURANO_HB_BASE_IMG_USE_PNOR" $BACKING_BUILD/src/simu/configs/P8_MURANO.config> $sb/simu/configs/P8_MURANO.config
+egrep -v "SETENV GFW_P8_VENICE_HB_BASE_IMG_USE_PNOR" $BACKING_BUILD/src/simu/configs/P8_VENICE.config> $sb/simu/configs/P8_VENICE.config
+echo "SETENV GFW_P8_MURANO_HB_BASE_IMG_USE_PNOR no" >> $sb/simu/configs/P8_MURANO.config
+echo "SETENV GFW_P8_VENICE_HB_BASE_IMG_USE_PNOR no" >> $sb/simu/configs/P8_VENICE.config
+echo "SETENV GFW_P8_MURANO_HB_BASE_IMG_WITH_ECC no" >> $sb/simu/configs/P8_MURANO.config
+echo "SETENV GFW_P8_VENICE_HB_BASE_IMG_WITH_ECC no" >> $sb/simu/configs/P8_VENICE.config
diff --git a/src/build/citest/etc/workarounds.presimsetup b/src/build/citest/etc/workarounds.presimsetup
index aff5cba43..85c0fc21d 100755
--- a/src/build/citest/etc/workarounds.presimsetup
+++ b/src/build/citest/etc/workarounds.presimsetup
@@ -1,26 +1,26 @@
#!/bin/sh
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
#
-# $Source: src/build/citest/etc/workarounds.presimsetup $
+# $Source: src/build/citest/etc/workarounds.presimsetup $
#
-# IBM CONFIDENTIAL
+# IBM CONFIDENTIAL
#
-# COPYRIGHT International Business Machines Corp. 2011-2012
+# COPYRIGHT International Business Machines Corp. 2011,2012
#
-# p1
+# p1
#
-# Object Code Only (OCO) source materials
-# Licensed Internal Code Source Materials
-# IBM HostBoot Licensed Internal Code
+# Object Code Only (OCO) source materials
+# Licensed Internal Code Source Materials
+# IBM HostBoot Licensed Internal Code
#
-# The source code for this program is not published or other-
-# wise divested of its trade secrets, irrespective of what has
-# been deposited with the U.S. Copyright Office.
+# The source code for this program is not published or otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
#
-# Origin: 30
+# Origin: 30
#
-# IBM_PROLOG_END_TAG
+# IBM_PROLOG_END_TAG
##
## Workarounds that are run before start_simics is executed for the first time
## to setup the sandbox
@@ -33,3 +33,8 @@
#echo "WSALIAS HOSTBOOT_LEVEL FIPSLEVEL env/gfwb/simics-4.2.0/simics-4.2.83/fips/fld36/fi120201a700.42" >> $sb/simu/data/simicsInfo
#echo "WSALIAS HOSTBOOT_LEVEL SIMICSLEVEL env/vtechb/simics-4.2.0/simics-4.2.83/bin" >> $sb/simu/data/simicsInfo
+####### Remove with RTC: 59984
+echo "+++ Override simics level to support Micron parts."
+mkdir -p $sb/simu/data
+egrep -v "WSALIAS DEFAULT FIPSLEVEL" $BACKING_BUILD/src/simu/data/simicsInfo > $sb/simu/data/simicsInfo
+echo "WSALIAS DEFAULT FIPSLEVEL env/gfwf/simics-4.2.0/simics-4.2.98/fips/fld36/fi121205d800.42" >> $sb/simu/data/simicsInfo
diff --git a/src/build/simics/standalone.simics b/src/build/simics/standalone.simics
index 8ea2bdcee..7d6874cd9 100755
--- a/src/build/simics/standalone.simics
+++ b/src/build/simics/standalone.simics
@@ -1 +1,5 @@
p8Proc0.proc_fsi2host_mbox->responder_enable=1
+
+#Trigger the SBE start
+p8Proc0.proc_lbus_map.write 0x2870 0x50000000 #SBE Vital 0x281C
+p8Proc0.proc_lbus_map.write 0x2870 0x90000000 #SBE Vital 0x281C
diff --git a/src/include/usr/pnor/pnor_reasoncodes.H b/src/include/usr/pnor/pnor_reasoncodes.H
index 71d345873..a5b321b66 100644
--- a/src/include/usr/pnor/pnor_reasoncodes.H
+++ b/src/include/usr/pnor/pnor_reasoncodes.H
@@ -1,25 +1,25 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/include/usr/pnor/pnor_reasoncodes.H $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/pnor/pnor_reasoncodes.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2011,2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
#ifndef __PNOR_REASONCODES_H
#define __PNOR_REASONCODES_H
@@ -50,6 +50,7 @@ namespace PNOR
MOD_PNORDD_WRITELPC = 0x19, /**< pnordd.C : PnorDD::writeLPC */
MOD_PNORDD_ERASEFLASH = 0x1A, /**< pnordd.C : PnorDD::eraseFlash */
MOD_PNORDD_COMPAREANDWRITEBLOCK = 0x1B, /**< pnordd.C : PnorDD::compareAndWriteBlock */
+ MOD_PNORDD_MICRONOPCOMPLETE = 0x1C, /**< pnordd.C : PnorDD::micronOpComplete */
};
@@ -65,6 +66,7 @@ namespace PNOR
RC_LPC_ERROR = PNOR_COMP_ID | 0x08,
RC_BAD_STARTUP_RC = PNOR_COMP_ID | 0x09,
RC_UNSUPORTED_HARDWARE = PNOR_COMP_ID | 0x0A,
+ RC_MICRON_INCOMPLETE = PNOR_COMP_ID | 0x0B,
};
};
diff --git a/src/usr/pnor/pnordd.C b/src/usr/pnor/pnordd.C
index 1f5c0b272..0f4f3e29d 100644
--- a/src/usr/pnor/pnordd.C
+++ b/src/usr/pnor/pnordd.C
@@ -400,6 +400,7 @@ PnorDD::~PnorDD()
bool PnorDD::cv_sfcInitDone = false; //Static flag to ensure we only init the SFC one time.
uint32_t PnorDD::cv_nor_chipid = 0; //Detected NOR Flash Type
+uint32_t PnorDD::cv_hw_workaround = 0; //Hardware Workaround flags
/**
* STATIC
@@ -449,15 +450,19 @@ void PnorDD::sfcInit( )
//Determine NOR Flash type, configure SFC and PNOR DD as needed
l_err = getNORChipId(cv_nor_chipid);
- TRACFCOMP(g_trac_pnor, "PnorDD::sfcInit: cv_nor_chipid=0x%.8x> ", cv_nor_chipid );
-
- //TODO: Need to add support for VPO (RTC: 42325), Spansion NOR (RTC: 42326),
- // Micron NOR (RTC: 42328), Macronix (RTC: 42330), and Simics (RTC: 42331)
- // There will probably be some overlap between those stories, but keeping them
- // all separate for now to ensure everything is covered.
- if(SIMICS_NOR_ID == cv_nor_chipid)
+ TRACFCOMP(g_trac_pnor,
+ "PnorDD::sfcInit: cv_nor_chipid=0x%.8x> ",
+ cv_nor_chipid );
+
+ //TODO: Need to add support for VPO (RTC: 42325),
+ // Spansion NOR (RTC: 42326),, Macronix (RTC: 42330)
+ // There will probably be some overlap between those
+ // stories, but keeping them all separate for now to
+ // ensure everything is covered
+ if(MICRON_NOR_ID == cv_nor_chipid) /* Simics currently Micron */
{
- TRACFCOMP(g_trac_pnor, "PnorDD::sfcInit: Configuring SFC for SIMICS NOR> " );
+ TRACFCOMP(g_trac_pnor,
+ "PnorDD::sfcInit: Configuring SFC for SIMICS NOR> " );
uint32_t sm_erase_op = SPI_SIM_SM_ERASE_OP;
iv_erasesize_bytes = SPI_SIM_SM_ERASE_SZ;
@@ -473,7 +478,7 @@ void PnorDD::sfcInit( )
iv_erasesize_bytes);
if(l_err) { break; }
- //Enable 4-byte addressing for Macronix-type device
+ //Enable 4-byte addressing
SfcCmdReg_t sfc_cmd;
sfc_cmd.opcode = SPI_START4BA;
sfc_cmd.length = 0;
@@ -618,6 +623,7 @@ errlHndl_t PnorDD::pollSfcOpComplete(uint64_t i_pollTime)
// the wait each time through
//TODO tmp remove for VPO, need better polling strategy -- RTC43738
//nanosleep( 0, SFC_POLL_INCR_NS*(++loop) );
+ ++loop;
poll_time += SFC_POLL_INCR_NS*loop;
}
if( l_err ) { break; }
@@ -626,7 +632,9 @@ errlHndl_t PnorDD::pollSfcOpComplete(uint64_t i_pollTime)
// TODO: What errors do we check?
if( (sfc_stat.done == 0) )
{
- TRACFCOMP(g_trac_pnor, "PnorDD::pollSfcOpComplete> Error or timeout from LPC Status Register" );
+ TRACFCOMP(g_trac_pnor,
+ "PnorDD::pollSfcOpComplete> Error or timeout from SFC Status Register"
+ );
/*@
* @errortype
@@ -635,13 +643,14 @@ errlHndl_t PnorDD::pollSfcOpComplete(uint64_t i_pollTime)
* @userdata1[0:31] NOR Flash Chip ID
* @userdata1[32:63] Total poll time (ns)
* @userdata2[0:31] ECCB Status Register
- * @devdesc PnorDD::readLPC> Error or timeout from
- * LPC Status Register
+ * @devdesc PnorDD::pollSfcOpComplete> Error or timeout from
+ * SFC Status Register
*/
l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORDD_POLLSFCOPCOMPLETE,
PNOR::RC_LPC_ERROR,
- TWO_UINT32_TO_UINT64(cv_nor_chipid,poll_time),
+ TWO_UINT32_TO_UINT64(cv_nor_chipid,
+ poll_time),
TWO_UINT32_TO_UINT64(sfc_stat.data32,0));
l_err->collectTrace("PNOR");
@@ -658,6 +667,135 @@ errlHndl_t PnorDD::pollSfcOpComplete(uint64_t i_pollTime)
}
/**
+ * @brief Poll for Op complete on Micron NOR chips
+ * The current version of Micron parts require a special
+ * form of checking for erase and write complete.
+ */
+errlHndl_t PnorDD::micronOpComplete(uint64_t i_pollTime)
+{
+ errlHndl_t l_err = NULL;
+ TRACFCOMP( g_trac_pnor, "PnorDD::micronOpComplete> i_pollTime=0x%.8x",
+ i_pollTime );
+
+ do {
+
+ //Configure Get "Chip ID" command in SFC to check special
+ //Micron 'flag status' register
+ uint32_t confData = SPI_MICRON_FLAG_STAT << 24;
+ confData |= 0x00800001; // 8-> read, 1->1 bytes
+ TRACDCOMP( g_trac_pnor, "PnorDD::micronOpComplete> confData=0x%.8x",
+ confData );
+ l_err = writeRegSfc(SFC_CMD_SPACE,
+ SFC_REG_CHIPIDCONF,
+ confData);
+ if(l_err) { break; }
+
+
+ //Poll for complete status
+ uint32_t opStatus;
+ uint64_t poll_time = 0;
+ uint64_t loop = 0;
+ while( poll_time < i_pollTime )
+ {
+ //Issue Get Chip ID command (reading flag status)
+ SfcCmdReg_t sfc_cmd;
+ sfc_cmd.opcode = SFC_OP_CHIPID;
+ sfc_cmd.length = 0;
+
+ l_err = writeRegSfc(SFC_CMD_SPACE,
+ SFC_REG_CMD,
+ sfc_cmd.data32);
+ if(l_err) { break; }
+
+ //Read the Status from the Command Buffer
+ l_err = readRegSfc(SFC_CMDBUF_SPACE,
+ 0, //Offset into CMD BUFF space in bytes
+ opStatus);
+ if(l_err) { break; }
+
+ //check for complete or error
+ // bit 0 = ready, bit 2=erase fail, bit 3=Program (Write) failure
+ if( (opStatus & 0xB0000000))
+ {
+ 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, SFC_POLL_INCR_NS*(++loop) );
+ ++loop;
+ poll_time += SFC_POLL_INCR_NS*loop;
+ }
+ if( l_err ) { break; }
+
+ // check for ready and no errors
+ // bit 0 = ready, bit 2=erase fail, bit 3=Program (Write) failure
+ if( (opStatus & 0xB0000000) != 0x80000000)
+ {
+ TRACFCOMP(g_trac_pnor,
+ "PnorDD::micronOpComplete> Error or timeout from Micron Flag Status Register (0x%.8X)",
+ opStatus);
+
+ /*@
+ * @errortype
+ * @moduleid PNOR::MOD_PNORDD_MICRONOPCOMPLETE
+ * @reasoncode PNOR::RC_MICRON_INCOMPLETE
+ * @userdata1[0:31] NOR Flash Chip ID
+ * @userdata1[32:63] Total poll time (ns)
+ * @userdata2[0:31] Micron Flag status register
+ * @devdesc PnorDD::micronOpComplete> Error or timeout from
+ * Micron Flag Status Register
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ PNOR::MOD_PNORDD_MICRONOPCOMPLETE,
+ PNOR::RC_MICRON_INCOMPLETE,
+ TWO_UINT32_TO_UINT64(cv_nor_chipid,
+ poll_time),
+ TWO_UINT32_TO_UINT64(opStatus,0));
+
+ l_err->collectTrace("PNOR");
+ l_err->collectTrace("XSCOM");
+
+ //Erase & Program error bits are sticky, so they need to be cleared.
+
+ //Configure Get "Chip ID" command in SFC to clear special
+ //Micron 'flag status' register. remaining bits are all zero
+ // since we just need to issue the SPI command.
+ uint32_t confData = SPI_MICRON_CLRFLAG_STAT << 24;
+ TRACDCOMP( g_trac_pnor, "PnorDD::micronOpComplete> confData=0x%.8x",
+ confData );
+ errlHndl_t tmp_err = NULL;
+ tmp_err = writeRegSfc(SFC_CMD_SPACE,
+ SFC_REG_CHIPIDCONF,
+ confData);
+ if(tmp_err) {
+ //commit this error and return the original
+ ERRORLOG::errlCommit(tmp_err,PNOR_COMP_ID);
+ }
+
+ //Issue Get Chip ID command (clearing flag status)
+ SfcCmdReg_t sfc_cmd;
+ sfc_cmd.opcode = SFC_OP_CHIPID;
+ sfc_cmd.length = 0;
+
+ l_err = writeRegSfc(SFC_CMD_SPACE,
+ SFC_REG_CMD,
+ sfc_cmd.data32);
+ if(l_err) { break; }
+
+ break;
+ }
+
+
+ }while(0);
+
+ return l_err;
+
+}
+
+/**
* @brief Read the NOR FLash ChipID
*/
errlHndl_t PnorDD::getNORChipId(uint32_t& o_chipId,
@@ -668,10 +806,19 @@ errlHndl_t PnorDD::getNORChipId(uint32_t& o_chipId,
i_spiOpcode );
do {
+ //Configure Get Chip ID opcode
+ uint32_t confData = i_spiOpcode << 24;
+ confData |= 0x00800003; // 8-> read, 3->3 bytes
+ TRACDCOMP( g_trac_pnor, "PnorDD::getNORChipId> confData=0x%.8x",
+ confData );
+ l_err = writeRegSfc(SFC_CMD_SPACE,
+ SFC_REG_CHIPIDCONF,
+ confData);
+ if(l_err) { break; }
//Issue Get Chip ID command
SfcCmdReg_t sfc_cmd;
- sfc_cmd.opcode = i_spiOpcode;
+ sfc_cmd.opcode = SFC_OP_CHIPID;
sfc_cmd.length = 0;
l_err = writeRegSfc(SFC_CMD_SPACE,
@@ -694,6 +841,57 @@ errlHndl_t PnorDD::getNORChipId(uint32_t& o_chipId,
// Only look at a portion of the data that is returned
o_chipId &= ID_MASK;
+ //Some micron chips require a special workaround required
+ //so need to set a flag for later use
+ //We can't read all 6 bytes above because not all MFG
+ //support that operation.
+ if(o_chipId == MICRON_NOR_ID)
+ {
+ //Change ChipID command to read back 6 bytes.
+ //If bit 1 is set in 2nd word of cmd buffer data, then
+ //We must do the workaround.
+ //Ex: CCCCCCLL 40000000
+ // CCCCCC -> Industry Standard Chip ID
+ // LL -> Lenght of Micron extended data
+ // 4 -> Bit to indicate we must to erase/write workaround
+ confData = i_spiOpcode << 24;
+ confData |= 0x00800006; // 8-> read, 6->6 bytes
+ l_err = writeRegSfc(SFC_CMD_SPACE,
+ SFC_REG_CHIPIDCONF,
+ confData);
+ if(l_err) { break; }
+
+ //Issue Get Chip ID command
+ SfcCmdReg_t sfc_cmd;
+ sfc_cmd.opcode = SFC_OP_CHIPID;
+ sfc_cmd.length = 0;
+
+ l_err = writeRegSfc(SFC_CMD_SPACE,
+ SFC_REG_CMD,
+ sfc_cmd.data32);
+ if(l_err) { break; }
+
+ uint32_t extIdData = 0;
+
+ //Read the Extended from the Command Buffer
+ l_err = readRegSfc(SFC_CMDBUF_SPACE,
+ 4, //Offset into CMD BUFF space in bytes
+ extIdData);
+ if(l_err) {
+ break;
+ }
+ if((extIdData & 0x40000000) == 0x00000000)
+ {
+ TRACFCOMP( g_trac_pnor,
+ "PnorDD::getNORChipId> Setting Micron workaround flag"
+ );
+ //Set Micron workaround flag
+ cv_hw_workaround |= HWWK_MICRON_WRT_ERASE;
+ }
+
+ }
+
+
}while(0);
return l_err;
@@ -745,7 +943,8 @@ errlHndl_t PnorDD::flushSfcBuf(uint32_t i_addr,
size_t i_size)
{
errlHndl_t l_err = NULL;
- TRACDCOMP( g_trac_pnor, "PnorDD::flushSfcBuf> i_addr=0x%.8x, i_size=0x%.8x",
+ TRACDCOMP( g_trac_pnor,
+ "PnorDD::flushSfcBuf> i_addr=0x%.8x, i_size=0x%.8x",
i_addr, i_size );
do {
@@ -765,9 +964,18 @@ errlHndl_t PnorDD::flushSfcBuf(uint32_t i_addr,
sfc_cmd.data32);
if(l_err) { break; }
- //Poll for complete status
- l_err = pollSfcOpComplete();
- if(l_err) { break; }
+ //check for special Micron Op Complete
+ if(cv_hw_workaround & HWWK_MICRON_WRT_ERASE)
+ {
+ l_err = micronOpComplete();
+ if(l_err) { break; }
+ }
+ else //Use Normal Op Complete
+ {
+ //Poll for complete status
+ l_err = pollSfcOpComplete();
+ if(l_err) { break; }
+ }
}while(0);
@@ -1358,7 +1566,9 @@ errlHndl_t PnorDD::eraseFlash(uint32_t i_address)
if(iv_erases[idx].addr == i_address)
{
iv_erases[idx].count++;
- TRACFCOMP(g_trac_pnor, "PnorDD::eraseFlash> Block 0x%.8X has %d erasures", i_address, iv_erases[idx].count );
+ TRACFCOMP(g_trac_pnor,
+ "PnorDD::eraseFlash> Block 0x%.8X has %d erasures",
+ i_address, iv_erases[idx].count );
break;
}
@@ -1368,12 +1578,16 @@ errlHndl_t PnorDD::eraseFlash(uint32_t i_address)
{
iv_erases[idx].addr = i_address;
iv_erases[idx].count = 1;
- TRACFCOMP(g_trac_pnor, "PnorDD::eraseFlash> Block 0x%.8X has %d erasures", i_address, iv_erases[idx].count );
+ TRACFCOMP(g_trac_pnor,
+ "PnorDD::eraseFlash> Block 0x%.8X has %d erasures",
+ i_address, iv_erases[idx].count );
break;
}
else if( idx == (ERASE_COUNT_MAX - 1))
{
- TRACFCOMP(g_trac_pnor, "PnorDD::eraseFlash> Erase counter full! Block 0x%.8X Erased", i_address );
+ TRACFCOMP(g_trac_pnor,
+ "PnorDD::eraseFlash> Erase counter full! Block 0x%.8X Erased",
+ i_address );
break;
}
}
@@ -1384,16 +1598,17 @@ errlHndl_t PnorDD::eraseFlash(uint32_t i_address)
break; //all done
}
- if(cv_nor_chipid != 0)
+ else if(cv_nor_chipid != 0)
{
- TRACDCOMP(g_trac_pnor, "PnorDD::eraseFlash> Erasing flash for cv_nor_chipid=0x%.8x, iv_mode=0x%.8x", cv_nor_chipid, iv_mode);
+ TRACDCOMP(g_trac_pnor,
+ "PnorDD::eraseFlash> Erasing flash for cv_nor_chipid=0x%.8x, iv_mode=0x%.8x",
+ cv_nor_chipid, iv_mode);
//Write erase address to ADR reg
l_err = writeRegSfc(SFC_CMD_SPACE,
SFC_REG_ADR,
i_address);
-
//Issue Erase command
SfcCmdReg_t sfc_cmd;
sfc_cmd.opcode = SFC_OP_ERASM;
@@ -1404,14 +1619,24 @@ errlHndl_t PnorDD::eraseFlash(uint32_t i_address)
sfc_cmd.data32);
if(l_err) { break; }
- //Poll for complete status
- l_err = pollSfcOpComplete();
- if(l_err) { break; }
-
+ //check for special Micron Op Complete
+ if(cv_hw_workaround & HWWK_MICRON_WRT_ERASE)
+ {
+ l_err = micronOpComplete();
+ if(l_err) { break; }
+ }
+ else //Use Normal Op Complete
+ {
+ //Poll for complete status
+ l_err = pollSfcOpComplete();
+ if(l_err) { break; }
+ }
}
else
{
- TRACFCOMP(g_trac_pnor, "PnorDD::eraseFlash> Erase not supported for cv_nor_chipid=%d", cv_nor_chipid );
+ TRACFCOMP(g_trac_pnor,
+ "PnorDD::eraseFlash> Erase not supported for cv_nor_chipid=%d",
+ cv_nor_chipid );
/*@
* @errortype
diff --git a/src/usr/pnor/pnordd.H b/src/usr/pnor/pnordd.H
index f82b991a4..e118f12a6 100644
--- a/src/usr/pnor/pnordd.H
+++ b/src/usr/pnor/pnordd.H
@@ -121,6 +121,12 @@ class PnorDD
SPI_GET_CHIPID_OP = 0x9F, /**< Default Op code for getting NOR ChipID */
SPI_START4BA = 0x37, /**< Enable Macronix 4-Byte addressing */
+ /*This command is only use on Micron NOR chips which require special
+ * procedure to check write & erase op complete
+ */
+ SPI_MICRON_FLAG_STAT = 0x70, /**< Check complete on Micron */
+ SPI_MICRON_CLRFLAG_STAT = 0x50, /**< Clear Micron Flag Status reg */
+
SPI_SIM_SM_ERASE_OP = 0x00000020, /**< Simics Op Code for Small Erase */
SPI_SIM_SM_ERASE_SZ = 0x1000, /**< Simics Small Erase Size */
};
@@ -131,8 +137,9 @@ class PnorDD
*/
enum NorChipIDs
{
- SIMICS_NOR_ID = 0x20ba2000, /**< CHIP ID returned by Simics NOR chip */
- VPO_NOR_ID = 0x20201800, /**< CHIP ID returned by VPO NOR chip */
+ /* Note: Simics currently models Micron NOR */
+ MICRON_NOR_ID = 0x20ba2000, /**< Micron NOR chip ID */
+ VPO_NOR_ID = 0x20201800, /**< VPO NOR chip ID */
ID_MASK = 0xFFFFFF00, /**< Only look at 3 bytes */
};
@@ -163,8 +170,7 @@ class PnorDD
SFC_REG_ADRCMS = 0x8C, /**< ADRCMS : Second Intf NOR Allocation */
SFC_REG_OADRNB = 0x90, /**< OADRNB : Direct Access OBP Window Base Address */
SFC_REG_OADRNS = 0x94, /**< OADRNS : DIrect Access OPB Window Size */
-
-
+ SFC_REG_CHIPIDCONF = 0x9C, /**< CHIPIDCONF : config ChipId CMD */
};
/**
@@ -195,6 +201,14 @@ class PnorDD
};
+
+ /**
+ * Flags used to trigger Hardware workarounds
+ */
+ enum {
+ HWWK_MICRON_WRT_ERASE = 0x00000001, /**< Micron Wrt/Erase workaround */
+ };
+
/**
* @brief SFC Command Register Layout
*/
@@ -203,9 +217,9 @@ class PnorDD
uint32_t data32;
struct
{
- uint32_t reserved : 16; /**< 0:15 = Reserved */
- uint32_t opcode : 7; /**< 16:22 = OpCode */
- uint32_t length : 9; /**< 22:31 = Num bytes for ReadRaw/WriteRaw */
+ uint32_t reserved : 16; /**< 0:15 = Reserved */
+ uint32_t opcode : 7; /**< 16:22 = OpCode */
+ uint32_t length : 9; /**< 22:31 = Num bytes for Read/Write Raw */
};
SfcCmdReg_t() : data32(0) {};
};
@@ -261,6 +275,16 @@ class PnorDD
*/
errlHndl_t pollSfcOpComplete(uint64_t i_pollTime = SFC_POLL_TIME_NS);
+ /**
+ * @brief Poll for Op complete on Micron NOR chips
+ * The current version of Micron parts require a special
+ * form of checking for erase and write complete.
+ *
+ * @parm i_pollTime Amount of time to Poll, default SFC_POLL_TIME_NS
+ *
+ * @return Error from operation
+ */
+ errlHndl_t micronOpComplete(uint64_t i_pollTime = SFC_POLL_TIME_NS);
/**
* @brief Read the NOR FLash ChipID
@@ -575,6 +599,12 @@ class PnorDD
static uint32_t cv_nor_chipid;
/**
+ * @brief Hardware workarounds
+ *
+ */
+ static uint32_t cv_hw_workaround;
+
+ /**
* @brief indicates if SFC initialization has been performed.
*
*/
OpenPOWER on IntegriCloud