diff options
author | Stephen Cprek <smcprek@us.ibm.com> | 2013-11-12 15:33:35 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-12-12 16:15:53 -0600 |
commit | 07c9716fcf31ce5352ce412a643071ea89bd2ca1 (patch) | |
tree | cab98e95ad2fa2a34bd122e21d5ba49c49675c56 /src/usr | |
parent | 1fe455d3400fd80d99176ad7f60a630ac7ce1b76 (diff) | |
download | blackbird-hostboot-07c9716fcf31ce5352ce412a643071ea89bd2ca1.tar.gz blackbird-hostboot-07c9716fcf31ce5352ce412a643071ea89bd2ca1.zip |
Handle Multiple TOCs and removed side code
Also added Hostboot Base image version header
Change-Id: I0fc878a48b9449e5d4875fd14525faefe01b1ace
RTC: 34764
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/7276
Tested-by: Jenkins Server
Reviewed-by: Brian H. Horton <brianh@linux.ibm.com>
Reviewed-by: ADAM R. MUHLE <armuhle@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')
-rw-r--r-- | src/usr/errl/errlmanager.C | 4 | ||||
-rw-r--r-- | src/usr/hwas/hwasPlatDeconfigGard.C | 3 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C | 4 | ||||
-rwxr-xr-x | src/usr/i2c/test/eepromddtest.H | 1 | ||||
-rw-r--r-- | src/usr/pnor/pnorrp.C | 448 | ||||
-rw-r--r-- | src/usr/pnor/pnorrp.H | 53 | ||||
-rw-r--r-- | src/usr/pnor/test/pnorddtest.H | 41 | ||||
-rw-r--r-- | src/usr/pnor/test/pnorrptest.H | 104 | ||||
-rw-r--r-- | src/usr/sbe/sbe_update.C | 1 | ||||
-rw-r--r-- | src/usr/targeting/attrrp.C | 1 | ||||
-rw-r--r-- | src/usr/testcore/rtloader/loader.H | 3 | ||||
-rw-r--r-- | src/usr/vfs/vfsrp.C | 3 | ||||
-rw-r--r-- | src/usr/vpd/ipvpd.C | 8 | ||||
-rw-r--r-- | src/usr/vpd/rtvpd_load.C | 1 | ||||
-rwxr-xr-x | src/usr/vpd/spd.C | 16 | ||||
-rw-r--r-- | src/usr/vpd/vpd.C | 3 | ||||
-rw-r--r-- | src/usr/vpd/vpd.H | 15 |
17 files changed, 419 insertions, 290 deletions
diff --git a/src/usr/errl/errlmanager.C b/src/usr/errl/errlmanager.C index 06d78c59c..7bb4e0631 100644 --- a/src/usr/errl/errlmanager.C +++ b/src/usr/errl/errlmanager.C @@ -838,9 +838,7 @@ void ErrlManager::setupPnorInfo() { // Get SPD PNOR section info from PNOR RP PNOR::SectionInfo_t info; - errlHndl_t err = PNOR::getSectionInfo( PNOR::HB_ERRLOGS, - PNOR::CURRENT_SIDE, - info ); + errlHndl_t err = PNOR::getSectionInfo( PNOR::HB_ERRLOGS, info ); if (err) { diff --git a/src/usr/hwas/hwasPlatDeconfigGard.C b/src/usr/hwas/hwasPlatDeconfigGard.C index 3f1a330a0..ce54620e1 100644 --- a/src/usr/hwas/hwasPlatDeconfigGard.C +++ b/src/usr/hwas/hwasPlatDeconfigGard.C @@ -368,8 +368,7 @@ errlHndl_t _GardRecordIdSetup( void *&io_platDeconfigGard) // get the PNOR address. PNOR::SectionInfo_t l_section; - l_pErr = PNOR::getSectionInfo(PNOR::GUARD_DATA, PNOR::CURRENT_SIDE, - l_section); + l_pErr = PNOR::getSectionInfo(PNOR::GUARD_DATA, l_section); if (l_pErr) { HWAS_ERR("PNOR::getSectionInfo failed!!!"); diff --git a/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C b/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C index 962d097c8..4b44419c2 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C +++ b/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C @@ -112,7 +112,7 @@ errlHndl_t loadPoreImage( char *& o_rporeAddr, do { // Get WINK PNOR section info from PNOR RP - l_errl = PNOR::getSectionInfo( PNOR::WINK,PNOR::CURRENT_SIDE, l_info ); + l_errl = PNOR::getSectionInfo( PNOR::WINK, l_info ); if( l_errl ) { break; @@ -488,7 +488,7 @@ void* call_host_build_winkle( void *io_pArgs ) // call the HWP with each fapi::Target FAPI_INVOKE_HWP( l_errl, - p8_slw_build_fixed, + p8_slw_build_fixed, l_fapi_cpu_target, //Proc chip target. reinterpret_cast<void*>(l_pPoreImage), l_pImageOut, diff --git a/src/usr/i2c/test/eepromddtest.H b/src/usr/i2c/test/eepromddtest.H index d8e0fef9f..4cd4fad37 100755 --- a/src/usr/i2c/test/eepromddtest.H +++ b/src/usr/i2c/test/eepromddtest.H @@ -270,7 +270,6 @@ class EEPROMTest: public CxxTest::TestSuite PNOR::SectionInfo_t pnorSectionInfo; err = PNOR::getSectionInfo(PNOR::HB_EXT_CODE, - PNOR::CURRENT_SIDE, pnorSectionInfo); if ( err || diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C index e4171e79f..1d52b2a39 100644 --- a/src/usr/pnor/pnorrp.C +++ b/src/usr/pnor/pnorrp.C @@ -38,6 +38,7 @@ #include "common/ffs_hb.H" //Hostboot definition of user data in ffs_entry struct. #include <pnor/ecc.H> #include <kernel/console.H> +#include <endian.h> // Trace definition trace_desc_t* g_trac_pnor = NULL; @@ -72,7 +73,6 @@ const char* cv_EYECATCHER[] = { // "XXX", /**< NUM_SECTIONS : Used as invalid entry */ }; - /** * @brief set up _start() task entry procedure for PNOR daemon */ @@ -87,12 +87,32 @@ TASK_ENTRY_MACRO( PnorRP::init ); * @brief Return the size and address of a given section of PNOR data */ errlHndl_t PNOR::getSectionInfo( PNOR::SectionId i_section, - PNOR::SideSelect i_side, PNOR::SectionInfo_t& o_info ) { - return Singleton<PnorRP>::instance().getSectionInfo(i_section,i_side,o_info); + return Singleton<PnorRP>::instance().getSectionInfo(i_section,o_info); } +namespace PNOR +{ + +/** + * @brief calculates the checksum on data(ffs header/entry) and will return + * 0 if the checksums match + */ +uint32_t pnor_ffs_checksum(void* data, size_t size) +{ + uint32_t checksum = 0; + + for (size_t i = 0; i < (size/4); i++) + { + checksum ^= ((uint32_t*)data)[i]; + } + + checksum = htobe32(checksum); + return checksum; +} + +}; /** * STATIC @@ -150,15 +170,11 @@ void* wait_for_message( void* unused ) * @brief Constructor */ PnorRP::PnorRP() -: iv_msgQ(NULL) +: iv_TOC_used(0) +,iv_msgQ(NULL) ,iv_startupRC(0) { TRACFCOMP(g_trac_pnor, "PnorRP::PnorRP> " ); - - //Default to PNOR Side A for now. - //TODO: Determine proper side (RTC: 34764) - iv_curSide = PNOR::SIDE_A; - // setup everything in a separate function initDaemon(); @@ -257,21 +273,14 @@ void PnorRP::initDaemon() * @brief Return the size and address of a given section of PNOR data */ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section, - PNOR::SideSelect i_side, PNOR::SectionInfo_t& o_info ) { - //TRACDCOMP(g_trac_pnor, "PnorRP::getSectionInfo> i_section=%d, i_side=%X", i_section, i_side ); + //TRACDCOMP(g_trac_pnor, "PnorRP::getSectionInfo> i_section=%d", i_section ); errlHndl_t l_errhdl = NULL; PNOR::SectionId id = i_section; - PNOR::SideSelect side = i_side; do { - if(side == PNOR::CURRENT_SIDE) - { - side = iv_curSide; - } - // Abort this operation if we had a startup failure uint64_t rc = 0; if( didStartupFail(rc) ) @@ -298,23 +307,23 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section, } // Zero-length means the section is invalid - if( 0 == iv_TOC[side][id].size ) + if( 0 == iv_TOC[id].size ) { - TRACFCOMP( g_trac_pnor, "PnorRP::getSectionInfo> Invalid Section Requested : i_section=%d, side=%d", i_section, side ); - TRACFCOMP(g_trac_pnor, "o_info={ id=%d, size=%d }", iv_TOC[side][i_section].id, iv_TOC[side][i_section].size ); + TRACFCOMP( g_trac_pnor, "PnorRP::getSectionInfo> Invalid Section Requested : i_section=%d", i_section ); + TRACFCOMP(g_trac_pnor, "o_info={ id=%d, size=%d }", iv_TOC[i_section].id, iv_TOC[i_section].size ); /*@ * @errortype * @moduleid PNOR::MOD_PNORRP_GETSECTIONINFO * @reasoncode PNOR::RC_INVALID_SECTION * @userdata1 Requested Section - * @userdata2 Requested Side + * @userdata2 TOC used * @devdesc PnorRP::getSectionInfo> Invalid Address for read/write */ l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_PNORRP_GETSECTIONINFO, PNOR::RC_INVALID_SECTION, TO_UINT64(i_section), - TO_UINT64(side)); + iv_TOC_used); l_errhdl->collectTrace(PNOR_COMP_NAME); // set the return section to our invalid data @@ -323,17 +332,17 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section, } } while(0); + if (PNOR::INVALID_SECTION != id) { - TRACDCOMP( g_trac_pnor, "PnorRP::getSectionInfo: i_section=%d, side=%d : id=%d", i_section, side, iv_TOC[side][i_section].id ); + TRACDCOMP( g_trac_pnor, "PnorRP::getSectionInfo: i_section=%d, id=%d", i_section, iv_TOC[i_section].id ); // copy my data into the external format - o_info.id = iv_TOC[side][id].id; - o_info.side = iv_TOC[side][id].side; + o_info.id = iv_TOC[id].id; o_info.name = cv_EYECATCHER[id]; - o_info.vaddr = iv_TOC[side][id].virtAddr; - o_info.size = iv_TOC[side][id].size; - o_info.eccProtected = (bool)(iv_TOC[side][id].integrity & + o_info.vaddr = iv_TOC[id].virtAddr; + o_info.size = iv_TOC[id].size; + o_info.eccProtected = (bool)(iv_TOC[id].integrity & FFS_INTEG_ECC_PROTECT); } @@ -349,183 +358,250 @@ errlHndl_t PnorRP::readTOC() TRACUCOMP(g_trac_pnor, "PnorRP::readTOC>" ); errlHndl_t l_errhdl = NULL; uint8_t* tocBuffer = NULL; -#define SIDELESS_VADDR_INDEX 2 - uint64_t nextVAddr[] = {SIDEA_VADDR, SIDEB_VADDR, SIDELESS_VADDR}; bool fatal_error = false; + bool TOC_0_failed = false; do{ - // Zero out my table - for( uint64_t side = 0; side < NUM_SIDES; side++ ) + iv_TOC_used = 0; + + for (uint32_t cur_TOC = 0; cur_TOC < NUM_TOCS; ++cur_TOC) { + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC verifying TOC: %d",cur_TOC); + uint64_t nextVAddr = BASE_VADDR; + + // Zero out my table for( size_t id = PNOR::FIRST_SECTION; id <= PNOR::NUM_SECTIONS; //include extra entry for error paths ++id ) { - iv_TOC[side][id].id = (PNOR::SectionId)id; - iv_TOC[side][id].side = (PNOR::SideSelect)side; + iv_TOC[id].id = (PNOR::SectionId)id; //everything else should default to zero } - } - - // Read TOC information - // assume 1 chip with only 1 side for now, no sideless - const uint32_t cur_side = PNOR::SIDE_A; - // TOC starts at offset zero - - tocBuffer = new uint8_t[PAGESIZE]; - l_errhdl = readFromDevice( FFS_TABLE_BASE_ADDR, 0, false, - tocBuffer, fatal_error ); - if( l_errhdl ) { break; } + // Read TOC information from TOC 0 and then TOC 1 + tocBuffer = new uint8_t[PAGESIZE]; + if (cur_TOC == 0) + { + l_errhdl = readFromDevice( TOC_0_OFFSET, 0, false, + tocBuffer, fatal_error ); + } + else if (cur_TOC == 1) + { + l_errhdl = readFromDevice( TOC_1_OFFSET, 0, false, + tocBuffer, fatal_error ); + } - ffs_hdr* l_ffs_hdr = (ffs_hdr*) tocBuffer; + if( l_errhdl ) + { + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC readFromDevice Failed."); + break; + } - //TODO: verify checksum of header RTC: 44147 + ffs_hdr* l_ffs_hdr = (ffs_hdr*) tocBuffer; - TRACFCOMP(g_trac_pnor, "PnorRp::readTOC: FFS Block size = 0x%.8X, Partition Table Size = 0x%.8x, entry_count=%d", - l_ffs_hdr->block_size, l_ffs_hdr->size, l_ffs_hdr->entry_count); + // ffs entry check, 0 if checksums match + if( PNOR::pnor_ffs_checksum(l_ffs_hdr, FFS_HDR_SIZE) != 0) + { + //@TODO - RTC:90780 - May need to handle this differently in SP-less config + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC pnor_ffs_checksum header checksums do not match."); + if (cur_TOC == 0) + { + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC TOC 0 failed header checksum"); + TOC_0_failed = true; + iv_TOC_used = 1; + continue; + } + else if (cur_TOC == 1 && TOC_0_failed) + { + // Both TOC's failed + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC both TOC's are corrupted"); + INITSERVICE::doShutdown( PNOR::RC_PARTITION_TABLE_INVALID); + } + else + { + // TOC 1 failed + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC TOC 1 failed header checksum"); + break; + } + } - uint64_t spaceUsed = (sizeof(ffs_entry))*l_ffs_hdr->entry_count; + // Only check header if on first TOC or the first TOC failed + if (cur_TOC == 0 || TOC_0_failed) + { + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC: FFS Block size = 0x%.8X, Partition Table Size = 0x%.8x, entry_count=%d", + l_ffs_hdr->block_size, l_ffs_hdr->size, l_ffs_hdr->entry_count); - /* Checking FFS Header to make sure it looks valid */ - bool header_good = true; - if(l_ffs_hdr->magic != FFS_MAGIC) - { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Invalid magic number in FFS header: 0x%.4X", - l_ffs_hdr->magic); - header_good = false; - } - else if(l_ffs_hdr->version != SUPPORTED_FFS_VERSION) - { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unsupported FFS Header version: 0x%.4X", - l_ffs_hdr->version); - header_good = false; - } - else if(l_ffs_hdr->entry_size != sizeof(ffs_entry)) - { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unexpected entry_size(0x%.8x) in FFS header: 0x%.4X", l_ffs_hdr->entry_size); - header_good = false; - } - else if(l_ffs_hdr->entries == NULL) - { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: FFS Header pointer to entries is NULL."); - header_good = false; - } - else if(l_ffs_hdr->block_size != PAGESIZE) - { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unsupported Block Size(0x%.4X). PNOR Blocks must be 4k", - l_ffs_hdr->block_size); - header_good = false; - } - else if(l_ffs_hdr->block_count == 0) - { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unsupported BLock COunt(0x%.4X). Device cannot be zero blocks in length.", - l_ffs_hdr->block_count); - header_good = false; - } - //Make sure all the entries fit in specified partition table size. - else if(spaceUsed > - ((l_ffs_hdr->block_size * l_ffs_hdr->size) - sizeof(ffs_hdr))) - { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: FFS Entries (0x%.16X) go past end of FFS Table.", - spaceUsed); - crit_assert(0); - } + uint64_t spaceUsed = (sizeof(ffs_entry))*l_ffs_hdr->entry_count; - if(!header_good) - { - //Shutdown if we detected a partition table issue for any reason - INITSERVICE::doShutdown( PNOR::RC_PARTITION_TABLE_INVALID); - } + /* Checking FFS Header to make sure it looks valid */ + bool header_good = true; + if(l_ffs_hdr->magic != FFS_MAGIC) + { + TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Invalid magic number in FFS header: 0x%.4X", + l_ffs_hdr->magic); + header_good = false; + } + else if(l_ffs_hdr->version != SUPPORTED_FFS_VERSION) + { + TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Unsupported FFS Header version: 0x%.4X", + l_ffs_hdr->version); + header_good = false; + } + else if(l_ffs_hdr->entry_size != sizeof(ffs_entry)) + { + TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Unexpected entry_size(0x%.8x) in FFS header: 0x%.4X", l_ffs_hdr->entry_size); + header_good = false; + } + else if(l_ffs_hdr->entries == NULL) + { + TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: FFS Header pointer to entries is NULL."); + header_good = false; + } + else if(l_ffs_hdr->block_size != PAGESIZE) + { + TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Unsupported Block Size(0x%.4X). PNOR Blocks must be 4k", + l_ffs_hdr->block_size); + header_good = false; + } + else if(l_ffs_hdr->block_count == 0) + { + TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Unsupported BLock COunt(0x%.4X). Device cannot be zero blocks in length.", + l_ffs_hdr->block_count); + header_good = false; + } + //Make sure all the entries fit in specified partition table size. + else if(spaceUsed > + ((l_ffs_hdr->block_size * l_ffs_hdr->size) - sizeof(ffs_hdr))) + { + TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: FFS Entries (0x%.16X) go past end of FFS Table.", + spaceUsed); + header_good = false; + } - ffs_hb_user_t* ffsUserData = NULL; + if(!header_good) + { + //Shutdown if we detected a partition table issue for any reason + if (TOC_0_failed) + { + INITSERVICE::doShutdown( PNOR::RC_PARTITION_TABLE_INVALID); + } + //Try TOC1 + continue; + } + } - //Walk through all the entries in the table and parse the data. - ffs_entry* cur_entry = (l_ffs_hdr->entries); + ffs_hb_user_t* ffsUserData = NULL; - for(uint32_t i=0; i<l_ffs_hdr->entry_count; i++) - { - TRACUCOMP(g_trac_pnor, "PnorRp::readTOC: Entry %d, name=%s, pointer=0x%X", i, cur_entry->name, (uint64_t)cur_entry); + //Walk through all the entries in the table and parse the data. + ffs_entry* cur_entry = (l_ffs_hdr->entries); - //TODO: verify checksum of entry RTC: 44147 + for(uint32_t i=0; i<l_ffs_hdr->entry_count; i++) + { + TRACUCOMP(g_trac_pnor, "PnorRP::readTOC: Entry %d, name=%s, pointer=0x%X", i, cur_entry->name, (uint64_t)cur_entry); - uint32_t secId = PNOR::INVALID_SECTION; + uint32_t secId = PNOR::INVALID_SECTION; - //Figure out section enum - for(uint32_t eyeIndex=PNOR::TOC; eyeIndex < PNOR::NUM_SECTIONS; eyeIndex++) - { - if(strcmp(cv_EYECATCHER[eyeIndex], cur_entry->name) == 0) + // ffs entry check, 0 if checksums match + if( PNOR::pnor_ffs_checksum(cur_entry, FFS_ENTRY_SIZE) != 0) { - secId = eyeIndex; - TRACUCOMP(g_trac_pnor, "PnorRp::readTOC: sectionId=%d", secId); - break; + //@TODO - RTC:90780 - May need to handle this differently in SP-less config + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC pnor_ffs_checksum entry checksums do not match."); + if (cur_TOC == 0) + { + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC TOC 0 entry checksum failed"); + TOC_0_failed = true; + iv_TOC_used = 1; + break; + } + else if (cur_TOC == 1 && TOC_0_failed) + { + // Both TOC's failed + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC both TOC's are corrupted"); + INITSERVICE::doShutdown( PNOR::RC_PARTITION_TABLE_INVALID); + } + else + { + // TOC 1 failed + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC TOC 1 entry checksum failed"); + break; + } } - } - if(secId == PNOR::INVALID_SECTION) - { - TRACFCOMP(g_trac_pnor, "PnorRp::readTOC: Unrecognized Section name(%s), skipping", cur_entry->name); - continue; - } + // Only set data if on first TOC or the first TOC failed + if (cur_TOC == 0 || TOC_0_failed) + { + //Figure out section enum + for(uint32_t eyeIndex=PNOR::TOC; eyeIndex < PNOR::NUM_SECTIONS; eyeIndex++) + { + if(strcmp(cv_EYECATCHER[eyeIndex], cur_entry->name) == 0) + { + secId = eyeIndex; + TRACUCOMP(g_trac_pnor, "PnorRP::readTOC: sectionId=%d", secId); + break; + } + } - ffsUserData = (ffs_hb_user_t*)&(cur_entry->user); + if(secId == PNOR::INVALID_SECTION) + { + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC: Unrecognized Section name(%s), skipping", cur_entry->name); + continue; + } - //size - iv_TOC[cur_side][secId].size = ((uint64_t)cur_entry->size)*PAGESIZE; + ffsUserData = (ffs_hb_user_t*)&(cur_entry->user); + //size + iv_TOC[secId].size = ((uint64_t)cur_entry->size)*PAGESIZE; - //virtAddr - //The PNOR data is broken up into 3 blocks of Virtual Addresses, A, B, and Sideless. - //For Sections found to be sideless, both PNOR sides will map to the same virtual address. - //TODO RTC: 34764, remove VADDR ranges for SIDE B & SIDELESS - iv_TOC[cur_side][secId].virtAddr = nextVAddr[cur_side]; - nextVAddr[cur_side] += iv_TOC[cur_side][secId].size; + //virtAddr + iv_TOC[secId].virtAddr = nextVAddr; + nextVAddr += iv_TOC[secId].size; - //flashAddr - iv_TOC[cur_side][secId].flashAddr = ((uint64_t)cur_entry->base)*PAGESIZE; + //flashAddr + iv_TOC[secId].flashAddr = ((uint64_t)cur_entry->base)*PAGESIZE; - //chipSelect - iv_TOC[cur_side][secId].chip = ffsUserData->chip; + //chipSelect + iv_TOC[secId].chip = ffsUserData->chip; - //user data - iv_TOC[cur_side][secId].integrity = ffsUserData->dataInteg; - iv_TOC[cur_side][secId].version = ffsUserData->verCheck; - iv_TOC[cur_side][secId].misc = ffsUserData->miscFlags; + //user data + iv_TOC[secId].integrity = ffsUserData->dataInteg; + iv_TOC[secId].version = ffsUserData->verCheck; + iv_TOC[secId].misc = ffsUserData->miscFlags; - TRACFCOMP(g_trac_pnor, "PnorRp::readTOC: User Data %s", cur_entry->name); - TRACFBIN(g_trac_pnor, "PnorRp::readTOC: Bin Dump",ffsUserData, sizeof(ffs_hb_user_t) ); + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC: User Data %s", cur_entry->name); + //TRACFBIN(g_trac_pnor, "PnorRP::readTOC: Bin Dump",ffsUserData, sizeof(ffs_hb_user_t) ); - if (iv_TOC[cur_side][secId].version == FFS_VERS_SHA512) - { - TRACFCOMP(g_trac_pnor, "PnorRp::readTOC: Incrementing Flash Address for SHA Header"); - if (iv_TOC[cur_side][secId].integrity == FFS_INTEG_ECC_PROTECT) - { - iv_TOC[cur_side][secId].flashAddr += (PAGESIZE*9)/8; - } - else - { - iv_TOC[cur_side][secId].flashAddr += PAGESIZE; + if (iv_TOC[secId].version == FFS_VERS_SHA512) + { + TRACFCOMP(g_trac_pnor, "PnorRP::readTOC: Incrementing Flash Address for SHA Header"); + if (iv_TOC[secId].integrity == FFS_INTEG_ECC_PROTECT) + { + iv_TOC[secId].flashAddr += PAGESIZE_PLUS_ECC; + } + else + { + iv_TOC[secId].flashAddr += PAGESIZE; + } + } + + if((iv_TOC[secId].flashAddr + iv_TOC[secId].size) > (l_ffs_hdr->block_count*PAGESIZE)) + { + TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Partition(%s) at base address (0x%.8x) extends past end of flash device", + cur_entry->name, iv_TOC[secId].flashAddr); + INITSERVICE::doShutdown( PNOR::RC_PARTITION_TABLE_INVALID); + } } + + cur_entry++; } - if((iv_TOC[cur_side][secId].flashAddr + iv_TOC[cur_side][secId].size) > (l_ffs_hdr->block_count*PAGESIZE)) + //keep these traces here until PNOR is rock-solid + for(PNOR::SectionId tmpId = PNOR::FIRST_SECTION; + tmpId < PNOR::NUM_SECTIONS; + tmpId = (PNOR::SectionId) (tmpId + 1) ) { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Partition(%s) at base address (0x%.8x) extends past end of flash device", - cur_entry->name, iv_TOC[cur_side][secId].flashAddr); - INITSERVICE::doShutdown( PNOR::RC_PARTITION_TABLE_INVALID); + TRACFCOMP(g_trac_pnor, "%s: size=0x%.8X flash=0x%.8X virt=0x%.16X", cv_EYECATCHER[tmpId], iv_TOC[tmpId].size, iv_TOC[tmpId].flashAddr, iv_TOC[tmpId].virtAddr ); } - - cur_entry++; } - - //keep these traces here until PNOR is rock-solid - for(PNOR::SectionId tmpId = PNOR::FIRST_SECTION; - tmpId < PNOR::NUM_SECTIONS; - tmpId = (PNOR::SectionId) (tmpId + 1) ) - { - TRACFCOMP(g_trac_pnor, "%s: size=0x%.8X flash=0x%.8X virt=0x%.16X", cv_EYECATCHER[tmpId], iv_TOC[PNOR::SIDE_A][tmpId].size, iv_TOC[PNOR::SIDE_A][tmpId].flashAddr, iv_TOC[PNOR::SIDE_A][tmpId].virtAddr ); - } - }while(0); if(tocBuffer != NULL) @@ -538,8 +614,6 @@ errlHndl_t PnorRP::readTOC() return l_errhdl; } - - /** * @brief Message receiver */ @@ -699,6 +773,7 @@ errlHndl_t PnorRP::readFromDevice( uint64_t i_offset, data_to_read, read_size, DEVICE_PNOR_ADDRESS(i_chip,i_offset) ); + if( l_errhdl ) { TRACFCOMP(g_trac_pnor, "PnorRP::readFromDevice> Error from device : RC=%X", l_errhdl->reasonCode() ); @@ -855,18 +930,17 @@ errlHndl_t PnorRP::computeDeviceAddr( void* i_vaddr, } // find the matching section - PNOR::SideSelect side = PNOR::SIDE_A; PNOR::SectionId id = PNOR::INVALID_SECTION; - l_errhdl = computeSection( l_vaddr, side, id ); + l_errhdl = computeSection( l_vaddr, id ); if( l_errhdl ) { return l_errhdl; } // pull out the information we need to return from our global copy - o_chip = iv_TOC[side][id].chip; - o_ecc = (bool)(iv_TOC[side][id].integrity & FFS_INTEG_ECC_PROTECT); - o_offset = l_vaddr - iv_TOC[side][id].virtAddr; //offset into section + o_chip = iv_TOC[id].chip; + o_ecc = (bool)(iv_TOC[id].integrity & FFS_INTEG_ECC_PROTECT); + o_offset = l_vaddr - iv_TOC[id].virtAddr; //offset into section // for ECC we need to figure out where the ECC-enhanced offset is // before tacking on the offset to the section @@ -875,7 +949,7 @@ errlHndl_t PnorRP::computeDeviceAddr( void* i_vaddr, o_offset = (o_offset * 9) / 8; } // add on the offset of the section itself - o_offset += iv_TOC[side][id].flashAddr; + o_offset += iv_TOC[id].flashAddr; TRACUCOMP( g_trac_pnor, "< PnorRP::computeDeviceAddr: i_vaddr=%X, o_offset=0x%X, o_chip=%d", l_vaddr, o_offset, o_chip ); return l_errhdl; @@ -893,7 +967,6 @@ PnorRP& PnorRP::getInstance() * @brief Figure out which section a VA belongs to */ errlHndl_t PnorRP::computeSection( uint64_t i_vaddr, - PNOR::SideSelect& o_side, PNOR::SectionId& o_id ) { errlHndl_t errhdl = NULL; @@ -901,37 +974,15 @@ errlHndl_t PnorRP::computeSection( uint64_t i_vaddr, o_id = PNOR::INVALID_SECTION; do { - // first figure out which side it is on (slight performance boost) - if( (i_vaddr >= SIDEA_VADDR) - && (i_vaddr < (SIDEA_VADDR + SIDE_SIZE)) ) - { - o_side = PNOR::SIDE_A; - } - else if( (i_vaddr >= SIDEB_VADDR) - && (i_vaddr < (SIDEB_VADDR + SIDE_SIZE)) ) - { - o_side = PNOR::SIDE_B; - } - else if( (i_vaddr >= SIDELESS_VADDR) - && (i_vaddr < (SIDELESS_VADDR + SIDE_SIZE)) ) - { - o_side = iv_curSide; - } - else - { - //break to send down error path - break; - } - // loop through all sections to find a matching id for( PNOR::SectionId id = PNOR::FIRST_SECTION; id < PNOR::NUM_SECTIONS; id = (PNOR::SectionId) (id + 1) ) { - if( (i_vaddr >= iv_TOC[o_side][id].virtAddr) - && (i_vaddr < (iv_TOC[o_side][id].virtAddr + iv_TOC[o_side][id].size)) ) + if( (i_vaddr >= iv_TOC[id].virtAddr) + && (i_vaddr < (iv_TOC[id].virtAddr + iv_TOC[id].size)) ) { - o_id = iv_TOC[o_side][id].id; + o_id = iv_TOC[id].id; break; } } @@ -958,7 +1009,6 @@ errlHndl_t PnorRP::computeSection( uint64_t i_vaddr, return errhdl; } - return errhdl; } diff --git a/src/usr/pnor/pnorrp.H b/src/usr/pnor/pnorrp.H index 8c2fb2abc..a1e463973 100644 --- a/src/usr/pnor/pnorrp.H +++ b/src/usr/pnor/pnorrp.H @@ -41,22 +41,34 @@ class PnorRP * @brief Static Initializer * @param[in] ref to errlHndl_t */ - static void init( errlHndl_t &io_rtaskRetErrl ); + static void init( errlHndl_t &io_rtaskRetErrl ); /** * @brief Return the size and address of a given section of PNOR data * Called by external PNOR::getSectionInfo() * * @param[in] i_section PNOR section - * @param[in] i_side Side select * @param[out] o_info Location and size information * * @return errlHndl_t Error log if request was invalid */ errlHndl_t getSectionInfo( PNOR::SectionId i_section, - PNOR::SideSelect i_side, PNOR::SectionInfo_t& o_info ); + /** + * @brief Creates a 4-byte Cyclic Redundancy Check (CRC) on the data + * provided. The last iteration of the for-loop includes the ffs + * checksum itself. Therefore if the 4-byte CRC created matches + * the ffs checksum, the resulting CRC will be 0 + * + * @param[in] ptr Pointer to the data + * + * @param[in] size Size of the data + * + * @return uint32_t return 4-byte CRC, 0 if checksums match + */ + uint32_t pnor_ffs_checksum(void* data, size_t size); + protected: /** * @brief Constructor @@ -70,24 +82,18 @@ class PnorRP private: - /** * PNOR Constants */ + static const uint32_t NUM_TOCS = 2; + static const uint64_t TOC_0_OFFSET = 0; + static const uint64_t TOC_1_OFFSET = 0x8000; + enum { BASE_VADDR = VMM_VADDR_PNOR_RP, /**< 2GB = 0x80000000*/ + TOTAL_SIZE = 64*MEGABYTE, /**< Allocate 64 MB (0x4000000)*/ - NUM_SIDES = 2, /**< A, B */ - - SIDE_SIZE = 32*MEGABYTE, /**< Allocate 32 MB (0x2000000) of VA per side */ - - NUM_VADDR_BLOCKS = NUM_SIDES+1, /**< Number of VADDR blocks. */ - SIDEA_VADDR = BASE_VADDR, /**< Base address of Side A */ - SIDEB_VADDR = SIDEA_VADDR + SIDE_SIZE, /**< Base address of Side B */ - SIDELESS_VADDR = SIDEB_VADDR + SIDE_SIZE, /**< Sideless data Base Addr */ - - TOTAL_SIZE = SIDE_SIZE*NUM_VADDR_BLOCKS, /**< Size of PNOR VA region */ LAST_VADDR = BASE_VADDR + TOTAL_SIZE, /**< End of our VA range */ /** Real number of bytes required to read 1 logical page */ @@ -98,11 +104,15 @@ class PnorRP }; /** + * Which TOC (0 or 1) is used after verifying both. + */ + uint32_t iv_TOC_used; + + /** * Internal information to deal with the sections of PNOR */ struct SectionData_t { PNOR::SectionId id; /**< Identifier for this section */ - PNOR::SideSelect side; /** Side Select */ uint64_t virtAddr; /**< Virtual address for the start of the section */ uint32_t flashAddr; /**< Address in flash */ uint32_t size; /**< Actual size of content in bytes (not including ECC) */ @@ -123,12 +133,7 @@ class PnorRP /** * Cached copy of section data */ - SectionData_t iv_TOC[NUM_SIDES][PNOR::NUM_SECTIONS+1]; - - /** - * Currently selected PNOR Side - */ - PNOR::SideSelect iv_curSide; + SectionData_t iv_TOC[PNOR::NUM_SECTIONS+1]; /** * Pointer to the message queue where we receive messages @@ -154,7 +159,8 @@ class PnorRP void initDaemon(); /** - * @brief Read the TOC and store section information + * @brief Verify both TOC's and store section information from one of the + * verified TOC's * * @return Error from device */ @@ -217,13 +223,11 @@ class PnorRP * @brief Figure out which section a VA belongs to * * @param[in] i_vaddr Virtual address of page - * @param[out] o_side Which side of the flash * @param[out] o_id Which section of PNOR * * @return Error if VA is bad */ errlHndl_t computeSection( uint64_t i_vaddr, - PNOR::SideSelect& o_side, PNOR::SectionId& o_id ); /** @@ -254,6 +258,7 @@ class PnorRP * @brief Static instance function for testcase only */ static PnorRP& getInstance(); + }; diff --git a/src/usr/pnor/test/pnorddtest.H b/src/usr/pnor/test/pnorddtest.H index eccb24dd4..546240cb9 100644 --- a/src/usr/pnor/test/pnorddtest.H +++ b/src/usr/pnor/test/pnorddtest.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ /* */ /* p1 */ /* */ @@ -67,7 +67,6 @@ class PnorDdTest : public CxxTest::TestSuite // Get SPD PNOR section info from PNOR RP l_err = PNOR::getSectionInfo( PNOR::TEST, - PNOR::CURRENT_SIDE, info ); if(l_err) { @@ -111,7 +110,7 @@ class PnorDdTest : public CxxTest::TestSuite { TARGETING::Target* l_testTarget = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; - size_t l_size = sizeof(uint64_t); + size_t l_size = sizeof(uint64_t); errlHndl_t l_err = NULL; uint64_t fails = 0; uint64_t total = 0; @@ -146,7 +145,7 @@ class PnorDdTest : public CxxTest::TestSuite total++; if(l_size != sizeof(uint64_t)) { - TS_FAIL("PnorDdTest::test_readwrite: PNORDD write 1: Write length not expected value. Addr: 0x%llx, Exp: %d, Act: %d", l_address, + TS_FAIL("PnorDdTest::test_readwrite: PNORDD write 1: Write length not expected value. Addr: 0x%llx, Exp: %d, Act: %d", l_address, sizeof(uint64_t), l_size); fails++; } @@ -169,7 +168,7 @@ class PnorDdTest : public CxxTest::TestSuite total++; if(l_size != sizeof(uint64_t)) { - TS_FAIL("PnorDdTest::test_readwrite: PNORDD write 2: Write length not expected value. Addr: 0x%llx, Exp: %d, Act: %d", l_address, + TS_FAIL("PnorDdTest::test_readwrite: PNORDD write 2: Write length not expected value. Addr: 0x%llx, Exp: %d, Act: %d", l_address, sizeof(uint64_t), l_size); fails++; } @@ -199,7 +198,7 @@ class PnorDdTest : public CxxTest::TestSuite total++; if(l_size != sizeof(uint64_t)) { - TS_FAIL("PnorDdTest::test_readwrite: PNORDD read 1: Read length not expected value. Addr: 0x%llx, Exp: %d, Act: %d", l_address, + TS_FAIL("PnorDdTest::test_readwrite: PNORDD read 1: Read length not expected value. Addr: 0x%llx, Exp: %d, Act: %d", l_address, sizeof(uint64_t), l_size); fails++; } @@ -228,7 +227,7 @@ class PnorDdTest : public CxxTest::TestSuite total++; if(l_size != sizeof(uint64_t)) { - TS_FAIL("PnorDdTest::test_readwrite: PNORDD read 2: Read length not expected value. Addr: 0x%llx, Exp: %d, Act: %d", l_address, + TS_FAIL("PnorDdTest::test_readwrite: PNORDD read 2: Read length not expected value. Addr: 0x%llx, Exp: %d, Act: %d", l_address, sizeof(uint64_t), l_size); fails++; } @@ -247,7 +246,7 @@ class PnorDdTest : public CxxTest::TestSuite { TARGETING::Target* l_testTarget = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; - size_t l_size = sizeof(uint64_t); + size_t l_size = sizeof(uint64_t); errlHndl_t l_err = NULL; uint64_t fails = 0; uint64_t total = 0; @@ -382,7 +381,7 @@ class PnorDdTest : public CxxTest::TestSuite { TARGETING::Target* l_testTarget = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; - size_t l_size = sizeof(uint64_t); + size_t l_size = sizeof(uint64_t); errlHndl_t l_err = NULL; uint64_t fails = 0; uint64_t total = 0; @@ -398,7 +397,7 @@ class PnorDdTest : public CxxTest::TestSuite break; } - // Find the nearest erase-block (4K) boundary + // Find the nearest erase-block (4K) boundary uint64_t l_boundary = (base_address+4096) - (base_address%4096); uint64_t l_address = 0; @@ -454,7 +453,7 @@ class PnorDdTest : public CxxTest::TestSuite { PnorDD* pnordd = NULL; uint8_t* fake_space = NULL; - size_t l_size = sizeof(uint64_t); + size_t l_size = sizeof(uint64_t); errlHndl_t l_err = NULL; uint64_t fails = 0; uint64_t total = 0; @@ -481,7 +480,7 @@ class PnorDdTest : public CxxTest::TestSuite = supported_modes.begin(); m != supported_modes.end(); ++m ) - { + { if( pnordd ) { delete pnordd; @@ -500,7 +499,7 @@ class PnorDdTest : public CxxTest::TestSuite pnordd = new PnorDD(*m, reinterpret_cast<uint64_t>(fake_space), (4 * KILOBYTE)); - //Adjusting the address by an arbitrary multiplier to keep + //Adjusting the address by an arbitrary multiplier to keep //successive tests from always using the same memory space. scratch_space = (*m)*0x20; } @@ -515,7 +514,7 @@ class PnorDdTest : public CxxTest::TestSuite "PnorDdTest::test_readwrite_modes> Skipped due to not finding test section in PNOR" ); continue; } - //Adjusting the address by an arbitrary multiplier to keep + //Adjusting the address by an arbitrary multiplier to keep //successive tests from always using the same memory space. scratch_space += (*m)*0x20; } @@ -650,7 +649,7 @@ class PnorDdTest : public CxxTest::TestSuite { PnorDD* pnordd = NULL; uint8_t* fake_space = NULL; - size_t l_size = sizeof(uint64_t); + size_t l_size = sizeof(uint64_t); errlHndl_t l_err = NULL; uint64_t fails = 0; uint64_t total = 0; @@ -696,8 +695,8 @@ class PnorDdTest : public CxxTest::TestSuite pnordd = new PnorDD(*m, reinterpret_cast<uint64_t>(fake_space), (4 * KILOBYTE)); - - //Adjusting the address by an arbitrary multiplier to keep + + //Adjusting the address by an arbitrary multiplier to keep //successive tests from always using the same memory space. scratch_space = (*m)*0x30; @@ -713,7 +712,7 @@ class PnorDdTest : public CxxTest::TestSuite "PnorDdTest::test_readwrite_modes> Skipped due to not finding test section in PNOR" ); continue; } - //Adjusting the address by an arbitrary multiplier to keep + //Adjusting the address by an arbitrary multiplier to keep //successive tests from always using the same memory space. scratch_space += (*m)*0x30; } @@ -841,7 +840,7 @@ class PnorDdTest : public CxxTest::TestSuite { PnorDD* pnordd = NULL; uint8_t* fake_space = NULL; - size_t l_size = sizeof(uint64_t); + size_t l_size = sizeof(uint64_t); errlHndl_t l_err = NULL; uint64_t fails = 0; uint64_t total = 0; @@ -904,7 +903,7 @@ class PnorDdTest : public CxxTest::TestSuite } } - // Find the nearest erase-block (4K) boundary + // Find the nearest erase-block (4K) boundary uint64_t l_boundary = (scratch_space+4096) - (scratch_space%4096); uint64_t l_address = 0; @@ -981,7 +980,7 @@ Leaving it commented out because the test-case will not dynamically find the ext { TARGETING::Target* l_testTarget = MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; - size_t l_size = sizeof(uint64_t); + size_t l_size = sizeof(uint64_t); errlHndl_t l_err = NULL; do{ diff --git a/src/usr/pnor/test/pnorrptest.H b/src/usr/pnor/test/pnorrptest.H index 71766fea0..d96379a8c 100644 --- a/src/usr/pnor/test/pnorrptest.H +++ b/src/usr/pnor/test/pnorrptest.H @@ -40,6 +40,7 @@ #include <devicefw/userif.H> #include <pnor/ecc.H> #include "../pnorrp.H" +#include "../ffs.h" extern trace_desc_t* g_trac_pnor; @@ -75,7 +76,7 @@ class PnorRpTest : public CxxTest::TestSuite for( uint64_t idx = 0; idx < numSections; idx++) { total++; - errhdl = PNOR::getSectionInfo( testSections[idx], PNOR::CURRENT_SIDE, info ); + errhdl = PNOR::getSectionInfo( testSections[idx], info ); if( errhdl ) { TRACFCOMP(g_trac_pnor, "PnorRpTest::test_sectionInfo> ERROR : getSectionInfo returned error for %d : RC=%X", @@ -131,7 +132,7 @@ class PnorRpTest : public CxxTest::TestSuite // use the TEST partition as scratch space PNOR::SectionInfo_t info; - errhdl = PNOR::getSectionInfo( PNOR::TEST, PNOR::SIDE_A, info ); + errhdl = PNOR::getSectionInfo( PNOR::TEST, info ); if( errhdl ) { TRACFCOMP( g_trac_pnor, "PnorRpTest::test_ECC> ERROR : getSectionInfo returned error for PNOR::TEST : RC=%X", errhdl->reasonCode() ); @@ -247,10 +248,9 @@ class PnorRpTest : public CxxTest::TestSuite fails++; } } - //Enable this to test the UE handling, not turning on by default // because it causes a shutdown -#if 0 +#if 0 TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ECC: Attempting UE" ); // flush the page to make sure it gets out to the device totals++; @@ -290,7 +290,6 @@ class PnorRpTest : public CxxTest::TestSuite TS_FAIL("PnorRpTest::test_ECC: UE did not kill the task!."); #endif - TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ECC> %d/%d fails", fails, total ); }; @@ -316,7 +315,7 @@ class PnorRpTest : public CxxTest::TestSuite // use the TEST partition as scratch space PNOR::SectionInfo_t info; - PNOR::getSectionInfo( PNOR::TEST, PNOR::SIDE_A, info ); + PNOR::getSectionInfo( PNOR::TEST, info ); msg_t* msg = msg_allocate(); @@ -496,8 +495,99 @@ class PnorRpTest : public CxxTest::TestSuite TRACFCOMP(g_trac_pnor, "PnorRpTest::test_AddrReadWrite> %d/%d fails", fails, total ); }; - //@todo - import config data from build and compare to section info + /** + * @brief PNOR RP test - TOC + * Verify TOC checksum errors for both TOC's fail silently and + * pick up data from the other TOC. Test corrupts both header and + * first entry because they are checked separately in pnorrp.C + * + */ + void test_TOC(void) + { + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_TOC Start" ); + + bool fatal_error = false; + uint64_t offset = 0; + uint8_t* tocHeader = new uint8_t[PAGESIZE]; + uint8_t* tocEntry = new uint8_t[PAGESIZE]; + uint8_t* corruptBuffer = new uint8_t[PAGESIZE]; + + // Corrupt both ffs header and first entry for each TOC + for (uint32_t cur_TOC = 0; cur_TOC < PnorRP::NUM_TOCS; ++cur_TOC) + { + uint32_t TOC_used = cur_TOC; + + if (cur_TOC == 0) + { + offset = PnorRP::TOC_0_OFFSET; + } + else + { + offset = PnorRP::TOC_1_OFFSET; + } + + // Read cur_TOC header data + PnorRP::getInstance().readFromDevice( offset, 0, false, tocHeader, + fatal_error ); + + // Corrupt cur_TOC header data + memcpy(corruptBuffer, tocHeader, PAGESIZE); + corruptBuffer[0] = 0xFF; + corruptBuffer[1] = 0xFF; + PnorRP::getInstance().writeToDevice( offset, 0, false, + corruptBuffer ); + // Check if cur_TOC failed that other TOC is used + PnorRP::getInstance().readTOC(); + TOC_used = PnorRP::getInstance().iv_TOC_used; + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_TOC : TOC %d Corrupt Header Toc_used = %d", cur_TOC, TOC_used); + + if (TOC_used == cur_TOC) + { + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_TOC> ERROR : TOC %d is corrupted, did not use other TOC", cur_TOC); + TS_FAIL("PnorRpTest::test_TOC> ERROR : TOC %d is corrupted, did not use other TOC"); + } + + // Fix cur_TOC header + PnorRP::getInstance().writeToDevice( offset, 0, false, tocHeader ); + + // Read cur_TOC first entry data + PnorRP::getInstance().readFromDevice( offset + FFS_HDR_SIZE, 0, + false, tocEntry, + fatal_error ); + + // Corrupt cur_TOC header data + memcpy(corruptBuffer, tocEntry, PAGESIZE); + corruptBuffer[0] = 0xFF; + corruptBuffer[1] = 0xFF; + PnorRP::getInstance().writeToDevice( offset + FFS_HDR_SIZE, 0, + false, corruptBuffer ); + + // Check if cur_TOC failed that other TOC is used + TOC_used = cur_TOC; + PnorRP::getInstance().readTOC(); + TOC_used = PnorRP::getInstance().iv_TOC_used; + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_TOC : TOC %d Corrupt Entry Toc_used = %d", cur_TOC, TOC_used); + + if (TOC_used == cur_TOC) + { + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_TOC> ERROR : TOC %d is corrupted, did not use other TOC ENTRY", cur_TOC); + TS_FAIL("PnorRpTest::test_TOC> ERROR : TOC %d is corrupted, did not use other TOC", cur_TOC); + } + + // Fix cur_TOC first entry + PnorRP::getInstance().writeToDevice( offset + FFS_HDR_SIZE, 0, + false, tocEntry ); + } + + delete tocHeader; + delete tocEntry; + delete corruptBuffer; + + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_TOC End"); + } + + //@todo - import config data from build and compare to section info }; diff --git a/src/usr/sbe/sbe_update.C b/src/usr/sbe/sbe_update.C index 171112f3c..39721d780 100644 --- a/src/usr/sbe/sbe_update.C +++ b/src/usr/sbe/sbe_update.C @@ -389,7 +389,6 @@ namespace SBE // Get SBE PNOR section info from PNOR RP err = PNOR::getSectionInfo( pnorSectionId, - PNOR::CURRENT_SIDE, pnorInfo ); if(err) { diff --git a/src/usr/targeting/attrrp.C b/src/usr/targeting/attrrp.C index de2a6b21f..bb1f82eee 100644 --- a/src/usr/targeting/attrrp.C +++ b/src/usr/targeting/attrrp.C @@ -266,7 +266,6 @@ namespace TARGETING // Locate attribute section in PNOR. PNOR::SectionInfo_t l_pnorSectionInfo; l_errl = PNOR::getSectionInfo(PNOR::HB_DATA, - PNOR::CURRENT_SIDE, l_pnorSectionInfo); if (l_errl) break; diff --git a/src/usr/testcore/rtloader/loader.H b/src/usr/testcore/rtloader/loader.H index b60c830e2..ea36f1126 100644 --- a/src/usr/testcore/rtloader/loader.H +++ b/src/usr/testcore/rtloader/loader.H @@ -49,8 +49,7 @@ class RuntimeLoaderTest : public CxxTest::TestSuite PNOR::SectionInfo_t runtimeSection; errlHndl_t l_errl = - PNOR::getSectionInfo(PNOR::HB_RUNTIME, PNOR::CURRENT_SIDE, - runtimeSection); + PNOR::getSectionInfo(PNOR::HB_RUNTIME, runtimeSection); if (l_errl) { diff --git a/src/usr/vfs/vfsrp.C b/src/usr/vfs/vfsrp.C index c08b10016..4d7eeb4b2 100644 --- a/src/usr/vfs/vfsrp.C +++ b/src/usr/vfs/vfsrp.C @@ -117,8 +117,7 @@ errlHndl_t VfsRp::_init() // Discover PNOR virtual address of extended image PNOR::SectionInfo_t l_pnor_info; - // Always use CURRENT_SIDE. PNOR RP will know if that is A or B. - err = PNOR::getSectionInfo(PNOR::HB_EXT_CODE, PNOR::CURRENT_SIDE, l_pnor_info); + err = PNOR::getSectionInfo(PNOR::HB_EXT_CODE, l_pnor_info); if(!err) { iv_pnor_vaddr = l_pnor_info.vaddr; diff --git a/src/usr/vpd/ipvpd.C b/src/usr/vpd/ipvpd.C index 23321631b..384ff46c2 100644 --- a/src/usr/vpd/ipvpd.C +++ b/src/usr/vpd/ipvpd.C @@ -533,12 +533,11 @@ errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr, do { - // Call a function in the common VPD code + // Call a function in the common VPD code VPD::pnorInformation info; info.segmentSize = iv_vpdSectionSize; info.maxSegments = iv_vpdMaxSections; info.pnorSection = iv_pnorSection; - info.pnorSide = PNOR::CURRENT_SIDE; err = VPD::readPNOR( i_byteAddr, i_numBytes, o_data, @@ -816,7 +815,6 @@ errlHndl_t IpVpdFacade::writeKeyword ( const char * i_keywordName, info.segmentSize = iv_vpdSectionSize; info.maxSegments = iv_vpdMaxSections; info.pnorSection = iv_pnorSection; - info.pnorSide = PNOR::CURRENT_SIDE; err = VPD::writePNOR( i_offset+byteAddr, keywordSize, i_buffer, @@ -839,8 +837,8 @@ errlHndl_t IpVpdFacade::writeKeyword ( const char * i_keywordName, // Finally, send it down to the FSP msgdata.rec_num = i_target->getAttr<TARGETING::ATTR_VPD_REC_NUM>(); - memcpy( msgdata.record, i_recordName, RECORD_BYTE_SIZE ); - memcpy( msgdata.keyword, i_keywordName, KEYWORD_BYTE_SIZE ); + memcpy( msgdata.record, i_recordName, RECORD_BYTE_SIZE ); + memcpy( msgdata.keyword, i_keywordName, KEYWORD_BYTE_SIZE ); err = VPD::sendMboxWriteMsg( keywordSize, i_buffer, i_target, diff --git a/src/usr/vpd/rtvpd_load.C b/src/usr/vpd/rtvpd_load.C index cb393e996..77152da9f 100644 --- a/src/usr/vpd/rtvpd_load.C +++ b/src/usr/vpd/rtvpd_load.C @@ -50,7 +50,6 @@ errlHndl_t bld_vpd_image(PNOR::SectionId vpd_type, errlHndl_t err = NULL; PNOR::SectionInfo_t info; err = PNOR::getSectionInfo( vpd_type, - PNOR::CURRENT_SIDE, info ); if(!err) diff --git a/src/usr/vpd/spd.C b/src/usr/vpd/spd.C index 14c139dec..172feadbc 100755 --- a/src/usr/vpd/spd.C +++ b/src/usr/vpd/spd.C @@ -116,7 +116,7 @@ errlHndl_t getMemType ( uint8_t & o_memType, * @param[out] o_modType - The module type value to return. * * @param[in] i_target - The target to read data from. - * + * * @param[in] i_memType - The memory type * * @return errlHndl_t - NULL if successful, otherwise a pointer @@ -270,7 +270,7 @@ errlHndl_t spdWriteKeywordValue ( DeviceFW::OperationType i_opType, break; } - // Check the Basic Memory Type + // Check the Basic Memory Type if(( SPD_DDR3 == memType ) || ( SPD_DDR4 == memType )) { err = spdWriteValue( keyword, @@ -338,7 +338,6 @@ errlHndl_t spdFetchData ( uint64_t i_byteAddr, info.segmentSize = DIMM_SPD_SECTION_SIZE; info.maxSegments = DIMM_SPD_MAX_SECTIONS; info.pnorSection = PNOR::DIMM_JEDEC_VPD; - info.pnorSide = PNOR::CURRENT_SIDE; err = VPD::readPNOR( i_byteAddr, i_numBytes, o_data, @@ -394,7 +393,6 @@ errlHndl_t spdWriteData ( uint64_t i_offset, info.segmentSize = DIMM_SPD_SECTION_SIZE; info.maxSegments = DIMM_SPD_MAX_SECTIONS; info.pnorSection = PNOR::DIMM_JEDEC_VPD; - info.pnorSide = PNOR::CURRENT_SIDE; err = VPD::writePNOR( i_offset, i_numBytes, i_data, @@ -660,7 +658,7 @@ errlHndl_t spdWriteValue ( uint64_t i_keyword, break; } - // We are not handling writes that are not on a byte + // We are not handling writes that are not on a byte // boundary until we absolutely need to. There are // no writable keywords that are not on byte boundaries if( entry->bitMask ) @@ -708,7 +706,7 @@ errlHndl_t spdWriteValue ( uint64_t i_keyword, VPD::VpdWriteMsg_t msgdata; msgdata.rec_num = i_target->getAttr<TARGETING::ATTR_VPD_REC_NUM>(); //XXXX=offset relative to whole section - memcpy( msgdata.record, "XXXX", sizeof(msgdata.record) ); + memcpy( msgdata.record, "XXXX", sizeof(msgdata.record) ); msgdata.offset = entry->offset; err = VPD::sendMboxWriteMsg( io_buflen, io_buffer, @@ -821,7 +819,7 @@ errlHndl_t ddr3SpecialCases(const KeywordData & i_kwdData, 0x0 ); break; }; - + TRACSSCOMP( g_trac_spd, EXIT_MRK"ddr3SpecialCases()" ); return err; } @@ -904,7 +902,7 @@ errlHndl_t ddr4SpecialCases(const KeywordData & i_kwdData, // ================================================== // 4 byte - LSB first, no mask case CAS_LATENCIES_SUPPORTED_DDR4: - // Get 4th byte + // Get 4th byte err = spdFetchData( i_kwdData.offset, 1, /* Read 1 byte at a time */ &tmpBuffer[0], @@ -1367,7 +1365,7 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData, i_kwdData.modSpec ) ); break; } - + } while( 0 ); TRACSSCOMP( g_trac_spd, diff --git a/src/usr/vpd/vpd.C b/src/usr/vpd/vpd.C index 78314a400..bd33e3895 100644 --- a/src/usr/vpd/vpd.C +++ b/src/usr/vpd/vpd.C @@ -84,7 +84,6 @@ errlHndl_t getPnorAddr ( pnorInformation & i_pnorInfo, { // Get SPD PNOR section info from PNOR RP err = PNOR::getSectionInfo( i_pnorInfo.pnorSection, - i_pnorInfo.pnorSide, info ); if( err ) @@ -306,7 +305,7 @@ errlHndl_t sendMboxWriteMsg ( size_t i_numBytes, l_err->collectTrace("SPD",1024); } - // just commit the log and move on, nothing else to do + // just commit the log and move on, nothing else to do errlCommit( l_err, VPD_COMP_ID ); l_err = NULL; diff --git a/src/usr/vpd/vpd.H b/src/usr/vpd/vpd.H index f35bf9eb9..41729bdf0 100644 --- a/src/usr/vpd/vpd.H +++ b/src/usr/vpd/vpd.H @@ -37,11 +37,10 @@ struct pnorInformation uint64_t segmentSize; uint64_t maxSegments; PNOR::SectionId pnorSection; - PNOR::SideSelect pnorSide; }; /** - * @brief VPD Message Types + * @brief VPD Message Types */ enum VPD_MSG_TYPE { @@ -53,13 +52,13 @@ enum VPD_MSG_TYPE /** * @brief Message definition for VPD Write Request * - * - data0 : + * - data0 : * - [16] VPD Record Number * - [32] 4-byte ASCII String for record name * 'XXXX'=Entire VPD section from PNOR * - [16] 2-byte ASCII String for keyword or offset into SPD * 'XX'=Entire VPD record - * - data1 : + * - data1 : * - [64] Size of binary data in bytes * - extra data : Binary VPD Data */ @@ -114,8 +113,8 @@ errlHndl_t getPnorAddr ( pnorInformation & i_pnorInfo, * * @param[in] i_target - The chip target to access the data for. * - * @param[in] i_pnorInfo - Information about the PNOR section and side that we - * need to know to make the request. + * @param[in] i_pnorInfo - Information about the PNOR section that we need to + * know to make the request. * * @param[in/out] io_cachedAddr - The address offset to the data chunk in * PNOR. @@ -147,8 +146,8 @@ errlHndl_t readPNOR ( uint64_t i_byteAddr, * * @param[in] i_target - The chip target to access the data for. * - * @param[in] i_pnorInfo - Information about the PNOR section and side that we - * need to know to make the request. + * @param[in] i_pnorInfo - Information about the PNOR section that we need to + * know to make the request. * * @param[in/out] io_cachedAddr - The address offset to the data chunk in * PNOR. |