summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2015-04-27 13:48:57 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2015-07-02 16:17:58 -0500
commit3f6449495b5922c13c9b977b252f9638ccb8cf4c (patch)
tree4b790e9e8bc19d777922f6d21567b74159c8342a /src
parent8ffdfc861b944e1d8768c2b81377bd7e8b5a92a5 (diff)
downloadtalos-hostboot-3f6449495b5922c13c9b977b252f9638ccb8cf4c.tar.gz
talos-hostboot-3f6449495b5922c13c9b977b252f9638ccb8cf4c.zip
Fix handling of ECC protected partitions at runtime
Modify the code to only check ECC on the logical size of the data that is read, rather than on the full physical size. Change-Id: Ia45989e64ef70e63542274ef59df2cc755f8082e Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/17467 Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Reviewed-by: PRACHI GUPTA <pragupta@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/pnor/pnor_reasoncodes.H1
-rw-r--r--src/usr/pnor/runtime/rt_pnor.C35
-rw-r--r--src/usr/testcore/rtloader/loader.H11
3 files changed, 42 insertions, 5 deletions
diff --git a/src/include/usr/pnor/pnor_reasoncodes.H b/src/include/usr/pnor/pnor_reasoncodes.H
index 148f916f2..31744bae5 100644
--- a/src/include/usr/pnor/pnor_reasoncodes.H
+++ b/src/include/usr/pnor/pnor_reasoncodes.H
@@ -151,6 +151,7 @@ namespace PNOR
//termination_rc
RC_INVALID_WORKING_TOC = PNOR_COMP_ID | 0x28,
RC_INVALID_TOC = PNOR_COMP_ID | 0x29,
+ RC_WRONG_SIZE_FROM_READ = PNOR_COMP_ID | 0x2A,
};
enum UserDetailsTypes
diff --git a/src/usr/pnor/runtime/rt_pnor.C b/src/usr/pnor/runtime/rt_pnor.C
index d434f2656..2874d409c 100644
--- a/src/usr/pnor/runtime/rt_pnor.C
+++ b/src/usr/pnor/runtime/rt_pnor.C
@@ -379,6 +379,37 @@ errlHndl_t RtPnor::readFromDevice (uint64_t i_procId,
else if( l_rc != static_cast<int>(l_readSize) )
{
TRACFCOMP( g_trac_pnor, "RtPnor::readFromDevice: only read 0x%X bytes, expecting 0x%X", l_rc, l_readSize );
+
+ if( PNOR::TOC == i_section )
+ {
+ // we can't know how big the TOC partition is without
+ // reading it so we have to make a request for more
+ // data and then handle a smaller amount getting returned
+ TRACFCOMP( g_trac_pnor, "Ignoring mismatch for TOC" );
+ }
+ else // everything else should have a known size
+ {
+ /*@
+ * @errortype
+ * @moduleid PNOR::MOD_RTPNOR_READFROMDEVICE
+ * @reasoncode PNOR::RC_WRONG_SIZE_FROM_READ
+ * @userdata1[00:31] section ID
+ * @userdata1[32:63] requested size of read
+ * @userdata2[00:31] requested start offset into flash
+ * @userdata2[32:63] actual amount read
+ * @devdesc Amount of data read from pnor does
+ * not match expected size
+ * @custdesc Error accessing system firmware flash
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ PNOR::MOD_RTPNOR_READFROMDEVICE,
+ PNOR::RC_WRONG_SIZE_FROM_READ,
+ TWO_UINT32_TO_UINT64(i_section,l_readSize),
+ TWO_UINT32_TO_UINT64(l_offset,l_rc),
+ true);
+ break;
+ }
}
}
else
@@ -405,10 +436,12 @@ errlHndl_t RtPnor::readFromDevice (uint64_t i_procId,
{
TRACFCOMP(g_trac_pnor, "RtPnor::readFromDevice: removing ECC...");
// remove the ECC and fix the original data if it is broken
+ size_t l_eccSize = (l_rc/9)*8;
+ l_eccSize = std::min( l_eccSize, i_size );
PNOR::ECC::eccStatus ecc_stat =
PNOR::ECC::removeECC(reinterpret_cast<uint8_t*>(l_dataToRead),
reinterpret_cast<uint8_t*>(o_data),
- l_rc); //actual size of read data
+ l_eccSize); //logical size of read data
// create an error if we couldn't correct things
if( ecc_stat == PNOR::ECC::UNCORRECTABLE )
diff --git a/src/usr/testcore/rtloader/loader.H b/src/usr/testcore/rtloader/loader.H
index 50c3b84d3..acc215912 100644
--- a/src/usr/testcore/rtloader/loader.H
+++ b/src/usr/testcore/rtloader/loader.H
@@ -369,10 +369,11 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
// read far enough in the section so it doesn't collide
// with other test cases
+ size_t l_bytes_to_read = i_sizeBytes;
if (l_id == PNOR::TEST)
{
//adjust the size of data if we are reading the entire sec
- i_sizeBytes = (i_offset == 0)? (((l_info.size -
+ l_bytes_to_read = (i_offset == 0)? (((l_info.size -
PNOR::pnorTestSec_rt_readwrite_offset)*9)/8) :
i_sizeBytes;
i_offset = ((PNOR::pnorTestSec_rt_readwrite_offset*9)/8);
@@ -382,9 +383,9 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
TRACFCOMP(g_trac_hbrt,"rt_pnor_read: calling"
" deviceRead: offset:0x%X, flashAddr:0x%X, size:0x%X",
- i_offset, l_flashAddr, i_sizeBytes);
+ i_offset, l_flashAddr, l_bytes_to_read);
- l_err = DeviceFW::deviceRead (pnor_target, o_data, i_sizeBytes,
+ l_err = DeviceFW::deviceRead (pnor_target, o_data, l_bytes_to_read,
DEVICE_PNOR_ADDRESS(i_proc, l_flashAddr));
if (l_err)
{
@@ -393,8 +394,10 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
}
} while (0);
- //commit the error
+ //by default tell the caller we read everything they asked for
int rc = i_sizeBytes;
+
+ //commit the error
if (l_err)
{
errlCommit(l_err,CXXTEST_COMP_ID);
OpenPOWER on IntegriCloud