diff options
Diffstat (limited to 'src/usr/hwpf/ifcompiler/initScom.C')
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initScom.C | 1778 |
1 files changed, 0 insertions, 1778 deletions
diff --git a/src/usr/hwpf/ifcompiler/initScom.C b/src/usr/hwpf/ifcompiler/initScom.C deleted file mode 100755 index 35b93812c..000000000 --- a/src/usr/hwpf/ifcompiler/initScom.C +++ /dev/null @@ -1,1778 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/ifcompiler/initScom.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2011,2014 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -// Change Log ************************************************************************************* -// -// Flag Track Userid Date Description -// ----- -------- -------- -------- ------------------------------------------------------------- -// D754106 dgilbert 06/14/10 Create -// dg001 D774126 dgilbert 09/30/10 Check that colname EXPR is last column in spytable -// dg002 SW039868 dgilbert 10/15/10 Add support to filter unneeded inits by EC -// dg003 SW047506 dgilbert 12/09/10 More filtering enhancements -// andrewg 05/24/11 Port over for VPL/PgP -// andrewg 09/19/11 Updates based on review -// andrewg 11/09/11 Multi-dimensional array and move to common fapi include -// mjjones 11/17/11 Output attribute listing -// camvanng 12/12/11 Support multiple address ranges within a SCOM address -// Use strtoull vs strtoul for 32-bit platforms -// camvanng 12/15/11 Support for multiple duplicate addresses setting different bits -// camvanng 01/20/12 Support for using a range of indexes for array attributes -// camvanng 02/14/12 Support binary and hex scom addresses -// Support for array at beginning of scom address -// Fix bug in string size when converting decimal to hex string -// 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 -// camvanng 06/27/12 Improve error and debug tracing -// End Change Log ********************************************************************************* -// $Id: initScom.C,v 1.11 2014/06/30 20:20:00 thi Exp $ -/** - * @file initSpy.C - * @brief Definition of the initScom Class. Represents the information parsed from an initfile scom - * statement. - */ - -#include <initScom.H> -#include <initSymbols.H> -#include <initCompiler.H> -#include <stdlib.h> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <fstream> -#include <set> -#include <stdexcept> - -extern void yyerror(const char * s); -extern init::ScomList * yyscomlist; // only use this during parsing -std::map<string,string> yytarget; //generic target name & corresponding real name - -namespace init { -extern ostringstream dbg; // debug output -}; - -using namespace init; - -Scom::WHEN_SUBTYPE_MAP Scom::cv_when_subtypes; - -//------------------------------------------------------------------------------------------------- - -Scom::Scom(BINSEQ::const_iterator & bli, Symbols * i_symbols): - iv_symbols(i_symbols), - iv_when(NONE), - iv_scom_length(0), - iv_scom_offset(0), - iv_when_rpn(i_symbols) - -{ - - iv_scom_length = Rpn::extract16(bli); - iv_scom_offset = Rpn::extract16(bli); - uint32_t id = Rpn::extract16(bli); - uint32_t numcols = Rpn::extract16(bli); - uint32_t numrows = Rpn::extract16(bli); - - numcols &= ~SUBTYPE_MASK; - - // Get our SCOM address - uint32_t l_addr_size = 0; - iv_scom_addr_hex = iv_symbols->get_numeric_data(iv_symbols->get_rpn_id(id),l_addr_size); - - - if( iv_scom_length != 0 && iv_scom_length != 0xffff) // most common values - { - if(iv_scom_length < 65) // max scom len is 64 bits - { - for(size_t i = 0; i < numrows; ++i) - add_bit_range(iv_scom_offset, iv_scom_offset + iv_scom_length - 1); - } - else // What's this? - { - ostringstream errs; - errs << "ERROR: Scom::Scom: Invalid scom bit length [" - << iv_scom_length << "]" << endl; - throw range_error(errs.str()); - } - } - - for(size_t i = 0; i < numrows; ++i) - { - uint8_t length = *bli++; // first byte is length of rpn sequence - //printf("Creating scom data rpn, length %u\n", length); - - Rpn rpn(iv_symbols); // blank RPNs - rpn.bin_read(bli, length); // read rpn sequence - iv_scom_rpn.push_back(rpn); - } - - if(numcols) - { - for(size_t i = 0; i < numrows; ++i) iv_row_rpn.push_back(Rpn(iv_symbols)); // blank RPNs - - // Read col heads - for(size_t i = 0; i < numcols; ++i) - { - Rpn col_name_rpn(iv_symbols); // blank RPNs - col_name_rpn.bin_read_one_id(bli); - iv_col_vars.push_back(col_name_rpn); - iv_cols_rpn.push_back(iv_row_rpn); // copy in blank row RPNs for this column - } - - for(size_t row_n = 0; row_n < numrows; ++row_n) - { - 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 - - // 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) - { - // Last col rpn is not limited to one op if it's "expr" - it gets the rest of the RPN - if(cli == (iv_cols_rpn.end() - 1)) - { - while(bli < bli_end) bli = rpi->bin_read_one_op(bli); - break; - } - bli = rpi->bin_read_one_op(bli); - ++cli; - rpi = (*cli).begin() + row_n; - } - } - } - else ++bli; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::set_when(const string * when_str) -{ - - string s(*when_str); - for(string::iterator c = s.begin(); c != s.end(); ++c) *c = toupper(*c); - if(s.size()) - { - size_t i = 0; - for(size_t i = 1; i < sizeof(when_char)/sizeof(when_char[0]); ++i) - { - if(s[0] == when_char[i]) - { - set_when((SCOM_WHEN)i); - break; - } - } - if(i == sizeof(when_char)/sizeof(when_char[0])) - { - string errs("Illegal when="); - errs.append(s); - yyerror(errs.c_str()); - } - s.erase(0,1); - - if(s.size()) - { - WHEN_SUBTYPE_MAP::const_iterator i = cv_when_subtypes.find(s); - if(i != cv_when_subtypes.end()) - { - set_sub_when(i->second); - } - else - { - std::ostringstream oss; - oss << "Illegal 'when=' subvalue: [" << s << ']'; - yyerror(oss.str().c_str()); - } - } - } - else - { - yyerror("Missing 'when =' value"); - } -} - -//------------------------------------------------------------------------------------------------- - -void Scom::add_col(const string & i_colname) -{ - string s(i_colname); - for(string::iterator i = s.begin(); i != s.end(); ++i) *i = toupper(*i); - Rpn col_rpn(s,iv_symbols); // = iv_symbols->use_symbol(s); - - // add check - Can't add any more cols after EXPR column dg001a - if(iv_col_vars.size()) - { - Rpn exp_rpn("EXPR",iv_symbols); - if(exp_rpn == iv_col_vars.back()) // expr col already added - can't add any more cols - { - if (s == "EXPR") - { - yyerror("Scom:: add_col: Multiple EXPR columns specified."); - } - else - { - yyerror("Scom:: add_col: EXPR must be the last column"); - } - } - } - - // if the entire column is unconditionally true it can be left out - // This check will be done later as this scom might be split by bit-ranges. - - iv_col_vars.push_back(col_rpn); - iv_cols_rpn.push_back(iv_row_rpn); // add the collected row RPNs - iv_row_rpn.clear(); -} - -//------------------------------------------------------------------------------------------------- - -void Scom::add_row_rpn(Rpn * i_rpn) -{ - // The row gets parsed before the col name - // So collect the row RPNs and apply them when the col name gets added - - // Replace the Rpn "ANY" EQ with TRUE dg003a - Rpn any_rpn("ANY",iv_symbols); - Rpn true_rpn(iv_symbols); - true_rpn.push_op(TRUE_OP); - - // The column EXPR can have an lone "ANY" rpn - so add EQ. - if(any_rpn == (*i_rpn)) i_rpn->push_op(EQ); - any_rpn.push_op(EQ); - - if(any_rpn == (*i_rpn)) iv_row_rpn.push_back(true_rpn); // Replace col == ANY with TRUE - else - { - iv_row_rpn.push_back(*i_rpn); - } - delete i_rpn; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::add_bit_range(uint32_t start, uint32_t end) -{ - // make sure they are added in order - dbg << "Add bit range " << dec << start << " to " << end << endl; - iv_range_list.push_back(RANGE(start,end)); -} - -//------------------------------------------------------------------------------------------------- -// Range gets parsed before the target symbol (k,n,p,c) - so save it -void Scom::add_target_range(uint32_t r1, uint32_t r2) -{ - if(r1 > r2) - { - uint32_t rt = r1; - r1 = r2; - r2 = rt; - } - iv_target_ranges.push_back(RANGE(r1,r2)); -} - -//------------------------------------------------------------------------------------------------- - -void Scom::make_target(const char * i_symbol) -{ - string s(i_symbol); - Rpn r(iv_symbols); - size_t rsize = iv_target_ranges.size(); - - if(rsize == 0) - { - yyerror("Target given w/o a range"); - } - // if more than one target - use list - else - { - for(RANGE_LIST::iterator iter = iv_target_ranges.begin(); iter != iv_target_ranges.end(); ++iter) - { - for(uint32_t v = iter->first; v <= iter->second; ++v) - { - r.push_int(v); - } - } - if(rsize > 1) r.push_op(LIST); // if more than one target - r.push_op(EQ); - } - - iv_row_rpn.push_back(r); - add_col(s); - iv_target_ranges.clear(); -} - -//------------------------------------------------------------------------------------------------- - -string Scom::list_one(RANGE range) -{ - ostringstream oss; - - uint32_t numcols = iv_col_vars.size() | (iv_when & SUBTYPE_MASK); // WHEN subtype goes in numcols - uint32_t bitlen = range.second + 1 - range.first; - if (bitlen) - { - iv_scom_length = bitlen; // don't overwrite iv_scom_length if bitlen == 0 - iv_scom_offset = range.first; // don't overwrite iv_scom_offset if bitlen == 0 - } - - uint32_t allrows = 0; - uint32_t numrows = 0; - - if(iv_cols_rpn.size()) allrows = iv_cols_rpn.front().size(); - if (allrows == 0) allrows = 1; - - // If there is a bit range we need to select only the rows that apply to this spyname - if(bitlen) - { - for(RANGE_LIST::iterator r = iv_range_list.begin(); r != iv_range_list.end(); ++r) - { - if((*r) == range) ++numrows; - } - } - else numrows = allrows; // else select all the rows - - oss << hex << setfill('0'); - oss << "------------"; - oss << " Scom Address: 0x" << setw(16) << iv_scom_addr_hex; - dbg << " Scom Address: 0x" << hex << setfill('0') << setw(16) << iv_scom_addr_hex << endl; - if(bitlen) - { - oss << '~' << dec << range.first; - if(range.first != range.second) oss << ':' << range.second; - oss << hex; - } - oss << ' ' << "------------" << endl - << "When= " << (iv_when & WHEN_MASK) << endl; - - oss << "0x" << setw(4) << iv_scom_length << "\t\t" << "Scom length" << endl - << "0x" << setw(4) << iv_scom_offset << "\t\t" << "Scom offset" << endl; - - //oss << "0x" << setw(8) << iv_symbols->get_spy_id(spyname) << '\t'; - - oss << "0x" << setw(4) << numcols << "\t\t" << "Number of columns" << endl - << "0x" << setw(4) << numrows << "\t\t" << "Number of rows" << endl; - - // If there is a bit range we need to select only the spyv rows that apply to this spyname - - if(bitlen) - { - RPN_LIST::iterator i = iv_scom_rpn.begin(); - for(RANGE_LIST::iterator r = iv_range_list.begin(); r != iv_range_list.end(); ++r,++i) - { - if ((*r) == range) - { - oss << i->listing("Length of rpn for spyv",Rpn::cv_empty_str,true); - } - } - } - else // get all rows - { - for(RPN_LIST::iterator i = iv_scom_rpn.begin(); i != iv_scom_rpn.end(); ++i) - { - oss << i->listing("Length of rpn for spyv",Rpn::cv_empty_str,true); - } - } - oss << endl; - - - // list the column names that are really CINI VARS - for(RPN_LIST::iterator i = iv_col_vars.begin(); i != iv_col_vars.end(); ++i) - { - oss << i->listing("",Rpn::cv_empty_str,true); - //Rpn col_rpn = *i; - //string desc = iv_symbols->find_name(rpn_id); - //if(desc.size() == 0) desc = "Variable not found!"; - - //oss << "0x" << setw(4) << iv_symbols->get_tag(*i) << "\t\t" << desc << endl; - } - oss << endl << endl; - - - - uint32_t usedrows = 0; - if(iv_cols_rpn.size() == 0) - { - oss << "ROW " << 1 << "\n0x00" << "\t\t" << "0 BYTES" << endl; - } - else - { - for(size_t n = 0; n < allrows; ++n) - { - Rpn rpn(iv_symbols); - if(bitlen) // only get rows that match the current bitrange - { - if(iv_range_list[n] != range) continue; - } - ++usedrows; - oss << "ROW " << usedrows << endl; - - // Build up the row Rpn for row n - for(COL_LIST::iterator i = iv_cols_rpn.begin(); i != iv_cols_rpn.end(); ++i) - { - rpn.append(i->at(n)); - } - oss << rpn.listing(NULL,Rpn::cv_empty_str,true) << endl; - } - } - - return oss.str(); -} - -//------------------------------------------------------------------------------------------------- - -string Scom::listing() -{ - ostringstream oss; - - set<RANGE> ranges; - ranges.insert(iv_range_list.begin(),iv_range_list.end()); - - //oss << list_one(RANGE(1,0)) << endl; - if(ranges.size()) - { - for(set<RANGE>::iterator r = ranges.begin(); r != ranges.end(); ++r) - { - oss << list_one(*r) << endl; - } - } - else - { - oss << list_one(RANGE(1,0)) << endl; - } - - return oss.str(); -} - -//------------------------------------------------------------------------------------------------- - -uint32_t Scom::bin_listing(BINSEQ & blist) -{ - set<RANGE> ranges; - uint32_t scom_count = 0; - uint32_t addr_num = 0; - - row_optimize(); // delete any rows that are unconditionally false. + merge rows - - //printf("bin_listing: iv_scom_rpn size = %u\n", iv_scom_rpn.size()); - - //Skip this scom if after row_optimize, there's no scom data to write - if (iv_scom_rpn.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) - { - dbg << "SCOM::bin_listing: SCOM[" << dec << scom_count << "] Address: " - << hex << *i << endl; - 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,strtoull((*i).c_str(),NULL,16), addr_num, RANGE(1,0)); - } - } - } - - return scom_count; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::bin_list_one(BINSEQ & blist,uint64_t i_addr, uint32_t i_addr_num, RANGE range) -{ - - uint32_t numaddrs = iv_scom_addr.size(); //Number of Scom addresses for this Scom - uint32_t numcols = iv_col_vars.size() | (iv_when & SUBTYPE_MASK); // WHEN subtype goes in numcols - -// No range support - uint32_t bitlen = range.second + 1 - range.first; - - if (bitlen) - { - iv_scom_length = bitlen; // don't overwrite iv_scom_length if bitlen == 0 - iv_scom_offset = range.first; // don't overwrite iv_scom_offset if bitlen == 0 - } - - uint32_t allrows = 0; - uint32_t numrows = 0; - - if(iv_cols_rpn.size()) allrows = iv_cols_rpn.front().size(); - if (allrows == 0) allrows = 1; - - // If there is a bit range we need to select only the rows that apply to this spyname - if(bitlen) - { - for(RANGE_LIST::iterator r = iv_range_list.begin(); r != iv_range_list.end(); ++r) - { - if((*r) == range) ++numrows; - } - } - else numrows = allrows; // else select all the rows - - // If every row rpn in a column is unconditionally true then remove the col. - if(iv_col_vars.size()) - { - vector< pair<RPN_LIST::iterator, COL_LIST::iterator> > deletes; - RPN_LIST::iterator cv = iv_col_vars.begin(); // -> column header Rpn - COL_LIST::iterator cr = iv_cols_rpn.begin(); // -> RPN list of row segments for the column - for(; cv != iv_col_vars.end(); ++cv,++cr) - { - bool remove_it = true; - for(RPN_LIST::const_iterator r = cr->begin(); r != cr->end(); ++r) - { - if(!(r->isTrue())) - { - remove_it = false; - break; - } - } - if(remove_it) - { - deletes.push_back( pair<RPN_LIST::iterator, COL_LIST::iterator>(cv,cr) ); - } - } - while(deletes.size()) - { - pair<RPN_LIST::iterator, COL_LIST::iterator> p = deletes.back(); - deletes.pop_back(); - dbg << "COL is unconditionally true. Removing column " << (p.first)->symbol_names() - << endl; - iv_col_vars.erase(p.first); - iv_cols_rpn.erase(p.second); - --numcols; - } - } - - Rpn::set16(blist,(uint16_t)iv_scom_length); - Rpn::set16(blist,(uint16_t)iv_scom_offset); - - // Just put the SCOM address in place of the spy id - //uint32_t id = iv_symbols->get_spy_id(spyname); - //Rpn::set32(blist,id); - // TODO - Probably need to get scom address id here - //Rpn::set32(blist,(uint32_t)iv_address); - - Rpn *l_scom_addr = new init::Rpn(i_addr,yyscomlist->get_symbols()); - l_scom_addr->bin_str(blist,numaddrs,i_addr_num,false); - delete l_scom_addr; - - - Rpn::set16(blist,(uint16_t)numcols); - Rpn::set16(blist,(uint16_t)numrows); - - // If there is a bit range we need to select only the spyv rows that apply to this spyname - if(bitlen) - { - RPN_LIST::iterator i = iv_scom_rpn.begin(); - for(RANGE_LIST::iterator r = iv_range_list.begin(); r != iv_range_list.end(); ++r,++i) - { - if ((*r) == range) - { - i->bin_str(blist,numaddrs,i_addr_num,true,true); //Add length to blist - } - } - } - else // get all rows - { - for(RPN_LIST::iterator i = iv_scom_rpn.begin(); i != iv_scom_rpn.end(); ++i) - { - i->bin_str(blist,numaddrs,i_addr_num,true,true); //Add length to blist - } - } - - // list the column names that are really CINI VARS - for(RPN_LIST::iterator i = iv_col_vars.begin(); i != iv_col_vars.end(); ++i) - { - i->bin_str(blist,numaddrs,i_addr_num,false); // false means don't prepend an RPN byte count to the binary rpn appended. - //uint16_t tag = iv_symbols->get_tag(*i); - //blist.push_back((uint8_t)(tag >> 8)); - //blist.push_back((uint8_t) tag); - } - - if(iv_cols_rpn.size() == 0) blist.push_back(0); - else - { - for(size_t n = 0; n < allrows; ++n) - { - Rpn rpn(iv_symbols); - if(bitlen) // only get rows that match the current bitrange - { - if(iv_range_list[n] != range) continue; - } - - // Build up the row Rpn for row n - for(COL_LIST::iterator i = iv_cols_rpn.begin(); i != iv_cols_rpn.end(); ++i) - { - rpn.append(i->at(n)); - } - rpn.bin_str(blist,numaddrs,i_addr_num,true); - } - } -} - -//------------------------------------------------------------------------------------------------- -// Delete any rows that are unconditionally false -// Merge rows that can be merged -// -void Scom::row_optimize() //dg003a -{ - size_t row = 0; - if (iv_cols_rpn.size()) row = iv_cols_rpn.front().size(); - if(row == 0) return; - - // Look for false rows - do - { - bool remove_me = false; - --row; - for(COL_LIST::iterator i = iv_cols_rpn.begin(); i != iv_cols_rpn.end(); ++i) - { - if (i->at(row).isFalse()) - { - remove_me = true; - break; - } - } - if(remove_me) - { - iv_scom_rpn.erase(iv_scom_rpn.begin() + row); //remove spyv - if (0 == iv_scom_rpn.size()) - { - 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); - } - - 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); - - // now look for rows to merge - // for now limit to spies with EXPR as the only column - // Because the interpreter looks down the rows until it finds one that's "true" then stops, the order - // of rows cant't be modified. This means only rows next to each other can be merged. - // This makes for very large Rpn strings - turn on later when we have better redundancy reduction in RPNs -#if defined(__LATER__) - Rpn r_expr("EXPR", iv_symbols); - row = iv_spyv_rpn.size(); - if ((row > 1) && (iv_col_vars.size() == 1) && (iv_col_vars.front() == r_expr)) - { - --row; - do - { - size_t row1 = row - 1; - - if (iv_spyv_rpn.at(row) == iv_spyv_rpn.at(row1)) - { - if (iv_range_list.size() == 0 || (iv_range_list.at(row) == iv_range_list.at(row1))) - { - // merge - Rpn * rp = new Rpn(iv_cols_rpn.back().at(row)); - iv_cols_rpn.back().at(row1).push_merge(rp, Rpn::OR); // this will delete rp - iv_spyv_rpn.erase(iv_spyv_rpn.begin() + row); - if (iv_range_list.size()) iv_range_list.erase(iv_range_list.begin() + row); - for (COL_LIST::iterator i = iv_cols_rpn.begin(); i != iv_cols_rpn.end(); ++i) - { - i->erase(i->begin() + row); - } - dbg << "ROW " << row+1 << " and " << row1+1 << " have been merged in " << get_key_name() << endl; - } - } - } while (--row); - } -#endif -} - - - -//------------------------------------------------------------------------------------------------- - -bool Scom::compare(Scom & that) -{ - bool result = false; //true; -// TODO -#if 0 - ostringstream oss; - oss << hex << setfill('0'); - // spyname(s) should have already been tested - oss << get_key_name() << endl; - if(iv_spy_type != that.iv_spy_type || - iv_when != that.iv_when || - iv_spy_length != that.iv_spy_length || - iv_spy_offset != that.iv_spy_offset || - iv_array_addr != that.iv_array_addr) - { - result = false; - oss << "type: " << setw(8) << iv_spy_type << ' ' << that.iv_spy_type << endl; - oss << "when: " << setw(8) << iv_when << ' ' << that.iv_when << endl; - oss << "len: " << setw(8) << iv_spy_length << ' ' << that.iv_spy_length << endl; - oss << "offset: " << setw(8) << iv_spy_offset << ' ' << that.iv_spy_offset << endl; - oss << "array: " << setw(8) << iv_array_addr << ' ' << that.iv_array_addr << endl; - } - // need to expand all Rpns to verify resolution of vars and lits - // when Rpn - string rpn1 = iv_when_rpn.listing("",iv_spy_names.front(),false); - string rpn2 = that.iv_when_rpn.listing("",iv_spy_names.front(),false); - if(rpn1 != rpn2) - { - result = false; - oss << "this when Rpn:" << endl << rpn1 << endl; - oss << "that when Rpn:" << endl << rpn2 << endl; - } - - // spyv Rpn - if(iv_spyv_rpn.size() != that.iv_spyv_rpn.size()) - { - result = false; - oss << "this spyv Rpn(s):" << endl; - for(RPN_LIST::iterator r1 = iv_spyv_rpn.begin(); r1 != iv_spyv_rpn.end(); ++r1) - oss << r1->listing("",iv_spy_names.front(),false) << endl; - oss << "that spyv Rpn(s):" << endl; - for(RPN_LIST::iterator r1 = that.iv_spyv_rpn.begin(); r1 != that.iv_spyv_rpn.end(); ++r1) - oss << r1->listing("",iv_spy_names.front(),false) << endl; - } - else - { - RPN_LIST::iterator r1 = iv_spyv_rpn.begin(); - RPN_LIST::iterator r2 = that.iv_spyv_rpn.begin(); - for(; r1 != iv_spyv_rpn.end(); ++r1, ++r2) - { - rpn1 = r1->listing("",iv_spy_names.front(),false); - rpn2 = r2->listing("",iv_spy_names.front(),false); - if(rpn1 != rpn2) - { - result = false; - oss << "this spyv Rpn:" << endl << rpn1 << endl; - oss << "that spyv Rpn:" << endl << rpn2 << endl; - } - } - } - - // column names - if(iv_col_vars.size() != that.iv_col_vars.size()) - { - result = false; - oss << "this col names:" << endl; - for(RPN_LIST::iterator i = iv_col_vars.begin(); i != iv_col_vars.end(); ++i) - { - oss << i->symbol_names() << endl; - } - oss << "that col names:" << endl; - for(RPN_LIST::iterator i = that.iv_col_vars.begin(); i != that.iv_col_vars.end(); ++i) - { - oss << i->symbol_names() << endl; - } - } - else - { - RPN_LIST::iterator i = iv_col_vars.begin(); - RPN_LIST::iterator j = that.iv_col_vars.begin(); - for(;i != iv_col_vars.end(); ++i, ++j) - { - //string s1 = iv_symbols->find_name(*i); - //string s2 = that.iv_symbols->find_name(*j); - if((*i) != (*j)) - { - result = false; - oss << "this col name: " << i->symbol_names() << endl; - oss << "that col name: " << j->symbol_names() << endl; - } - } - } - - // row Rpns - Rpn r1(iv_symbols); - Rpn r2(that.iv_symbols); - for(COL_LIST::iterator c = iv_cols_rpn.begin(); c != iv_cols_rpn.end(); ++c) - { - for(RPN_LIST::iterator r = c->begin(); r != c->end(); ++r) - { - r1.append(*r); - } - } - for(COL_LIST::iterator c = that.iv_cols_rpn.begin(); c != that.iv_cols_rpn.end(); ++c) - { - for(RPN_LIST::iterator r = c->begin(); r != c->end(); ++r) - { - r2.append(*r); - } - } - rpn1 = r1.listing("",iv_spy_names.front(),false); - rpn2 = r2.listing("",iv_spy_names.front(),false); - if(rpn1 != rpn2) - { - result = false; - oss << "this row/col rpn:" << endl; - oss << rpn1 << endl; - oss << "that row/col rpn:" << endl; - oss << rpn2 << endl; - } - - if(!result) cout << oss.str(); -#endif - return result; -} - - -//================================================================================================= -// SpyList Class definitions -//================================================================================================= - -ScomList::ScomList(const string & initfile, FILELIST & defines, ostream & stats, uint32_t i_ec) - : - iv_syntax_version(0), - iv_symbols(new Symbols(defines)), - iv_stats(stats), - iv_ec(i_ec) - -{ - yyscomlist = this; - - // What type of input? text(*.initfile) or binary(*.if) ? - size_t pos = initfile.rfind('.'); - string type; - if(pos != string::npos) - { - type = initfile.substr(pos+1); - } - - if(type.compare(0,8,"initfile") == 0) // source is text *.initfile - { - char line[100]; - string first_line; - yyin = fopen(initfile.c_str(), "r"); - if(!yyin) - { - string ers("ERROR: ScomList::ScomList: Could not open initfile: "); - ers.append(initfile); - throw invalid_argument(ers); - } - - // In Syntax version 1 the first or second line contains the CVS version - fgets(line,100,yyin); - first_line = line; - fgets(line,100,yyin); - first_line.append(line); - yyline = 3; - - dbg << "======================= Begin Parse ========================" << endl; - yyparse(); // Parse the initfile - dbg << "======================= End Parse ==========================" << endl; - - if(iv_syntax_version == 1) - { - // example pattern ..... $Id: galaxy.initfile,v 5.0 ...... - size_t pos = first_line.find("$Id:"); - if(pos != string::npos) - { - istringstream iss(first_line.substr(pos+4)); - string tok; - iss >> tok; // ex. galaxy.initfile,v - iss >> tok; // ex. 5.0 - iv_cvs_versions = tok; // just want the version number - eg '5.0' - } - } - - iv_stats << '*' << setw(20) << "lines:" << setw(6) << yyline-1 << endl; - iv_stats << '*' << setw(20) << "Scom statements:" << setw(6) << iv_scom_list.size() << endl; - // TODO num var/lits num lits found - } - else if(type.compare(0,2,"if") == 0) // source is binary *.if file - { -// TODO - No support for this currently -#if 0 - dbg << "======================= Begin Uncompiling ========================" << endl; - - BINSEQ bin_seq; - ifstream ifs(initfile.c_str(), ios_base::in | ios_base::binary); - if(!ifs) - { - string msg("ERROR: SpyList::Could not open "); - msg.append(initfile); - throw invalid_argument(msg); - } - while(1) - { - int ch = ifs.get(); - if (!(ifs.good())) break; - bin_seq.push_back(ch); - } - ifs.close(); - - // Turn this back into a list of spies - BINSEQ::const_iterator bli = bin_seq.begin(); - BINSEQ::const_iterator b; - - iv_syntax_version = Rpn::extract32(bli); - bli += 8; - if(iv_syntax_version == 1) - { - for(b = bli-8; (b != bli) && (*b); ++b) - { - iv_cvs_versions.push_back(*b); - } - } - else - { - // offset to CVS sub version section - b = bin_seq.begin() + Rpn::extract32(bli); - size_t size = Rpn::extract16(b); - while(size--) iv_cvs_versions.push_back(*b++); - } - - b = bin_seq.begin() + Rpn::extract32(bli); - iv_symbols->restore_var_bseq(b); - - b = bin_seq.begin() + Rpn::extract32(bli); - iv_symbols->restore_lit_bseq(b); - - size_t section_count = Rpn::extract32(bli); - if(section_count > LAST_WHEN_TYPE) - { - throw range_error("ERROR: SpyList::SpyList - Inalid # of sections"); - } - - for(size_t i = 0; i < section_count; ++i) - { - size_t spy_type = Rpn::extract32(bli); // type - size_t offset = Rpn::extract32(bli); // offset - size_t count = Rpn::extract32(bli); // Number of spies - - b = bin_seq.begin() + offset; - if(!(b < bin_seq.end())) - { - throw overflow_error("ERROR: SpyList::SpyList - iterator overflowed sequence"); - } - if(spy_type > LAST_WHEN_TYPE || spy_type == 0) - { - throw range_error("ERROR: SpyList::SpyList - when= type out of range"); - } - while(count--) - { - Scom * s = new Scom(b,iv_symbols); - insert(s); - s->set_when((SPY_WHEN)spy_type); - } - } -#endif - dbg << "======================= End Uncompiling ========================" << endl; - } - else - { - ostringstream ess; - ess << "ERROR: SpyList::SpyList Invalid file type: " << type; - ess << "\n source: " << initfile; - throw invalid_argument(ess.str()); - } -} - -//------------------------------------------------------------------------------------------------- - -ScomList::~ScomList() -{ - delete iv_symbols; -} - -//------------------------------------------------------------------------------------------------- - -void ScomList::clear() -{ - for(SCOM_LIST::iterator i = iv_scom_list.begin(); i != iv_scom_list.end(); ++i) delete i->second; - iv_scom_list.clear(); -} - -//------------------------------------------------------------------------------------------------- - -void ScomList::set_syntax_version(uint32_t v) -{ - if(v != 1 && v != 2) yyerror("ScomList:: set_syntax_version: Invalid Syntax Version"); - iv_syntax_version = v; -} - -//------------------------------------------------------------------------------------------------- - -void ScomList::compile(BINSEQ & bin_seq) -{ - uint32_t count_s = 0; - uint32_t section_count = 0; - size_t offset = 0; - - - BINSEQ blist_v; // vars - BINSEQ blist_i; // lits - BINSEQ blist_l; // when=L spies - BINSEQ blist_s; // when=S spies - BINSEQ blist_c; // when=C spies - BINSEQ blist_d; // when=D spies - - // Make the BINSEQs big enough to hopefully never have to resize - blist_v.reserve(0x00400); - blist_i.reserve(0x02000); - blist_l.reserve(0x30000); - blist_s.reserve(0x03000); - blist_c.reserve(0x03000); - blist_d.reserve(0x03000); - - - dbg << "======================== Begin compile ============================" << endl; - Rpn::set32(bin_seq,iv_syntax_version); // bytes[0:3] - - // bytes [4:12] - if(iv_syntax_version == 2) - { - const char * s = "SEE SUBV"; - for(; *s != 0; ++s) bin_seq.push_back(*s); - istringstream iss(iv_cvs_versions); - string vers; - while(iss >> vers) - { - stats << '*' << setw(20) << "Version:" << " " << vers << endl; - } - } - else if (iv_syntax_version == 1) - { - if(iv_cvs_versions.size()) - { - size_t len = iv_cvs_versions.size(); - if(len > 8) { iv_cvs_versions.erase(9); len = 8; } - for(string::const_iterator s = iv_cvs_versions.begin(); - s != iv_cvs_versions.end(); ++s) - { - bin_seq.push_back(*s); - } - while(len < 8) { bin_seq.push_back(0); ++len; } - stats << '*' << setw(20) << "Version:" << setw(6) << iv_cvs_versions << endl; - } - else - { - throw range_error("ERROR: ScomList::compile: No CVS version(s) specified"); - } - } - else // syntax version already validated to be 1 or 2 - so if we get here it was never set. - { - throw range_error("ERROR: ScomList::compile: No syntax version specified!"); - } - stats << '*' << setw(20) << "Syntax Version:" << setw(6) << iv_syntax_version << endl; - - - // Determine the number of scoms in each section - - for(SCOM_LIST::iterator i = iv_scom_list.begin(); i != iv_scom_list.end(); ++i) - { - // Filter out filtered spies dg003a - if(!(i->second->valid_when(dbg,iv_ec))) - { - continue; - } - - count_s += i->second->bin_listing(blist_s); - - } - if(count_s) ++section_count; - - // 28 bytes of File Header Data - offset = 28; - stats << '*' << setw(20) << "Sections:" << setw(6) << section_count << endl; - - // for verion 2 add offset to CVS versions section - if(iv_syntax_version == 2) - { - offset += 4; - Rpn::set32(bin_seq,offset); - offset += iv_cvs_versions.length() + 2; - } - // offset now points to start of Var Symbol Table - - iv_symbols->bin_vars(blist_v); // get Var table - iv_symbols->bin_lits(blist_i); // Get Lit table - - Rpn::set32(bin_seq,offset); // Offset to Variable Symbol Table - offset += blist_v.size(); // offset += var table byte size - Rpn::set32(bin_seq,offset); // Offset to Literal Symbol Table - offset += blist_i.size(); // offset += lit table byte size - - //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 - } - - if(iv_syntax_version == 2) // Add Sub-version section - { - Rpn::set16(bin_seq,(uint16_t)iv_cvs_versions.length()); // Length of Sub version - bin_seq.insert(bin_seq.end(), iv_cvs_versions.begin(), iv_cvs_versions.end()); - } - - bin_seq.insert(bin_seq.end(), blist_v.begin(), blist_v.end()); // add var table section - bin_seq.insert(bin_seq.end(), blist_i.begin(), blist_i.end()); // add lit table section - - 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; - dbg << "======================== End compile ============================" << endl; -} - -//------------------------------------------------------------------------------------------------- - -bool Scom::valid_when(ostream & msg, uint32_t i_ec) //dg002a dg003c -{ - bool result = true; - - // unconditional state was determined earlier - if( iv_when_rpn.isTrue()) // unconditionally true - Rpn is not needed. - iv_when_rpn.clear(); - else if( iv_when_rpn.isFalse()) //unconditionally false - result = false; - else if(i_ec != 0xffffffff) - { - if(iv_when_rpn.resolve_ec(i_ec) == false) result = false; - } -#if 0 - if(result == false) - { - msg << hex; - SPY_NAMES::iterator i = iv_spy_names.begin(); - // if more than one spyname, the first is just the stem of the name - skip it - if(iv_spy_names.size() > 1) ++i; - - for(; i != iv_spy_names.end(); ++i) - { - if(i_ec != 0xffffffff) - msg << "For EC " << i_ec << ": "; - - msg << "Removing spy " << *i << endl; - } - msg << iv_when_rpn.listing("WHEN RPN","",true) << endl; - } -#endif - return result; -} - -//------------------------------------------------------------------------------------------------- - -void ScomList::listing(BINSEQ & bin_seq,ostream & olist) -{ - dbg << "======================= Begin Listing ========================" << endl; - - BINSEQ::const_iterator bli = bin_seq.begin(); - BINSEQ::const_iterator b; - uint32_t syntax_version = Rpn::extract32(bli); - - string cvs_versions; - - olist << hex << setfill('0'); - olist << "--------------- FILE HEADER ------------------------\n\n"; - olist << fmt8(syntax_version) << "[Syntax Version]\n" - << "0x"; - bli += 8; - for(b = bli-8; b != bli; ++b) olist << setw(2) << (uint32_t)(*b); - olist << " ["; - for(b = bli-8; b != bli; ++b) if((*b) != 0) olist << (char)(*b); - olist << "]\t[CVS Version]\n"; - if(syntax_version == 2) - { - size_t offset = Rpn::extract32(bli); - olist << fmt8(offset) << "[Offset to Sub-Version Section]\n"; - } - - uint32_t var_table_offset = Rpn::extract32(bli); - uint32_t lit_table_offset = Rpn::extract32(bli); - - olist << fmt8(var_table_offset) << "[Offset to Attribute Symbol Table]\n"; - olist << fmt8(lit_table_offset) << "[Offset to Literal Symbol Table]\n"; - - - b = bin_seq.begin() + var_table_offset; - iv_symbols->restore_var_bseq(b); - - b = bin_seq.begin() + lit_table_offset; - iv_symbols->restore_lit_bseq(b); - - b = bli; // save - - size_t offset = Rpn::extract32(bli); // offset - size_t count = Rpn::extract32(bli); // Number of spies - - olist << fmt8(offset) << "[Scom Section Offset]\n"; - olist << fmt8(count) << "[Number of scoms]\n"; - - olist << endl; - - if(syntax_version == 2) - { - olist << "--------------- Sub Version Section ---------------\n\n"; - uint16_t len = Rpn::extract16(bli); - olist << "0x" << setw(4) << len << "\t\t" - << "Length of Sub Version Section\n\n"; - for(uint16_t i = 0; i < len; ++i) olist << (char)(*bli++); - olist << endl; - } - - if (yytarget.size()) - { - olist << "------------------- TARGET MAPPING ------------------------\n\n" - << endl; - std::map<string,string>::iterator i; - for (i = yytarget.begin(); i != yytarget.end(); i++) - { - olist << i->first << setfill(' ') << setw(30 - i->first.length()) - << " = " << i->second << endl; - } - } - - olist << iv_symbols->listing() << endl; - - if (count) - { - olist << "------------------- SCOM TABLES ------------------------\n\n" - << endl; - - bli = b; // restore - - olist << "------------ Scoms -----------\n\n"; - - b = bin_seq.begin() + offset; - if(!(b < bin_seq.end())) - { - throw overflow_error("ERROR: ScomList::listing: iterator overflowed sequence"); - } - - 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; - - uint64_t l_addr = s->get_address_hex(); - //cout << "ScomList::listing: iv_scom_address_hex 0x" << hex << l_addr << endl; - - //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; - - uint32_t l_length = s->get_scom_length(); - - //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; - - //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(); - - //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; - } - else - { - ostringstream oss; - oss << "ScomList::listing: Duplicate scom statements found: " - "Address 0x" << hex << l_addr << endl; - throw invalid_argument(oss.str()); - } - } - - //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; -} - -//------------------------------------------------------------------------------------------------- - -void ScomList::attr_listing(BINSEQ & bin_seq,ostream & olist) -{ - olist << iv_symbols->attr_listing(); -} - -//------------------------------------------------------------------------------------------------- - -string ScomList::fmt8(uint32_t val) -{ - ostringstream oss; - oss << setfill('0'); - oss << "0x" << hex << setw(8) << val << "\t " << '[' << dec << val << ']' << '\t'; - if(val < 1000) oss << '\t'; - return oss.str(); -} - - -//------------------------------------------------------------------------------------------------- - -void ScomList::insert(Scom * i_scom) -{ - uint64_t l_addr = i_scom->get_address(); - iv_scom_list.insert(pair<uint64_t, Scom *>(l_addr, i_scom)); -} - -//------------------------------------------------------------------------------------------------- - -bool ScomList::compare(ScomList & that) -{ - bool result = true; - dbg << "======================= Begin Compare ========================" << endl; - if(iv_scom_list.size() != that.iv_scom_list.size()) - { - cout << "E> Lists are not the same size" << endl; - result = false; - } - - // check each spy section - for(SCOM_LIST::iterator i = iv_scom_list.begin(); i != iv_scom_list.end(); ++i) - { - // The name checks spyname, arrayaddr (if array), bitrange(s) (if any) - uint64_t l_addr = i->second->get_address(); - SCOM_LIST::iterator j = that.iv_scom_list.find(l_addr); - if(j == that.iv_scom_list.end()) - { - cout << "E> " << l_addr << " not found in both lists!" << endl; - result = false; - continue; - } - if(i->second->compare(*(j->second)) == false) - { - cout << "E> Spy: " << l_addr << " does not match!" << endl; - result = false; - } - } - - // check for spies in that that are not in this - for(SCOM_LIST::iterator i = that.iv_scom_list.begin(); i != that.iv_scom_list.end(); ++i) - { - uint64_t l_addr = i->second->get_address(); - SCOM_LIST::iterator j = iv_scom_list.find(l_addr); - if(j == iv_scom_list.end()) - { - cout << "E> " << l_addr << " not found in both lists!" << endl; - result = false; - } - } - dbg << "======================= End Compare ========================" << endl; - return result; -} - -//------------------------------------------------------------------------------------------------- - -//------------------------------------------------------------------------------------------------- - -void Scom::set_scom_address(const string & i_scom_addr) -{ - - if(iv_scom_addr.size()) - { - yyerror("Scom::set_scom_address: SCOM Address already set!"); - } - else - { - iv_scom_addr.push_back(i_scom_addr); - // cout << "I>Scom::set_scom_address: " << i_scom_addr << " is the output string!" << endl; - } -} - -//------------------------------------------------------------------------------------------------- - - -void Scom::dup_scom_address(const string & i_scom_addr) -{ - // cout << "I>Scom::dup_scom_address: "<< i_scom_addr << " is the output string!" << endl; - - //If we have a range of values - size_t l_pos = i_scom_addr.find(".."); - if (l_pos != string::npos) - { - // Convert the range specified to decimal values and check for valid range - uint64_t l_num1 = strtoull((i_scom_addr.substr(0,l_pos)).c_str(), NULL, 16); - uint64_t l_num2 = strtoull((i_scom_addr.substr(l_pos + 2)).c_str(), NULL, 16); - // cout << "I>Scom:dup_scom_address: " << l_num1 << " - " << l_num2 << endl; - if (l_num1 >= l_num2) - { - std::ostringstream oss; - oss << "Scom::dup_scom_address: Invalid scom address range: " << i_scom_addr; - yyerror(oss.str().c_str()); - } - - for (uint64_t num = l_num1; num <= l_num2; num++) - { - // For each value within the range, create a hex string of the correct size - string l_scom_addr = dec2hexString(num, l_pos); - - if (iv_scom_addr.size() == 0) - { - // If there are no base address, create the duplicate addresses by pushing back - // each value within the range - iv_dup_scom_addr.push_back(l_scom_addr); - // cout << "I>Scom::dup_scom_address: iv_dup_scom_addr" << iv_dup_scom_addr.back() << endl; - } - else - { - // If there are base addresses, create the dupicate addresses by appending each - // value within the range to the base addresses. - for (size_t i = 0; i < iv_scom_addr.size(); i++) - { - iv_dup_scom_addr.push_back(iv_scom_addr.at(i) + l_scom_addr); - // cout << "I>Scom::dup_scom_address: iv_dup_scom_addr " << iv_dup_scom_addr.back() << endl; - } - } - } - } - // Else we have a single value - else - { - // If there are no base address, create the duplicate address by pushing back the specified - // value - if (iv_scom_addr.size() == 0) - { - iv_dup_scom_addr.push_back(i_scom_addr); - // cout << "I>Scom::dup_scom_address: iv_dup_scom_addr " << iv_dup_scom_addr.back() << endl; - } - else - { - // If there are base addresses, create the dupicate addresses by appending the - // specified value to the base addresses. - for (size_t i = 0; i < iv_scom_addr.size(); i++) - { - iv_dup_scom_addr.push_back(iv_scom_addr.at(i) + i_scom_addr); - // cout << "I>Scom::dup_scom_address: iv_dup_scom_addr " << iv_dup_scom_addr.back() << endl; - } - } - } -} - -//------------------------------------------------------------------------------------------------- - -void Scom::copy_dup_scom_address() -{ - // cout << "I>Scom::copy_dup_scom_address: iv_scom_addr size "<< iv_scom_addr.size() - // << " iv_dup_scom_addr size " << iv_dup_scom_addr.size() << endl; - - iv_scom_addr.clear(); - iv_scom_addr = iv_dup_scom_addr; - iv_dup_scom_addr.clear(); - - // cout << "I>Scom::copy_dup_scom_address: iv_scom_addr size "<< iv_scom_addr.size() - // << " iv_dup_scom_addr size " << iv_dup_scom_addr.size() << endl; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::set_scom_suffix(const string & i_scom_addr) -{ - - if(iv_scom_addr.size() == 0) - { - std::ostringstream oss; - oss << "Scom::set_scom_suffix: No base scom address to append suffix " << i_scom_addr; - yyerror(oss.str().c_str()); - } - else - { - // cout << "I>Scom::set_scom_suffix: iv_scom_addr size " << iv_scom_addr.size() << endl; - for(size_t i = 0; i < iv_scom_addr.size(); ++i) - { - // cout << "I>Scom::set_scom_suffix: iv_scom_addr " << iv_scom_addr.at(i) << endl; - iv_scom_addr.at(i) = iv_scom_addr.at(i) + i_scom_addr; - // cout << "I>Scom::set_scom_suffix: iv_scom_addr appended " << iv_scom_addr.at(i) << endl; - } - } - - // cout << "I>Scom::set_scom_suffix: "<< i_scom_addr << " is the output string!" << endl; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::set_scom_address_bin(const string & i_scom_addr) -{ - - if(iv_scom_addr_bin.size()) - { - yyerror("Scom::set_scom_address_bin: Binary SCOM Address already set!"); - } - else - { - iv_scom_addr_bin.push_back(i_scom_addr); - } - - // cout << "I>Scom::set_scom_address_bin: " << i_scom_addr << " is the output string!" << endl; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::dup_scom_address_bin(const string & i_scom_addr) -{ - // cout << "I>Scom::dup_scom_address_bin: "<< i_scom_addr << " is the output string!" << endl; - - //If we have a range of values - size_t l_pos = i_scom_addr.find(".."); - if (l_pos != string::npos) - { - // Convert the range specified to decimal values and check for valid range - uint64_t l_num1 = strtoull((i_scom_addr.substr(0,l_pos)).c_str(), NULL, 2); - uint64_t l_num2 = strtoull((i_scom_addr.substr(l_pos + 2)).c_str(), NULL, 2); - // cout << "I>Scom:dup_scom_address_bin: " << l_num1 << " - " << l_num2 << endl; - if (l_num1 >= l_num2) - { - std::ostringstream oss; - oss << "Scom::dup_scom_address_bin: Invalid binary scom address range: " - << i_scom_addr; - yyerror(oss.str().c_str()); - } - - for (uint64_t num = l_num1; num <= l_num2; num++) - { - // For each value within the range, create a binary string of the correct size - string l_scom_addr = dec2binString(num, l_pos); - - if (iv_scom_addr_bin.size() == 0) - { - // If there are no base address, create the duplicate addresses by pushing back - // each value within the range - iv_dup_scom_addr_bin.push_back(l_scom_addr); - // cout << "I>Scom::dup_scom_address_bin: iv_dup_scom_addr_bin " << iv_dup_scom_addr_bin.back() << endl; - } - else - { - // If there are base addresses, create the dupicate addresses by appending each - // value within the range to the base addresses. - for (size_t i = 0; i < iv_scom_addr_bin.size(); i++) - { - iv_dup_scom_addr_bin.push_back(iv_scom_addr_bin.at(i) + l_scom_addr); - // cout << "I>Scom::dup_scom_address_bin: iv_dup_scom_addr_bin " << iv_dup_scom_addr_bin.back() << endl; - } - } - } - } - // Else we have a single value - else - { - // If there are no base address, create the duplicate address by pushing back the specified - // value - if (iv_scom_addr_bin.size() == 0) - { - iv_dup_scom_addr_bin.push_back(i_scom_addr); - // cout << "I>Scom::dup_scom_address_bin: iv_dup_scom_addr_bin " << iv_dup_scom_addr_bin.back() << endl; - } - else - { - // If there are base addresses, create the dupicate addresses by appending the - // specified value to the base addresses. - for (size_t i = 0; i < iv_scom_addr_bin.size(); i++) - { - iv_dup_scom_addr_bin.push_back(iv_scom_addr_bin.at(i) + i_scom_addr); - // cout << "I>Scom::dup_scom_address_bin: iv_dup_scom_addr_bin " << iv_dup_scom_addr_bin.back() << endl; - } - } - } -} - -//------------------------------------------------------------------------------------------------- - -void Scom::copy_dup_scom_address_bin() -{ - // cout << "I>Scom::copy_dup_scom_address_bin: iv_scom_addr_bin size "<< iv_scom_addr_bin.size() - // << " iv_dup_scom_addr_bin size " << iv_dup_scom_addr_bin.size() << endl; - - iv_scom_addr_bin.clear(); - iv_scom_addr_bin = iv_dup_scom_addr_bin; - iv_dup_scom_addr_bin.clear(); - - // cout << "I>Scom::copy_dup_scom_address_bin: iv_scom_addr_bin size "<< iv_scom_addr_bin.size() - // << " iv_dup_scom_addr_bin size " << iv_dup_scom_addr_bin.size() << endl; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::set_scom_suffix_bin(const string & i_scom_addr) -{ - - if(iv_scom_addr_bin.size() == 0) - { - std::ostringstream oss; - oss << "Scom::set_scom_suffix_bin: No base binary scom address to append suffix " - << i_scom_addr; - yyerror(oss.str().c_str()); - } - else - { - for(size_t i = 0; i < iv_scom_addr_bin.size(); ++i) - { - iv_scom_addr_bin.at(i) = iv_scom_addr_bin.at(i) + i_scom_addr; - } - } - - // cout << "I>Scom::set_scom_suffix_bin: "<< i_scom_addr << " is the output string!" << endl; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::append_scom_address_bin() -{ - for (size_t i = 0; i < iv_scom_addr_bin.size(); i++) - { - if (0 != (iv_scom_addr_bin.at(i).size() % 4)) - { - std::ostringstream oss; - oss << "Scom::append_scom_address_bin: Binary scom address " - << iv_scom_addr_bin.at(i) << " is a partial hex!"; - yyerror(oss.str().c_str()); - break; - } - else - { - // Duplicate the scom addresses - uint64_t l_num = strtoull(iv_scom_addr_bin.at(i).c_str(), NULL, 2); - string l_scom_addr = dec2hexString(l_num, iv_scom_addr_bin.at(i).size() / 4); - dup_scom_address(l_scom_addr); - } - } - - if (iv_dup_scom_addr.size()) - { - // Copy duplicate scom addresses to the base scom addresses - copy_dup_scom_address(); - iv_scom_addr_bin.clear(); - } -} - -//------------------------------------------------------------------------------------------------- -string Scom::dec2hexString(uint64_t i_num, size_t i_str_size) -{ - stringstream l_ss; - l_ss.width(i_str_size); // Set string width - l_ss.fill('0'); // Prefill with '0' - l_ss << hex << i_num; - - return l_ss.str(); -} - -//------------------------------------------------------------------------------------------------- -string Scom::dec2binString(uint64_t i_num, size_t i_str_size) -{ - size_t l_size = sizeof(i_num) * 8; - char l_buf[l_size]; - size_t l_idx = l_size; - - do - { - l_buf[--l_idx] = '0' + (i_num & 1); - i_num >>= 1; - } while (--i_str_size); - - return string(l_buf + l_idx, l_buf + l_size); -} - -string Scom::addr_listing() -{ - std::stringstream l_ss; - l_ss << "\t\t\tSCOM Addresses" << endl; - //l_ss << std::hex << std::setfill('0'); - - for (size_t i = 0; i < iv_scom_addr.size(); i++) - { - //l_ss << "0x" << std::setw(16) << op_id << "\t\t" << OP_TXT[op_id] << std::endl; - l_ss << iv_scom_addr.at(i) << endl; - } - return l_ss.str(); -} |