diff options
Diffstat (limited to 'src/usr/diag/prdf/common/rule/prdrCompile.C')
-rw-r--r-- | src/usr/diag/prdf/common/rule/prdrCompile.C | 525 |
1 files changed, 525 insertions, 0 deletions
diff --git a/src/usr/diag/prdf/common/rule/prdrCompile.C b/src/usr/diag/prdf/common/rule/prdrCompile.C new file mode 100644 index 000000000..67f417fbf --- /dev/null +++ b/src/usr/diag/prdf/common/rule/prdrCompile.C @@ -0,0 +1,525 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/common/rule/prdrCompile.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] 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 */ + +#include <map> +#include <list> +#include <vector> +#include <stack> +#include <fstream> + +// It is important to limit what is included here. We don't want to include +// files that include external components such as the errl or targeting code. +// Otherwise, we will pull in way too much code just to compile this on file. +#include <attributeenums.H> // For TARGETING::TYPE enum + +// define needed to enable x86 rule parser code only +#define __PRD_RULE_COMPILE +#include <prdrCommon.H> +#include <prdrToken.H> +#include <UtilHash.H> +#include <prdfEnums.H> + +using namespace PRDR_COMPILER; + +int yyline; +std::stack<std::pair<std::string, int> > yyincfiles; + +namespace PRDR_COMPILER +{ + +Chip * g_currentChip; // the current chip +std::map<std::string, Expr *> g_rules; // list of rules. +std::map<std::string, Group *> g_groups; // list of bit groups +std::map<std::string, Group *> g_actionclasses; // list of actions +std::map<std::string, std::string> g_attentionStartGroup; + +// Internal list of references, to make sure every reference resolved. +std::list<std::pair<std::string, std::string> > g_references; + +Prdr::HashCollisionMap g_groupHashCollision; +Prdr::HashCollisionMap g_regsHashCollision; + +// Used in error reference outputting. +uint32_t g_nextAndBit; +bool g_hadError; + +} // end namespace PRDR_COMPILER + +//-------------------------------------------- +// main +//-------------------------------------------- +int main(int argc, char ** argv) +{ + if (argc != 2) + { + std::cerr << "No destination file given." << std::endl; + exit(-1); + } + + FILE * l_prfFile = fopen(argv[1], "w+"); + if (NULL == l_prfFile) + { + std::cerr << "Error opening file for output." << std::endl; + exit(-1); + } + + std::ofstream l_htmlFile((std::string(argv[1]) + ".html").c_str()); + std::ofstream l_errFile((std::string(argv[1]) + ".err.C").c_str()); + std::ofstream l_regFile((std::string(argv[1]) + ".reg.C").c_str()); + +#ifndef __HOSTBOOT_MODULE + // Get Backing build or sandbox name. + std::string l_backingBuild(getenv("SANDBOXBASE")); + l_backingBuild = l_backingBuild.substr(l_backingBuild.find_last_of('/')+1); +#else + std::string l_backingBuild("HOSTBOOT"); +#endif + + // setup HTML headers. + l_htmlFile << "<HTML><HEAD><STYLE type=\"text/css\">" << std::endl; + l_htmlFile << "TABLE { border-collapse: collapse; border: solid; " + << "border-width: 3px; " + << "margin-left: auto; margin-right: auto; width: 100% }" + << std::endl; + l_htmlFile << "TH { border: solid; border-width: thin; padding: 3px }" + << std::endl; + l_htmlFile << "TD { border: solid; border-width: thin; padding: 3px }" + << std::endl; + l_htmlFile << "</STYLE>" << std::endl; + + // setup error signature file. + l_errFile << "#include <prdrErrlPluginsSupt.H>" << std::endl; + l_errFile << "PRDR_ERROR_SIGNATURE_TABLE_START "; + + // setup register id file. + l_regFile << "#include <prdrErrlPluginsSupt.H>" << std::endl; + l_regFile << "PRDR_REGISTER_ID_TABLE_START "; + + yyline = 1; // current line is 1. + g_currentChip = NULL; // initialize current chip. + + uint16_t l_size; + + // parse standard input. + yyparse(); + + // verify references. + prdrCheckReferences(); + + // output chip. + if (NULL != g_currentChip) + { + g_currentChip->output(l_prfFile); + g_currentChip->outputRegisterFile(l_regFile); + //g_currentChip->print(); + } + else + { + yyerror("No chip define!"); + exit(1); + } + + l_htmlFile << "<TITLE> PRD Table: " + << g_currentChip->cv_name->substr(1, + g_currentChip->cv_name->length()-2) + << "</TITLE>" + << std::endl; + l_htmlFile << "</HEAD><BODY>" << std::endl; + + // output rules. + l_size = htons((uint16_t)g_rules.size()); + PRDR_FWRITE(&l_size, sizeof(l_size), 1, l_prfFile); + for (std::map<std::string, Expr *>::iterator i = g_rules.begin(); + i != g_rules.end(); + i++) + { + (*i).second->output(l_prfFile); + }; + + // set error register HOM_TYPE + l_errFile << "( 0x" << std::hex << g_currentChip->cv_targetType << ", 0x" + << std::hex << g_currentChip->cv_signatureOffset + << " )" << std::endl; + + // output bit groups + uint32_t l_pos = 0; + l_size = htons((uint16_t)g_groups.size()); + PRDR_FWRITE(&l_size, sizeof(l_size), 1, l_prfFile); + l_size = htons((uint16_t)prdrGetRefId(&g_attentionStartGroup["CHECK_STOP"])); + PRDR_FWRITE(&l_size, sizeof(l_size), 1, l_prfFile); + l_size = htons((uint16_t)prdrGetRefId(&g_attentionStartGroup["RECOVERABLE"])); + PRDR_FWRITE(&l_size, sizeof(l_size), 1, l_prfFile); + l_size = htons((uint16_t)prdrGetRefId(&g_attentionStartGroup["SPECIAL"])); + PRDR_FWRITE(&l_size, sizeof(l_size), 1, l_prfFile); + //@jl02 JL Adding this code to account for the new Attention entry type. + l_size = htons((uint16_t)prdrGetRefId(&g_attentionStartGroup["UNIT_CS"])); // @jl02 + PRDR_FWRITE(&l_size, sizeof(l_size), 1, l_prfFile); // @jl02 + + l_htmlFile << "<H2> Register Groups </H2>" << std::endl; + l_htmlFile << "Generated from " << l_backingBuild << "<BR>" << std::endl; + + for (std::map<std::string, Group *>::iterator i = g_groups.begin(); + i != g_groups.end(); + i++, l_pos++) + { + (*i).second->output(l_prfFile); + (*i).second->generateDoxygen(l_htmlFile, (*i).first, l_errFile); + } + + // output action classes. + l_size = htons((uint16_t)g_actionclasses.size()); + PRDR_FWRITE(&l_size, sizeof(l_size), 1, l_prfFile); + + l_htmlFile << "<H2> Actions </H2>" << std::endl; + l_htmlFile << "Generated from " << l_backingBuild << "<BR>" << std::endl; + l_htmlFile << "<TABLE>" << std::endl; + l_htmlFile << "<TR><TH> Action Class </TH> " + << "<TH> Description </TH> " + << "<TH> Actions </TH></TR>" << std::endl; + + for (std::map<std::string, Group *>::iterator i = + g_actionclasses.begin(); + i != g_actionclasses.end(); + i++) + { + (*i).second->output(l_prfFile); + (*i).second->generateDoxygen(l_htmlFile, (*i).first); + } + + l_htmlFile << "</TABLE>" << std::endl; + + fclose(l_prfFile); + + l_htmlFile << "</HTML>"; + l_htmlFile.close(); + + // Add chip's extra signatures. + l_errFile << "//---- Extra Signatures ----" << std::endl; + for (std::list<ExtraSignature>::iterator i + = g_currentChip->cv_sigExtras.begin(); + i != g_currentChip->cv_sigExtras.end(); + i++) + { + l_errFile << "\tPRDR_ERROR_SIGNATURE ( 0x" + << std::setfill('0') << std::setw(8) << std::hex + << i->iv_sig << ", " << *(i->iv_sname) << ", " + << *(i->iv_desc) << ")" << std::endl; + } + + l_errFile << "PRDR_ERROR_SIGNATURE_TABLE_END" << std::endl; + l_errFile.close(); + + l_regFile << "PRDR_REGISTER_ID_TABLE_END" << std::endl; + l_regFile.close(); + + return (g_hadError ? -1 : 0); +}; + +namespace PRDR_COMPILER +{ + +std::map<std::string, uint32_t> g_refId; +std::map<std::string, char> g_refType; + +uint16_t prdrGetRefId(std::string * i_name) +{ + if (NULL == i_name) + { + yyerror("ICE - NPE."); + return 0; + } + + uint32_t l_refId = g_refId[*i_name]; + + //fprintf(stderr, "%s: %08x\n", i_name->c_str(), l_refId); + return l_refId; +}; + +char prdrGetRefType(std::string * i_name) +{ + if (NULL == i_name) + { + yyerror("ICE - NPE."); + return 0; + } + + char l_refType = g_refType[*i_name]; + + return l_refType; +}; + +void prdrCheckReferences() +{ + do + { + uint32_t l_refId = 1; + + if (NULL == g_currentChip) + break; + + for (RegisterList::iterator i = g_currentChip->cv_reglist.begin(); + i != g_currentChip->cv_reglist.end(); + i++) + { + g_refId[*(*i)->cv_sname] = l_refId++; + g_refType[*(*i)->cv_sname] = Prdr::REF_REG; + } + + for (std::map<std::string, Expr *>::iterator i = g_rules.begin(); + i != g_rules.end(); + i++) + { + g_refId[(*i).first] = l_refId++; + g_refType[(*i).first] = Prdr::REF_RULE; + } + + for (std::map<std::string, Group *>::iterator i = g_groups.begin(); + i != g_groups.end(); + i++) + { + g_refId[(*i).first] = l_refId++; + g_refType[(*i).first] = Prdr::REF_GRP; + } + + for (std::map<std::string, Group *>::iterator i = + g_actionclasses.begin(); + i != g_actionclasses.end(); + i++) + { + g_refId[(*i).first] = l_refId++; + g_refType[(*i).first] = Prdr::REF_ACT; + } + + for (std::list<std::pair<std::string, std::string> >::iterator i = + g_references.begin(); + i != g_references.end(); + i++) + { + if (std::string::npos == (*i).first.find(g_refType[(*i).second])) + { + if (char() == g_refType[(*i).second]) + { + std::string l_tmp = "Undefined reference for "; + l_tmp += (*i).second; + yyerror(l_tmp.c_str()); + } + else + { + std::string l_tmp = "Bad reference type: expected "; + l_tmp += (*i).first + " but found "; + l_tmp += g_refType[(*i).second]; + l_tmp += " for " + (*i).second; + yyerror(l_tmp.c_str()); + } + } + } + + } while (false); + return; +}; + +std::list<std::string> prdrParseDoxygen(std::string & i_string) +{ + std::list<std::string> l_result; + + std::string l_input = i_string; + std::string l_tmp; + + for (int i = 0; i < 2; i++) // grab title and short desc. + { + std::string::size_type l_pos = l_input.find('\n'); + l_result.push_back(l_input.substr(0, l_pos)); + l_input.erase(0,l_pos+1); + } + l_result.push_back(l_input); // push long desc. + + return l_result; +}; + +uint32_t prdrCaptureGroupMap( const std::string & i_arg ) +{ + if ( 0 == i_arg.compare("never") ) + { + return 0; + } + else if ( 0 == i_arg.compare("default") ) + { + return 1; + } + else + { + uint16_t hash = PRDF::Util::hashString( i_arg.c_str() ); + Prdr::HashCollisionMap::iterator i = g_groupHashCollision.find(hash); + if ( g_groupHashCollision.end() != i ) + { + if ( 0 != i_arg.compare(i->second) ) + { + g_hadError = true; // Compile error + + std::cerr << "Capture Group hash collision '" << i_arg << "' " + << std::hex << "[0x" + << std::setfill('0') << std::setw(4) + << hash << "]" + << ": previous group was '" << i->second << "'" + << std::endl; + } + } + g_groupHashCollision[hash] = i_arg; + + return hash; + } +} + +uint32_t prdrCaptureTypeMap(const std::string & i_arg) +{ + if ("primary" == i_arg) + return 1; + if ("secondary" == i_arg) + return 2; + return 1; +} + +} // end namespace PRDR_COMPILER + +#include <prdfCalloutMap.H> // for enums +#undef __prdfCalloutMap_H +#define PRDF_RULE_COMPILER_ENUMS +#include <prdfCalloutMap.H> // for string-to-enum arrays +#undef PRDF_RULE_COMPILER_ENUMS + +namespace PRDR_COMPILER +{ + +std::map<std::string, uint32_t> g_ActionArgMap; + +uint32_t prdrActionArgMap(const std::string & i_arg) +{ + using namespace PRDF; + using namespace std; + + static bool l_initialized = false; + + do + { + if (l_initialized) + break; + + // Initialize Callout priorities. + for (CalloutPriority_t * i = calloutPriorityArray; NULL != i->str; i++) + { + g_ActionArgMap[i->str] = i->val; + } + + // Initialize target types. + g_ActionArgMap["TYPE_PROC"] = TARGETING::TYPE_PROC; + g_ActionArgMap["TYPE_NX"] = TARGETING::TYPE_NX; + g_ActionArgMap["TYPE_EX"] = TARGETING::TYPE_EX; + g_ActionArgMap["TYPE_XBUS"] = TARGETING::TYPE_XBUS; + g_ActionArgMap["TYPE_ABUS"] = TARGETING::TYPE_ABUS; + g_ActionArgMap["TYPE_PCI"] = TARGETING::TYPE_PCI; + g_ActionArgMap["TYPE_MCS"] = TARGETING::TYPE_MCS; + g_ActionArgMap["TYPE_MEMBUF"] = TARGETING::TYPE_MEMBUF; + g_ActionArgMap["TYPE_L4"] = TARGETING::TYPE_L4; + g_ActionArgMap["TYPE_MBA"] = TARGETING::TYPE_MBA; + g_ActionArgMap["TYPE_OCC"] = TARGETING::TYPE_OCC; + g_ActionArgMap["TYPE_PSI"] = TARGETING::TYPE_PSI; + g_ActionArgMap["TYPE_NA"] = TARGETING::TYPE_NA; + + // Initialize symbolic callouts. + for ( SymCallout_t * i = symCalloutArray; NULL != i->str; i++ ) + { + g_ActionArgMap[i->str] = i->val; + } + + // Initialize SDC Flags. + // FIXME: RTC 119976 + // Not quite happy with the way this is implemented. + // Would like to move the macros to another file like we + // did with prdfCalloutMap.H, but will need to do this later. + #define PRDF_SDC_FLAGS_MAP_ONLY + #define PRDF_SDC_FLAGS_MAP + #define PRDF_SDC_FLAG(name, value) \ + g_ActionArgMap[#name] = value; + #define PRDF_SDC_FLAGS_MAP_END + + #define PRDF_GARD_POLICY_MAP_ONLY + #define PRDF_GARD_POLICY_MAP + #define PRDF_GARD_POLICY(name, value) \ + g_ActionArgMap[#name] = value; + #define PRDF_GARD_POLICY_MAP_END + #undef iipServiceDataCollector_h + #include <iipServiceDataCollector.h> + + +#ifdef __HOSTBOOT_MODULE + //Note: Hostboot does not support dump.So,defining dump type here + //to retain common rule code for hostboot and FSP. + g_ActionArgMap["DUMP_CONTENT_SW"] = 0x80000000; + g_ActionArgMap["DUMP_CONTENT_HW"] = 0x40000000; + g_ActionArgMap["DUMP_CONTENT_SH"] = 0x20000000; + g_ActionArgMap["DUMP_CONTENT_CORE"] = 0x10000000; +#else + // Initialize Dump values. //@ecdf + #include <hdctContent.H> + #undef __hdctContent_H__ + #undef HDCT_CONTENT_T + #undef HDCT_CONTENT_V + #undef HDCT_CONTENT_T_END + #define HDCT_CONTENT_T + #define HDCT_CONTENT_V(name, value) \ + g_ActionArgMap["DUMP_" #name] = value; + #define HDCT_CONTENT_T_END + #undef HDCT_COMMAND_T + #undef HDCT_COMMAND_V + #undef HDCT_COMMAND_T_END + #define HDCT_COMMAND_T + #define HDCT_COMMAND_V(name, value) + #define HDCT_COMMAND_T_END + #include <hdctContent.H> + +#endif + + // Initialize MFG thresholds. + #define PRDF_MFGTHRESHOLD_TABLE_BEGIN + #define PRDF_MFGTHRESHOLD_TABLE_END + #define PRDF_MFGTHRESHOLD_ENTRY(a,b) \ + g_ActionArgMap[#a] = b; + #include <prdfMfgThresholdAttrs.H> + + + l_initialized = true; + + } while (false); + + if (g_ActionArgMap.end() == g_ActionArgMap.find(i_arg)) //@pw01 + { + yyerror((std::string("Undefined argument: ")+i_arg).c_str()); + } + + return g_ActionArgMap[i_arg]; +} + +} // end namespace PRDR_COMPILER + |