diff options
Diffstat (limited to 'src/usr/spd/spd.C')
-rwxr-xr-x | src/usr/spd/spd.C | 242 |
1 files changed, 135 insertions, 107 deletions
diff --git a/src/usr/spd/spd.C b/src/usr/spd/spd.C index 1286385cd..a421a14b9 100755 --- a/src/usr/spd/spd.C +++ b/src/usr/spd/spd.C @@ -41,7 +41,7 @@ #include <vfs/vfs.H> #include <spd/spdreasoncodes.H> #include <spd/spdenums.H> - +#include <algorithm> #include "spd.H" #include "spdDDR3.H" @@ -69,9 +69,27 @@ TRAC_INIT( & g_trac_spd, "SPD", 4096 ); // Defines // ---------------------------------------------- + namespace SPD { +/** +* @brief Compare two values and return whether e2 is greater than +* the e1 value. This is used during lower_bound to cut +* search time down. +* +* @param[in] e1 - Structure to be searched, using the Keyword +* value in that structure. +* +* @param[in] e2 - Structure to be searched, using the Keyword +* value in that structure. +* +* @return boolean - Whether or not e2.keyword is larger than +* e1.keyword. +*/ +bool compareEntries ( const KeywordData e1, + const KeywordData e2 ); + // Register the perform Op with the routing code for DIMMs. DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD, DeviceFW::SPD, @@ -305,9 +323,9 @@ errlHndl_t spdGetValue ( uint64_t i_keyword, { if( SPD_DDR3 == i_DDRRev ) { - kwdData = ddr3Data; + // Put the table into an array arraySize = (sizeof(ddr3Data)/sizeof(ddr3Data[0])); - + kwdData = ddr3Data; } else { @@ -333,76 +351,18 @@ errlHndl_t spdGetValue ( uint64_t i_keyword, break; } - // TODO - A binary_search algorithm will be implemented with - // Story 4709. - // Loop through the lookup table. - bool keywordFound = false; - for( uint32_t i = 0; i < arraySize; i++ ) - { - if( kwdData[i].keyword == i_keyword ) - { - keywordFound = true; - - if( kwdData[i].isSpecialCase ) - { - // Handle special cases where data isn't sequential - // or is in reverse order from what would be read. - err = spdSpecialCases( i_keyword, - io_buffer, - io_buflen, - i_target, - i, - i_DDRRev ); - - break; - } - - // Check io_buflen versus size in table - err = spdCheckSize( io_buflen, - kwdData[i].length, - i_keyword ); - - if( err ) - { - break; - } - - // Read length requested - err = spdFetchData( kwdData[i].offset, - kwdData[i].length, - tmpBuffer, - i_target ); - - if( err ) - { - break; - } - - // if useBitmask set, mask and then shift data - if( kwdData[i].useBitMask ) - { - // Any bit mask/shifting will always be on a <1 Byte value - // thus, we touch only byte 0. - tmpBuffer[0] = tmpBuffer[0] & kwdData[i].bitMask; - tmpBuffer[0] = tmpBuffer[0] >> kwdData[i].shift; - } - - // Set length read - io_buflen = kwdData[i].length; - break; - } - } - - if( err ) - { - break; - } + // Set the searching structure equal to the keyword we're looking for. + KeywordData tmpKwdData; + tmpKwdData.keyword = i_keyword; + KeywordData * entry = std::lower_bound( kwdData, + &kwdData[arraySize], + tmpKwdData, + compareEntries ); - if( !keywordFound ) + if( entry == &kwdData[arraySize] ) { TRACFCOMP( g_trac_spd, - ERR_MRK"Could not find keyword (0x%04x) in lookup table!", - i_keyword ); + ERR_MRK"No matching keyword entry found!" ); /*@ * @errortype @@ -418,8 +378,55 @@ errlHndl_t spdGetValue ( uint64_t i_keyword, SPD_KEYWORD_NOT_FOUND, i_keyword, 0x0 ); + + break; + } + + if( entry->isSpecialCase ) + { + // Handle special cases where data isn't sequential + // or is in reverse order from what would be read. + err = spdSpecialCases( (*entry), + io_buffer, + io_buflen, + i_target, + i_DDRRev ); + + break; + } + + // Check io_buflen versus size in table + err = spdCheckSize( io_buflen, + (*entry).length, + i_keyword ); + + if( err ) + { break; } + + // Read length requested + err = spdFetchData( (*entry).offset, + (*entry).length, + tmpBuffer, + i_target ); + + if( err ) + { + break; + } + + // if useBitmask set, mask and then shift data + if( (*entry).useBitMask ) + { + // Any bit mask/shifting will always be on a <1 Byte value + // thus, we touch only byte 0. + tmpBuffer[0] = tmpBuffer[0] & (*entry).bitMask; + tmpBuffer[0] = tmpBuffer[0] >> (*entry).shift; + } + + // Set length read + io_buflen = (*entry).length; } while( 0 ); if( err ) @@ -439,11 +446,10 @@ errlHndl_t spdGetValue ( uint64_t i_keyword, // ------------------------------------------------------------------ // spdSpecialCases // ------------------------------------------------------------------ -errlHndl_t spdSpecialCases ( uint64_t i_keyword, +errlHndl_t spdSpecialCases ( KeywordData i_kwdData, void * io_buffer, size_t & io_buflen, TARGETING::Target * i_target, - uint64_t i_entry, uint64_t i_DDRRev ) { errlHndl_t err = NULL; @@ -457,7 +463,7 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, // Handle each of the special cases here if( SPD_DDR3 == i_DDRRev ) { - switch( i_keyword ) + switch( i_kwdData.keyword ) { case CAS_LATENCIES_SUPPORTED: // Length 2 bytes @@ -467,12 +473,12 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, // Check Size of buffer err = spdCheckSize( io_buflen, 2, - i_keyword ); + i_kwdData.keyword ); if( err ) break; // Get MSB - err = spdFetchData( ddr3Data[i_entry].offset, + err = spdFetchData( i_kwdData.offset, 1, /* Read 1 byte at a time */ &tmpBuffer[0], i_target ); @@ -480,10 +486,10 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, if( err ) break; // Mask and shift if needed - if( ddr3Data[i_entry].useBitMask ) + if( i_kwdData.useBitMask ) { - tmpBuffer[0] = tmpBuffer[0] & ddr3Data[i_entry].bitMask; - tmpBuffer[0] = tmpBuffer[0] >> ddr3Data[i_entry].shift; + tmpBuffer[0] = tmpBuffer[0] & i_kwdData.bitMask; + tmpBuffer[0] = tmpBuffer[0] >> i_kwdData.shift; } // Get LSB @@ -506,12 +512,12 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, // Check Size of buffer err = spdCheckSize( io_buflen, 2, - i_keyword ); + i_kwdData.keyword ); if( err ) break; // Get MSB - err = spdFetchData( ddr3Data[i_entry].offset, + err = spdFetchData( i_kwdData.offset, 1, /* Read 1 byte at a time */ &tmpBuffer[0], i_target ); @@ -519,10 +525,10 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, if( err ) break; // Mask and shift if needed - if( ddr3Data[i_entry].useBitMask ) + if( i_kwdData.useBitMask ) { - tmpBuffer[0] = tmpBuffer[0] & ddr3Data[i_entry].bitMask; - tmpBuffer[0] = tmpBuffer[0] >> ddr3Data[i_entry].shift; + tmpBuffer[0] = tmpBuffer[0] & i_kwdData.bitMask; + tmpBuffer[0] = tmpBuffer[0] >> i_kwdData.shift; } // Get LSB @@ -545,12 +551,12 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, // Check size of buffer err = spdCheckSize( io_buflen, 2, - i_keyword ); + i_kwdData.keyword ); if( err ) break; // Get MSB - err = spdFetchData( ddr3Data[i_entry].offset, + err = spdFetchData( i_kwdData.offset, 1, /* Read 1 byte at a time */ &tmpBuffer[0], i_target ); @@ -558,10 +564,10 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, if( err ) break; // Mask and shift if needed - if( ddr3Data[i_entry].useBitMask ) + if( i_kwdData.useBitMask ) { - tmpBuffer[0] = tmpBuffer[0] & ddr3Data[i_entry].bitMask; - tmpBuffer[0] = tmpBuffer[0] >> ddr3Data[i_entry].shift; + tmpBuffer[0] = tmpBuffer[0] & i_kwdData.bitMask; + tmpBuffer[0] = tmpBuffer[0] >> i_kwdData.shift; } // Get LSB @@ -584,12 +590,12 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, // Check size of buffer err = spdCheckSize( io_buflen, 2, - i_keyword ); + i_kwdData.keyword ); if( err ) break; // Get MSB - err = spdFetchData( ddr3Data[i_entry].offset, + err = spdFetchData( i_kwdData.offset, 1, /* Read 1 byte at a time */ &tmpBuffer[0], i_target ); @@ -616,12 +622,12 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, // Check size of buffer err = spdCheckSize( io_buflen, 2, - i_keyword ); + i_kwdData.keyword ); if( err ) break; // Get MSB - err = spdFetchData( ddr3Data[i_entry].offset, + err = spdFetchData( i_kwdData.offset, 1, /* Read 1 byte at a time */ &tmpBuffer[0], i_target ); @@ -629,10 +635,10 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, if( err ) break; // Mask and shift if needed - if( ddr3Data[i_entry].useBitMask ) + if( i_kwdData.useBitMask ) { - tmpBuffer[0] = tmpBuffer[0] & ddr3Data[i_entry].bitMask; - tmpBuffer[0] = tmpBuffer[0] >> ddr3Data[i_entry].shift; + tmpBuffer[0] = tmpBuffer[0] & i_kwdData.bitMask; + tmpBuffer[0] = tmpBuffer[0] >> i_kwdData.shift; } // Get LSB @@ -655,12 +661,12 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, // Check size of buffer err = spdCheckSize( io_buflen, 2, - i_keyword ); + i_kwdData.keyword ); if( err ) break; // Get MSB - err = spdFetchData( ddr3Data[i_entry].offset, + err = spdFetchData( i_kwdData.offset, 1, /* Read 1 byte at a time */ &tmpBuffer[0], i_target ); @@ -687,12 +693,12 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, // Check size of buffer err = spdCheckSize( io_buflen, 2, - i_keyword ); + i_kwdData.keyword ); if( err ) break; // Get MSB - err = spdFetchData( ddr3Data[i_entry].offset, + err = spdFetchData( i_kwdData.offset, 1, /*Read 1 byte at a time */ &tmpBuffer[0], i_target ); @@ -714,7 +720,7 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, default: TRACFCOMP( g_trac_spd, ERR_MRK"Unknown keyword (0x%04x) for DDR3 special cases!", - i_keyword ); + i_kwdData.keyword ); /*@ * @errortype @@ -722,14 +728,14 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid SPD_SPECIAL_CASES * @userdata1 SPD Keyword - * @userdata2 Table Entry + * @userdata2 UNUSED * @devdesc Keyword is not a special case keyword. */ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, SPD_SPECIAL_CASES, SPD_INVALID_SPD_KEYWORD, - i_keyword, - i_entry ); + i_kwdData.keyword, + 0x0 ); break; }; } @@ -745,15 +751,14 @@ errlHndl_t spdSpecialCases ( uint64_t i_keyword, * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid SPD_SPECIAL_CASES * @userdata1 SPD Keyword - * @userdata2[0:31] SPD Table entry - * @userdata2[32:63] DIMM DDR Revision + * @userdata2 DIMM DDR Revision * @devdesc Invalid DDR Revision */ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, SPD_SPECIAL_CASES, SPD_INVALID_BASIC_MEMORY_TYPE, - i_keyword, - TWO_UINT32_TO_UINT64( i_entry, i_DDRRev) ); + i_kwdData.keyword, + i_DDRRev ); break; } @@ -915,4 +920,27 @@ errlHndl_t spdReadBinaryFile ( uint64_t i_byteAddr, } +// ------------------------------------------------------------------ +// compareEntries +// ------------------------------------------------------------------ +bool compareEntries ( const KeywordData e1, + const KeywordData e2 ) +{ + // e1 is the iterator value + // e2 is the search value + TRACUCOMP( g_trac_spd, + INFO_MRK"e1: 0x%04x, e2: 0x%04x", + e1.keyword, + e2.keyword ); + if( e2.keyword > e1.keyword ) + { + return true; + } + else + { + return false; + } +} + + } // end namespace SPD |