diff options
author | CamVan Nguyen <ctnguyen@us.ibm.com> | 2012-06-11 13:10:13 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-06-15 16:13:10 -0500 |
commit | b97837c8364cb04aed2582ac58b89365c1e14875 (patch) | |
tree | f0b65f3fc8127e393363d75614a03206e99e8485 /src | |
parent | 62e206399932f5c8729f24f38a12fb4db58f185b (diff) | |
download | talos-hostboot-b97837c8364cb04aed2582ac58b89365c1e14875.tar.gz talos-hostboot-b97837c8364cb04aed2582ac58b89365c1e14875.zip |
SCOM Initifile: SW146714: Use two bytes to store row rpn sequence byte count.
Change-Id: I617fe3267df98a85820c789553323d431ab9c5ee
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1184
Tested-by: Jenkins Server
Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com>
Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/usr/hwpf/hwp/fapiHwpExecInitFile.C | 22 | ||||
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initRpn.C | 34 | ||||
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initRpn.H | 7 | ||||
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initScom.C | 240 |
4 files changed, 183 insertions, 120 deletions
diff --git a/src/usr/hwpf/hwp/fapiHwpExecInitFile.C b/src/usr/hwpf/hwp/fapiHwpExecInitFile.C index b23ce5133..6c5d6040b 100644 --- a/src/usr/hwpf/hwp/fapiHwpExecInitFile.C +++ b/src/usr/hwpf/hwp/fapiHwpExecInitFile.C @@ -55,6 +55,8 @@ * camvanng 05/22/2012 Ability to do simple operations * on attributes in the scom * data column + * SW146714 camvanng 06/08/2012 Use two bytes to store row + * rpn sequence byte count */ #include <fapiHwpExecInitFile.H> @@ -994,7 +996,7 @@ void loadScomSection(ifInfo_t & io_ifInfo, } //Read the row data for each row - l_rowSize = 0; + uint16_t l_rowSize = 0; l_rowPtr = NULL; uint32_t c; @@ -1011,10 +1013,10 @@ void loadScomSection(ifInfo_t & io_ifInfo, fapiAssert(false); } - //If have expr column, need another byte to store its length + //If have expr column, need another two bytes to store its length if (l_scoms[i].hasExpr) { - l_rowSize++; + l_rowSize += 2; } //Allocate the space @@ -1056,11 +1058,12 @@ void loadScomSection(ifInfo_t & io_ifInfo, //if present if (l_scoms[i].hasExpr) { - l_rowSize--; - *l_rowPtr = l_rowSize; //Save the length of the expr + //Save the length of the expr + l_rowSize -= 2; + *l_rowPtr++ = (uint8_t)(l_rowSize >> 8); + *l_rowPtr++ = (uint8_t)l_rowSize; IF_DBG("loadScomSection: scom[%u]: rowData[%u] " - "expr len 0x%02x", i, j, *l_rowPtr); - l_rowPtr++; + "expr len 0x%02x%02x", i, j, *(l_rowPtr-2), *(l_rowPtr-1)); //Read in the rest of the expression, which goes to the //end of the row @@ -1140,7 +1143,7 @@ fapi::ReturnCode executeScoms(ifData_t & i_ifData) fapi::ReturnCode l_rc; uint16_t l_numSimpleCols = 0; - uint8_t l_len = 0; + uint16_t l_len = 0; char * l_rowExpr = NULL; char * l_colExpr = NULL; uint16_t l_row; @@ -1284,7 +1287,8 @@ fapi::ReturnCode executeScoms(ifData_t & i_ifData) l_len = *((uint8_t*)l_rowExpr); l_rowExpr++; - //l_len--; //remove the length value from the length left + l_len = (l_len << 8) + *((uint8_t*)l_rowExpr); + l_rowExpr++; l_rc = evalRpn(i_ifData, l_rowExpr, l_len, false, true); diff --git a/src/usr/hwpf/ifcompiler/initRpn.C b/src/usr/hwpf/ifcompiler/initRpn.C index d926e62f1..2443ae9d4 100755 --- a/src/usr/hwpf/ifcompiler/initRpn.C +++ b/src/usr/hwpf/ifcompiler/initRpn.C @@ -40,6 +40,7 @@ // camvanng 05/07/12 Support for associated target attributes // camvanng 05/22/12 Ability to do simple operations on attributes // in the scom_data column +// SW146714 camvanng 06/08/12 Use two bytes to store row rpn sequence byte count // End Change Log ********************************************************************************* /** @@ -588,7 +589,7 @@ Rpn * Rpn::merge(Rpn * i_rpn) //------------------------------------------------------------------------------------------------- // See header file for contract -void Rpn::bin_read(BINSEQ::const_iterator & bli, uint8_t i_size, Symbols * symbols) +void Rpn::bin_read(BINSEQ::const_iterator & bli, uint16_t i_size, Symbols * symbols) { if(symbols) iv_symbols = symbols; @@ -847,7 +848,8 @@ std::string Rpn::listing(const char * i_desc, const std::string & spyname, bool //------------------------------------------------------------------------------------------------- // binary version to write to file -void Rpn::bin_str(BINSEQ & o_blist, uint32_t i_num_addrs, uint32_t i_addr_num, bool i_prepend_count) +void Rpn::bin_str(BINSEQ & o_blist, uint32_t i_num_addrs, uint32_t i_addr_num, + bool i_prepend_count, bool i_one_byte_count) { BINSEQ blist; uint32_t count = 0; @@ -939,9 +941,35 @@ void Rpn::bin_str(BINSEQ & o_blist, uint32_t i_num_addrs, uint32_t i_addr_num, b } } + //std::cout << "Rpn::bit_str(): iv_rpnstack size: " << iv_rpnstack.size() << std::endl; + //std::cout << " Rpn::bit_str(): rpn byte count: " << count << std::endl; if (i_prepend_count) { - o_blist.push_back((uint8_t) count); + if (true == i_one_byte_count) + { + //Expect count <= 255 + if (0xFF < count) + { + std::ostringstream errss; + errss << "Rpn::bin_str: count " << count << " > 0xFF\n"; + throw std::invalid_argument(errss.str()); + } + + o_blist.push_back((uint8_t) count); + } + else + { + //Expect count <= 65535 + if (0xFFFF < count) + { + std::ostringstream errss; + errss << "Rpn::bin_str: count " << count << " > 0xFFFF\n"; + throw std::invalid_argument(errss.str()); + } + + o_blist.push_back((uint8_t)(count >> 8)); + o_blist.push_back((uint8_t) count); + } } o_blist.insert(o_blist.end(), blist.begin(), blist.end()); diff --git a/src/usr/hwpf/ifcompiler/initRpn.H b/src/usr/hwpf/ifcompiler/initRpn.H index 7e87554c8..5f6fddd32 100755 --- a/src/usr/hwpf/ifcompiler/initRpn.H +++ b/src/usr/hwpf/ifcompiler/initRpn.H @@ -38,6 +38,7 @@ // camvanng 01/20/12 Support for using a range of indexes for array attributes // camvanng 05/22/12 Ability to do simple operations on attributes // in the scom_data column +// SW146714 camvanng 06/08/12 Use two bytes to store row rpn sequence byte count // End Change Log ********************************************************************************* /** @@ -193,12 +194,14 @@ namespace init * @param i_num_addrs number of Scom addresses for this Scom * @param i_addr_num the nth addr with the range of Scom addresses * @param i_prepend_count Flag to indicate prepend rpn count to binary string + * @param i_one_byte_count Flag to indicate whether to use 1 byte to store + * the byte count (default is to use 2 bytes) when i_prepend_count == true * @PRE should never be called until all symbols in the initfile have been * "looked up" or the binary tags for Symbols and Numbers may not be accurate * @return void */ void bin_str(BINSEQ & blist, uint32_t i_num_addrs, uint32_t i_addr_num, - bool i_prepend_count = false); + bool i_prepend_count = false, bool i_one_byte_count = false); /** * Read binary sequence to recreate this Rpn sequence @@ -209,7 +212,7 @@ namespace init * @post if symbols != NULL then iv_symbols is replaced with symbols */ void bin_read(BINSEQ::const_iterator & bli, - uint8_t i_size = 2, + uint16_t i_size = 2, Symbols * symbols = NULL); // read binary sequence to recreate RPN /** diff --git a/src/usr/hwpf/ifcompiler/initScom.C b/src/usr/hwpf/ifcompiler/initScom.C index 7fc527693..5e60a5fcd 100755 --- a/src/usr/hwpf/ifcompiler/initScom.C +++ b/src/usr/hwpf/ifcompiler/initScom.C @@ -43,6 +43,8 @@ // camvanng 05/07/12 Support for associated target attributes // camvanng 05/22/12 Ability to do simple operations on attributes // in the scom_data column +// SW146714 camvanng 06/08/12 Use two bytes to store row rpn sequence byte count +// Handle case where after row_optimize(), there's no Scom to write // End Change Log ********************************************************************************* /** @@ -140,9 +142,12 @@ Scom::Scom(BINSEQ::const_iterator & bli, Symbols * i_symbols): { COL_LIST::iterator cli = iv_cols_rpn.begin(); // *cli is list of row rpns for col RPN_LIST::iterator rpi = (*cli).begin() + row_n; // *rpi is current row rpn for first col - BINSEQ::const_iterator bli_end = bli + (*bli); // end of rpn in bin seq - ++bli; ++bli_end; // adjust for first byte being len + // The next len bytes belong to this row + uint16_t rpn_byte_count = (*bli++ << 8) + (*bli++); // length of rpn sequece + //printf("Create scom from binseq: rpn byte count: %u\n", rpn_byte_count); + BINSEQ::const_iterator bli_end = bli + rpn_byte_count; // end of rpn in bin seq + // Simple cols are divided by OPs // LIST op has two additional bytes (len,op) while(bli < bli_end) @@ -271,7 +276,7 @@ void Scom::add_row_rpn(Rpn * i_rpn) void Scom::add_bit_range(uint32_t start, uint32_t end) { // make sure they are added in order - dbg << "Add bit range " << start << " to " << end; + dbg << "Add bit range " << start << " to " << end << endl; iv_range_list.push_back(RANGE(start,end)); } @@ -470,35 +475,41 @@ uint32_t Scom::bin_listing(BINSEQ & blist) row_optimize(); // delete any rows that are unconditionally false. + merge rows - ranges.insert(iv_range_list.begin(),iv_range_list.end()); - - SCOM_ADDR::iterator i = iv_scom_addr.begin(); + //printf("bin_listing: iv_scom_rpn size = %u\n", iv_scom_rpn.size()); - for(; i != iv_scom_addr.end(); ++i, ++addr_num) + //Skip this scom if after row_optimize, there's no scom data to write + if (iv_scom_rpn.size()) { - //printf("scom address:%s\n",(*i).c_str()); - if(ranges.size()) + ranges.insert(iv_range_list.begin(),iv_range_list.end()); + + SCOM_ADDR::iterator i = iv_scom_addr.begin(); + + for(; i != iv_scom_addr.end(); ++i, ++addr_num) { - for(set<RANGE>::iterator r = ranges.begin(); r != ranges.end(); ++r) + //printf("scom address:%s\n",(*i).c_str()); + if(ranges.size()) + { + for(set<RANGE>::iterator r = ranges.begin(); r != ranges.end(); ++r) + { + ++scom_count; + //bin_list_one(blist,*i,*r); + // The following sequence will optimize the bytecode for this spy + // - Compile the spy into bytecode for a range of bits + // - Recreate the spy from the bytecode + // - Compile the recreated spy back into bytecode. + BINSEQ temp; + bin_list_one(temp,strtoull((*i).c_str(),NULL,16), addr_num, *r); + BINSEQ::const_iterator bi = temp.begin(); + Scom s(bi,iv_symbols); + s.bin_list_one(blist,strtoull((*i).c_str(),NULL,16), addr_num, RANGE(1,0)); + } + } + else { ++scom_count; - //bin_list_one(blist,*i,*r); - // The following sequence will optimize the bytecode for this spy - // - Compile the spy into bytecode for a range of bits - // - Recreate the spy from the bytecode - // - Compile the recreated spy back into bytecode. - BINSEQ temp; - bin_list_one(temp,strtoull((*i).c_str(),NULL,16), addr_num, *r); - BINSEQ::const_iterator bi = temp.begin(); - Scom s(bi,iv_symbols); - s.bin_list_one(blist,strtoull((*i).c_str(),NULL,16), addr_num, RANGE(1,0)); + bin_list_one(blist,strtoull((*i).c_str(),NULL,16), addr_num, RANGE(1,0)); } } - else - { - ++scom_count; - bin_list_one(blist,strtoull((*i).c_str(),NULL,16), addr_num, RANGE(1,0)); - } } return scom_count; @@ -596,7 +607,7 @@ void Scom::bin_list_one(BINSEQ & blist,uint64_t i_addr, uint32_t i_addr_num, RAN { if ((*r) == range) { - i->bin_str(blist,numaddrs,i_addr_num,true); //Add length to blist + i->bin_str(blist,numaddrs,i_addr_num,true,true); //Add length to blist } } } @@ -604,7 +615,7 @@ void Scom::bin_list_one(BINSEQ & blist,uint64_t i_addr, uint32_t i_addr_num, RAN { for(RPN_LIST::iterator i = iv_scom_rpn.begin(); i != iv_scom_rpn.end(); ++i) { - i->bin_str(blist,numaddrs,i_addr_num,true); //Add length to blist + i->bin_str(blist,numaddrs,i_addr_num,true,true); //Add length to blist } } @@ -664,14 +675,27 @@ void Scom::row_optimize() //dg003a if(remove_me) { iv_scom_rpn.erase(iv_scom_rpn.begin() + row); //remove spyv - //Need to remove rpn row segment from each iv_cols_rpn rpn list - for(COL_LIST::iterator i = iv_cols_rpn.begin(); i != iv_cols_rpn.end(); ++i) + if (0 == iv_scom_rpn.size()) { - i->erase(i->begin() + row); + iv_col_vars.clear(); + iv_cols_rpn.clear(); + if(iv_range_list.size()) + { + iv_range_list.clear(); + } + } + else + { + //Need to remove rpn row segment from each iv_cols_rpn rpn list + for(COL_LIST::iterator i = iv_cols_rpn.begin(); i != iv_cols_rpn.end(); ++i) + { + i->erase(i->begin() + row); + } + if(iv_range_list.size()) iv_range_list.erase(iv_range_list.begin() + row); } - if(iv_range_list.size()) iv_range_list.erase(iv_range_list.begin() + row); - //dbg << "ROW is unconditionally false. Removing row " << row+1 << " from " << get_key_name() << endl; + dbg << "initScom: row_optimize: ROW is unconditionally false. Removing row " << row+1 << endl; + dbg << "initScom: row_optimize: iv_scom_rpn size " << iv_scom_rpn.size() << endl; } } while (row); @@ -1119,7 +1143,7 @@ void ScomList::compile(BINSEQ & bin_seq) Rpn::set32(bin_seq,offset); // Offset to Literal Symbol Table offset += blist_i.size(); // offset += lit table byte size - if(count_s) + //if(count_s) //Need to write this either way { Rpn::set32(bin_seq,offset); // SCOM Section offset Rpn::set32(bin_seq,count_s); // Number of SCOM's @@ -1137,8 +1161,8 @@ void ScomList::compile(BINSEQ & bin_seq) if(count_s) { bin_seq.insert(bin_seq.end(), blist_s.begin(), blist_s.end()); // add SCOM section - stats << '*' << setw(20) << "S scoms:" << setw(6) << count_s << endl; } + stats << '*' << setw(20) << "S scoms:" << setw(6) << count_s << endl; dbg << "======================== End compile ============================" << endl; } @@ -1251,100 +1275,104 @@ void ScomList::listing(BINSEQ & bin_seq,ostream & olist) } olist << iv_symbols->listing() << endl; - olist << "------------------- SCOM TABLES ------------------------\n\n" - << endl; - - bli = b; // restore - olist << "------------ Scoms -----------\n\n"; - - b = bin_seq.begin() + offset; - if(!(b < bin_seq.end())) + if (count) { - throw overflow_error("ERROR: ScomList::listing - iterator overflowed sequence"); - } + olist << "------------------- SCOM TABLES ------------------------\n\n" + << endl; - SCOM_LIST l_scom_list; - SCOM_LIST::const_iterator i; - pair<SCOM_LIST::const_iterator, SCOM_LIST::const_iterator> ret; - while (count --) - { - Scom * s = new Scom(b,iv_symbols); - olist << s->listing() << endl; + bli = b; // restore - uint64_t l_addr = s->get_address_hex(); - //cout << "ScomList::listing: iv_scom_address_hex 0x" << hex << l_addr << endl; + olist << "------------ Scoms -----------\n\n"; - //Check for duplicate scom statements - bool l_dup_scoms = false; - ret = l_scom_list.equal_range(l_addr); - if (ret.first != ret.second) + b = bin_seq.begin() + offset; + if(!(b < bin_seq.end())) { - //cout << "ScomList::listing: Duplicate scom addresses found" << endl; + throw overflow_error("ERROR: ScomList::listing - iterator overflowed sequence"); + } - uint32_t l_length = s->get_scom_length(); + SCOM_LIST l_scom_list; + SCOM_LIST::const_iterator i; + pair<SCOM_LIST::const_iterator, SCOM_LIST::const_iterator> ret; + while (count --) + { + Scom * s = new Scom(b,iv_symbols); + olist << s->listing() << endl; - //If writing all bits - if (l_length == 0) - { - l_dup_scoms = true; - } - else - { - uint32_t l_start = s->get_scom_offset(); //start bit - uint32_t l_end = l_start + l_length - 1; //end bit - //cout << "ScomList::listing: offset " << dec << l_start - // << " end " << l_end << " length " << l_length << endl; + uint64_t l_addr = s->get_address_hex(); + //cout << "ScomList::listing: iv_scom_address_hex 0x" << hex << l_addr << endl; - //loop through all the matches and check for duplicate bits - for (i = ret.first; i != ret.second; ++i) - { - uint32_t l_length2 = i->second->get_scom_length(); + //Check for duplicate scom statements + bool l_dup_scoms = false; + ret = l_scom_list.equal_range(l_addr); + if (ret.first != ret.second) + { + //cout << "ScomList::listing: Duplicate scom addresses found" << endl; - //If writing all bits - if (l_length2 == 0) - { - l_dup_scoms = true; - break; - } + uint32_t l_length = s->get_scom_length(); - uint32_t l_start2 = i->second->get_scom_offset(); //start bit - uint32_t l_end2 = l_start2 + l_length2 - 1; //end bit - //cout << "ScomList::listing: offset2 " << l_start2 - // << " end2 " << l_end2 << " length2 " << l_length2 << endl; + //If writing all bits + if (l_length == 0) + { + l_dup_scoms = true; + } + else + { + uint32_t l_start = s->get_scom_offset(); //start bit + uint32_t l_end = l_start + l_length - 1; //end bit + //cout << "ScomList::listing: offset " << dec << l_start + // << " end " << l_end << " length " << l_length << endl; - // check for duplicate bits - if ((l_start <= l_end2) && (l_start2 <= l_end)) + //loop through all the matches and check for duplicate bits + for (i = ret.first; i != ret.second; ++i) { - // ranges overlap - l_dup_scoms = true; - break; + uint32_t l_length2 = i->second->get_scom_length(); + + //If writing all bits + if (l_length2 == 0) + { + l_dup_scoms = true; + break; + } + + uint32_t l_start2 = i->second->get_scom_offset(); //start bit + uint32_t l_end2 = l_start2 + l_length2 - 1; //end bit + //cout << "ScomList::listing: offset2 " << l_start2 + // << " end2 " << l_end2 << " length2 " << l_length2 << endl; + + // check for duplicate bits + if ((l_start <= l_end2) && (l_start2 <= l_end)) + { + // ranges overlap + l_dup_scoms = true; + break; + } } } } - } - if (false == l_dup_scoms) - { - l_scom_list.insert(pair<uint64_t,Scom *>(l_addr, s)); - //cout << "ScomList::listing: l_scom_list size " << l_scom_list.size() << endl; + if (false == l_dup_scoms) + { + l_scom_list.insert(pair<uint64_t,Scom *>(l_addr, s)); + //cout << "ScomList::listing: l_scom_list size " << l_scom_list.size() << endl; + } + else + { + ostringstream oss; + oss << "ScomList::listing: Duplicate scom statements found: " + "Address 0x" << hex << l_addr << endl; + throw invalid_argument(oss.str()); + } } - else + + //Free memory + for (i = l_scom_list.begin(); i != l_scom_list.end(); ++i) { - ostringstream oss; - oss << "ScomList::listing: Duplicate scom statements found: " - "Address 0x" << hex << l_addr << endl; - throw invalid_argument(oss.str()); + delete i->second; } + l_scom_list.clear(); } - //Free memory - for (i = l_scom_list.begin(); i != l_scom_list.end(); ++i) - { - delete i->second; - } - l_scom_list.clear(); - dbg << "======================= End Listing ========================" << endl; } |