diff options
author | Zane Shelley <zshelle@us.ibm.com> | 2012-09-20 12:18:46 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-11-07 16:13:29 -0600 |
commit | 63aca27a47a3b60ca107c12cad8d132a0cfeb64c (patch) | |
tree | e3e38fb25b6986223f8ba8f617f04697f4801b2d /src/usr/diag/prdf/framework/rule | |
parent | 1190a8872faeac22924a4528c9fbeabdafe9fad6 (diff) | |
download | blackbird-hostboot-63aca27a47a3b60ca107c12cad8d132a0cfeb64c.tar.gz blackbird-hostboot-63aca27a47a3b60ca107c12cad8d132a0cfeb64c.zip |
Initial port of PRD to Hostboot
Change-Id: I7ee2673131d4891d482e99a403a36300b79e547e
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1853
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/diag/prdf/framework/rule')
27 files changed, 7300 insertions, 0 deletions
diff --git a/src/usr/diag/prdf/framework/rule/iipTemplates.C b/src/usr/diag/prdf/framework/rule/iipTemplates.C new file mode 100755 index 000000000..b5d7629c8 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/iipTemplates.C @@ -0,0 +1,39 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/iipTemplates.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 1996,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include <iipDomainContainer.h> +#include <iipDomainContainer.C> +#include <prdfRuleChip.H> + +template class DomainContainer<PrdfRuleChip>; + +// Change Log ********************************************************* +// +// Flag Reason Vers Date Coder Description +// ---- -------- ---- -------- -------- ------------------------------ +// DGILBERT Initial Creation +// F429488 fips 12/16/03 mkobler Added prdfMcChip template +// F494911 f310 03/04/05 iawillia Added PrdfRuleChip template. +// dg01 f300 04/05/06 dgilbert Added Domain of prdfExtensibleChip +// dg02 F557969 f310 07/05/06 dgilbert Remove obsolite parts +// End Change Log ***************************************************** diff --git a/src/usr/diag/prdf/framework/rule/makefile b/src/usr/diag/prdf/framework/rule/makefile new file mode 100755 index 000000000..56846c303 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/makefile @@ -0,0 +1,133 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/diag/prdf/framework/rule/makefile $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2012 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG + +ROOTPATH = ../../../../../.. + +RULEOBJDIR = ${ROOTPATH}/obj/modules/prdf/rule + +#------------------------------------------------------------------------------ +# Generated files +#------------------------------------------------------------------------------ +PRDR_CMP = prdrCompile +PRDR_CMP_o = ${PRDR_CMP}.o +PRDR_CMP_C = ${PRDR_CMP}.C + +PRDR_CMP_YACC = ${PRDR_CMP}.y +PRDR_CMP_YACC_o = ${PRDR_CMP_YACC}.o +PRDR_CMP_YACC_C = ${PRDR_CMP_YACC}.C +PRDR_CMP_YACC_H = ${PRDR_CMP_YACC}.H + +PRDR_CMP_FLEX = ${PRDR_CMP}.lex +PRDR_CMP_FLEX_o = ${PRDR_CMP_FLEX}.o +PRDR_CMP_FLEX_C = ${PRDR_CMP_FLEX}.C + +PRDR_CMP_PATH = ${RULEOBJDIR}/${PRDR_CMP} +PRDR_CMP_o_PATH = ${RULEOBJDIR}/${PRDR_CMP_o} + +PRDR_CMP_YACC_o_PATH = ${RULEOBJDIR}/${PRDR_CMP_YACC_o} +PRDR_CMP_YACC_C_PATH = ${RULEOBJDIR}/${PRDR_CMP_YACC_C} +PRDR_CMP_YACC_H_PATH = ${RULEOBJDIR}/${PRDR_CMP_YACC_H} + +PRDR_CMP_FLEX_o_PATH = ${RULEOBJDIR}/${PRDR_CMP_FLEX_o} +PRDR_CMP_FLEX_C_PATH = ${RULEOBJDIR}/${PRDR_CMP_FLEX_C} + +include ../../prd_ruletable.mk # for PRDR_RULE_TABLE_TARGETS + +#------------------------------------------------------------------------------- +# code_pass +#------------------------------------------------------------------------------- + +# Build the .prf image files +EXTRA_PARTS = $(addprefix ${IMGDIR}/, ${PRDR_RULE_TABLE_TARGETS}) + +# Clean up the auto generate source files +EXTRA_CLEAN = ${PRDR_CMP_PATH} \ + ${PRDR_CMP_o_PATH} \ + ${PRDR_CMP_YACC_o_PATH} \ + ${PRDR_CMP_YACC_C_PATH} \ + ${PRDR_CMP_YACC_H_PATH} \ + ${PRDR_CMP_FLEX_o_PATH} \ + ${PRDR_CMP_FLEX_C_PATH} \ + $(addprefix ${RULEOBJDIR}/, ${PRDR_RULE_TABLE_TARGETS}) + +# NOTE: All rules defined in this makefile must be done after this line +# otherwise the default rule 'all' will not be called. +include ${ROOTPATH}/config.mk + +#------------------------------------------------------------------------------- +# Build the flex/yacc source code +#------------------------------------------------------------------------------- + +${PRDR_CMP_YACC_C_PATH} ${PRDR_CMP_YACC_H_PATH}: ${PRDR_CMP_YACC} + mkdir -p ${RULEOBJDIR} + bison -d -o ${PRDR_CMP_YACC_C_PATH} $^ + +PRDR_CMP_FLEX: ; # Discard implicit rule for %.lex <- %.lex.C +${PRDR_CMP_FLEX_C_PATH}: ${PRDR_CMP_FLEX} + mkdir -p ${RULEOBJDIR} + flex -o$@ $^ + +#------------------------------------------------------------------------------ +# Build the PRD rule compiler +#------------------------------------------------------------------------------ + +USERDEFINES = -D__HOSTBOOT_MODULE -O3 -pipe + +${PRDR_CMP_YACC_o_PATH}: ${PRDR_CMP_YACC_C_PATH} ${PRDR_CMP_YACC_H_PATH} + i686-mcp6-g++ -c $(USERDEFINES) $< \ + -I ./ -I ../../util -I ${RULEOBJDIR} \ + -o $@ + +${PRDR_CMP_FLEX_o_PATH}: ${PRDR_CMP_FLEX_C_PATH} ${PRDR_CMP_YACC_H_PATH} + i686-mcp6-g++ -c $(USERDEFINES) $< \ + -I ./ -I ../../util -I ${RULEOBJDIR} \ + -o $@ + +${PRDR_CMP_o_PATH}: ${PRDR_CMP_C} + i686-mcp6-g++ -c $(USERDEFINES) $< \ + -I ./ -I ../.. -I ../../util -I ${GENDIR} -I ${RULEOBJDIR} \ + -I ../resolution -I ../service \ + -o $@ + +${PRDR_CMP_PATH}: ${PRDR_CMP_YACC_o_PATH} ${PRDR_CMP_FLEX_o_PATH} \ + ${PRDR_CMP_o_PATH} + i686-mcp6-g++ $(USERDEFINES) \ + ${PRDR_CMP_YACC_o_PATH} ${PRDR_CMP_FLEX_o_PATH} ${PRDR_CMP_o_PATH} \ + -o $@ + +#------------------------------------------------------------------------------ +# Build the .prf files +#------------------------------------------------------------------------------ + +vpath %.rule ../../plat/pegasus +PRDRPP_SEARCHDIRS = -I../../plat/pegasus + +# Build .prf files from .rule files and store them in ${RULEOBJDIR} +${RULEOBJDIR}/%.prf : %.rule ${PRDR_CMP_PATH} + cat $< | ./prdrpp ${PRDRPP_SEARCHDIRS} \ + | i686-mcp6-jail ${PRDR_CMP_PATH} $@ + +# Copy all .prf files from ${RULEOBJDIR} to ${IMGDIR} +${EXTRA_PARTS}: ${IMGDIR}/% : ${RULEOBJDIR}/% + cp -f $^ $@ + diff --git a/src/usr/diag/prdf/framework/rule/prdfGroup.C b/src/usr/diag/prdf/framework/rule/prdfGroup.C new file mode 100755 index 000000000..2b10643aa --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdfGroup.C @@ -0,0 +1,279 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdfGroup.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include <prdfGroup.H> +#include <prdfBitString.H> +#include <prdfResolutionMap.H> +#include <iipResetErrorRegister.h> +#include <prdfMain.H> +#include <iipServiceDataCollector.h> + +PrdfGroup::~PrdfGroup() +{ + RegisterList_t::const_iterator l_errRegsEnd = cv_errRegs.end(); + for (RegisterList_t::const_iterator i = cv_errRegs.begin(); + i != l_errRegsEnd; + ++i) + { + delete *i; + } + + ResMaps_t::const_iterator l_resMapsEnd = cv_resMaps.end(); + for (ResMaps_t::const_iterator i = cv_resMaps.begin(); + i != l_resMapsEnd; + ++i) + { + delete (ResolutionMap *)(*i).second; + } + + // Delete filters. + FilterList_t::const_iterator l_filterEnd = cv_filters.end(); + for (FilterList_t::const_iterator i = cv_filters.begin(); + i != l_filterEnd; + ++i) + { + delete (*i); + } +} + +int32_t PrdfGroup::Analyze(STEP_CODE_DATA_STRUCT & i_step) +{ + using namespace PRDF; + int32_t l_rc = -1; + ServiceDataCollector l_backupStep(*i_step.service_data); + int32_t l_tmpRC = SUCCESS; + + RegisterList_t::const_iterator l_errRegsEnd = cv_errRegs.end(); + for (RegisterList_t::const_iterator i = cv_errRegs.begin(); + (i != l_errRegsEnd) && (l_rc != SUCCESS); + ++i) + { + (*i_step.service_data) = l_backupStep; + l_tmpRC = (*i)->Analyze(i_step); + + if (PRD_SCAN_COMM_REGISTER_ZERO != l_tmpRC) + { + l_rc = l_tmpRC; + } + } + if (PRD_SCAN_COMM_REGISTER_ZERO == l_tmpRC) + { + l_rc = l_tmpRC; + } + + if (0 == cv_errRegs.size()) + l_rc = cv_defaultRes.Resolve(i_step); + + return l_rc; +}; + +void PrdfGroup::Add(SCAN_COMM_REGISTER_CLASS * i_reg, + const uint8_t * i_bits, + size_t i_bitSize, + Resolution & i_action, + PrdfResetAndMaskPair & i_resets, + uint16_t i_scrID, + bool i_reqTranspose) +{ + prdfFilter * l_transposeFilter = NULL; + uint8_t l_bits[1] = { '\0' }; + ResolutionMap * l_res = cv_resMaps[i_reg]; + + if (NULL == l_res) + { + l_res = cv_resMaps[i_reg] = new prdfResolutionMap(1, cv_defaultRes); + ResetAndMaskErrorRegister * l_errReg = + new ResetAndMaskErrorRegister(*i_reg, *l_res, i_scrID); + cv_errRegs.push_back(l_errReg); + + // Sort reset and mask lists. + std::sort(i_resets.first.begin(), i_resets.first.end()); + std::sort(i_resets.second.begin(), i_resets.second.end()); + + // Remove duplicate resets and masks. + i_resets.first.erase( + std::unique(i_resets.first.begin(), i_resets.first.end()), + i_resets.first.end()); + i_resets.second.erase( + std::unique(i_resets.second.begin(), i_resets.second.end()), + i_resets.second.end()); + + // Add resets. + std::for_each(i_resets.first.begin(), i_resets.first.end(), + std::bind1st( + std::mem_fun(&ResetAndMaskErrorRegister::addReset), + l_errReg) + ); + + // Add masks. + std::for_each(i_resets.second.begin(), i_resets.second.end(), + std::bind1st( + std::mem_fun(&ResetAndMaskErrorRegister::addMask), + l_errReg) + ); + } + + // This action requires a transpose filter (multiple bits &'d) + if (i_reqTranspose) + { + // Create key and transposition filter. Add to filter list. + prdfBitKey l_tmpKey(i_bits, i_bitSize); + l_transposeFilter = new prdfFilterTranspose(l_tmpKey, + cv_nextBitForTranspose); + cv_filters.push_back(l_transposeFilter); + + // Update bit string pointers/values. + l_bits[0] = cv_nextBitForTranspose++; + i_bits = l_bits; + i_bitSize = 1; + + // Check for existing transposition filter, create link as needed. + if (NULL != l_res->getFilter()) + { + l_transposeFilter = new FilterLink(*l_res->getFilter(), + *l_transposeFilter); // pw01 + cv_filters.push_back(l_transposeFilter); + } + + // Assign transpose filter. + l_res->setFilter(l_transposeFilter); + } + + // Add action to resolution. + l_res->Add(i_bits, i_bitSize, &i_action); +}; + +void PrdfGroup::Add(SCAN_COMM_REGISTER_CLASS * i_reg, + Resolution & i_action, + PrdfResetAndMaskPair & i_resets, + uint16_t i_scrID) +{ + ResolutionMap * l_res = cv_resMaps[i_reg]; + + if (NULL == l_res) + { + l_res = cv_resMaps[i_reg] = new prdfResolutionMap(1, cv_defaultRes); + ResetAndMaskErrorRegister * l_errReg = + new ResetAndMaskErrorRegister(*i_reg, *l_res, i_scrID); + cv_errRegs.push_back(l_errReg); + + // Sort reset and mask lists. + std::sort(i_resets.first.begin(), i_resets.first.end()); + std::sort(i_resets.second.begin(), i_resets.second.end()); + + // Remove duplicate resets and masks. + i_resets.first.erase( + std::unique(i_resets.first.begin(), i_resets.first.end()), + i_resets.first.end()); + i_resets.second.erase( + std::unique(i_resets.second.begin(), i_resets.second.end()), + i_resets.second.end()); + + // Add resets. + std::for_each(i_resets.first.begin(), i_resets.first.end(), + std::bind1st( + std::mem_fun(&ResetAndMaskErrorRegister::addReset), + l_errReg) + ); + + // Add masks. + std::for_each(i_resets.second.begin(), i_resets.second.end(), + std::bind1st( + std::mem_fun(&ResetAndMaskErrorRegister::addMask), + l_errReg) + ); + } + + l_res->ReplaceDefaultWith(i_action); + +}; + +void PrdfGroup::AddFilter(prdfFilter * i_filter) +{ + // Add to filter list, for deallocation later. + cv_filters.push_back(i_filter); + + // Iterate through all resolution maps. + for(ResMaps_t::const_iterator i = cv_resMaps.begin(); + i != cv_resMaps.end(); + i++) + { + // Get old filter. + prdfFilter * l_filter = ((ResolutionMap *)(*i).second)->getFilter(); + + // Need new filter link? + if (NULL != l_filter) + { + // Use original filters first. (we add transposes first.) + l_filter = new FilterLink(*l_filter, + *i_filter); // pw01 + + // Add to filter list, for deallocation later. + cv_filters.push_back(l_filter); + } + else + { + l_filter = i_filter; + } + + // Assign filter to resolution map. + ((ResolutionMap *)(*i).second)->setFilter(l_filter); + } +} + + + +const BIT_STRING_CLASS & PrdfGroup::Read(ATTENTION_TYPE i_attn) +{ + static BIT_STRING_BUFFER_CLASS a(64); + return a; +}; + +BIT_LIST_CLASS PrdfGroup::Filter(const BIT_STRING_CLASS & i) +{ + return BIT_LIST_CLASS(); +}; + +int32_t PrdfGroup::Lookup(STEP_CODE_DATA_STRUCT & i_step, BIT_LIST_CLASS & b) +{ + return -1; +}; + +int32_t PrdfGroup::Reset(const BIT_LIST_CLASS & b, STEP_CODE_DATA_STRUCT & i_step) +{ + return -1; +}; + +// Change Log ********************************************************* +// +// Flag Reason Vers Date Coder Description +// ---- -------- ---- -------- -------- ------------------------------- +// F494911 f310 03/04/05 iawillia Initial File Creation +// F510901 f300 07/15/05 iawillia Add support for resets/masks. +// D520844 f300 09/14/05 iawillia Add destructor to free memory. +// D515833 f300 09/19/05 iawillia Use VMap instead of Map. +// F544848 f300 04/03/06 iawillia Add multi-bit support. +// F548507 f300 04/21/06 iawillia Prevent multiple reset/masks. +// F557408 f310 06/16/06 iawillia Add single-bit filter support. +// pw01 D568068 f310 08/29/06 iawillia Fix filter order. +// End Change Log ***************************************************** diff --git a/src/usr/diag/prdf/framework/rule/prdfGroup.H b/src/usr/diag/prdf/framework/rule/prdfGroup.H new file mode 100755 index 000000000..4bf12ab0a --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdfGroup.H @@ -0,0 +1,113 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdfGroup.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDFGROUP_H +#define __PRDFGROUP_H + +#include <iipErrorRegisterType.h> +#include <iipResetErrorRegister.h> +#include <map> +#include <utility> // for pair + +#include <vector> +#include <prdfFilters.H> + +// forward decls +class Resolution; +class ResolutionMap; +class SCAN_COMM_REGISTER_CLASS; +class ErrorRegister; +// end forward decls + +typedef std::pair<ResetAndMaskErrorRegister::ResetRegisterVector, + ResetAndMaskErrorRegister::ResetRegisterVector> + PrdfResetAndMaskPair; + +/*class PrdfResetAndMaskPair + : public std::pair<ResetAndMaskErrorRegister::ResetRegisterVector, + ResetAndMaskErrorRegister::ResetRegisterVector> + {};*/ + +class PrdfGroup : public ErrorRegisterType +{ + public: + PrdfGroup(Resolution & i_default) + : cv_nextBitForTranspose(64), cv_defaultRes(i_default) {}; + + ~PrdfGroup(); + + int32_t Analyze(STEP_CODE_DATA_STRUCT &); + + void Add(SCAN_COMM_REGISTER_CLASS *, + const uint8_t *, + size_t, + Resolution &, + PrdfResetAndMaskPair &, + uint16_t, // SCRID. + bool + ); // add standard action. + + void Add(SCAN_COMM_REGISTER_CLASS * i_reg, + Resolution & i_action, + PrdfResetAndMaskPair &, + uint16_t i_scrID); // add default action. + + void AddFilter(prdfFilter * i_filter); + + /** + * No Filters applied by this Error Register - so undo is no-op + */ + virtual bool FilterUndo(prdfBitKey & i_bit_list) { return false; } + + protected: + const BIT_STRING_CLASS & Read(ATTENTION_TYPE i_attn); + BIT_LIST_CLASS Filter(const BIT_STRING_CLASS &); + int32_t Lookup(STEP_CODE_DATA_STRUCT &, BIT_LIST_CLASS &); + int32_t Reset(const BIT_LIST_CLASS &, STEP_CODE_DATA_STRUCT &); + + typedef std::vector<ErrorRegister *> RegisterList_t; + typedef std::vector<prdfFilter *> FilterList_t; + + typedef std::map<SCAN_COMM_REGISTER_CLASS *, ResolutionMap *> ResMaps_t; + ResMaps_t cv_resMaps; + RegisterList_t cv_errRegs; + FilterList_t cv_filters; + uint8_t cv_nextBitForTranspose; + Resolution & cv_defaultRes; + +}; + + +#endif + +// Change Log ********************************************************* +// +// Flag Reason Vers Date Coder Description +// ---- -------- ---- -------- -------- ------------------------------- +// F494911 f310 03/04/05 iawillia Initial File Creation +// F510901 f300 07/15/05 iawillia Add support for resets/masks. +// D520844 f300 09/14/05 iawillia Add destructor to free memory. +// D515833 f300 09/19/05 iawillia Use VMap instead of Map. +// F544848 f300 04/03/06 iawillia Add multi-bit support. +// F557408 f310 06/16/06 iawillia Add single-bit filter support. +// End Change Log ***************************************************** diff --git a/src/usr/diag/prdf/framework/rule/prdfPluginDef.H b/src/usr/diag/prdf/framework/rule/prdfPluginDef.H new file mode 100755 index 000000000..3b03d01b7 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdfPluginDef.H @@ -0,0 +1,368 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdfPluginDef.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDFPLUGINDEF_H +#define __PRDFPLUGINDEF_H + +#include <stdint.h> + +#ifdef __HOSTBOOT_MODULE + #include <stdlib.h> +#else + #include <cstdlib> +#endif + +namespace PrdfPluginDef +{ + class ParameterList + { + }; + + template <typename _A> + class SingleParameter : public ParameterList + { + private: + _A cv_value; + + public: + SingleParameter(_A v) : cv_value(v) {}; + operator _A() { return cv_value; }; + }; + + template <typename _A> + inline SingleParameter<_A> * + bindParm(_A v) { return new SingleParameter<_A>(v); }; + + template <typename _A, typename _B> + class TwoParameter : public ParameterList + { + private: + _A cv_valueA; + _B cv_valueB; + + public: + TwoParameter(_A vA, _B vB) : cv_valueA(vA), cv_valueB(vB) {}; + _A getA() { return cv_valueA; }; + _B getB() { return cv_valueB; }; + }; + + template <typename _A, typename _B> + inline TwoParameter<_A, _B> * + bindParm(_A vA, _B vB) { return new TwoParameter<_A,_B>(vA,vB); }; + + template <typename _A, typename _B, typename _C> + class ThreeParameter : public ParameterList + { + private: + _A cv_valueA; + _B cv_valueB; + _C cv_valueC; + + public: + ThreeParameter(_A vA, _B vB, _C vC) + : cv_valueA(vA), cv_valueB(vB), cv_valueC(vC) {}; + _A getA() { return cv_valueA; }; + _B getB() { return cv_valueB; }; + _C getC() { return cv_valueC; }; + }; + + template <typename _A, typename _B, typename _C> + inline ThreeParameter<_A, _B, _C> * + bindParm(_A vA, _B vB, _C vC) + { return new ThreeParameter<_A,_B,_C>(vA,vB,vC); }; + + template <typename _A, typename _B, typename _C, typename _D> + class FourParameter : public ParameterList + { + private: + _A cv_valueA; + _B cv_valueB; + _C cv_valueC; + _D cv_valueD; + + public: + FourParameter(_A vA, _B vB, _C vC, _D vD) + : cv_valueA(vA), cv_valueB(vB), cv_valueC(vC), + cv_valueD(vD) + {}; + _A getA() { return cv_valueA; }; + _B getB() { return cv_valueB; }; + _C getC() { return cv_valueC; }; + _D getD() { return cv_valueD; }; + }; + + template <typename _A, typename _B, typename _C, typename _D> + inline FourParameter<_A, _B, _C, _D> * + bindParm(_A vA, _B vB, _C vC, _D vD) + { return new FourParameter<_A,_B,_C,_D>(vA,vB,vC,vD); }; + + +}; + +class PrdfExtensibleFunctionType +{ + public: + virtual ~PrdfExtensibleFunctionType() {}; +}; + +template <typename _ExtensibleObject> +class PrdfExtensibleFunction : public PrdfExtensibleFunctionType +{ + public: + virtual ~PrdfExtensibleFunction() { } // zs01 + virtual int32_t operator()(_ExtensibleObject * A, + PrdfPluginDef::ParameterList * B) = 0; +}; + +class PrdfExtensibleChip; +class PrdfExtensibleDomain; +typedef PrdfExtensibleFunction<PrdfExtensibleChip> PrdfExtensibleChipFunction; +typedef PrdfExtensibleFunction<PrdfExtensibleDomain> + PrdfExtensibleDomainFunction; + + +template <typename _ExtensibleObject> +class PrdfPlugin : public PrdfExtensibleFunction<_ExtensibleObject> +{ + protected: + int32_t (*_func)(_ExtensibleObject *, PrdfPluginDef::ParameterList *); + public: + explicit PrdfPlugin(int32_t (*func)(_ExtensibleObject *, + PrdfPluginDef::ParameterList *)) + : _func(func) {}; + + int32_t operator()(_ExtensibleObject * A, + PrdfPluginDef::ParameterList * B) + { + int32_t i = 0; + if (NULL != _func) + { + i = _func(A,B); + } + delete B; + return i; + }; +}; + +template <typename _ExtensibleObject> +class PrdfPlugin_0arg : public PrdfExtensibleFunction<_ExtensibleObject> +{ + protected: + int32_t (*_func)(_ExtensibleObject *); + public: + explicit PrdfPlugin_0arg(int32_t (*func)(_ExtensibleObject *)) + : _func(func) {}; + + int32_t operator()(_ExtensibleObject * A, + PrdfPluginDef::ParameterList * B) + { + int32_t i = _func(A); + delete B; + return i; + }; +}; + +template <typename _ExtensibleObject> +inline PrdfPlugin_0arg<_ExtensibleObject> + bind_plugin(int32_t (*func)(_ExtensibleObject *)) + { return PrdfPlugin_0arg<_ExtensibleObject>(func); }; + +template <typename _ExtensibleObject> +inline PrdfPlugin_0arg<_ExtensibleObject> * + bind_plugin_ptr(int32_t (*func)(_ExtensibleObject *), void * ptr) + { return new (ptr) PrdfPlugin_0arg<_ExtensibleObject>(func); }; + +template <typename _A, typename _ExtensibleObject> +class PrdfPlugin_1arg : public PrdfExtensibleFunction<_ExtensibleObject> +{ + protected: + int32_t (*_func)(_ExtensibleObject *, _A); + public: + explicit PrdfPlugin_1arg(int32_t (*func)(_ExtensibleObject *, _A)) + : _func(func) {}; + + int32_t operator()(_ExtensibleObject * A, + PrdfPluginDef::ParameterList * B) + { + int32_t i = _func(A, + (_A)static_cast<PrdfPluginDef::SingleParameter<_A> &>(*B)); + delete B; + return i; + }; +}; + +template <typename _A, typename _ExtensibleObject> +inline PrdfPlugin_1arg<_A, _ExtensibleObject> + bind_plugin(int32_t (*func)(_ExtensibleObject *, _A)) + { return PrdfPlugin_1arg<_A, _ExtensibleObject>(func); }; + +template <typename _A, typename _ExtensibleObject> +inline PrdfPlugin_1arg<_A, _ExtensibleObject> * + bind_plugin_ptr(int32_t (*func)(_ExtensibleObject *, _A), void * ptr) + { return new (ptr) PrdfPlugin_1arg<_A, _ExtensibleObject>(func); }; + + +template <typename _A, typename _B, typename _ExtensibleObject> +class PrdfPlugin_2arg : public PrdfExtensibleFunction<_ExtensibleObject> +{ + protected: + int32_t (*_func)(_ExtensibleObject *, _A, _B); + public: + explicit PrdfPlugin_2arg(int32_t (*func)(_ExtensibleObject *, _A, _B)) + : _func(func) {}; + + int32_t operator()(_ExtensibleObject * A, + PrdfPluginDef::ParameterList * B) + { + int32_t i = _func(A, + static_cast<PrdfPluginDef::TwoParameter<_A,_B> *>(B)->getA(), + static_cast<PrdfPluginDef::TwoParameter<_A,_B> *>(B)->getB()); + delete B; + return i; + }; +}; + +template <typename _A, typename _B, typename _ExtensibleObject> +inline PrdfPlugin_2arg<_A, _B, _ExtensibleObject> + bind_plugin(int32_t (*func)(_ExtensibleObject *, _A, _B)) + { return PrdfPlugin_2arg<_A, _B, _ExtensibleObject>(func); }; + +template <typename _A, typename _B, typename _ExtensibleObject> +inline PrdfPlugin_2arg<_A, _B, _ExtensibleObject> * + bind_plugin_ptr(int32_t (*func)(_ExtensibleObject *, _A, _B), void * ptr) + { return new (ptr) PrdfPlugin_2arg<_A, _B, _ExtensibleObject>(func); }; + + +template <typename _A, typename _B, typename _C, typename _ExtensibleObject> +class PrdfPlugin_3arg : public PrdfExtensibleFunction<_ExtensibleObject> +{ + protected: + int32_t (*_func)(_ExtensibleObject *, _A, _B, _C); + public: + explicit PrdfPlugin_3arg(int32_t (*func) + (_ExtensibleObject *, _A, _B, _C)) + : _func(func) {}; + + int32_t operator()(_ExtensibleObject * A, + PrdfPluginDef::ParameterList * B) + { + int32_t i = _func(A, + static_cast<PrdfPluginDef::ThreeParameter<_A,_B,_C> *> + (B)->getA(), + static_cast<PrdfPluginDef::ThreeParameter<_A,_B,_C> *> + (B)->getB(), + static_cast<PrdfPluginDef::ThreeParameter<_A,_B,_C> *> + (B)->getC() + ); + delete B; + return i; + }; +}; + +template <typename _A, typename _B, typename _C, typename _ExtensibleObject> +inline PrdfPlugin_3arg<_A, _B, _C, _ExtensibleObject> + bind_plugin(int32_t (*func)(_ExtensibleObject *, _A, _B, _C)) + { return PrdfPlugin_3arg<_A, _B, _C, _ExtensibleObject>(func); }; + +template <typename _A, typename _B, typename _C, typename _ExtensibleObject> +inline PrdfPlugin_3arg<_A, _B, _C, _ExtensibleObject> * + bind_plugin_ptr(int32_t (*func)(_ExtensibleObject *, _A, _B, _C), + void * ptr) + { return new (ptr) + PrdfPlugin_3arg<_A, _B, _C, _ExtensibleObject>(func); }; + +template <typename _A, typename _B, typename _C, typename _D, + typename _ExtensibleObject> +class PrdfPlugin_4arg : public PrdfExtensibleFunction<_ExtensibleObject> +{ + protected: + int32_t (*_func)(_ExtensibleObject *, _A, _B, _C, _D); + public: + explicit PrdfPlugin_4arg(int32_t (*func) + (_ExtensibleObject *, _A, _B, _C, _D)) + : _func(func) {}; + + int32_t operator()(_ExtensibleObject * A, + PrdfPluginDef::ParameterList * B) + { + int32_t i = _func(A, + static_cast<PrdfPluginDef::FourParameter<_A,_B,_C,_D> *> + (B)->getA(), + static_cast<PrdfPluginDef::FourParameter<_A,_B,_C,_D> *> + (B)->getB(), + static_cast<PrdfPluginDef::FourParameter<_A,_B,_C,_D> *> + (B)->getC(), + static_cast<PrdfPluginDef::FourParameter<_A,_B,_C,_D> *> + (B)->getD() + ); + delete B; + return i; + }; +}; + +template <typename _A, typename _B, typename _C, typename _D, + typename _ExtensibleObject> +inline PrdfPlugin_4arg<_A, _B, _C, _D, _ExtensibleObject> + bind_plugin(int32_t (*func)(_ExtensibleObject *, _A, _B, _C, _D)) + { return PrdfPlugin_4arg<_A, _B, _C, _D, _ExtensibleObject>(func); }; + +template <typename _A, typename _B, typename _C, typename _D, + typename _ExtensibleObject> +inline PrdfPlugin_4arg<_A, _B, _C, _D, _ExtensibleObject> * + bind_plugin_ptr(int32_t (*func)(_ExtensibleObject *, _A, _B, _C, _D), + void * ptr) + { return new (ptr) + PrdfPlugin_4arg<_A, _B, _C, _D, _ExtensibleObject>(func); }; + + +#define __PRDF_PLUGIN_XYZ(X,Y,Z) X##Y##Z +#define __PRDF_PLUGIN_MAKENAME(X,Y,Z) __PRDF_PLUGIN_XYZ(X,Y,Z) + +#define PRDF_PLUGIN_DEFINE(CHIP,PLUGIN_NAME) \ + class __PRDF_PLUGIN_MAKENAME(PrdfPlugin_Registration_,CHIP,PLUGIN_NAME) \ + { \ + private: \ + PrdfExtensibleFunctionType * cv_plugin; \ + PrdfPluginRegisterClass cv_registerClass; \ + char cv_plugin_space[sizeof(PrdfPlugin<PrdfExtensibleChip>)]; \ + public: \ + __PRDF_PLUGIN_MAKENAME(PrdfPlugin_Registration_,CHIP,PLUGIN_NAME)() : \ + cv_plugin( bind_plugin_ptr(&PRDF::CHIP::PLUGIN_NAME, \ + &cv_plugin_space) ), \ + cv_registerClass(#CHIP,#PLUGIN_NAME,cv_plugin) \ + {} \ + }; \ + __PRDF_PLUGIN_MAKENAME(PrdfPlugin_Registration_,CHIP,PLUGIN_NAME) \ + __PRDF_PLUGIN_MAKENAME(g_PluginRegistration_,CHIP,PLUGIN_NAME) +#endif + +#include <prdfPluginMap.H> + +// Change Log ********************************************************* +// +// Flag Reason Vers Date Coder Description +// ---- -------- ---- -------- -------- ------------------------------- +// F494911 f310 03/04/05 iawillia Initial File Creation +// F522638 f300 09/27/05 iawillia Add 4 parm, fix possible obj strip. +// zs01 D620028 f330 07/25/07 zshelle Support for mcp5 compiler +// End Change Log ***************************************************** diff --git a/src/usr/diag/prdf/framework/rule/prdfPluginMap.C b/src/usr/diag/prdf/framework/rule/prdfPluginMap.C new file mode 100755 index 000000000..a2dfa838e --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdfPluginMap.C @@ -0,0 +1,53 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdfPluginMap.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2005,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include <prdfPluginMap.H> + +PrdfPluginGlobalMap & prdfGetPluginGlobalMap() +{ + static PrdfPluginGlobalMap g_globalPluginMap; + return g_globalPluginMap; +}; + +void PrdfPluginGlobalMap::registerPlugin(const char * i_chipName, + const char * i_pluginName, + PrdfExtensibleFunctionType * i_plugin) +{ + this->cv_globalMap[i_chipName][i_pluginName] = i_plugin; +}; + +PrdfPluginMap & PrdfPluginGlobalMap::getPlugins(const char * i_chipName) +{ + return this->cv_globalMap[i_chipName]; +}; + +PrdfPluginRegisterClass::PrdfPluginRegisterClass( + const char * i_chipName, + const char * i_pluginName, + PrdfExtensibleFunctionType * i_plugin) +{ + prdfGetPluginGlobalMap().registerPlugin(i_chipName, + i_pluginName, + i_plugin); +}; + diff --git a/src/usr/diag/prdf/framework/rule/prdfPluginMap.H b/src/usr/diag/prdf/framework/rule/prdfPluginMap.H new file mode 100755 index 000000000..b9344cb1c --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdfPluginMap.H @@ -0,0 +1,75 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdfPluginMap.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2005,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDFPLUGINMAP_H +#define __PRDFPLUGINMAP_H + +#include <map> +#include <prdfPluginDef.H> +#include <string.h> +#include <functional> + +class PrdfExtensibleChip; + +/** + * @brief custom comparison functor to pass to a map container + * that uses char* as the key + */ +struct PrdfStrCompare : public std::binary_function<const char*, const char*, bool> +{ + public: + bool operator() (const char* str1, const char* str2) const + { + return strcmp(str1, str2) < 0; + } +}; + +typedef std::map<const char *, PrdfExtensibleFunctionType *, PrdfStrCompare> PrdfPluginMap; + +class PrdfPluginGlobalMap; +PrdfPluginGlobalMap & prdfGetPluginGlobalMap(); + +class PrdfPluginGlobalMap +{ + private: + std::map<const char *, PrdfPluginMap, PrdfStrCompare> cv_globalMap; + + public: + PrdfPluginGlobalMap() : cv_globalMap() {}; + + void registerPlugin(const char * i_chipName, + const char * i_pluginName, + PrdfExtensibleFunctionType * i_plugin); + + PrdfPluginMap & getPlugins(const char * i_chipName); +}; + +class PrdfPluginRegisterClass +{ + public: + PrdfPluginRegisterClass(const char * i_chipName, + const char * i_pluginName, + PrdfExtensibleFunctionType * i_plugin); +}; + +#endif diff --git a/src/usr/diag/prdf/framework/rule/prdfRuleChip.C b/src/usr/diag/prdf/framework/rule/prdfRuleChip.C new file mode 100755 index 000000000..5a0f1f5d1 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdfRuleChip.C @@ -0,0 +1,1003 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdfRuleChip.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __HOSTBOOT_MODULE + #include <utilreg.H> // for UtilReg + #include <prdfMfgThresholdMgr.H> + #include <prdfSdcFileControl.H> //for SyncAnalysis +#endif + +#include <iipglobl.h> // for SystemPtr. + +#include <prdfRuleChip.H> +#include <prdrLoadChip.H> +#include <prdrLoadChipCache.H> +#include <prdfOperatorRegister.H> +#include <prdfGroup.H> +#include <prdfPluginMap.H> +#include <prdrCommon.H> // for enums. + +#include <prdfScanFacility.H> // for ScanFacility +#include <iipResolutionFactory.h> // for ResolutionFactory +#include <iipCaptureData.h> // for CaptureData +#include <iipServiceDataCollector.h> // for ServiceDataCollector +#include <prdfErrorSignature.H> // for ErrorSignature +#include <iipResolution.h> // for Resolutions +#include <iipEregResolution.h> // for EregResolution +#include <xspprdDumpResolution.h> // for DumpResolution +#include <xspprdTryResolution.h> // for TryResolution +#include <prdfPluginCallResolution.H> // for PrdfPluginCallResolution +#include <prdfAnalyzeConnected.H> // for prdfAnalyzeConnected +#include <iipSystem.h> // for System +#include <xspprdFlagResolution.h> +#include <prdfPfa5Data.h> // for errl user data flags. + +#include <prdfPlatServices.H> // for getConnected + +#include <errlentry.H> // for errl. +#include <utilfile.H> // for UtilFile +#include <UtilHash.H> // for Util::hashString + +#include <prdfResetOperators.H> +#include <algorithm> + +template <bool Type> +struct ResetAndMaskTransformer + : public std::unary_function<Prdr::PrdrRegister::ResetOrMaskStruct, + ResetAndMaskErrorRegister::ResetRegisterStruct> +{ + ResetAndMaskTransformer(ScanFacility & i_scanFactory, + TARGETING::TargetHandle_t i_pchipHandle , + size_t i_scomlen) + : cv_scanFactory(i_scanFactory), + cv_pchipHandle (i_pchipHandle ), + cv_scomlen(i_scomlen) + {}; + + virtual ~ResetAndMaskTransformer() {}; // zs01 + + virtual ResetAndMaskErrorRegister::ResetRegisterStruct + operator()(const Prdr::PrdrRegister::ResetOrMaskStruct & i) + { + ResetAndMaskErrorRegister::ResetRegisterStruct o; + + o.read = &cv_scanFactory.GetScanCommRegister(cv_pchipHandle , + i.addr_r, + cv_scomlen); + o.write = &cv_scanFactory.GetScanCommRegister(cv_pchipHandle , + i.addr_w, + cv_scomlen); + + switch (i.op) + { + case Prdr::OR: + o.op = getStaticResetOperator<OrOperator<Type> >(); + break; + + case Prdr::AND: + o.op = getStaticResetOperator<AndOperator<Type> >(); + break; + + case Prdr::XOR: + o.op = getStaticResetOperator<XorOperator<Type> >(); + break; + + case Prdr::NOT: + o.op = getStaticResetOperator<NotOperator<Type> >(); + break; + + default: + o.op = NULL; // TODO: ERROR! Assert... + break; + } + + return o; + }; + + private: + ScanFacility & cv_scanFactory; + TARGETING::TargetHandle_t cv_pchipHandle ; + size_t cv_scomlen; +}; + + +void PrdfRuleChip::loadRuleFile(ScanFacility & i_scanFactory, + ResolutionFactory & i_reslFactory) +{ + using namespace PRDF; + + RegMap_t l_regMap; + Reset_t l_resetMap; + PrdfResetAndMaskPair l_currentResets; + uint32_t l_regMax = 0; + uint32_t l_vregMax = 0; + GroupMap_t l_groupMap; + uint32_t l_groupMax = 0; + ActionMap_t l_actionMap; + uint32_t l_actionMax = 0; + uint32_t l_id = 1; + + SharedThreshold_t l_sharedThresholds; + + Prdr::PrdrChip * l_chip; + + /* Initialize local data struct to pass to sub-functions */ + RuleFileData l_localData = { l_regMap, l_groupMap, l_actionMap, + i_scanFactory, i_reslFactory, + this->GetChipHandle(), l_chip, + l_resetMap, l_currentResets, + l_sharedThresholds + }; + + // Parse chip file. + cv_errl = Prdr::LoadChipCache::loadChip(cv_fileName, &l_chip); + if (NULL == l_chip) + { + // TODO: Do we need to percAbend? We were unable to succesfully + // load our chip objects. + return; + } + + // Get default dump type. + cv_dumpType = l_chip->cv_dumpType; + + // Set signature offset for capture data output. + iv_sigOff = l_chip->cv_signatureOffset; + + // create hardware regs. + for (int i = 0; i < l_chip->cv_regCount; i++) + { + uint16_t hashId = l_chip->cv_registers[i].cv_name; + + l_regMap[l_id] = cv_hwRegs[hashId] + = &i_scanFactory.GetScanCommRegister( + this->GetChipHandle(), + l_chip->cv_registers[i].cv_scomAddr, + l_chip->cv_registers[i].cv_scomLen ); + l_regMap[l_id]->SetId(hashId); + + // Copy reset registers. + std::transform + (l_chip->cv_registers[i].cv_resets.begin(), + l_chip->cv_registers[i].cv_resets.end(), + std::back_inserter(l_resetMap[l_id].first), + ResetAndMaskTransformer<RESETOPERATOR_RESET>( + i_scanFactory, + this->GetChipHandle(), + l_chip->cv_registers[i].cv_scomLen) + ); + + // Copy mask registers. + std::transform + (l_chip->cv_registers[i].cv_masks.begin(), + l_chip->cv_registers[i].cv_masks.end(), + std::back_inserter(l_resetMap[l_id].second), + ResetAndMaskTransformer<RESETOPERATOR_MASK>( + i_scanFactory, + this->GetChipHandle(), + l_chip->cv_registers[i].cv_scomLen) + ); + + //This flag signifies that a mapping IS or ISN'T created between a + // uint32_t mapping and a vector of SCAN_COMM_REGISTER_CLASS pointers. + //If there is no mapping outside of the for loop then it is because + // there is a capture type or requirement without a group statement in the rule file. + bool l_group_is_created = false; + // Copy into capture groups. + std::vector<Prdr::PrdrRegister::CaptureInfoStruct>::const_iterator + l_capturesEnd = l_chip->cv_registers[i].cv_captures.end(); + //For each capture in this register save a Group Type or Requirement. + for(std::vector<Prdr::PrdrRegister::CaptureInfoStruct>::const_iterator + j = l_chip->cv_registers[i].cv_captures.begin(); + j != l_capturesEnd; + ++j) + { + if ('G' == (*j).op) + { + cv_hwCaptureGroups[(*j).data[0]].push_back(l_regMap[l_id]); + l_group_is_created = true; //@jl06 Added this to indicate group was created. + } + // @jl04 a Start. + // This else if was added for a new capture "type" for registers primary/secondary. + // Cannot put the "type" in with the G group otherwise it will show up as a + // i_group of 2 which is not called. + else if('T' == (*j).op) + { + //@jl06. d Deleted temporary declaration of PrdfCaptureType in + // favor of an anonymous declaration. Calls ctor twice. + cv_hwCaptureType[l_regMap[l_id]] = + PrdfCaptureType((RegType)(*j).data[0]); //@jl06 c. + } + // @jl04 a Stop. + else if ('f' == (*j).op) + { + PrdfCaptureRequirement req; + req.cv_func = this->getExtensibleFunction(j->func); + + cv_hwCaptureReq[l_regMap[l_id]] = req; + } + else // 'C' + { + PrdfCaptureRequirement req; + req.cv_TargetType = (*j).data[0]; + req.cv_TargetIndex = (*j).data[1]; + req.cv_func = NULL; + + cv_hwCaptureReq[l_regMap[l_id]] = req; + } + } + if (!l_group_is_created) // @jl06 c Add to default group if none there. + { + // Add to default if no group specified. + cv_hwCaptureGroups[1].push_back(l_regMap[l_id]); + } + + l_regMax = l_id++; + + } + + for (int i = 0; i < l_chip->cv_ruleCount; i++) + { + if (l_regMap[l_id]) // check if it already exists. + { + l_vregMax = l_id++; + continue; + } + + l_currentResets = PrdfResetAndMaskPair(); + + SCAN_COMM_REGISTER_CLASS * l_tmp = + this->createVirtualRegister(&l_chip->cv_rules[i], l_localData); + + l_regMap[l_id] = l_tmp; + l_resetMap[l_id] = l_currentResets; + l_vregMax = l_id++; + }; + + // initialize all the pointers for the groups, but don't construct their + // data yet. + Resolution & l_defaultResolution = + i_reslFactory.GetCalloutResolution( this->GetChipHandle(), + MRU_MED ); + for (int i = 0; i < l_chip->cv_groupCount; i++) + { + PrdfGroup * l_tmp = new PrdfGroup(l_defaultResolution); + l_groupMap[l_id] = l_tmp; + l_groupMax = l_id++; + }; + + for (int i = 0; i < l_chip->cv_actionCount; i++) + { + if (l_actionMap[i]) + { + l_actionMax = l_id++; + continue; + } + + // createActionClass will add to the actionMap. + this->createActionClass(i, l_localData); + //l_actionMap[l_id] = l_tmp; + l_actionMax = l_id++; + } + + for (int i = 0; i < l_chip->cv_groupCount; i++) + { + this->createGroup((PrdfGroup *) l_groupMap[i+l_vregMax+1], + i, + l_localData); + } + for (int i = 0; i < NUM_GROUP_ATTN; i++) // @jl02 UNIT_CS Changes. JL + cv_groupAttn[i] = l_groupMap[l_chip->cv_groupAttn[i]]; + + // Call initialize plugin. + PrdfExtensibleChipFunction * l_init = getExtensibleFunction("Initialize", true); + if (NULL != l_init) + { + (*l_init) + (this, + PrdfPluginDef::bindParm<void*>(NULL) + ); + } + + return; +}; + +PrdfRuleChip::~PrdfRuleChip() +{ + if (NULL != cv_dataBundle) + { + delete cv_dataBundle; + } +}; + + +int32_t PrdfRuleChip::Analyze(STEP_CODE_DATA_STRUCT & i_serviceData, + ATTENTION_TYPE i_attnType) +{ + using namespace PRDF; + ServiceDataCollector & i_sdc = *(i_serviceData.service_data); + ErrorSignature & l_errSig = *(i_sdc.GetErrorSignature()); + CaptureData & capture = i_serviceData.service_data->GetCaptureData(); // @jl04 a Add this for Drop call. + + // Set current ATTN type to input value. + // If we don't do this, then the AttnRegisters don't work. + i_sdc.SetCauseAttentionType(i_attnType); // @pw02 @pw04 + + int32_t l_rc = SUCCESS; + + // Set Signature Chip Id. + l_errSig.setChipId( GetId() ); + + // Set default dump flags. //@ecdf + //FIXME: take out hwTableContent for now for Hostboot + #ifdef __HOSTBOOT_MODULE + i_sdc.SetDump(/*(hwTableContent)cv_dumpType,*/ GetChipHandle()); + #else + i_sdc.SetDump((hwTableContent)cv_dumpType, GetChipHandle()); + #endif + + // Get capture data for this chip. Allow override. + PrdfExtensibleChipFunction * l_ignoreCapture = + getExtensibleFunction("PreventDefaultCapture", true); + bool l_shouldPreventDefaultCapture = false; + + (*l_ignoreCapture) + (this, PrdfPluginDef::bindParm<STEP_CODE_DATA_STRUCT&, bool&> + (i_serviceData, l_shouldPreventDefaultCapture)); + + if (!l_shouldPreventDefaultCapture) + { + // Drop secondary capture from earlier chips. + capture.Drop(SECONDARY); + + // Read capture data. + this->CaptureErrorData(i_sdc.GetCaptureData()); + } + + // Analyze group. + ErrorRegisterType * l_errReg = NULL; + switch (i_attnType) + { + case CHECK_STOP: + l_errReg = cv_groupAttn[0]; + break; + + case RECOVERABLE: + l_errReg = cv_groupAttn[1]; + break; + + case SPECIAL: + l_errReg = cv_groupAttn[2]; + break; + + case UNIT_CS: // @jl02 JL Added this code to support the new Unit Check Stop. + l_errReg = cv_groupAttn[3]; // @jl02 JL I don't know if this is the correct cv_groupAttn to add here or if it's needed. + break; + + } + if (NULL != l_errReg) + { //mp02 a Start + //Call any pre analysis functions + PrdfExtensibleChipFunction * l_preAnalysis = + getExtensibleFunction("PreAnalysis", true); + bool analyzed = false; + (*l_preAnalysis)(this, + PrdfPluginDef::bindParm<STEP_CODE_DATA_STRUCT&,bool&> + (i_serviceData,analyzed)); + if ( !analyzed) + l_rc = l_errReg->Analyze(i_serviceData); + } //mp02 a Stop + // mp02d l_rc = l_errReg->Analyze(i_serviceData); + else //@jl07 + l_rc = PRD_SCAN_COMM_REGISTER_ZERO; //@jl07 + + // Don't do reset or mask on CS. @pw03 + if (CHECK_STOP != i_serviceData.service_data->GetAttentionType()) //@pw04 + { + #ifndef __HOSTBOOT_MODULE + SyncAnalysis (i_sdc); //mp01 Add call to Sync SDC + #endif + // Call mask plugin. + if (i_serviceData.service_data->IsAtThreshold()) + { + PrdfExtensibleChipFunction * l_mask = + getExtensibleFunction("MaskError", true); + (*l_mask)(this, + PrdfPluginDef::bindParm<STEP_CODE_DATA_STRUCT&>(i_serviceData) + ); //@pw01 + } + + // Call reset plugin. + PrdfExtensibleChipFunction * l_reset = + getExtensibleFunction("ResetError", true); + (*l_reset)(this, + PrdfPluginDef::bindParm<STEP_CODE_DATA_STRUCT&>(i_serviceData) + ); //@pw01 + } + + // Call postanalysis plugin. + // @jl02 JL Adding PostAnalysis plugin call. + PrdfExtensibleChipFunction * l_postanalysis = + getExtensibleFunction("PostAnalysis", true); + // @jl02 the true above means that a plugin may not exist for this call. + // @jl02 JL Adding call for post analysis. + (*l_postanalysis)(this, + PrdfPluginDef::bindParm<STEP_CODE_DATA_STRUCT&>(i_serviceData)); + + return l_rc; +}; + +int32_t PrdfRuleChip::CaptureErrorData(CaptureData & i_cap, int i_group) +{ + using namespace TARGETING; + using namespace PRDF; + + std::vector<SCAN_COMM_REGISTER_CLASS *>::const_iterator l_hwCaptureEnd = + cv_hwCaptureGroups[i_group].end(); + for (std::vector<SCAN_COMM_REGISTER_CLASS *>::const_iterator i = + cv_hwCaptureGroups[i_group].begin(); + i != l_hwCaptureEnd; + ++i) + { + // Check that requirements are satisfied. + if (PrdfCaptureRequirement() != cv_hwCaptureReq[*i]) + { + PrdfCaptureRequirement req = cv_hwCaptureReq[*i]; + if (NULL != req.cv_func) + { + bool l_cap = true; + (*req.cv_func)(this, PrdfPluginDef::bindParm<bool &>(l_cap)); + if (!l_cap) + continue; + } + else + { + bool l_indexValid =false; + TargetHandleList l_ptargetHandleList = + PlatServices::getConnected(this->GetChipHandle(), + (TARGETING::TYPE) req.cv_TargetType); + TargetHandleList ::iterator itrTarget =l_ptargetHandleList.begin(); + for( ; itrTarget != l_ptargetHandleList.end();itrTarget++ ) + { + if (req.cv_TargetIndex == PlatServices::getTargetPosition(*itrTarget)) + { + l_indexValid = true; + break; + } + } + if(false == l_indexValid) + { + continue; + } + } + } + + i_cap.Add(this->GetChipHandle(), + (*i)->GetId() ^ this->getSignatureOffset(), + *(*i), + CaptureData::BACK, //@jl04 c change this because of proto. + cv_hwCaptureType[*i].cv_regType); //@jl04 c Changed this function call to add a param. + } + + // Call "PostCapture" plugin + PrdfExtensibleChipFunction * l_postCapture = + getExtensibleFunction("PostCapture", true); + + (*l_postCapture) + (this, + PrdfPluginDef::bindParm<CaptureData &, int>(i_cap, i_group) + ); + + return SUCCESS; +} + +SCAN_COMM_REGISTER_CLASS * +PrdfRuleChip::createVirtualRegister( + Prdr::PrdrExpr * i_vReg, + RuleFileData & i_data + ) +{ + SCAN_COMM_REGISTER_CLASS * l_arg[4] = { NULL }; + uint32_t l_tmp32 = 0; + SCAN_COMM_REGISTER_CLASS * l_rc = NULL; + + switch(i_vReg->cv_op) + { + case Prdr::NOT: + l_arg[0] = createVirtualRegister(i_vReg->cv_value[0].p, i_data); + l_rc = &i_data.cv_scanFactory.GetNotRegister(*l_arg[0]); + break; + + case Prdr::LSHIFT: + case Prdr::RSHIFT: + l_arg[0] = createVirtualRegister(i_vReg->cv_value[0].p, i_data); + l_tmp32 = i_vReg->cv_value[1].p->cv_value[0].i; + l_rc = (Prdr::LSHIFT == i_vReg->cv_op + ? + &i_data.cv_scanFactory.GetLeftShiftRegister(*l_arg[0], + l_tmp32) + : + &i_data.cv_scanFactory.GetRightShiftRegister(*l_arg[0], + l_tmp32) + ); + break; + + case Prdr::OR: + case Prdr::AND: + l_arg[0] = createVirtualRegister(i_vReg->cv_value[0].p, i_data); + l_arg[1] = createVirtualRegister(i_vReg->cv_value[1].p, i_data); + l_rc = (Prdr::OR == i_vReg->cv_op + ? + &i_data.cv_scanFactory.GetOrRegister(*l_arg[0], + *l_arg[1]) + : + &i_data.cv_scanFactory.GetAndRegister(*l_arg[0], + *l_arg[1]) + ); + break; + + + case Prdr::REF_REG: + std::copy(i_data.cv_resets[i_vReg->cv_value[0].i].first.begin(), + i_data.cv_resets[i_vReg->cv_value[0].i].first.end(), + std::back_inserter(i_data.cv_currentResets.first)); + std::copy(i_data.cv_resets[i_vReg->cv_value[0].i].second.begin(), + i_data.cv_resets[i_vReg->cv_value[0].i].second.end(), + std::back_inserter(i_data.cv_currentResets.second)); + l_rc = i_data.cv_regMap[i_vReg->cv_value[0].i]; + break; + + case Prdr::REF_RULE: + if (NULL == i_data.cv_regMap[i_vReg->cv_value[0].i]) + i_data.cv_regMap[i_vReg->cv_value[0].i] = + createVirtualRegister( + &i_data.cv_loadChip-> + cv_rules[i_vReg->cv_value[0].i], + i_data); + l_rc = i_data.cv_regMap[i_vReg->cv_value[0].i]; + break; + + case Prdr::ATTNLINK: + if (NULL != i_vReg->cv_value[0].p) + l_arg[0] = createVirtualRegister(i_vReg->cv_value[0].p, i_data); + + if (NULL != i_vReg->cv_value[1].p) + l_arg[1] = createVirtualRegister(i_vReg->cv_value[1].p, i_data); + + if (NULL != i_vReg->cv_value[2].p) + l_arg[2] = createVirtualRegister(i_vReg->cv_value[2].p, i_data); + + if (NULL != i_vReg->cv_value[3].p) + l_arg[3] = createVirtualRegister(i_vReg->cv_value[3].p, i_data); + + l_rc = &i_data.cv_scanFactory.GetAttnTypeRegister(*l_arg[0], /*passing null object*/ + *l_arg[1], /*passing null object*/ + *l_arg[2], /*passing null object*/ + *l_arg[3]); /*passing null object*/ + break; + + case Prdr::BIT_STR: + { + uint32_t l_size = i_vReg->cv_bitStrVect.size(); + BIT_STRING_BUFFER_CLASS l_bs(l_size * 64); + + for (uint32_t i = 0; i < l_size; i++) + { + l_bs.SetFieldJustify(32*(2*i) , 32, + (i_vReg->cv_bitStrVect[i] >> 32) & 0xFFFFFFFF); + l_bs.SetFieldJustify(32*((2*i)+1), 32, + (i_vReg->cv_bitStrVect[i] & 0xFFFFFFFF)); + } + + l_rc = &i_data.cv_scanFactory.GetConstantRegister(l_bs); + } + break; + + } + + return l_rc; +}; + +Resolution * +PrdfRuleChip::createActionClass(uint32_t i_action, + PrdfRuleChip::RuleFileData & i_data) +{ + if (NULL != i_data.cv_actionMap[i_action]) + return i_data.cv_actionMap[i_action]; + + Resolution * l_tmpRes = NULL, * l_retRes = NULL; + for (int i = 0; i < i_data.cv_loadChip->cv_actionSize[i_action]; i++) + { + l_tmpRes = this->createResolution( + &(i_data.cv_loadChip->cv_actions[i_action][i]), + i_data); + if (0 == i) + { + l_retRes = l_tmpRes; + } + else + { + l_retRes = &i_data.cv_reslFactory. + LinkResolutions(*l_retRes, *l_tmpRes); + } + } + + if (NULL == l_retRes) // @pw05 + { + class NullResolution : public Resolution + { + public: + int32_t Resolve(STEP_CODE_DATA_STRUCT & data) + { return SUCCESS; }; + }; + + static NullResolution l_nullRes; + l_retRes = &l_nullRes; + } + + i_data.cv_actionMap[i_action] = l_retRes; + return l_retRes; +}; + +Resolution * +PrdfRuleChip::createResolution(Prdr::PrdrExpr * i_action, + PrdfRuleChip::RuleFileData & i_data) +{ + using namespace PRDF; + + Resolution * l_rc = NULL; + + switch (i_action->cv_op) + { + case Prdr::REF_ACT: + l_rc = this->createActionClass(i_action->cv_value[0].i - + (i_data.cv_loadChip->cv_regCount + + i_data.cv_loadChip->cv_ruleCount + + i_data.cv_loadChip->cv_groupCount + + 1), + i_data); + break; + + case Prdr::REF_GRP: + l_rc = &i_data.cv_reslFactory.GetEregResolution( + *i_data.cv_groupMap[i_action->cv_value[0].i]); + break; + + case Prdr::ACT_TRY: // TRY + l_rc = &i_data.cv_reslFactory.GetTryResolution( + *(this->createResolution(i_action->cv_value[0].p, + i_data)), + *(this->createResolution(i_action->cv_value[1].p, + i_data)) + ); + break; + + case Prdr::ACT_FUNC: // FUNCCALL + l_rc = &i_data.cv_reslFactory.GetPluginCallResolution( + this, + this->getExtensibleFunction(i_action->cv_actFunc) + ); + break; + + case Prdr::ACT_FLAG: // FLAG + l_rc = &i_data.cv_reslFactory.GetFlagResolution( + (ServiceDataCollector::Flag) i_action->cv_value[0].i); + break; + + case Prdr::ACT_THRES: // Threshold + // The values which different parameter will have + // cv_value[0,1] error frequency and time in sec for field threshold + //cv_value[4] true if mnfg threshols needs to be picked up from mnfg file, false otherwise + // cv_value [2,3]: error frequency and time in sec for mnfg threshold if cv_value[4] is false + // otheiwse cv_value[3] tells which threshold needs to pick up from mnfg file + // cv_value[5] maski id if shared threshold + if (0 == i_action->cv_value[5].i) + { + if ( !PlatServices::mfgMode() ) + { + l_rc = &i_data.cv_reslFactory.GetThresholdSigResolution( + ThresholdResolution::ThresholdPolicy( + (uint16_t)i_action->cv_value[0].i, i_action->cv_value[1].i)); + } + else if(i_action->cv_value[4].i) + { + // FIXME : need to uncomment PrdfMfgThresholdMgr after we figure it out + #ifndef __HOSTBOOT_MODULE + l_rc = &i_data.cv_reslFactory.GetThresholdSigResolution( + *(PrdfMfgThresholdMgr::getInstance()-> + getThresholdP(i_action->cv_value[3].i))); + #endif + } + else + { + l_rc = &i_data.cv_reslFactory.GetThresholdSigResolution( + ThresholdResolution::ThresholdPolicy( + (uint16_t)i_action->cv_value[2].i, i_action->cv_value[3].i)); + } + } + else + if (NULL == i_data.cv_sharedThresholds[i_action->cv_value[5].i]) + { + if ( !PRDF::PlatServices::mfgMode() ) + { + l_rc = &i_data.cv_reslFactory. + GetThresholdResolution(i_action->cv_value[5].i, + ThresholdResolution::ThresholdPolicy((uint16_t)i_action->cv_value[0].i, i_action->cv_value[1].i)); + } + else if(i_action->cv_value[4].i) + { + // FIXME : need to uncomment PrdfMfgThresholdMgr after we figure it out + #ifndef __HOSTBOOT_MODULE + l_rc = &i_data.cv_reslFactory. + GetThresholdResolution(i_action->cv_value[5].i, + *(PrdfMfgThresholdMgr::getInstance()-> + getThresholdP(i_action->cv_value[3].i))); + #endif + } + else + { + l_rc = &i_data.cv_reslFactory. + GetThresholdResolution(i_action->cv_value[5].i, + ThresholdResolution::ThresholdPolicy((uint16_t)i_action->cv_value[2].i, i_action->cv_value[3].i)); + } + i_data.cv_sharedThresholds[i_action->cv_value[5].i] = l_rc; + } + else + { + l_rc = i_data.cv_sharedThresholds[i_action->cv_value[5].i]; + } + break; + + + case Prdr::ACT_DUMP: // DUMP : TODO: Allow dump connected. + #ifdef __HOSTBOOT_MODULE + //FIXME: comment out hwtablecontent for hostboot + l_rc = &i_data.cv_reslFactory.GetDumpResolution( + /*(hwTableContent) i_action->cv_value[0].i,*/ + GetChipHandle()); + #else + l_rc = &i_data.cv_reslFactory.GetDumpResolution( + (hwTableContent) i_action->cv_value[0].i, + GetChipHandle()); + #endif + break; + + case Prdr::ACT_GARD: // GARD + l_rc = &i_data.cv_reslFactory.GetGardResolution( + (GardResolution::ErrorType) i_action->cv_value[0].i); + break; + + case Prdr::ACT_ANALY: // ANALYZE + l_rc = &i_data.cv_reslFactory.GetAnalyzeConnectedResolution( + this->GetChipHandle(), + (TARGETING::TYPE) i_action->cv_value[0].i, + i_action->cv_value[1].i); + break; + + case Prdr::ACT_CALL: // CALLOUT + switch ((char)i_action->cv_value[0].i) + { + case 'c': // connected chip. + l_rc = &i_data.cv_reslFactory.GetConnectedCalloutResolution( + this->GetChipHandle(), + (TARGETING::TYPE) i_action->cv_value[2].i, + i_action->cv_value[3].i, + (CalloutPriorityEnum) i_action->cv_value[1].i, + (NULL == i_action->cv_value[4].p ? NULL : + (this->createResolution( + i_action->cv_value[4].p, i_data))) + + ); + break; + + case 'p': // Procedure. + l_rc = &i_data.cv_reslFactory.GetCalloutResolution( + (SymbolicFru) i_action->cv_value[2].i, + (CalloutPriorityEnum) i_action->cv_value[1].i); + break; + + case 's': // SELF + default: + l_rc = &i_data.cv_reslFactory.GetCalloutResolution( + this->GetChipHandle(), + (CalloutPriorityEnum) i_action->cv_value[1].i); + break; + + }; + break; + + case Prdr::ACT_CAPT: // Capture resolution. + l_rc = &i_data.cv_reslFactory.GetCaptureResolution( + this, + i_action->cv_value[0].i); + break; + }; + + return l_rc; +}; + +void PrdfRuleChip::createGroup(PrdfGroup * i_group, + uint32_t i_groupId, + PrdfRuleChip::RuleFileData & i_data) +{ + // Internal class to collapse the bit string. + class CreateBitString + { + public: + static void execute(std::vector<uint8_t> & i_bits, + Prdr::PrdrExpr * i_expr) + { + if (NULL == i_expr) + return; + if (i_expr->cv_op == Prdr::INT_SHORT) + { + i_bits.push_back(i_expr->cv_value[0].i); + } + else // must be an | or & operator. + { + // Expand bit string from left side. + CreateBitString::execute(i_bits, i_expr->cv_value[0].p); + // Expand bit string from right side. + CreateBitString::execute(i_bits, i_expr->cv_value[1].p); + } + }; + }; + + for (int i = 0; i < i_data.cv_loadChip->cv_groupSize[i_groupId]; i++) + { + std::vector<uint8_t> l_bits; // Vector to hold bit string. + + // TODO : handle & transformations. + + // Get expression for group's line. + Prdr::PrdrExpr * l_expr = &i_data.cv_loadChip->cv_groups[i_groupId][i]; + + // Execute internal (recursive) class to generate bit string. + CreateBitString::execute(l_bits, l_expr->cv_value[1].p); + + // Add expression to group. + i_group->Add(i_data.cv_regMap[l_expr->cv_value[0].i], + &(*l_bits.begin()), + l_bits.size(), + *(this->createResolution(l_expr->cv_value[2].p, i_data)), + i_data.cv_resets[l_expr->cv_value[0].i], + (i_data.cv_regMap[l_expr->cv_value[0].i]->GetId() + + i_data.cv_loadChip->cv_signatureOffset) & 0xffff, + Prdr::AND == l_expr->cv_value[1].p->cv_op + ); + + } // end for. + + // Do flags. --- + + // Do Priority filter flag. + if (i_data.cv_loadChip->cv_groupFlags[i_groupId] & + Prdr::PRDR_GROUP_FILTER_PRIORITY) + { + std::vector<uint8_t> l_bits; + CreateBitString::execute(l_bits, + i_data.cv_loadChip->cv_groupPriorityBits[i_groupId]); + + prdfFilter * l_filter = new PrioritySingleBitFilter(l_bits); + i_group->AddFilter(l_filter); + } + + // Do single bit filter flag. + if (i_data.cv_loadChip->cv_groupFlags[i_groupId] & + Prdr::PRDR_GROUP_FILTER_SINGLE_BIT) + { + prdfFilter * l_filter = new SingleBitFilter(); + i_group->AddFilter(l_filter); + } +} + +PrdfExtensibleChipFunction * + PrdfRuleChip::getExtensibleFunction(const char * i_func, bool i_expectNull) +{ + PrdfExtensibleFunctionType * plugin = + prdfGetPluginGlobalMap().getPlugins(cv_fileName)[i_func]; + if (NULL == plugin) + { + static PrdfPlugin<PrdfExtensibleChip> l_nullPlugin(NULL); + plugin = &l_nullPlugin; + + if (!i_expectNull) + { + errlHndl_t l_errl = NULL; + + PRDF_CREATE_ERRL(l_errl, + ERRL_SEV_UNRECOVERABLE, + ERRL_ETYPE_NOT_APPLICABLE, + SRCI_ERR_INFO, + SRCI_NO_ATTR, + PRDF_PRDFRULECHIP, + LIC_REFCODE, + PRDF_CODE_FAIL, + __LINE__, + 0, 0, 0); + + PRDF_ADD_FFDC(l_errl, + cv_fileName, + strlen(cv_fileName), + prdfErrlVer1, + prdfErrlString); + + PRDF_ADD_FFDC(l_errl, + i_func, + strlen(i_func), + prdfErrlVer1, + prdfErrlString); + + PRDF_COMMIT_ERRL(l_errl, ERRL_ACTION_REPORT); + } + + } + return (PrdfExtensibleChipFunction *) plugin; + +} + +SCAN_COMM_REGISTER_CLASS * PrdfRuleChip::getRegister(const char * i_reg, + bool i_expectNull) +{ + uint16_t hashId = Util::hashString( i_reg ); + + SCAN_COMM_REGISTER_CLASS * l_register = cv_hwRegs[hashId]; + + if (NULL == l_register) + { + static PrdfNullRegister l_nullRegister(1024); + l_register = &l_nullRegister; + + if (!i_expectNull) + { + errlHndl_t l_errl = NULL; + PRDF_CREATE_ERRL(l_errl, + ERRL_SEV_UNRECOVERABLE, + ERRL_ETYPE_NOT_APPLICABLE, + SRCI_ERR_INFO, + SRCI_NO_ATTR, + PRDF_PRDFRULECHIP, + LIC_REFCODE, + PRDF_CODE_FAIL, + __LINE__, + 1, 0, 0); + + PRDF_ADD_FFDC(l_errl, + cv_fileName, + strlen(cv_fileName), + prdfErrlVer1, + prdfErrlString); + + + PRDF_ADD_FFDC(l_errl, + i_reg, + strlen(i_reg), + prdfErrlVer1, + prdfErrlString); + + PRDF_COMMIT_ERRL(l_errl, ERRL_ACTION_REPORT); + } + + } + return l_register; +} diff --git a/src/usr/diag/prdf/framework/rule/prdfRuleChip.H b/src/usr/diag/prdf/framework/rule/prdfRuleChip.H new file mode 100755 index 000000000..9c0b0859f --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdfRuleChip.H @@ -0,0 +1,193 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdfRuleChip.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDFRULECHIP_H +#define __PRDFRULECHIP_H + +#include <iipchip.h> +#include <prdfErrlSmartPtr.H> + +#include <iipsdbug.h> // for ATTENTION_TYPE +#include <prdfExtensibleChip.H> +#include <prdfPluginDef.H> + +#include <string.h> +#include <vector> +#include <map> +#include <iipResetErrorRegister.h> +#include "prdrCommon.H" //@jl02 Added this to get the constant value from the enum. +#include <iipCaptureData.h> // @jl04 Added this for the RegType used for register = "PRIMARY" or "SECONDARY" +//--------------------------------------- +// Forward decls. +class SCAN_COMM_REGISTER_CLASS; +class ScanFacility; +class ResolutionFactory; +class STEP_CODE_DATA_STRUCT; +class CaptureData; +class ErrorRegisterType; +class Resolution; +namespace Prdr +{ + class PrdrChip; + class PrdrExpr; +}; +class PrdfGroup; +typedef std::pair<ResetAndMaskErrorRegister::ResetRegisterVector, + ResetAndMaskErrorRegister::ResetRegisterVector> + PrdfResetAndMaskPair; + +// x86 compile wants this here - not forward declaired dgilbert +class PrdfCaptureRequirement +{ + public: + PrdfCaptureRequirement() : + cv_TargetType(TARGETING::TYPE_NA), cv_TargetIndex(0), cv_func(NULL) { }; + + uint32_t cv_TargetType; + uint32_t cv_TargetIndex; + PrdfExtensibleChipFunction * cv_func; + + inline bool operator!=(const PrdfCaptureRequirement & r) + { + return ( (cv_TargetType != r.cv_TargetType) || + (cv_TargetIndex != r.cv_TargetIndex) || + (cv_func != r.cv_func) ); + }; +}; + +//-------------------------------------- +// @jl04 a Start. +// Adding capture requirement type for transporting data. +class PrdfCaptureType +{ + public: + RegType cv_regType; + // if (reg == 1) reg = PRIMARY; + // if (reg == 2) reg = SECONDARY; + PrdfCaptureType(RegType reg = PRIMARY):cv_regType(reg){}; +}; +// @jl04 a Stop. +//-------------------------------------- + + +class PrdfRuleChip : public PrdfExtensibleChip +{ + public: + + typedef std::map<uint32_t, SCAN_COMM_REGISTER_CLASS *> RegMap_t; + typedef std::map<uint32_t, ErrorRegisterType *> GroupMap_t; + typedef std::map<uint32_t, Resolution *> ActionMap_t; + typedef std::map<uint32_t, PrdfResetAndMaskPair> Reset_t; + typedef std::map<uint32_t, Resolution *> SharedThreshold_t; + + struct RuleFileData + { + RegMap_t & cv_regMap; + GroupMap_t & cv_groupMap; + ActionMap_t & cv_actionMap; + + ScanFacility & cv_scanFactory; + ResolutionFactory & cv_reslFactory; + + TARGETING::TargetHandle_t cv_chipHandle; + Prdr::PrdrChip *& cv_loadChip; // pw01 + + Reset_t & cv_resets; + PrdfResetAndMaskPair & cv_currentResets; + + SharedThreshold_t & cv_sharedThresholds; + + }; + + public: + // TODO : add parameter for parent domains, connected chip classes. + PrdfRuleChip(const char * i_fileName, + TARGETING::TargetHandle_t i_pTargetHandle, + ScanFacility & i_scanFactory, + ResolutionFactory & i_reslFactory + ) + : PrdfExtensibleChip(i_pTargetHandle), + cv_fileName(i_fileName), + cv_dumpType(0), //@ecdf + cv_dataBundle(NULL) + { + this->loadRuleFile(i_scanFactory, i_reslFactory); + }; + + ~PrdfRuleChip(); + + int32_t Analyze(STEP_CODE_DATA_STRUCT &, ATTENTION_TYPE); + int32_t CaptureErrorData(CaptureData &, int i_group = 1); + int32_t MaskError(uint32_t i) { return SUCCESS; }; + + PrdfExtensibleChipFunction * + getExtensibleFunction(const char *, bool = false); + SCAN_COMM_REGISTER_CLASS * getRegister(const char *, bool = false); + PrdfDataBundle *& getDataBundle() { return cv_dataBundle; }; + + uint32_t getSignatureOffset() const { return iv_sigOff; }; + + private: + const char * cv_fileName; + PrdfErrlSmartPtr cv_errl; + + uint32_t cv_dumpType; //@ecdf + + uint32_t iv_sigOff; + + std::map<uint16_t, SCAN_COMM_REGISTER_CLASS *> cv_hwRegs; + + typedef std::map<uint32_t, std::vector<SCAN_COMM_REGISTER_CLASS *> > HwCaptureGroup_t; + HwCaptureGroup_t cv_hwCaptureGroups; + + typedef std::map<SCAN_COMM_REGISTER_CLASS *, PrdfCaptureRequirement> HwCaptureReq_t; + HwCaptureReq_t cv_hwCaptureReq; + + //Adding another std::map for passing some data to capture stuff. + typedef std::map<SCAN_COMM_REGISTER_CLASS *, PrdfCaptureType> HwCaptureType_t; + HwCaptureType_t cv_hwCaptureType; + + PrdfDataBundle * cv_dataBundle; + ErrorRegisterType * cv_groupAttn[NUM_GROUP_ATTN]; // @jl02 JL Changed from 3 to 4 with this const type. + + void loadRuleFile(ScanFacility &, + ResolutionFactory &); + + SCAN_COMM_REGISTER_CLASS * + createVirtualRegister(Prdr::PrdrExpr *, + RuleFileData &); + + Resolution * + createActionClass(uint32_t, + RuleFileData &); + + Resolution * + createResolution(Prdr::PrdrExpr *, + RuleFileData &); + + void createGroup(PrdfGroup *, + uint32_t, + RuleFileData &); +}; + +#endif diff --git a/src/usr/diag/prdf/framework/rule/prdfRuleFiles.C b/src/usr/diag/prdf/framework/rule/prdfRuleFiles.C new file mode 100755 index 000000000..4be2704ea --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdfRuleFiles.C @@ -0,0 +1,45 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdfRuleFiles.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2008,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDFRULEFILES_H +#define __PRDFRULEFILES_H + +/** + * @file prdfRuleFiles.C + * @brief Contains the name of each chip's associated file. + */ + +namespace PRDF +{ + // Pegasus P8 Chip + const char * Proc = "Proc"; + const char * Ex = "Ex"; + const char * Mcs = "Mcs"; + + // Pegasus Centaur Chip + const char * Membuf = "Membuf"; + const char * Mba = "Mba"; + +}; + +#endif diff --git a/src/usr/diag/prdf/framework/rule/prdfRuleFiles.H b/src/usr/diag/prdf/framework/rule/prdfRuleFiles.H new file mode 100755 index 000000000..6515bd7df --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdfRuleFiles.H @@ -0,0 +1,47 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdfRuleFiles.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDFRULEFILES_H +#define __PRDFRULEFILES_H + +/** + * @file prdfRuleFiles.H + * @brief Contains the name of each chip's associated .prf file. + */ + +namespace PRDF +{ + + // Pegasus P8 Chip + extern const char * Proc; + extern const char * Ex; + extern const char * Mcs; + + // Pegasus Centaur Chip + extern const char * Membuf; + extern const char * Mba; + +}; + +#endif + diff --git a/src/usr/diag/prdf/framework/rule/prdrChip.H b/src/usr/diag/prdf/framework/rule/prdrChip.H new file mode 100755 index 000000000..ea1826d11 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrChip.H @@ -0,0 +1,189 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrChip.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDRCHIP_H +#define __PRDRCHIP_H + +#include <string> +#include <stdint.h> + +#include <netinet/in.h> + +#include <prdrRegister.H> + +class PrdrExtraSignature +{ + public: + uint32_t iv_sig; + std::string * iv_sname; + std::string * iv_desc; + + PrdrExtraSignature(uint32_t i_sig, + std::string * i_sname, + std::string * i_desc) : iv_sig(i_sig), + iv_sname(i_sname), + iv_desc(i_desc) {}; + + PrdrExtraSignature & operator=(const PrdrExtraSignature & l_rhs) + { + this->iv_sig = l_rhs.iv_sig; + this->iv_sname = l_rhs.iv_sname; + this->iv_desc = l_rhs.iv_desc; + + return *this; + }; +}; + +class PrdrChip +{ + public: + std::string * cv_sname; + std::string * cv_name; + uint32_t cv_chipid; + uint32_t cv_targetType; + uint32_t cv_signatureOffset; + uint32_t cv_dumptype; //@ecdf + PrdrRegisterList cv_reglist; + std::list<PrdrExtraSignature> cv_sigExtras; + + uint16_t cv_scomlen; // Default Scom Address. + + std::string cv_name_default; + + PrdrChip() : cv_sname(NULL), + cv_name(&cv_name_default), + cv_chipid(0), + cv_targetType(0), + cv_signatureOffset(0), + cv_dumptype(0), //@ecdf + cv_reglist(), + cv_sigExtras(), + cv_scomlen(0) {}; + + static void merge(PrdrChip * i_l, PrdrChip * i_r) + { + if (NULL != i_r->cv_sname) + i_l->cv_sname = i_r->cv_sname; + if (&i_r->cv_name_default != i_r->cv_name) + i_l->cv_name = i_r->cv_name; + if (0 != i_r->cv_chipid) + i_l->cv_chipid = i_r->cv_chipid; + if (0 != i_r->cv_scomlen) + i_l->cv_scomlen = i_r->cv_scomlen; + if (0 != i_r->cv_targetType) + i_l->cv_targetType = i_r->cv_targetType; + if (0 != i_r->cv_signatureOffset) + i_l->cv_signatureOffset = i_r->cv_signatureOffset; + if (0 != i_r->cv_dumptype) //@ecdf + i_l->cv_dumptype = i_r->cv_dumptype; + + i_l->cv_reglist.insert(i_l->cv_reglist.end(), + i_r->cv_reglist.begin(), + i_r->cv_reglist.end()); + + i_l->cv_sigExtras.insert(i_l->cv_sigExtras.end(), + i_r->cv_sigExtras.begin(), + i_r->cv_sigExtras.end()); + }; + + void print() + { + using namespace std; + cout << "Chip " << *cv_sname << ":" << endl; + cout << "\tLong Name: " << *cv_name << endl; + cout << "\tChip ID: " << cv_chipid << endl; + cout << "\tTarget Type: " << cv_targetType << endl; + cout << "\tSignature Offset: " << cv_signatureOffset << endl; + cout << "\tDefault Dumptype: " << cv_dumptype << endl; //@ecdf + cout << "\tDefault ScomLen: " << cv_scomlen << endl; + cout << "\tRegisters: (" << cv_reglist.size() << ")" << endl; + for (PrdrRegisterList::iterator i = cv_reglist.begin(); + i != cv_reglist.end(); + i++) + { + (*i)->print(); + } + }; + + + int output(FILE * l_file) + { + uint32_t l_temp; + uint16_t l_temp16; + + fwrite("PRDRCHIP", 8, 1, l_file); + + l_temp = htonl(cv_chipid); + fwrite(&l_temp, sizeof(l_temp), 1, l_file); + + l_temp = htonl(cv_targetType); + fwrite(&l_temp, sizeof(l_temp), 1, l_file); + + l_temp = htonl(cv_signatureOffset); + fwrite(&l_temp, sizeof(l_temp), 1, l_file); + + // Write dumptype to file. //@ecdf + l_temp = htonl(cv_dumptype); + fwrite(&l_temp, sizeof(l_temp), 1, l_file); + + l_temp16 = htons(cv_scomlen); + fwrite(&l_temp16, sizeof(l_temp16), 1, l_file); + + l_temp16 = htons(cv_reglist.size()); + fwrite(&l_temp16, sizeof(l_temp16), 1, l_file); + + for (PrdrRegisterList::iterator i = cv_reglist.begin(); + i != cv_reglist.end(); + i++) + { + (*i)->output(l_file, cv_signatureOffset); + } + + return 0; + } + + void outputRegisterFile(std::ostream & o_file) + { + o_file << "( 0x" << std::hex << cv_targetType << ", 0x" << std::hex + << cv_signatureOffset << " )" << std::endl; + + for (PrdrRegisterList::iterator i = cv_reglist.begin(); + i != cv_reglist.end(); + i++) + { + (*i)->outputRegisterFile(o_file, cv_signatureOffset); + } + + }; +}; + +#endif + +// Change Log ********************************************************* +// +// Flag Reason Vers Date Coder Description +// ---- -------- ---- -------- -------- ------------------------------- +// F494911 f310 03/04/05 iawillia Initial File Creation +// ecdf F550548 f300 05/04/06 iawillia eClipz DUMP flags support. +// D586213 f310 02/19/07 iawillia Add extra signature support. +// End Change Log ***************************************************** diff --git a/src/usr/diag/prdf/framework/rule/prdrCommon.H b/src/usr/diag/prdf/framework/rule/prdrCommon.H new file mode 100755 index 000000000..46a20cd62 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrCommon.H @@ -0,0 +1,178 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrCommon.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2005,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDRCOMMON_H +#define __PRDRCOMMON_H + +/** + * @file prdrCommon.H + * @brief Common enums, typedefs, etc. between compiler and loader for rule + * table code. + */ + +#include <map> +#include <stdint.h> + +#ifdef __PRD_RULE_COMPILE + #include <string> +#endif + +// @jl02 JL adding a constant for the number of attention types. +enum PrdrNumberOfAttentions +{ + NUM_GROUP_ATTN = 4, +}; + + +/** + * @namespace Prdr + * @brief Namespace to encapsulate Prdr specific enums, classes, and typedefs. + */ +namespace Prdr +{ + /** + * @enum PrdrRegisterFlags + * @brief Flags for which register attributes are contained in a register + * definition. + * + * When loading the .prf file, each register entry will contain a set of + * these flags that describe what attributes are non-default (and therefore + * contained in the file). + */ + enum PrdrRegisterFlags + { + /** Non-default scomlen */ + PRDR_REGISTER_SCOMLEN = 0x1, + /** Resets defined */ + PRDR_REGISTER_RESETS = 0x2, + /** Masks defined */ + PRDR_REGISTER_MASKS = 0x4, + /** Capture requirements */ + PRDR_REGISTER_CAPTURE = 0x8, + }; + + /** + * @enum PrdrGroupFlags + * @brief Flags for which group attributes are contained in a group + * definition. + * + * When loading the .prf file, each group entry will contain a set of + * these flags that describe what attributes are non-default (and therefore + * contained in the file). + */ + enum PrdrGroupFlags + { + /** Single Bit Filter */ + PRDR_GROUP_FILTER_SINGLE_BIT = 0x1, + /** Priority Bit Filter */ + PRDR_GROUP_FILTER_PRIORITY = 0x2, + }; + + /** + * @enum PrdrTimeBaseFlags + * @brief Enums for time base + * + * When reading rule file, these flags can be used to write in prf files + * for time base values. + */ + enum PrdrTimeBaseFlags + { + PRDR_TIME_BASE_SEC = 1, + PRDR_TIME_BASE_MIN = PRDR_TIME_BASE_SEC * 60, + PRDR_TIME_BASE_HOUR = PRDR_TIME_BASE_MIN * 60, + PRDR_TIME_BASE_DAY = PRDR_TIME_BASE_HOUR * 24, + }; + + /** + * @enum PrdrExprOps + * @brief Single char op's defined for .prf files. + * + * Needed for properly reading/writing .prf files. + */ + enum PrdrExprOps + { + REF_RULE = 'r', + REF_REG = 'e', + REF_GRP = 'g', + REF_ACT = 'a', + INTEGER = 'I', + INT_SHORT = 'i', + BIT_STR = 'B', + NOT = '~', + AND = '&', + OR = '|', + XOR = '^', + LSHIFT = 174, // ASCII left-shift + RSHIFT = 175, // ASCII right-shift + RULE = 'R', + GROUP = 'G', + ACTION = 'A', + + ATTNLINK = 'L', + + ACT_THRES = 't', + ACT_ANALY = 'y', + ACT_TRY = '{', + ACT_DUMP = 'd', + ACT_GARD = '-', + ACT_CALL = 'c', + ACT_FUNC = 'f', + ACT_FLAG = 'F', + ACT_CAPT = 'C', + }; + + class PrdrSignatureOp + { + public: + enum { DEFAULT_SIGNATURE = 0x0 }; + + static uint16_t combineSig( uint16_t a, uint16_t b ) + { + // The two signature will be XOR'd together and there is a + // possibility that the signature could be the same, which would + // result in 0. So, rotate the first signature to essentially + // scramble it. This should be able to create a unique signature. + a = ((a & 0xff80) >> 7) | ((a & 0x007f) << 9); // rotate left 9 bits + return ( (a ^ b) & 0xffff ); + }; + }; + + #ifdef __PRD_RULE_COMPILE + typedef std::map<uint16_t, std::string> HashCollisionMap; + #endif +}; + +#endif + + +// Change Log ********************************************************* +// +// Flag Reason Vers Date Coder Description +// ---- -------- ---- -------- -------- ------------------------------- +// D515833 f300 09/19/05 iawillia Add capture support. +// F526728 f300 10/25/05 iawillia Add >> and << operators to rules. +// F534311 f300 01/10/06 iawillia Add Bit string. +// F557408 f310 06/16/06 iawillia Add single-bit filter support. +// jl02 F605874 f330 07/31/07 lukas Add functions to PRD framework/Galaxy +// 2 code for unit CS. +// End Change Log ***************************************************** diff --git a/src/usr/diag/prdf/framework/rule/prdrCompile.C b/src/usr/diag/prdf/framework/rule/prdrCompile.C new file mode 100755 index 000000000..4f9028953 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrCompile.C @@ -0,0 +1,548 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrCompile.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* 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. + +#ifdef CONTEXT_x86_nfp + +// TODO: Need support for attributeenums.H in x86.nfp. For now stub out the TYPE +// enum values. + +namespace TARGETING +{ + enum TYPE + { + TYPE_NA = 0x00000000, + TYPE_DIMM = 0x00000003, + TYPE_MEMBUF = 0x00000006, + TYPE_PROC = 0x00000007, + TYPE_EX = 0x0000000A, + TYPE_MCS = 0x0000000F, + TYPE_MBA = 0x00000011, + }; +} + +#else + +#include <attributeenums.H> // For TARGETING::TYPE enum + +#endif + +// define needed to enable x86 rule parser code only +#define __PRD_RULE_COMPILE +#include <prdrCommon.H> +#include <prdrToken.H> +#include <UtilHash.H> + +int yyline; +std::stack<std::pair<std::string, int> > yyincfiles; + +PrdrChip * g_currentChip; // the current chip +std::map<std::string, PrdrExpr *> g_rules; // list of rules. +std::map<std::string, PrdrGroup *> g_groups; // list of bit groups +std::map<std::string, PrdrGroup *> 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; + +//-------------------------------------------- +// 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); + } + +#ifndef __HOSTBOOT_MODULE + + 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()); + + // Get Backing build or sandbox name. + std::string l_backingBuild(getenv("SANDBOXBASE")); + l_backingBuild = l_backingBuild.substr(l_backingBuild.find_last_of('/')+1); + + // 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 <prdrErrlPluginSupt.H>" << std::endl; + l_errFile << "PRDR_ERROR_SIGNATURE_TABLE_START "; + + // setup register id file. + l_regFile << "#include <prdrErrlPluginSupt.H>" << std::endl; + l_regFile << "PRDR_REGISTER_ID_TABLE_START "; + +#endif + + 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); +#ifndef __HOSTBOOT_MODULE + g_currentChip->outputRegisterFile(l_regFile); +#endif + //g_currentChip->print(); + } + else + { + yyerror("No chip define!"); + exit(1); + } + +#ifndef __HOSTBOOT_MODULE + + 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; + +#endif + + // output rules. + l_size = htons((uint16_t)g_rules.size()); + fwrite(&l_size, sizeof(l_size), 1, l_prfFile); + for (std::map<std::string, PrdrExpr *>::iterator i = g_rules.begin(); + i != g_rules.end(); + i++) + { + (*i).second->output(l_prfFile); + }; + +#ifndef __HOSTBOOT_MODULE + // set error register HOM_TYPE + l_errFile << "( 0x" << std::hex << g_currentChip->cv_targetType << ", 0x" + << std::hex << g_currentChip->cv_signatureOffset + << " )" << std::endl; +#endif + + // output bit groups + uint32_t l_pos = 0; + l_size = htons((uint16_t)g_groups.size()); + fwrite(&l_size, sizeof(l_size), 1, l_prfFile); + l_size = htons((uint16_t)prdrGetRefId(&g_attentionStartGroup["CHECK_STOP"])); + fwrite(&l_size, sizeof(l_size), 1, l_prfFile); + l_size = htons((uint16_t)prdrGetRefId(&g_attentionStartGroup["RECOVERABLE"])); + fwrite(&l_size, sizeof(l_size), 1, l_prfFile); + l_size = htons((uint16_t)prdrGetRefId(&g_attentionStartGroup["SPECIAL"])); + 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 + fwrite(&l_size, sizeof(l_size), 1, l_prfFile); // @jl02 + +#ifndef __HOSTBOOT_MODULE + + l_htmlFile << "<H2> Register Groups </H2>" << std::endl; + l_htmlFile << "Generated from " << l_backingBuild << "<BR>" << std::endl; + +#endif + + for (std::map<std::string, PrdrGroup *>::iterator i = g_groups.begin(); + i != g_groups.end(); + i++, l_pos++) + { + (*i).second->output(l_prfFile); +#ifndef __HOSTBOOT_MODULE + (*i).second->generateDoxygen(l_htmlFile, (*i).first, l_errFile); +#endif + }; + + // output action classes. + l_size = htons((uint16_t)g_actionclasses.size()); + fwrite(&l_size, sizeof(l_size), 1, l_prfFile); + +#ifndef __HOSTBOOT_MODULE + + 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; + +#endif + + for (std::map<std::string, PrdrGroup *>::iterator i = + g_actionclasses.begin(); + i != g_actionclasses.end(); + i++) + { + (*i).second->output(l_prfFile); +#ifndef __HOSTBOOT_MODULE + (*i).second->generateDoxygen(l_htmlFile, (*i).first); +#endif + }; + +#ifndef __HOSTBOOT_MODULE + l_htmlFile << "</TABLE>" << std::endl; +#endif + + fclose(l_prfFile); + +#ifndef __HOSTBOOT_MODULE + l_htmlFile << "</HTML>"; + l_htmlFile.close(); +#endif + +#ifndef __HOSTBOOT_MODULE + // Add chip's extra signatures. + l_errFile << "//---- Extra Signatures ----" << std::endl; + for (std::list<PrdrExtraSignature>::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(); +#endif + + return (g_hadError ? -1 : 0); +}; + +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 (PrdrRegisterList::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, PrdrExpr *>::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, PrdrGroup *>::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, PrdrGroup *>::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. + + // TODO : take care of the @tags. + + 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 = 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; +} + +#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 + +std::map<std::string, uint32_t> g_ActionArgMap; +uint32_t prdrActionArgMap(const std::string & i_arg) +{ + using namespace PRDF; + + 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_EX"] = TARGETING::TYPE_EX; + g_ActionArgMap["TYPE_MCS"] = TARGETING::TYPE_MCS; + g_ActionArgMap["TYPE_MEMBUF"] = TARGETING::TYPE_MEMBUF; + g_ActionArgMap["TYPE_MBA"] = TARGETING::TYPE_MBA; + + // Initialize symbolic callouts. + for ( SymCallout_t * i = symCalloutArray; NULL != i->str; i++ ) + { + g_ActionArgMap[i->str] = i->val; + } + +#if 0 + // Initialize SDC Flags. + // FIXME: 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 + #undef iipServiceDataCollector_h + #include <iipServiceDataCollector.h> +#endif + + // Initialize Gard values. + // TODO: Map these from xspprdGardResolution.h + g_ActionArgMap["NoGard"] = 0; + g_ActionArgMap["Predictive"] = 1; + g_ActionArgMap["Uncorrectable"] = 2; + g_ActionArgMap["Fatal"] = 3; + g_ActionArgMap["Pending"] = 4; + g_ActionArgMap["CheckStopOnlyGard"] = 5; + g_ActionArgMap["DeconfigNoGard"] = 6; //mp01 + +#ifdef __HOSTBOOT_MODULE + // FIXME: Hostboot currently does not support dump contents. This is a + // temporary fix. + g_ActionArgMap["DUMP_CONTENT_HW"] = 0; + g_ActionArgMap["DUMP_CONTENT_SH"] = 1; + g_ActionArgMap["DUMP_CONTENT_HWSUPERNOVA"] = 2; +#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> + + // Initialize MFG thresholds. + #define PRDF_MFGTHRESHOLD_TABLE_BEGIN + #define PRDF_MFGTHRESHOLD_TABLE_END + #define PRDF_MFGTHRESHOLD_ENTRY(a,b,c) \ + g_ActionArgMap[#a] = b; + #include <prdfMfgThresholds.H> +#endif + + 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]; +} diff --git a/src/usr/diag/prdf/framework/rule/prdrCompile.lex b/src/usr/diag/prdf/framework/rule/prdrCompile.lex new file mode 100755 index 000000000..1c9ee1f54 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrCompile.lex @@ -0,0 +1,213 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrCompile.lex $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/* Pre C stuff: headers, etc. */ +%{ + +/** @file prdrCompile.lex + * + * This file contains all of the flex code for parsing rule-table tokens. + */ + +#include <stdlib.h> + +#include <prdrToken.H> // Token structure definition. +#include <prdrCompile.y.H> // Token enums from yacc code. + +#define YY_NO_UNPUT // No "Unput" function defined. +%} + +/* --- Basic type definitions --- */ + +/* Digits */ +digit [0-9] +hexdigit [0-9a-fA-F] + +/* Numerical constants */ +integer {digit}+ +hexint 0[xX]{hexdigit}+ + /* Bit-string is a hex string between two back-ticks */ +bitstring `{hexdigit}+` + +/* White space */ +whitespace [ \t]* +newline \n + +/* # starts a comment line */ +comment #.*{newline} + +/* IDs are any letter or underscore followed by any number of letters/numbers */ +id [A-Za-z_][A-Za-z0-9_]* + +/* --- end Basic type definitions --- */ + +/* Define special parse contexts for comments and .include headers */ +%x DOX_COMMENT +%x INCLUDED + +/* --- Begin Token Definitions --- */ +%% + + /* Parse numerical constants to "INTEGER" type. */ +{integer} { sscanf(yytext, "%llu", &yylval.long_integer); return PRDR_INTEGER; } +{hexint} { sscanf(yytext, "%llx", &yylval.long_integer); return PRDR_INTEGER; } + + /* Parse a bitstring to "BIT_STRING" type. */ +{bitstring} { + yylval.str_ptr = new std::string(yytext); + return PRDR_BIT_STRING; + } + /* Parse a string to a "STRING" type. Any number of characters between two + * quotes. + */ +\"[^"]*\" { + yylval.str_ptr = new std::string(yytext); + return PRDR_STRING; + } + /* Special end-of-file character. */ +<<EOF>> { return 0; } + + /* Various keyword tokens converted directly to the enum type. */ +chipid { return PRDR_CHIPID; } +sigoff { return PRDR_SIGNATURE_OFFSET; } +PRDR_ERROR_SIGNATURE { return PRDR_SIGNATURE_EXTRA; } +targettype { return PRDR_TARGETTYPE; } +register { return PRDR_REGISTER; } +name { return PRDR_NAME_KW; } +scomaddr { return PRDR_SCOMADDR; } +scomlen { return PRDR_SCOMLEN; } +bit { return PRDR_BIT_KW; } +reset { return PRDR_RESET_ADDR; } +mask { return PRDR_MASK_ADDR; } + +chip { return PRDR_CHIP; } +group { return PRDR_GROUP; } +type { return PRDR_TYPE; } /* @jl04 a Add this for primary/secondary type.*/ +actionclass { return PRDR_ACTIONCLASS; } +rule { return PRDR_RULE; } + +threshold { return PRDR_ACT_THRESHOLD; } +analyse { return PRDR_ACT_ANALYSE; } +analyze { return PRDR_ACT_ANALYSE; } +try { return PRDR_ACT_TRY; } +dump { return PRDR_ACT_DUMP; } +funccall { return PRDR_ACT_FUNCCALL; } +gard { return PRDR_ACT_GARD; } +callout { return PRDR_ACT_CALLOUT; } +flag { return PRDR_ACT_FLAG; } +capture { return PRDR_ACT_CAPTURE; } + +connected { return PRDR_CONNECTED; } +alternate { return PRDR_ALTERNATE; } +procedure { return PRDR_PROCEDURE; } + +attntype { return PRDR_ATTNTYPE; } +shared { return PRDR_SHARED_KW; } +req { return PRDR_REQUIRED_KW; } +field { return PRDR_FLD_KW; } +mfg { return PRDR_MFG_KW; } +mfg_file { return PRDR_MFG_FILE_KW; } +sec { return PRDR_TIME_SEC; } +min { return PRDR_TIME_MIN; } +hour { return PRDR_TIME_HOUR; } +day { return PRDR_TIME_DAY; } + +filter { return PRDR_FILTER; } +singlebit { return PRDR_FILTER_SINGLE_BIT; } +priority { return PRDR_FILTER_PRIORITY; } + +"\<\<" { return PRDR_OP_LEFTSHIFT; } +"\>\>" { return PRDR_OP_RIGHTSHIFT; } + + /* Parse an "ID" type */ +{id} { yylval.str_ptr = new std::string(yytext); return PRDR_ID;} + + /* Ignore extra white space */ +{whitespace} { } + /* Newline or comment line increments line count */ +{newline} { yyline++; } +{comment} { yyline++; } + + /* Any other arbitrary character is returned unchanged (used for parens, |, + * {, etc. in yacc code). + */ +. { return yytext[0]; } + + /* When we find the .included directive, we need to enter a special parse + * context. There is a preprocessor that runs that changes .include directives + * to a .included / .end_included pair. This is used for line counting on + * errors. + */ +"\.included" BEGIN INCLUDED; + /* Ignore extra whitespace */ +<INCLUDED>{whitespace} { } + /* Find the name of the file that was included, push current file and line + * number on to a "stack". When the included file is complete, we pop a pair + * of the stack to determine where we left off in the old file. + */ +<INCLUDED>\".*\" { + yyincfiles.push( + std::pair<std::string,int>( + std::string(yytext), + yyline) + ); + yyline = 1; + } + /* The newline after the .included indicates the .included directive is + * complete. We then return to the "INITIAL" context to parse the included + * file properly. + */ +<INCLUDED>{newline} BEGIN INITIAL; + /* The .end_included directive indicates an included file has ended. Pop the + * parent file/line number off the stack. + */ +"\.end_included" { + yyline = yyincfiles.top().second; + yyincfiles.pop(); + } + + /* A "slash-star-star" indicates a special comment context. This is used for + * the doxygen-style commenting and HTML documentation generation. + */ +"/**"+[ \t]* BEGIN DOX_COMMENT; + /* A "star-slash" indicates the end of a doxygen comment context. (just like + * C++) + */ +<DOX_COMMENT>[ \t]*\*[/] BEGIN INITIAL; + /* Any number of tabs at the beginning of a line, followed by a star followed + * by anything but a slash, followed by any number of tabs is ignored. + */ +<DOX_COMMENT>\n[ \t]*\*[^/][ \t]* { yyline++; return PRDR_DOX_ENDL; } + /* Find any comment line itself (non-star, non-newline) */ +<DOX_COMMENT>[^*\n]* { + yylval.str_ptr = new std::string(yytext); + return PRDR_DOX_COMMENT; + } + /* New-line in a comment is a special token. */ +<DOX_COMMENT>\n { yyline++; return PRDR_DOX_ENDL; } +%% + +/* User Code */ +int yywrap() { return 1;}; // We're only parsing one file, so always return 1. + // This is a lex-ism. + diff --git a/src/usr/diag/prdf/framework/rule/prdrCompile.y b/src/usr/diag/prdf/framework/rule/prdrCompile.y new file mode 100755 index 000000000..3de83cb2b --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrCompile.y @@ -0,0 +1,999 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrCompile.y $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/* chip.y */ + +/** @file prdrCompile.y + * + * This file contains all of the yacc code for parsing rule-table syntax and + * creating the abstract-syntax tree. + * + * None of this code is ran on the FSP. It is all used to generate data + * files. + * + * Important background: + * + * Compilers, such as yacc/bison, have the concept of a terminal vs. + * non-terminal token. A terminal token is one which is not built from others, + * such as a keyword. A non-terminal token is one that has syntax associated + * with it, such as an "expression" token that is made up of many sub-tokens. + * + * Suggested reading material on parsers/compilers would be + * http://en.wikipedia.org/wiki/Backus-Naur_form + */ + +/* Pre C stuff: headers, etc. */ +%{ +#include <prdrToken.H> +#include <prdrCommon.H> + +#include <string> + +#include <prdrRegister.H> // REVIEW NOTE: Move to token.h? + +%} + +/* Union for the 'yylval' variable in lex or $$ variables in yacc code. Used + * to store the data associated with a parsed token. + */ +%union{ + + /* NOTE: Though we will read from rule file every integer as 64 bit number, + * when creating prf file we will use, 64 bit number only for + * registers. For other we will use it as per need (mostly 32 bit) and + * number will be truncated. It will be dictated by code defined in + * prdrExpr.H and other rule parsing classes. */ + + /** 64 bit unsigned integer value from a token. */ + uint64_t long_integer; + + /** string value from a token. */ + std::string * str_ptr; + /** Parsed list of registers. */ + PrdrRegisterList * reglist; + /** A single parsed register. */ + PrdrRegister * reg; + /** A structure for the reset / mask keywords. */ + PrdrResetOrMaskStruct * reg_mask; + /** A chip object */ + PrdrChip * chip; + /** A sub-expression token. */ + PrdrExpr * expr; + /** A parsed group of bit-operation / action pairs */ + PrdrGroup * grp; + /** A list of strings */ + std::list<std::string *>* strlist; + /** A list of filters */ + std::list<PrdrGroup_Filter *>* filterlist; +} + + /* Indicates the name for the start symbol. (non-terminal) */ +%start input + + /* Define a number of terminal symbols and the portion of the union + * associated with each of them. + */ +%token <long_integer> PRDR_INTEGER +%token <str_ptr> PRDR_ID +%token <str_ptr> PRDR_STRING +%token <str_ptr> PRDR_BIT_STRING + + /* Define a number of terminal symbols without associated data: + * the keywords. + */ +%token PRDR_CHIP +%token PRDR_GROUP +%token PRDR_TYPE +%token PRDR_ACTIONCLASS +%token PRDR_RULE + +%token PRDR_CHIPID +%token PRDR_TARGETTYPE +%token PRDR_SIGNATURE_OFFSET +%token PRDR_SIGNATURE_EXTRA +%token PRDR_REGISTER +%token PRDR_NAME_KW +%token PRDR_SCOMADDR +%token PRDR_SCOMLEN +%token PRDR_RESET_ADDR +%token PRDR_MASK_ADDR +%token PRDR_BIT_KW +%token PRDR_OP_LEFTSHIFT +%token PRDR_OP_RIGHTSHIFT + +%token PRDR_ACT_THRESHOLD +%token PRDR_ACT_ANALYSE +%token PRDR_ACT_TRY +%token PRDR_ACT_DUMP +%token PRDR_ACT_FUNCCALL +%token PRDR_ACT_GARD +%token PRDR_ACT_CALLOUT +%token PRDR_ACT_FLAG +%token PRDR_ACT_CAPTURE + +%token PRDR_CONNECTED +%token PRDR_ALTERNATE +%token PRDR_PROCEDURE + +%token PRDR_ATTNTYPE +%token PRDR_SHARED_KW +%token PRDR_REQUIRED_KW +%token PRDR_MFG_KW +%token PRDR_FLD_KW +%token PRDR_MFG_FILE_KW +%token PRDR_TIME_SEC +%token PRDR_TIME_MIN +%token PRDR_TIME_HOUR +%token PRDR_TIME_DAY + +%token PRDR_FILTER +%token PRDR_FILTER_SINGLE_BIT +%token PRDR_FILTER_PRIORITY + + /* Terminal tokens for Doxygen-style comments */ +%token <str_ptr> PRDR_DOX_COMMENT +%token <str_ptr> PRDR_DOX_ENDL + + /* Non-terminal tokens and the data-type associated with them. */ +%type <reg> register reglines regline +%type <reg_mask> register_mask +%type <chip> chiplines chipline +%type <expr> ruleexpr ruleexpr_small ruleexpr_shift ruleop1 ruleop2 +%type <expr> bitgroup bitandlist bitorlist +%type <expr> time_units +%type <grp> grouplines groupline +%type <grp> actionlines + +%type <expr> actionline +%type <expr> action_threshold action_shared_threshold action_analyse +%type <expr> action_analyse_conn action_try action_capture +%type <expr> action_dump action_gard action_callout action_funccall action_flag +%type <expr> action_callout_alt + +%type <strlist> grpattns grpattns_item +%type <filterlist> grpfilters grpfilt_items grpfilt_item + +%type <str_ptr> dox_comment dox_commentline dox_commentblk + +%% +/* Grammars */ + + /* The 'input' (or start token) is simply any number of lines. */ +input: + | input line +; + + /* Lines can be a full chip, group, rule, or actionclass. */ +line: chip + | group + | rule + | actionclass +; + + /* A chip is a chip-keyword, id, and any number of "lines" */ +chip: PRDR_CHIP PRDR_ID '{' chiplines '}' ';' + { + // Create a default chip object is chiplines are empty. + if (NULL == $4) + $4 = new PrdrChip(); + + // Assign chip's shortname from ID. + $4->cv_sname = $2; + + // Set current chip to be this chip. + g_currentChip = $4; + } +; + + /* Any number of lines can make up a chiplines token. */ +chiplines: { $$ = NULL; } // empty line. + | chiplines chipline ';' + { + // Merge the chip lines together into a single object as needed. + if (NULL != $1) + { + if (NULL == $2) + $$ = NULL; + else + { + // Both are non-NULL, merge. + PrdrChip::merge($1, $2); + $$ = $1; + delete $2; + } + } + else + { + if (NULL == $2) + $$ = NULL; + else + $$ = $2; + } + } + +; + + /* Create a chip object based on the contents of the line. */ +chipline: { $$ = NULL; } // allow a free ;. + | PRDR_CHIPID PRDR_INTEGER + { + $$ = new PrdrChip(); + $$->cv_chipid = $2; + } + | PRDR_SIGNATURE_OFFSET PRDR_INTEGER + { + $$ = new PrdrChip(); + $$->cv_signatureOffset = $2; + } + | PRDR_SIGNATURE_EXTRA '(' PRDR_ID ',' PRDR_INTEGER ',' + PRDR_STRING ',' PRDR_STRING ')' + { + $$ = new PrdrChip(); + $$->cv_sigExtras.push_back(PrdrExtraSignature($5, $7, $9)); + } + | PRDR_TARGETTYPE PRDR_ID + { + $$ = new PrdrChip(); + $$->cv_targetType = prdrActionArgMap(*$2); + } + | PRDR_NAME_KW PRDR_STRING + { + $$ = new PrdrChip(); + $$->cv_name = $2; + } + | register // register non-terminal token. + { + $$ = new PrdrChip(); + $$->cv_reglist.push_back($1); + } + | PRDR_SCOMLEN PRDR_INTEGER + { + $$ = new PrdrChip(); + $$->cv_scomlen = $2; + } + | PRDR_ACT_DUMP PRDR_ID //@ecdf + { + $$ = new PrdrChip(); + $$->cv_dumptype = prdrActionArgMap(*$2); + } +; + + /* A register is the register-keyword, id, and a number of "lines". */ +register: PRDR_REGISTER PRDR_ID '{' reglines '}' + { + // Create register object as needed. + if (NULL == $4) + $$ = new PrdrRegister(); + else + $$ = $4; + + // Assign short-name. + $$->cv_sname = $2; + } +; + /* Any number of lines can make up a reglines token. */ +reglines: { $$ = NULL; } + | reglines regline ';' + { + // Merge register lines as needed. + if (NULL != $1) + { + if (NULL == $2) + $$ = NULL; + else + { + // Both are non-NULL, merge. + PrdrRegister::merge($1, $2); + $$ = $1; + delete $2; + } + } + else + { + if (NULL == $2) + $$ = NULL; + else + $$ = $2; + } + } +; + + /* Define all of the lines (expressions) that can be found in a register */ +regline: { $$ = NULL; } + | PRDR_NAME_KW PRDR_STRING + { + $$ = new PrdrRegister(); + $$->cv_name = $2; + } + | PRDR_NAME_KW PRDR_ID + { + $$ = new PrdrRegister(); + $$->cv_name = $2; + } + | PRDR_SCOMADDR PRDR_INTEGER + { + $$ = new PrdrRegister(); + $$->cv_scomaddr = $2; + } + | PRDR_SCOMLEN PRDR_INTEGER + { + $$ = new PrdrRegister(); + $$->cv_scomlen = $2; + + // Indicate that the register contains a non-default scomlen. + $$->cv_flags |= Prdr::PRDR_REGISTER_SCOMLEN; + } + | PRDR_RESET_ADDR '(' register_mask ')' + { + $$ = new PrdrRegister(); + + // Add reset register to list. + $$->cv_resets.push_back(*$3); + delete $3; + } + | PRDR_MASK_ADDR '(' register_mask ')' + { + $$ = new PrdrRegister(); + + // Add mask register to list. + $$->cv_masks.push_back(*$3); + delete $3; + } + | PRDR_ACT_CAPTURE PRDR_GROUP PRDR_ID + { + $$ = new PrdrRegister(); + + // Define capture group. + PrdrCaptureReqStruct tmp; + tmp.type = PrdrCaptureReqStruct::PRDR_CAPTURE_GROUPID; + tmp.data[0] = prdrCaptureGroupMap(*$3); + + $$->cv_captures.push_back(tmp); + } +//@jl04 Add a new capture "type" here for regsiters. + | PRDR_ACT_CAPTURE PRDR_TYPE PRDR_ID + { + $$ = new PrdrRegister(); + + // Define capture type. + PrdrCaptureReqStruct tmp; + tmp.type = PrdrCaptureReqStruct::PRDR_CAPTURE_TYPE; + tmp.data[0] = prdrCaptureTypeMap(*$3); + $$->cv_captures.push_back(tmp); + } +//@jl04 End. + + | PRDR_ACT_CAPTURE PRDR_REQUIRED_KW PRDR_CONNECTED '(' PRDR_ID ')' + { + $$ = new PrdrRegister(); + + // Define capture "connected" requirement. + PrdrCaptureReqStruct tmp; + tmp.type = PrdrCaptureReqStruct::PRDR_CAPTURE_CONN; + tmp.data[0] = prdrActionArgMap(*$5); + tmp.data[1] = 0; + + $$->cv_captures.push_back(tmp); + } + | PRDR_ACT_CAPTURE PRDR_REQUIRED_KW PRDR_CONNECTED '(' PRDR_ID ',' PRDR_INTEGER ')' + { + $$ = new PrdrRegister(); + + // Define capture "connected" requirement. + PrdrCaptureReqStruct tmp; + tmp.type = PrdrCaptureReqStruct::PRDR_CAPTURE_CONN; + tmp.data[0] = prdrActionArgMap(*$5); + tmp.data[1] = $7; + + $$->cv_captures.push_back(tmp); + } + | PRDR_ACT_CAPTURE PRDR_REQUIRED_KW PRDR_ACT_FUNCCALL '(' PRDR_STRING ')' + { + $$ = new PrdrRegister(); + + // Define funccall requirement. + PrdrCaptureReqStruct tmp; + tmp.type = PrdrCaptureReqStruct::PRDR_CAPTURE_FUNC; + tmp.str = *$5; + + $$->cv_captures.push_back(tmp); + } +; + + /* Define the possible reset/mask instructions. */ +register_mask: '|' ',' PRDR_INTEGER + { + $$ = new PrdrResetOrMaskStruct(); + $$->type = '|'; + $$->addr_r = $3; + $$->addr_w = $3; + } + | '|' ',' PRDR_INTEGER ',' PRDR_INTEGER + { + $$ = new PrdrResetOrMaskStruct(); + $$->type = '|'; + $$->addr_r = $3; + $$->addr_w = $5; + } + | '&' ',' PRDR_INTEGER + { + $$ = new PrdrResetOrMaskStruct(); + $$->type = '&'; + $$->addr_r = $3; + $$->addr_w = $3; + } + | '&' ',' PRDR_INTEGER ',' PRDR_INTEGER + { + $$ = new PrdrResetOrMaskStruct(); + $$->type = '&'; + $$->addr_r = $3; + $$->addr_w = $5; + } + | '^' ',' PRDR_INTEGER + { + $$ = new PrdrResetOrMaskStruct(); + $$->type = '^'; + $$->addr_r = $3; + $$->addr_w = $3; + } + | '^' ',' PRDR_INTEGER ',' PRDR_INTEGER + { + $$ = new PrdrResetOrMaskStruct(); + $$->type = '^'; + $$->addr_r = $3; + $$->addr_w = $5; + } + | '~' ',' PRDR_INTEGER + { + $$ = new PrdrResetOrMaskStruct(); + $$->type = '~'; + $$->addr_r = $3; + $$->addr_w = $3; + } + | '~' ',' PRDR_INTEGER ',' PRDR_INTEGER + { + $$ = new PrdrResetOrMaskStruct(); + $$->type = '~'; + $$->addr_r = $3; + $$->addr_w = $5; + } +; + + /* Define a group object. */ +group: PRDR_GROUP PRDR_ID grpattns grpfilters '{' grouplines '}' ';' + { + // Add to group map. + g_groups[*$2] = $6; + + // Add attentions to attention start list. + if (NULL != $3) + { + for (std::list<std::string *>::iterator i = $3->begin(); + i != $3->end(); + ++i) + { + g_attentionStartGroup[*(*i)] = *$2; + delete (*i); + } + } + + // Add filters to group. + if (NULL != $4) + { + for (std::list<PrdrGroup_Filter *>::iterator i = $4->begin(); + i != $4->end(); + ++i) + { + (*i)->AddFilter($6); + delete (*i); + } + } + + // Free string for group name. + delete $2; + } +; + + /* Definitions for attention directives. */ +grpattns: { $$ = NULL; } + | PRDR_ATTNTYPE grpattns_item { $$ = $2; } +; + + /* Individual attention types defined for group. */ +grpattns_item: grpattns_item ',' PRDR_ID + { + $$ = $1; + $$->push_back($3); + } + | PRDR_ID + { + $$ = new std::list<std::string *>; + $$->push_back($1); + } +; + + /* Definitions for filter directives. */ +grpfilters: { $$ = NULL; } + | PRDR_FILTER grpfilt_items { $$ = $2; } +; + + /* Individual filter types defined for group. */ +grpfilt_items: grpfilt_items ',' grpfilt_item + { + $$ = $1; + $$->push_back(*($3->begin())); + } + | grpfilt_item + { + $$ = $1; + } +; + +grpfilt_item: PRDR_FILTER_SINGLE_BIT + { + $$ = new std::list<PrdrGroup_Filter *>; + $$->push_back(new PrdrGroup_Filter_SingleBit); + } +; + +grpfilt_item: PRDR_FILTER_PRIORITY '(' bitandlist ')' + { + $$ = new std::list<PrdrGroup_Filter *>; + $$->push_back(new PrdrGroup_Filter_Priority($3)); + } +; + + + +grouplines: { $$ = new PrdrGroup(); } + | grouplines groupline ';' + { + PrdrGroup::merge($1,$2); + $$ = $1; + delete $2; + } | grouplines dox_comment groupline ';' + { + $3->setComment(*$2); + PrdrGroup::merge($1,$3); + $$ = $1; + delete $3; + } +; + +groupline: { $$ = new PrdrGroup(); } + | '(' PRDR_ID ',' bitgroup ')' '?' PRDR_ID + { + $$ = new PrdrGroup(); + $$->cv_rules.push_front(new PrdrExprRule($2,$4,$7)); + g_references.push_front(PrdrRefPair("r",*$2)); + g_references.push_front(PrdrRefPair("a",*$7)); + } + | '(' PRDR_ID ',' bitgroup ')' '?' action_analyse + { + $$ = new PrdrGroup(); + $$->cv_rules.push_front(new PrdrExprRule($2,$4,static_cast<PrdrExprRef *>($7)->cv_name)); + g_references.push_front(PrdrRefPair("r",*$2)); + g_references.push_front(PrdrRefPair("g",*static_cast<PrdrExprRef *>($7)->cv_name)); + } + | PRDR_ID + { + $$ = new PrdrGroup(); + $$->cv_rules.push_front(new PrdrExprRef($1)); + g_references.push_front(PrdrRefPair("g",*$1)); + } +; + +bitgroup: PRDR_BIT_KW '(' bitandlist ')' { $$ = $3; } + | PRDR_BIT_KW '(' bitorlist ')' { $$ = $3; } +; + +// TODO: Change to & instead of , +bitandlist: bitandlist ',' PRDR_INTEGER + { + $$ = new PrdrExprOp2(Prdr::AND, + $1, + new PrdrExprInt($3, Prdr::INT_SHORT)); + } + | PRDR_INTEGER + { + $$ = new PrdrExprInt($1, Prdr::INT_SHORT); + } +; + +bitorlist: bitorlist '|' PRDR_INTEGER + { + $$ = new PrdrExprOp2(Prdr::OR, + $1, + new PrdrExprInt($3, Prdr::INT_SHORT)); + } + | PRDR_INTEGER '|' PRDR_INTEGER + { + $$ = new PrdrExprOp2(Prdr::OR, + new PrdrExprInt($1, Prdr::INT_SHORT), + new PrdrExprInt($3, Prdr::INT_SHORT)); + } +; + +// TODO: Merge attention types. +rule: PRDR_RULE PRDR_ID '{' ruleexpr ';' '}' ';' + { + g_rules[*$2] = new PrdrExprOp1(Prdr::RULE, $4); + delete $2; + } + | PRDR_RULE PRDR_ID '{' PRDR_ID ':' ruleexpr ';' '}' ';' + { + g_rules[*$2] = new PrdrExprOp1(Prdr::RULE, + new PrdrExprAttnLink($4, $6, NULL, NULL, NULL, NULL, NULL, NULL)); + delete $2; + delete $4; + } + | PRDR_RULE PRDR_ID '{' PRDR_ID ':' ruleexpr ';' + PRDR_ID ':' ruleexpr ';' + '}' ';' + { + g_rules[*$2] = new PrdrExprOp1(Prdr::RULE, + new PrdrExprAttnLink($4, $6, $8, $10, NULL, NULL, NULL, NULL)); + delete $2; + delete $4; + delete $8; + } + | PRDR_RULE PRDR_ID '{' PRDR_ID ':' ruleexpr ';' + PRDR_ID ':' ruleexpr ';' + PRDR_ID ':' ruleexpr ';' + '}' ';' + { + g_rules[*$2] = new PrdrExprOp1(Prdr::RULE, + new PrdrExprAttnLink($4, $6, $8, $10, $12, $14, NULL, NULL)); + delete $2; + delete $4; + delete $8; + delete $12; + } + | PRDR_RULE PRDR_ID '{' PRDR_ID ':' ruleexpr ';' + PRDR_ID ':' ruleexpr ';' + PRDR_ID ':' ruleexpr ';' + PRDR_ID ':' ruleexpr ';' + '}' ';' + { + g_rules[*$2] = new PrdrExprOp1(Prdr::RULE, + new PrdrExprAttnLink($4, $6, $8, $10, $12, $14, $16, $18)); + delete $2; + delete $4; + delete $8; + delete $12; + delete $16; + } +; + +ruleexpr: ruleexpr_small { $$ = $1; } + | ruleexpr_small ruleop2 ruleexpr + { + $$ = $2; + static_cast<PrdrExprOp2 *>($$)->cv_arg[0] = $1; + static_cast<PrdrExprOp2 *>($$)->cv_arg[1] = $3; + } + | ruleexpr_shift { $$ = $1; } +; + +ruleexpr_small: '(' ruleexpr ')' { $$ = $2; } + | PRDR_ID + { + $$ = new PrdrExprRef($1); + g_references.push_front(PrdrRefPair("re", *$1)); + } + | ruleop1 ruleexpr_small + { + $$ = $1; + static_cast<PrdrExprOp1 *>($$)->cv_arg = $2; + } + | PRDR_BIT_STRING + { + $$ = new PrdrExprBitString(*$1); + delete $1; + } +; + +ruleexpr_shift: ruleexpr_small PRDR_OP_LEFTSHIFT PRDR_INTEGER + { + $$ = new PrdrExprOp2(Prdr::LSHIFT, + $1, + new PrdrExprInt($3)); + + } + | ruleexpr_small PRDR_OP_RIGHTSHIFT PRDR_INTEGER + { + $$ = new PrdrExprOp2(Prdr::RSHIFT, + $1, + new PrdrExprInt($3, Prdr::INT_SHORT)); + } +; + +ruleop1: '~' + { + $$ = new PrdrExprOp1(Prdr::NOT); + } +; + +ruleop2: '|' + { + $$ = new PrdrExprOp2(Prdr::OR); + } + | '&' + { + $$ = new PrdrExprOp2(Prdr::AND); + } + | '^' + { + $$ = new PrdrExprOp2(Prdr::XOR); + } +; + +actionclass: PRDR_ACTIONCLASS PRDR_ID '{' actionlines '}' ';' + { + g_actionclasses[*$2] = $4; + delete $2; + } + | dox_comment PRDR_ACTIONCLASS PRDR_ID '{' actionlines '}' ';' + { + $5->setComment(*$1); + g_actionclasses[*$3] = $5; + delete $3; + } +; + +actionlines: + { + $$ = new PrdrGroup(Prdr::ACTION); + } + | actionlines actionline ';' + { + if (NULL != $2) + $1->cv_rules.push_back($2); + $$ = $1; + } +; + +actionline: + { + $$ = NULL; + } + | PRDR_ID + { + $$ = new PrdrExprRef($1); + g_references.push_front(PrdrRefPair("a", *$1)); + } + | action_threshold { $$ = $1; } + | action_shared_threshold { $$ = $1; } + | action_analyse { $$ = $1; } + | action_analyse_conn { $$ = $1; } + | action_try { $$ = $1; } + | action_dump { $$ = $1; } + | action_gard { $$ = $1; } + | action_callout { $$ = $1; } + | action_funccall { $$ = $1; } + | action_flag { $$ = $1; } + | action_capture { $$ = $1; } +; + +action_threshold: PRDR_ACT_THRESHOLD '(' ')' + { + $$ = new PrdrExprAct_Thresh(); + } + | PRDR_ACT_THRESHOLD '(' PRDR_FLD_KW '(' PRDR_INTEGER time_units ')' ')' + { + $$ = new PrdrExprAct_Thresh($5, $6); + } + | PRDR_ACT_THRESHOLD '(' PRDR_FLD_KW '(' PRDR_INTEGER time_units ')' ',' PRDR_MFG_KW '(' PRDR_INTEGER time_units ')' ')' + { + $$ = new PrdrExprAct_Thresh($5, $6, $11, $12); + } + | PRDR_ACT_THRESHOLD '(' PRDR_FLD_KW '(' PRDR_INTEGER time_units ')' ',' PRDR_MFG_FILE_KW '(' PRDR_ID ')' ')' + { + $$ = new PrdrExprAct_Thresh($5, $6, 0, NULL, $11); + } +; + +action_shared_threshold: action_threshold PRDR_SHARED_KW '(' PRDR_INTEGER ')' + { + static_cast<PrdrExprAct_Thresh *>($1)->cv_3 = $4; + $$ = $1; + } +; + +time_units: + { + $$ = new PrdrExprTime(0xffffffff, Prdr::PRDR_TIME_BASE_SEC); + } + // FIXME: It is impossible to reach a theshold of 1000 per second because + // PRD cannot respond to attentions that quickly (at least on the + // FSP). Need to add code to check if the threshold is possible to + // based on the reaction type per attention ratio. (RTC: 51218) + | '/' PRDR_TIME_SEC + { + $$ = new PrdrExprTime(1, Prdr::PRDR_TIME_BASE_SEC); + } + | '/' PRDR_TIME_MIN + { + $$ = new PrdrExprTime(1, Prdr::PRDR_TIME_BASE_MIN); + } + | '/' PRDR_TIME_HOUR + { + $$ = new PrdrExprTime(1, Prdr::PRDR_TIME_BASE_HOUR); + } + | '/' PRDR_TIME_DAY + { + $$ = new PrdrExprTime(1, Prdr::PRDR_TIME_BASE_DAY); + } + | '/' PRDR_INTEGER PRDR_TIME_SEC + { + $$ = new PrdrExprTime($2, Prdr::PRDR_TIME_BASE_SEC); + } + | '/' PRDR_INTEGER PRDR_TIME_MIN + { + $$ = new PrdrExprTime($2, Prdr::PRDR_TIME_BASE_MIN); + } + | '/' PRDR_INTEGER PRDR_TIME_HOUR + { + $$ = new PrdrExprTime($2, Prdr::PRDR_TIME_BASE_HOUR); + } + | '/' PRDR_INTEGER PRDR_TIME_DAY + { + $$ = new PrdrExprTime($2, Prdr::PRDR_TIME_BASE_DAY); + } +; + +action_analyse: PRDR_ACT_ANALYSE '(' PRDR_ID ')' + { + $$ = new PrdrExprRef($3); + g_references.push_front(PrdrRefPair("g",*$3)); + } +; + +action_analyse_conn: PRDR_ACT_ANALYSE '(' PRDR_CONNECTED '(' PRDR_ID ')' ')' + { + $$ = new PrdrExprAct_Analyse($5); + } +; + +action_analyse_conn: PRDR_ACT_ANALYSE '(' PRDR_CONNECTED '(' PRDR_ID ',' PRDR_INTEGER ')' ')' + { + $$ = new PrdrExprAct_Analyse($5, $7); + } +; + +action_try: PRDR_ACT_TRY '(' actionline ',' actionline ')' + { + $$ = new PrdrExprAct_Try($3,$5); + } +; + +action_dump: PRDR_ACT_DUMP '(' PRDR_ID ')' //@ecdf + { + $$ = new PrdrExprAct_Dump($3); + } + // TODO: Allow Dump connected. +; + +action_gard: PRDR_ACT_GARD '(' PRDR_ID ')' + { + $$ = new PrdrExprAct_Gard($3); + } +; + +action_callout: PRDR_ACT_CALLOUT '(' PRDR_ID ')' + { + $$ = new PrdrExprAct_Callout($3); + } + | PRDR_ACT_CALLOUT '(' PRDR_CONNECTED '(' PRDR_ID action_callout_alt ')' ',' PRDR_ID ')' + { + $$ = new PrdrExprAct_Callout($9, $5, PrdrExprAct_Callout::CALLOUT_CHIP, 0xffffffff, $6); + } + | PRDR_ACT_CALLOUT '(' PRDR_CONNECTED '(' PRDR_ID ',' PRDR_INTEGER action_callout_alt ')' ',' PRDR_ID ')' + { + $$ = new PrdrExprAct_Callout($11, $5, PrdrExprAct_Callout::CALLOUT_CHIP, $7, $8); + } + + + | PRDR_ACT_CALLOUT '(' PRDR_PROCEDURE '(' PRDR_ID ')' ',' PRDR_ID ')' + { + $$ = new PrdrExprAct_Callout($8, $5, PrdrExprAct_Callout::CALLOUT_PROC); + } + +; + +action_callout_alt: + { + $$ = NULL; + } + | ',' PRDR_ALTERNATE '(' actionline ')' + { + $$ = $4; + } +; + +action_funccall: PRDR_ACT_FUNCCALL '(' PRDR_STRING ')' + { + $$ = new PrdrExprAct_Funccall($3); + } + | PRDR_ACT_FUNCCALL '(' PRDR_STRING ',' PRDR_ID ')' + { + $$ = new PrdrExprAct_Funccall($3, $5); + } +; + +action_flag: PRDR_ACT_FLAG '(' PRDR_ID ')' + { + $$ = new PrdrExprAct_Flag($3); + } +; + +action_capture: PRDR_ACT_CAPTURE '(' PRDR_ID ')' + { + $$ = new PrdrExprAct_Capture($3); + } +; + + +dox_comment: dox_commentblk + { + $$ = $1; + } + | dox_commentblk dox_comment + { + (*$1) += (*$2); + $$ = $1; + } +; + +dox_commentblk: dox_commentline + { + $$ = $1; + } + | PRDR_DOX_ENDL + { + $$ = new std::string("\n"); + } +; + +dox_commentline: PRDR_DOX_COMMENT + { + $$ = $1; + } +; + +%% +/* Additional C Code */ + +void yyerror(const char * s) +{ + if (yyincfiles.empty()) + fprintf(stderr, "Line %d: %s\n", yyline, s); + else + fprintf(stderr, "File %s Line %d: %s\n", + yyincfiles.top().first.c_str(), + yyline, + s); + + g_hadError = true; +} + diff --git a/src/usr/diag/prdf/framework/rule/prdrExpr.H b/src/usr/diag/prdf/framework/rule/prdrExpr.H new file mode 100755 index 000000000..adb32fad9 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrExpr.H @@ -0,0 +1,1046 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrExpr.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDREXPR_H +#define __PRDREXPR_H + +#include <map> +#include <list> +#include <sstream> +#include <stdint.h> +#include <typeinfo> // for typeid + +#include <netinet/in.h> + +#include <prdrCommon.H> // for enums. + +// -- Forward defs // +class PrdrExpr; +uint16_t prdrGetRefId(std::string *); +char prdrGetRefType(std::string *); +void prdrCheckReferences(); +uint32_t prdrActionArgMap(const std::string &); +uint32_t prdrCaptureGroupMap(const std::string &); +uint32_t prdrCaptureTypeMap(const std::string &); // @jl04 Type for registers. +std::list<std::string> prdrParseDoxygen(std::string & i_string); +class PrdrChip; +extern PrdrChip * g_currentChip; +extern std::map<std::string, PrdrExpr *> g_rules; +extern void yyerror(const char *); +extern uint32_t g_nextAndBit; +extern bool g_hadError; +// -- end Forward defs // + +using Prdr::PrdrSignatureOp; + +class PrdrExpr +{ + public: + + virtual int output(FILE *) = 0; + + virtual void setComment(std::string & i_comment) + { cv_doxcomment = i_comment; }; + + virtual void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { o_stream << "Using default."; }; + + virtual uint16_t getSignature() + { + std::cerr << "def sig: " << typeid(*this).name() + << std::endl; + return PrdrSignatureOp::DEFAULT_SIGNATURE; + }; + + + PrdrExpr() : cv_doxcomment("") {}; + virtual ~PrdrExpr() {}; + + protected: + std::string cv_doxcomment; +}; + +class PrdrExprRef : public PrdrExpr +{ + public: + std::string * cv_name; + + PrdrExprRef(std::string * n) : cv_name(n) {}; + + int output(FILE * i_file) + { + char l_op = prdrGetRefType(cv_name); + uint16_t l_id = htons(prdrGetRefId(cv_name)); + + fwrite(&l_op, 1, 1, i_file); + fwrite(&l_id, sizeof(l_id), 1, i_file); + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << "<A HREF=\"#" << *cv_name << "\">" + << *cv_name << "</A>"; + } + + virtual uint16_t getSignature() + { + if (Prdr::REF_REG == prdrGetRefType(cv_name)) + { + return Util::hashString(cv_name->c_str()); + } + else + { + PrdrExpr * tmp = g_rules[*cv_name]; + if (NULL == tmp) + { + std::cerr << "NPE: " << *cv_name << std::endl; + } + return (NULL == tmp ? + PrdrSignatureOp::DEFAULT_SIGNATURE + : tmp->getSignature() + ); + } + }; + +}; + +class PrdrExprInt : public PrdrExpr +{ + public: + uint32_t cv_value; + char cv_op; + + PrdrExprInt() : cv_op(Prdr::INTEGER) {}; + PrdrExprInt(uint32_t v, char o = Prdr::INTEGER) : cv_value(v), + cv_op(o) {}; + + int output(FILE * i_file) + { + char tmp = cv_op; + fwrite(&tmp, 1, 1, i_file); + + if (Prdr::INTEGER != cv_op) + { + uint16_t temp = htons((uint16_t) cv_value); + fwrite(&temp, sizeof(temp), 1, i_file); + } + else + { + uint32_t temp = htonl(cv_value); + fwrite(&temp, sizeof(temp), 1, i_file); + } + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << cv_value; + o_errFile << std::setfill('0') << std::setw(2) << std::hex + << cv_value; + }; + + uint16_t getSignature() { return PrdrSignatureOp::DEFAULT_SIGNATURE; }; +}; + +class PrdrExprTime : public PrdrExpr +{ + public: + + uint32_t iv_units; + Prdr::PrdrTimeBaseFlags iv_base; + + PrdrExprTime() : + iv_units(0xffffffff), iv_base(Prdr::PRDR_TIME_BASE_SEC) + {} + + PrdrExprTime( uint32_t units, Prdr::PrdrTimeBaseFlags base ) : + iv_units(units), iv_base(base) + {} + + int output( FILE * i_file ) + { + uint32_t seconds = 0xffffffff; + if ( (seconds / iv_base) > iv_units ) + seconds = iv_units * iv_base; + + seconds = htonl( seconds ); + fwrite( &seconds, sizeof(seconds), 1, i_file ); + + return 0; + } + + void generateDoxygen( std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr ) + { + uint32_t seconds = iv_units * iv_base; + + o_stream << iv_units << " "; + switch ( iv_base ) + { + case Prdr::PRDR_TIME_BASE_SEC: o_stream << "sec"; break; + case Prdr::PRDR_TIME_BASE_MIN: o_stream << "min"; break; + case Prdr::PRDR_TIME_BASE_HOUR: o_stream << "hour"; break; + case Prdr::PRDR_TIME_BASE_DAY: o_stream << "day"; break; + default: ; + } + } +}; + +class PrdrExprBitString : public PrdrExpr +{ + public: + std::string cv_value; + char cv_op; + + PrdrExprBitString() : cv_value(), cv_op(Prdr::BIT_STR) {}; + PrdrExprBitString(std::string v, char o = Prdr::BIT_STR) : cv_value(v), + cv_op(o) {}; + + int output(FILE * i_file) + { + char tmp = cv_op; + fwrite(&tmp, 1, 1, i_file); + + // subtract 2 backticks. + uint8_t len = (cv_value.length() - 2) * 4; + fwrite(&len, sizeof(len), 1, i_file); + + uint8_t tmp8 = 0; + + len = len / 4; + + // Output binary data from hex. + for (int i = 0; i < len; i++) + { + if (isdigit(cv_value[i+1])) + { + tmp8 |= cv_value[i+1] - '0'; + } + else + { + tmp8 |= toupper(cv_value[i+1]) - 'A' + 0xa; + } + + if (i == (len - 1)) + { + while ((i % 2) != 1) + { + tmp8 <<= 4; + i++; + } + } + if (i % 2 == 1) + { + fwrite(&tmp8, sizeof(tmp8), 1, i_file); + tmp8 = 0; + } + + tmp8 <<= 4; + } + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << cv_value; + o_errFile << cv_value; + }; + + uint16_t getSignature() { return PrdrSignatureOp::DEFAULT_SIGNATURE; }; +}; + + +class PrdrExprOp1 : public PrdrExpr +{ + public: + char cv_op; + PrdrExpr * cv_arg; + + PrdrExprOp1(char o) : cv_op(o) {}; + PrdrExprOp1(char o, PrdrExpr * a) : cv_op(o), cv_arg(a) {}; + + int output(FILE * i_file) + { + fwrite(&cv_op, 1, 1, i_file); + cv_arg->output(i_file); + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << cv_op << " "; + if (NULL != cv_arg) + cv_arg->generateDoxygen(o_stream, o_trailing, o_errFile); + }; + + uint16_t getSignature() + { + return (NULL == cv_arg ? + PrdrSignatureOp::DEFAULT_SIGNATURE + : cv_arg->getSignature() + ); + } + +}; + +class PrdrExprOp2 : public PrdrExpr +{ + public: + PrdrExpr * cv_arg[2]; + char cv_op; + + PrdrExprOp2(char o) : cv_op(o) {}; + PrdrExprOp2(char o, PrdrExpr * a1, PrdrExpr * a2) : cv_op(o) + { + cv_arg[0] = a1; cv_arg[1] = a2; + }; + + int output(FILE * i_file) + { + fwrite(&cv_op, 1, 1, i_file); + cv_arg[0]->output(i_file); + cv_arg[1]->output(i_file); + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + if (NULL != cv_arg[0]) + cv_arg[0]->generateDoxygen(o_stream, o_trailing, o_errFile); + o_stream << " " << cv_op << " "; + + if (NULL != cv_arg[1]) + cv_arg[1]->generateDoxygen(o_stream, o_trailing, o_errFile); + }; + + uint16_t getSignature() + { + return PrdrSignatureOp::combineSig( + (NULL == cv_arg[0] ? + PrdrSignatureOp::DEFAULT_SIGNATURE + : cv_arg[0]->getSignature() + ), + (NULL == cv_arg[1] ? + PrdrSignatureOp::DEFAULT_SIGNATURE + : cv_arg[1]->getSignature() + )); + }; + +}; + +class PrdrExprAttnLink : public PrdrExpr +{ + public: + static const int MAX_ATTNS = 4; + PrdrExpr * cv_arg[MAX_ATTNS]; + + PrdrExprAttnLink(std::string * attn1, PrdrExpr * exp1, + std::string * attn2, PrdrExpr * exp2, + std::string * attn3, PrdrExpr * exp3, + std::string * attn4, PrdrExpr * exp4) + { + for (int i = 0; i < MAX_ATTNS; i++) + cv_arg[i] = NULL; + + cv_arg[decodeAttnType(attn1)] = exp1; + if (NULL != exp2) + cv_arg[decodeAttnType(attn2)] = exp2; + if (NULL != exp3) + cv_arg[decodeAttnType(attn3)] = exp3; + if (NULL != exp4) + cv_arg[decodeAttnType(attn4)] = exp4; + }; + + int output(FILE * i_file) + { + char cv_op = Prdr::ATTNLINK; + fwrite(&cv_op, 1, 1, i_file); + + cv_op = 0; + for (int i = 0; i < MAX_ATTNS; i++) + if (NULL != cv_arg[i]) + cv_op++; + fwrite(&cv_op, 1, 1, i_file); + + for (int i = 0; i < MAX_ATTNS; i++) + if (NULL != cv_arg[i]) + { + cv_op = i; + fwrite(&cv_op, 1, 1, i_file); + cv_arg[i]->output(i_file); + } + + return 0; + } + + uint16_t getSignature() + { + uint16_t l_val = PrdrSignatureOp::DEFAULT_SIGNATURE; + for (int i = 0; i < MAX_ATTNS; i++) + if (NULL != cv_arg[i]) + l_val = PrdrSignatureOp::combineSig(l_val, + cv_arg[i]->getSignature()); + else + l_val = PrdrSignatureOp::combineSig(l_val, + PrdrSignatureOp::DEFAULT_SIGNATURE); + return l_val; + }; + + protected: + int decodeAttnType(std::string * attn) + { + if (NULL == attn) + { + yyerror("ICE - NPE."); + } + else if ("CHECK_STOP" == *attn) + { + return 0; + } + else if ("RECOVERABLE" == *attn) + { + return 1; + } + else if ("SPECIAL" == *attn) + { + return 2; + } + else if ("PROC_CS" == *attn) + { + return 3; + } + else if ("UNIT_CS" == *attn) // @jl02 Add UNIT_CS check. + { + return 3; // @jl02 + } + else + { + char error[256]; + strcpy(error, "Invalid attention name: "); + strncat(error, attn->c_str(), 255); + + yyerror(error); + } + return 0; + }; +}; + + +class PrdrExprRule : public PrdrExpr +{ + public: + std::string * cv_rulename; + PrdrExpr * cv_bits; + std::string * cv_actionname; + + PrdrExprRule(std::string * r, PrdrExpr * b, std::string * a) + : cv_rulename(r), cv_bits(b), cv_actionname(a) {}; + + int output(FILE * i_file) + { + uint16_t l_ref; + char l_op; + + l_op = Prdr::REF_RULE; + fwrite(&l_op, 1, 1, i_file); + l_ref = htons(prdrGetRefId(cv_rulename)); + fwrite(&l_ref, sizeof(l_ref), 1, i_file); + + cv_bits->output(i_file); + + l_op = prdrGetRefType(cv_actionname); + fwrite(&l_op, 1, 1, i_file); + l_ref = htons(prdrGetRefId(cv_actionname)); + fwrite(&l_ref, sizeof(l_ref), 1, i_file); + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + std::list<std::string> l_parsed = prdrParseDoxygen(cv_doxcomment); + + std::string l_name("N/A"), l_short("N/A"), l_long(""); + std::ostringstream l_errFront, l_errBits, l_errBack; + + l_errFront << "\tPRDR_ERROR_SIGNATURE ( 0x" + << std::setfill('0') << std::setw(4) + << std::hex + << ( (PrdrExprRef(cv_rulename).getSignature() + + g_currentChip->cv_signatureOffset) & 0xffff ) + << "00"; + + o_stream << "<TD align=\"center\">"; + cv_bits->generateDoxygen(o_stream, o_trailing, l_errBits); + + if (std::string() != l_parsed.front()) + { + l_name = l_parsed.front(); + } + l_parsed.pop_front(); + + if (std::string() != l_parsed.front()) + { + l_short = l_parsed.front(); + } + l_parsed.pop_front(); + + if (std::string() != l_parsed.front()) + { + l_long = l_parsed.front(); + } + + o_stream << "<TD align=\"center\">"; + if (std::string() != l_long) + { + o_stream << "<A HREF=\"#" << l_name << "\">"; + + o_trailing += "<B><A NAME='" + l_name + "'>" ; + o_trailing += l_name + ": </A></B>"; + + o_trailing += l_short + "<BR>"; + o_trailing += l_long + "<BR><BR>\n"; + } + o_stream << l_name; + if (std::string() != l_long) + { + o_stream << "</A>"; + o_trailing += "</A>"; + } + + o_stream << "<TD>" << l_short; + + + o_stream << "<TD><A HREF=\"#" << *cv_actionname << "\">" + << *cv_actionname << "</A>"; + + l_errBack << ", \"" << l_name << "\", \"" << l_short << "\""; + l_errBack << " )" << std::endl; + + for (size_t i = 0; i < (l_errBits.str().length()/2); i++) + { + o_errFile << l_errFront.str(); + + if (typeid(*cv_bits).name() == typeid(PrdrExprOp2).name()) + { + if (static_cast<PrdrExprOp2 *>(cv_bits)->cv_op == Prdr::AND) + { + o_errFile << std::setfill('0') << std::setw(2) + << std::hex; + o_errFile << g_nextAndBit; + g_nextAndBit++; + + i = 256; + } + else + { + o_errFile << l_errBits.str()[2*i] + << l_errBits.str()[2*i+1]; + } + } + else + { + o_errFile << l_errBits.str()[2*i] + << l_errBits.str()[2*i+1]; + } + + o_errFile << l_errBack.str(); + } + }; +}; + +class PrdrExprAct_Try : public PrdrExpr +{ + public: + PrdrExpr * cv_left, * cv_right; + + PrdrExprAct_Try(PrdrExpr * l, PrdrExpr * r) : cv_left(l), + cv_right(r) {}; + + int output(FILE * i_file) + { + char l_op; + + l_op = Prdr::ACT_TRY; + fwrite(&l_op, 1, 1, i_file); + cv_left->output(i_file); + cv_right->output(i_file); + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << "try { "; + if (NULL != cv_left) + cv_left->generateDoxygen(o_stream, o_trailing, o_errFile); + o_stream << ", "; + if (NULL != cv_right) + cv_right->generateDoxygen(o_stream, o_trailing, o_errFile); + o_stream << " } "; + }; + +}; + +class PrdrExprAct_Thresh : public PrdrExpr +{ + public: + PrdrExpr* cv_thresholdTime[2]; + //Maximum threshold value supported is 255 + uint8_t cv_field; + uint8_t cv_mfg; + uint32_t cv_3; + std::string * cv_mfg_file_thr; + + PrdrExprAct_Thresh( uint8_t i_field = 0, PrdrExpr * i_fieldTime = NULL, + uint8_t i_mfg = 0, PrdrExpr * i_mfgTime = NULL, + std::string * i_mfg_file = NULL ) : + cv_field(i_field), cv_mfg(i_mfg), cv_mfg_file_thr(i_mfg_file) + { + cv_thresholdTime[0] = i_fieldTime; + cv_thresholdTime[1] = i_mfgTime; + }; + + int output(FILE * i_file) + { + char l_op; + l_op = Prdr::ACT_THRES; + fwrite(&l_op, 1, 1, i_file); + + if (NULL == cv_thresholdTime[0]) + l_op = 0; + else if ( (NULL == cv_thresholdTime[1]) && + (NULL == cv_mfg_file_thr)) + { + l_op = 1; + } + else + l_op = 2; + + if (0 != cv_3) + l_op |= 0x40; + + if (NULL != cv_mfg_file_thr) + l_op |= 0x20; + + fwrite(&l_op, 1, 1, i_file); + + if (NULL != cv_thresholdTime[0]) + { + fwrite(&cv_field, sizeof(cv_field), 1, i_file); + cv_thresholdTime[0]->output(i_file); + if (NULL != cv_thresholdTime[1]) + { + fwrite(&cv_mfg, sizeof(cv_mfg), 1, i_file); + cv_thresholdTime[1]->output(i_file); + } + else if (NULL != cv_mfg_file_thr) + { + uint32_t l_tmp32 = prdrActionArgMap(*cv_mfg_file_thr); + l_tmp32 = htonl(l_tmp32); + fwrite(&l_tmp32, sizeof(l_tmp32), 1, i_file); + } + } + + if (0 != cv_3) + { + uint32_t l_tmp32 = htonl(cv_3); + fwrite(&l_tmp32, 4, 1, i_file); + } + + return 0; + } + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << "threshold("; + if (NULL != cv_thresholdTime[0]) + { + uint32_t units = cv_field; + o_stream <<" field"; + o_stream << "("; + o_stream << units; + o_stream << ","; + cv_thresholdTime[0]->generateDoxygen(o_stream, o_trailing, o_errFile); + o_stream << ")"; + if (NULL != cv_thresholdTime[1]) + { + units = cv_mfg; + o_stream << ", mfg"; + o_stream << "("; + o_stream << units; + o_stream << ","; + cv_thresholdTime[1]->generateDoxygen(o_stream, o_trailing, o_errFile); + o_stream << ")"; + } + else if (NULL != cv_mfg_file_thr) + { + o_stream << ", mfg_file"; + o_stream << "("; + o_stream << *cv_mfg_file_thr; + o_stream << ")"; + } + } + o_stream << ")"; + if (0 != cv_3) + { + o_stream << " shared(" << cv_3 << ")"; + } + }; + +}; + + +class PrdrExprAct_Dump : public PrdrExpr //@ecdf +{ + public: + std::string * cv_1; + + PrdrExprAct_Dump(std::string * i_1) : cv_1(i_1) {}; + + int output(FILE * i_file) + { + char l_op; + + l_op = Prdr::ACT_DUMP; + fwrite(&l_op, 1, 1, i_file); + + uint32_t l_dType; + + if (NULL == cv_1) + l_dType = prdrActionArgMap("DUMP_CONTENT_HW"); + else + l_dType = prdrActionArgMap(*cv_1); + l_dType = htonl(l_dType); + fwrite(&l_dType, sizeof(l_dType), 1, i_file); + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << "dump( " << *cv_1 << " ) "; + }; + +}; + +class PrdrExprAct_Gard : public PrdrExpr +{ + public: + std::string * cv_1; + + PrdrExprAct_Gard(std::string * i_1) : cv_1(i_1) {}; + + int output(FILE * i_file) + { + char l_op; + + l_op = Prdr::ACT_GARD; + fwrite(&l_op, 1, 1, i_file); + + uint32_t l_gType = htonl(prdrActionArgMap(*cv_1)); + fwrite(&l_gType, sizeof(l_gType), 1, i_file); + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << "gard( " << *cv_1 << " ) "; + }; + +}; + +class PrdrExprAct_Analyse : public PrdrExpr +{ + public: + std::string * cv_1; + uint32_t cv_2; + + PrdrExprAct_Analyse( std::string * i_1, uint32_t i_2 = 0xffffffff ) : + cv_1(i_1), cv_2(i_2) + {} + + int output(FILE * i_file) + { + char l_op = Prdr::ACT_ANALY; + fwrite(&l_op, 1, 1, i_file); + + uint32_t l_chipType = htonl(prdrActionArgMap(*cv_1)); + fwrite(&l_chipType, sizeof(l_chipType), 1, i_file); + + uint32_t l_chipIndx = htonl(cv_2); + fwrite(&l_chipIndx, sizeof(l_chipIndx), 1, i_file); + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << "analyze ( "; + o_stream << "connected ( " << *cv_1 ; + if ( 0xffffffff != cv_2 ) + o_stream << ", " << cv_2; + o_stream << " ) ) "; + } + +}; + +class PrdrExprAct_Callout : public PrdrExpr +{ + public: + std::string * cv_1, * cv_2; + uint32_t cv_3; + + PrdrExpr * cv_alt; + + enum Callout_type + { + CALLOUT_SELF = 's', + CALLOUT_CHIP = 'c', + CALLOUT_PROC = 'p', + }; + + Callout_type cv_type; + + PrdrExprAct_Callout(std::string * i_1, + std::string * i_2 = NULL, + Callout_type i_t = CALLOUT_SELF, + uint32_t i_3 = 0xffffffff, + PrdrExpr * i_alt = NULL) : + cv_1(i_1), cv_2(i_2), cv_3(i_3), cv_alt(i_alt), cv_type(i_t) + {} + + int output(FILE * i_file) + { + char l_op; + + l_op = Prdr::ACT_CALL; + fwrite(&l_op, 1, 1, i_file); + + l_op = cv_type; + fwrite(&l_op, 1, 1, i_file); + + uint32_t l_priority = htonl(prdrActionArgMap(*cv_1)); + fwrite(&l_priority, sizeof(l_priority), 1, i_file); + + if (CALLOUT_SELF != cv_type) + { + uint32_t l_arg = htonl(prdrActionArgMap(*cv_2)); + fwrite(&l_arg, sizeof(l_arg), 1, i_file); + + l_arg = htonl(cv_3); + fwrite(&l_arg, sizeof(l_arg), 1, i_file); + // Write bool for ALT resolution. + l_op = (NULL == cv_alt ? 0 : 1); + fwrite(&l_op, 1, 1, i_file); + + // Write ALT resolution. + if (NULL != cv_alt) + cv_alt->output(i_file); + } + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << "callout ( "; + if (CALLOUT_SELF == cv_type) + { + o_stream << "SELF, " << *cv_1 << " )"; + } + else if (CALLOUT_PROC == cv_type) + { + o_stream << "procedure ( " << *cv_2 << " ), " << *cv_1 << " ) "; + } + else + { + o_stream << "connected ( " << *cv_2 ; + if ( 0xffffffff != cv_3 ) + o_stream << ", " << cv_3; + o_stream << " ), " << *cv_1 << " ) "; + } + } + +}; + +class PrdrExprAct_Funccall : public PrdrExpr +{ + public: + std::string * cv_1, * cv_2; + + PrdrExprAct_Funccall(std::string * i_1, std::string * i_2 = NULL) : + cv_1(i_1), cv_2(i_2) {}; + + int output(FILE * i_file) + { + char l_op; + + l_op = Prdr::ACT_FUNC; + fwrite(&l_op, 1, 1, i_file); + + if ('"' == (*cv_1)[0]) + (*cv_1) = cv_1->substr(1, cv_1->size() - 2); + fwrite(cv_1->c_str(), cv_1->size() + 1, 1, i_file); + + uint32_t l_chip; + if (NULL != cv_2) + l_chip = htonl(prdrActionArgMap(*cv_2)); + else + l_chip = 0; + fwrite(&l_chip, sizeof(l_chip), 1, i_file); + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << "funccall( " << *cv_1; + if (NULL != cv_2) + o_stream << ", " << *cv_2; + o_stream << " ) "; + }; + + +}; + +class PrdrExprAct_Flag : public PrdrExpr +{ + public: + std::string * cv_1; + + PrdrExprAct_Flag(std::string * i_1) : cv_1(i_1) {}; + + int output(FILE * i_file) + { + char l_op; + + l_op = Prdr::ACT_FLAG; + fwrite(&l_op, 1, 1, i_file); + + uint32_t l_flag = htonl(prdrActionArgMap(*cv_1)); + fwrite(&l_flag, sizeof(l_flag), 1, i_file); + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << "flag( " << *cv_1 << " ) "; + }; + + +}; + +class PrdrExprAct_Capture : public PrdrExpr +{ + public: + std::string * cv_1; + + PrdrExprAct_Capture(std::string * i_1) : cv_1(i_1) {}; + + int output(FILE * i_file) + { + char l_op; + + l_op = Prdr::ACT_CAPT; + fwrite(&l_op, 1, 1, i_file); + + uint32_t l_group = htonl(prdrCaptureGroupMap(*cv_1)); + fwrite(&l_group, sizeof(l_group), 1, i_file); + + return 0; + }; + + void generateDoxygen(std::ostream & o_stream, + std::string & o_trailing, + std::ostream & o_errFile = std::cerr) + { + o_stream << "capture( " << *cv_1 << " ) "; + }; + + +}; + + +extern std::map<std::string, PrdrExpr *> g_rules; + +typedef std::pair<std::string, std::string> PrdrRefPair; +extern std::list<PrdrRefPair> g_references; + +#endif + +// Change Log ********************************************************* +// +// Flag Reason Vers Date Coder Description +// ---- -------- ---- -------- -------- ------------------------------- +// F494911 f310 03/04/05 iawillia Initial File Creation +// D515833 f300 09/19/05 iawillia Add capture support. +// F526728 f300 10/25/05 iawillia Add >> and << registers. +// F534311 f300 01/10/06 iawillia Add bit string expression. +// F544848 f300 04/03/06 iawillia Add multi-bit support. +// F549888 f300 05/01/06 iawillia Add Proc. CS attention. +// ecdf F550548 f300 05/04/06 iawillia eClipz DUMP flags support. +// D555348 f310 06/05/06 iawillia Update HTML generation. +// jl02 F605874 f330 07/31/07 lukas Add functions to PRD framework/Galaxy +// 2 code for unit CS. +// @jl04 F630836 f330 09/17/07 lukas Add error log Cap. type. +// End Change Log ***************************************************** diff --git a/src/usr/diag/prdf/framework/rule/prdrGroup.H b/src/usr/diag/prdf/framework/rule/prdrGroup.H new file mode 100755 index 000000000..ee0f1026b --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrGroup.H @@ -0,0 +1,247 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrGroup.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDRGROUP_H +#define __PRDRGROUP_H + +#include <string> +#include <list> +#include <netinet/in.h> + +#include <prdrExpr.H> +#include <prdrCommon.H> + +class PrdrChip; +extern PrdrChip * g_currentChip; +extern uint32_t g_nextAndBit; +class PrdrGroup_Filter; + +class PrdrGroup +{ + public: + std::list<PrdrExpr *> cv_rules; + PrdrExpr * cv_priorityList; + + char cv_op; + uint8_t cv_flags; + std::string cv_doxcomment; + + PrdrGroup() : + cv_priorityList(NULL), + cv_op(Prdr::GROUP), + cv_flags(0), + cv_doxcomment() {}; + PrdrGroup(char o) : + cv_priorityList(NULL), + cv_op(o), + cv_flags(0), + cv_doxcomment() {}; + + static void merge(PrdrGroup * i_l, PrdrGroup * i_r) + { + // Copy over rules. + i_l->cv_rules.insert(i_l->cv_rules.end(), + i_r->cv_rules.begin(), + i_r->cv_rules.end()); + + // Merge flags. + i_l->cv_flags |= i_r->cv_flags; + + // Set Priority list. + if (NULL != i_l->cv_priorityList) + i_r->cv_priorityList = i_l->cv_priorityList; + + }; + + void setComment(std::string & i_comment) + { + if (Prdr::GROUP == cv_op) + { + PrdrExpr * l_front = *(cv_rules.begin()); + if (NULL == l_front) + { + // ICE. + } + else + { + l_front->setComment(i_comment); + } + } + else if (Prdr::ACTION == cv_op) + { + cv_doxcomment = i_comment; + } + }; + + + void generateDoxygen(std::ostream & o_stream, + std::string i_name, + std::ostream & o_errFile = std::cerr) + { + std::string l_trailingInfo = ""; + + if (Prdr::GROUP == cv_op) + { + o_stream << "<H3><A NAME='" + i_name + "'>" + << i_name << "</A></H3>"; + + o_stream << "<TABLE><THEAD>" + << "<TR><TH colspan=\"4\" align=\"left\">" + << "Register Group: " << i_name + << "</TR>" << std::endl; + + o_stream << "<TR><TH width=\"7%\">Bit(s)<TH width=\"25%\">" + << "Name<TH width=\"50%\">Short Description" + << "<TH width=\"18%\">Actions</TR>" + << "</THEAD><TBODY>" + << std::endl; + + g_nextAndBit = 64; + } + else if (Prdr::ACTION == cv_op) + { + o_stream << "<TR>"; + o_stream << "<TD><P><A NAME='" << i_name << "'>" + << i_name << "</A></P></TD> "; + o_stream << "<TD>"; + if (std::string() != cv_doxcomment) + { + o_stream << cv_doxcomment; + } + o_stream << "</TD>"; + + o_stream << "<TD>" << std::endl; + } + + for (std::list<PrdrExpr *>::iterator i = cv_rules.begin(); + i != cv_rules.end(); + i++) + { + if (Prdr::GROUP == cv_op) + { + o_stream << "<TR>"; + } + else if (Prdr::ACTION == cv_op) + { + if (i != cv_rules.begin()) + o_stream << "<BR>" << std::endl; + + } + (*i)->generateDoxygen(o_stream, l_trailingInfo, o_errFile); + if (Prdr::GROUP == cv_op) + { + o_stream << "</TR>" << std::endl; + } + + } + if (Prdr::GROUP == cv_op) + { + o_stream << "</TBODY></TABLE><BR>" << std::endl; + o_stream << l_trailingInfo << std::endl; + o_stream << "</A>"; + } + else if (Prdr::ACTION == cv_op) + { + o_stream << "</TD></TR>" << std::endl; + } + }; + + int output(FILE * i_file) + { + fwrite(&cv_op, 1, 1, i_file); + + uint16_t l_ruleCount = htons(cv_rules.size()); + fwrite(&l_ruleCount, sizeof(l_ruleCount), 1, i_file); + + // Write flags for GROUP op. + if (Prdr::GROUP == cv_op) + { + fwrite(&cv_flags, 1, 1, i_file); + if (Prdr::PRDR_GROUP_FILTER_PRIORITY & cv_flags) + { + cv_priorityList->output(i_file); + } + } + + + for (std::list<PrdrExpr *>::iterator i = cv_rules.begin(); + i != cv_rules.end(); + i++) + { + (*i)->output(i_file); + } + + return 0; + }; + + +}; + +extern std::map<std::string, PrdrGroup *> g_groups; +extern std::map<std::string, PrdrGroup *> g_actionclasses; +extern std::map<std::string, std::string> g_attentionStartGroup; + +class PrdrGroup_Filter +{ + public: + virtual ~PrdrGroup_Filter() { } // zs01 + virtual void AddFilter(PrdrGroup *) = 0; +}; + +class PrdrGroup_Filter_SingleBit : public PrdrGroup_Filter +{ + public: + void AddFilter(PrdrGroup * i_group) + { + i_group->cv_flags |= Prdr::PRDR_GROUP_FILTER_SINGLE_BIT; + }; +}; + +class PrdrGroup_Filter_Priority : public PrdrGroup_Filter +{ + public: + PrdrGroup_Filter_Priority(PrdrExpr * i_list) : iv_list(i_list) {}; + + void AddFilter(PrdrGroup * i_group) + { + i_group->cv_flags |= Prdr::PRDR_GROUP_FILTER_PRIORITY; + i_group->cv_priorityList = iv_list; + }; + + private: + PrdrExpr * iv_list; +}; + + +#endif + +// Change Log ********************************************************* +// +// Flag Reason Vers Date Coder Description +// ---- -------- ---- -------- -------- ------------------------------- +// F494911 f310 03/04/05 iawillia Initial File Creation +// F544848 f300 04/03/06 iawillia Add multi-bit support. +// D555348 f310 06/05/06 iawillia Update HTML generation. +// F557408 f310 06/16/06 iawillia Add single-bit filter support. +// zs01 D620028 f330 07/25/07 zshelle Support for mcp5 compiler +// End Change Log ***************************************************** diff --git a/src/usr/diag/prdf/framework/rule/prdrLoadChip.C b/src/usr/diag/prdf/framework/rule/prdrLoadChip.C new file mode 100755 index 000000000..c885c55c9 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrLoadChip.C @@ -0,0 +1,505 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrLoadChip.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include <string.h> // for memcmp +#include <prdrCommon.H> + +#include <prdrLoadChip.H> +#include <errlentry.H> +#include <utilstream.H> +#include <UtilFunct.H> + +#include <prdf_service_codes.H> +#include <prdfThresholdResolutions.H> +#include <iipglobl.h> +#include <UtilHash.H> // for Util::hashString + +#include <algorithm> // for std::generate_n + +namespace Prdr +{ + +void prdrReadExpr(UtilStream & i_stream, PrdrExpr & o_expr); + +// NOTE: caller must call delete[] to release the buffer +void prdrReadString(UtilStream & i_stream, char *& o_string) +{ + char l_pBuf[100]; + memset(l_pBuf,'\0',100); + char* l_pCursor = l_pBuf; + + char l_tmp; + + do + { + i_stream >> l_tmp; + if ('\0' != l_tmp) + { + *l_pCursor = l_tmp; + l_pCursor++; + } + } while ('\0' != l_tmp); + + o_string = new char[strlen(l_pBuf) + 1]; + strcpy(o_string, l_pBuf); +} + +/** + * @brief read bit string data out from the stream + */ +void prdrReadBitString(UtilStream & i_stream, std::vector<uint64_t> & o_vector) +{ + uint64_t l_tmp64; + uint8_t l_tmp8; + i_stream >> l_tmp8; + + int length = (l_tmp8 / 8) + ((l_tmp8 % 8) != 0 ? 1 : 0); + + for (int i = 0; i < (length/8); i++) + { + i_stream >> l_tmp64; + o_vector.push_back(l_tmp64); + } +} + +errlHndl_t prdrLoadChip(UtilStream & i_stream, PrdrChip & o_chip) +{ + errlHndl_t l_errl = NULL; + + do + { + char l_temp[8]; + + // read header. + i_stream >> l_temp; + if (0 != memcmp(l_temp, "PRDRCHIP", 8)) + { + PRDF_ERR("prdrLoadChip() bad chip file - l_temp: %s ", l_temp); + // Bad chip file. + /*@ + * @errortype + * @refcode LIC_REFCODE + * @subsys EPUB_FIRMWARE_SP + * @reasoncode PRDF_CODE_FAIL + * + * @moduleid PRDF_PRDRLOADCHIP + * @userdata1 0x50524452 ("PRDR") + * @userdata2 0x43484950 ("CHIP") + * @devdesc Attempted to load chip rule file that lacked + * the proper header "PRDRCHIP". + */ + PRDF_CREATE_ERRL(l_errl, + ERRL_SEV_UNRECOVERABLE, + ERRL_ETYPE_NOT_APPLICABLE, + SRCI_ERR_INFO, + SRCI_NO_ATTR, + PRDF_PRDRLOADCHIP, + LIC_REFCODE, + PRDF_CODE_FAIL, + 0x50524452, // PRDR + 0x43484950, // CHIP + 0, 0); + break; + } + + // read chip info. + i_stream >> o_chip.cv_chipId; + i_stream >> o_chip.cv_targetType; + i_stream >> o_chip.cv_signatureOffset; + i_stream >> o_chip.cv_dumpType; //@ecdf + i_stream >> o_chip.cv_scomLen; + + // read registers. + i_stream >> o_chip.cv_regCount; + + if (o_chip.cv_regCount != 0) + { + o_chip.cv_registers = new PrdrRegister[o_chip.cv_regCount]; + for (uint32_t i = 0; i < o_chip.cv_regCount; i++) + { + i_stream >> o_chip.cv_registers[i].cv_name; + i_stream >> o_chip.cv_registers[i].cv_flags; + i_stream >> o_chip.cv_registers[i].cv_scomAddr; + + if (o_chip.cv_registers[i].cv_flags & + Prdr::PRDR_REGISTER_SCOMLEN) + { + i_stream >> o_chip.cv_registers[i].cv_scomLen; + } + else + { + o_chip.cv_registers[i].cv_scomLen = o_chip.cv_scomLen; + } + + if (o_chip.cv_registers[i].cv_flags & + Prdr::PRDR_REGISTER_RESETS) + { + // Read 'n' from stream. Read that many reset structs out + // of the stream, insert into cv_resets for register. + std::generate_n( + std::back_inserter( + o_chip.cv_registers[i].cv_resets + ), + Util::unary_input<uint16_t, UtilStream>(i_stream)(), + Util::unary_input<PrdrRegister::ResetOrMaskStruct, + UtilStream> (i_stream) + ); + + } + + if (o_chip.cv_registers[i].cv_flags & + Prdr::PRDR_REGISTER_MASKS) + { + // Read 'n' from stream. Read that many mask structs out + // of the stream, insert into cv_masks for register. + std::generate_n( + std::back_inserter( + o_chip.cv_registers[i].cv_masks + ), + Util::unary_input<uint16_t, UtilStream>(i_stream)(), + Util::unary_input<PrdrRegister::ResetOrMaskStruct, + UtilStream> (i_stream) + ); + + } + + if (o_chip.cv_registers[i].cv_flags & + Prdr::PRDR_REGISTER_CAPTURE) + { + // Read 'n' from stream. Read that many mask structs out + // of the stream, insert into cv_masks for register. + std::generate_n( + std::back_inserter( + o_chip.cv_registers[i].cv_captures + ), + Util::unary_input<uint16_t, UtilStream>(i_stream)(), + Util::unary_input<PrdrRegister::CaptureInfoStruct, + UtilStream> (i_stream) + ); + } + } + } + + // read rules. + i_stream >> o_chip.cv_ruleCount; + if (o_chip.cv_ruleCount != 0) + { + o_chip.cv_rules = new PrdrExpr[o_chip.cv_ruleCount]; + for (uint32_t i = 0; i < o_chip.cv_ruleCount; i++) + { + i_stream >> l_temp[0]; // should be 'R' + prdrReadExpr(i_stream, o_chip.cv_rules[i]); + } + } + + // read groups. + i_stream >> o_chip.cv_groupCount; + for (int i = 0; i < NUM_GROUP_ATTN; i++) // @jl02 JL Added this enum type for the number of Attention types. + i_stream >> o_chip.cv_groupAttn[i]; + if (o_chip.cv_groupCount != 0) + { + o_chip.cv_groups = new PrdrExpr * [o_chip.cv_groupCount]; + o_chip.cv_groupSize = new uint16_t[o_chip.cv_groupCount]; + o_chip.cv_groupFlags = new uint8_t[o_chip.cv_groupCount]; + o_chip.cv_groupPriorityBits = new PrdrExpr * [o_chip.cv_groupCount]; + for (uint32_t i = 0; i < o_chip.cv_groupCount; i++) + { + i_stream >> l_temp[0]; // should be 'G' + i_stream >> o_chip.cv_groupSize[i]; + i_stream >> o_chip.cv_groupFlags[i]; + if (Prdr::PRDR_GROUP_FILTER_PRIORITY & o_chip.cv_groupFlags[i]) + { + o_chip.cv_groupPriorityBits[i] = new PrdrExpr(); + prdrReadExpr(i_stream, *o_chip.cv_groupPriorityBits[i]); + } + else + { + o_chip.cv_groupPriorityBits[i] = NULL; + } + if (0 != o_chip.cv_groupSize[i]) + { + o_chip.cv_groups[i] = new PrdrExpr[o_chip.cv_groupSize[i]]; + for (uint32_t j = 0; j < o_chip.cv_groupSize[i]; j++) + { + prdrReadExpr(i_stream, o_chip.cv_groups[i][j]); + if (Prdr::REF_RULE == o_chip.cv_groups[i][j].cv_op) + { + for (int k = 1; k <= 2; k++) + { + o_chip.cv_groups[i][j].cv_value[k].p = + new PrdrExpr(); + o_chip.cv_groups[i][j].cv_deletePtr[k] = true; + + prdrReadExpr(i_stream, + *o_chip.cv_groups[i][j].cv_value[k].p); + } + } + } + } + else + { + o_chip.cv_groups[i] = new PrdrExpr[0]; /*accessing beyond memory*/ + // False error BEAM. + }; + } + } + + // read actions. + i_stream >> o_chip.cv_actionCount; + if (o_chip.cv_actionCount != 0) + { + o_chip.cv_actions = new PrdrExpr * [o_chip.cv_actionCount]; + o_chip.cv_actionSize = new uint16_t[o_chip.cv_actionCount]; + for (uint32_t i = 0; i < o_chip.cv_actionCount; i++) + { + i_stream >> l_temp[0]; // should be 'A' + i_stream >> o_chip.cv_actionSize[i]; + if (0 != o_chip.cv_actionSize[i]) + { + o_chip.cv_actions[i] = + new PrdrExpr[o_chip.cv_actionSize[i]]; + for (uint32_t j = 0; j < o_chip.cv_actionSize[i]; j++) + { + prdrReadExpr(i_stream, o_chip.cv_actions[i][j]); + } + } + else //@pw01 + { + o_chip.cv_actions[i] = NULL; + } + } + } + + } while (false); + + if (NULL == l_errl) + l_errl = i_stream.getLastError(); + + return l_errl; +} + +void prdrReadExpr(UtilStream & i_stream, PrdrExpr & o_expr) +{ + unsigned char l_tmpChar; + uint32_t l_tmp32; + uint16_t l_tmp16; + uint8_t l_tmp8; + bool l_tmpBool; + + i_stream >> o_expr.cv_op; + + switch(o_expr.cv_op) + { + case Prdr::AND: + case Prdr::OR: + case Prdr::XOR: + case Prdr::LSHIFT: + case Prdr::RSHIFT: + case Prdr::ACT_TRY: + o_expr.cv_value[0].p = new PrdrExpr(); + o_expr.cv_deletePtr[0] = true; + prdrReadExpr(i_stream, *o_expr.cv_value[0].p); + + o_expr.cv_value[1].p = new PrdrExpr(); + o_expr.cv_deletePtr[1] = true; + prdrReadExpr(i_stream, *o_expr.cv_value[1].p); + break; + + case Prdr::NOT: + o_expr.cv_value[0].p = new PrdrExpr(); + o_expr.cv_deletePtr[0] = true; + prdrReadExpr(i_stream, *o_expr.cv_value[0].p); + break; + + case Prdr::INTEGER: + case Prdr::ACT_GARD: + case Prdr::ACT_FLAG: + i_stream >> o_expr.cv_value[0].i; + break; + + case Prdr::REF_RULE: + case Prdr::REF_REG: + case Prdr::REF_GRP: + case Prdr::REF_ACT: + case Prdr::INT_SHORT: + i_stream >> l_tmp16; + o_expr.cv_value[0].i = l_tmp16; + break; + + case Prdr::BIT_STR: + o_expr.cv_bitStrVect.clear(); + prdrReadBitString(i_stream, o_expr.cv_bitStrVect); + break; + + case Prdr::ACT_THRES: + o_expr.cv_value[0].i = ThresholdResolution::cv_fieldDefault.interval; + o_expr.cv_value[1].i = ThresholdResolution::cv_fieldDefault.threshold; + o_expr.cv_value[2].i = ThresholdResolution::cv_mnfgDefault.interval; + o_expr.cv_value[3].i = ThresholdResolution::cv_mnfgDefault.threshold; + //The syntax of thresholds in rule file is + // op field_threshold field_intervale + //optional fields (mnfg_threshold, mnfg_interval } | mnfg_ilr_threshold | maskid + i_stream >> l_tmpChar; + l_tmpBool = (0x40 == (0x40 & l_tmpChar)); + l_tmpChar &= (~0x40); + o_expr.cv_value[4].i = (0x20 == (0x20 & l_tmpChar)); + l_tmpChar &= (~0x20); + // The values which different parameter will have + // cv_value[0,1] error frequency and time in sec for field threshold + //cv_value[4] true if mnfg threshols needs to be picked up from mnfg file, false otherwise + // cv_value [2, 3]: error frequency and time in sec for mnfg threshold if cv_value[4] is false + // otherwise cv_value[3] tells which threshold needs to pick up from mnfg file + // cv_value[5] maski id if shared threshold + if (0 != l_tmpChar) + for (uint8_t i = 0; i < l_tmpChar; i++) + { + if ( (1 != i) || (0 == o_expr.cv_value[4].i) ) + { + //entry has errorFrequency + i_stream >> l_tmp8; + o_expr.cv_value[2*i].i = l_tmp8; + } + i_stream >> o_expr.cv_value[2*i + 1].i; + } + if (l_tmpBool) + i_stream >> o_expr.cv_value[5]; + break; + + case Prdr::ACT_ANALY: + i_stream >> o_expr.cv_value[0].i; + i_stream >> o_expr.cv_value[1].i; + break; + + case Prdr::ACT_FUNC: + o_expr.cv_actFunc = NULL; + prdrReadString(i_stream, o_expr.cv_actFunc); + + i_stream >> o_expr.cv_value[1].i; + break; + + case Prdr::ACT_CALL: + i_stream >> l_tmpChar; + o_expr.cv_value[0].i = l_tmpChar; + i_stream >> o_expr.cv_value[1].i; + if ('s' != o_expr.cv_value[0].i) + { + i_stream >> o_expr.cv_value[2].i; + i_stream >> o_expr.cv_value[3].i; + + // Read ALT bool. + i_stream >> l_tmpChar; + if (0 != l_tmpChar) + { + o_expr.cv_value[4].p = new PrdrExpr(); + o_expr.cv_deletePtr[4] = true; + prdrReadExpr(i_stream, *o_expr.cv_value[4].p); + } + else + o_expr.cv_value[4].p = NULL; + } + break; + + case Prdr::ACT_DUMP: //@ecdf + i_stream >> o_expr.cv_value[0].i; + break; + + case Prdr::ATTNLINK: + i_stream >> l_tmpChar; // get count + l_tmp32 = l_tmpChar; + for (size_t i = 0; i < l_tmp32; i++) + { + i_stream >> l_tmpChar; // get index + o_expr.cv_value[l_tmpChar].p = new PrdrExpr(); + o_expr.cv_deletePtr[l_tmpChar] = true; + prdrReadExpr(i_stream, *o_expr.cv_value[l_tmpChar].p); + } + break; + + case Prdr::ACT_CAPT: + i_stream >> o_expr.cv_value[0].i; + + default: + break; + } +} + +PrdrRegister::PrdrRegister() : cv_name(0) +{} + +PrdrRegister::~PrdrRegister() +{ + for(std::vector<CaptureInfoStruct>::iterator + j = cv_captures.begin(); + j != cv_captures.end(); + ++j) + { + if (NULL != (*j).func) + { + delete[] (*j).func; + (*j).func = NULL; + } + } +} + +PrdrExpr::PrdrExpr() +{ + cv_op = 0; + cv_actFunc = NULL; + // Clear out the pointers and 'delete' settings. + for (uint32_t i = 0; i < MAX_VALUES; i++) + { + cv_deletePtr[i] = false; + cv_value[i].p = NULL; + } +} + +PrdrExpr::~PrdrExpr() +{ + // Special things for certain operator types... + switch (cv_op) + { + // On function call operator and bit string, + // cv_value[0].p points to a string. + case Prdr::ACT_FUNC: + if(NULL != cv_actFunc) + { + delete[] cv_actFunc; + cv_actFunc = NULL; + } + break; + case Prdr::BIT_STR: + cv_bitStrVect.clear(); + break; + + // No other special cases yet. + default: + break; + } + + // Delete all pointers. + for (uint32_t i = 0; i < MAX_VALUES; i++) + if (cv_deletePtr[i]) + delete (cv_value[i].p); +}; + +} // end namespace. diff --git a/src/usr/diag/prdf/framework/rule/prdrLoadChip.H b/src/usr/diag/prdf/framework/rule/prdrLoadChip.H new file mode 100755 index 000000000..40b7b18c1 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrLoadChip.H @@ -0,0 +1,240 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrLoadChip.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDRLOADCHIP_H +#define __PRDRLOADCHIP_H + +/** + * @file prdrLoadChip.H + * @brief Describes classes and enums needed to load a .prf file. + */ + + +//-------------------------------------------------------------------- +// Includes +//-------------------------------------------------------------------- + +#include <stdint.h> + +#include <errlentry.H> +#include <utilstream.H> + +#include <vector> + +#include <prdrCommon.H> +#include <targeting/common/target.H> + +//-------------------------------------------------------------------- + +/** + * @namespace Prdr + * @brief Namespace to encapsulate Prdr specific enums, classes, and typedefs. + */ +namespace Prdr +{ + /** + * @brief read string data out from the stream + * @note caller must call delete[] to release the buffer + */ + void prdrReadString(UtilStream & i_stream, char *& o_string); + + /** + * @class PrdrRegister + * @brief Holds data associated with a register. + */ + class PrdrRegister + { + public: + uint16_t cv_name; /** hash id of Register Short Name */ + + uint32_t cv_flags; /** Attribute flags */ + + uint64_t cv_scomAddr; /** Scom Address */ + uint16_t cv_scomLen; /** Scom Length */ + + PrdrRegister(); + ~PrdrRegister(); + + struct ResetOrMaskStruct + { + char op; + uint64_t addr_r; + uint64_t addr_w; + + friend UtilStream& operator>>(UtilStream& i_left, + ResetOrMaskStruct & i_right) + { + return (i_left >> i_right.op + >> i_right.addr_r + >> i_right.addr_w); + }; + }; + + std::vector<ResetOrMaskStruct> cv_resets; + std::vector<ResetOrMaskStruct> cv_masks; + + struct CaptureInfoStruct + { + uint8_t op; + uint32_t data[2]; + char * func; + + friend UtilStream& operator>>(UtilStream& i_left, + CaptureInfoStruct & i_right) + { + i_left >> i_right.op; + int loopMax = 0; + switch (i_right.op) + { + case 'G': + case 'T': + loopMax = 1; + break; + + case 'C': + loopMax = 2; + break; + + case 'f': + loopMax = 0; + break; + } + + for (int i = 0; i < loopMax; i++) + i_left >> i_right.data[i]; + + i_right.func = NULL; + if ('f' == i_right.op) + { + prdrReadString(i_left, i_right.func); + } + + return i_left; + } + }; + + std::vector<CaptureInfoStruct> cv_captures; + + }; + + /** + * @class PrdrExpr + * @brief Contains data for the basic rule object, the "expression". + */ + class PrdrExpr + { + public: + union value { uint32_t i; PrdrExpr * p; }; + + /** Maximum number of entries a expression can have. */ + static const uint32_t MAX_VALUES = 6; + + unsigned char cv_op; /** Type of expr this is. */ + + // Arrays for the expression entries. cv_deletePtr remembers if + // the p-value should be 'deleted' when we destruct this object. + bool cv_deletePtr[MAX_VALUES]; + value cv_value[MAX_VALUES]; + + // action function pointer + char * cv_actFunc; + // vector of bit string data + std::vector<uint64_t> cv_bitStrVect; + + /** + * @func PrdrExpr() + * @brief Default constructor. Clear entry arrays. + */ + PrdrExpr(); + + /** + * @func ~PrdrExpr() + * @brief Default destructor. Delete all attached pointers, as + * requested. + */ + ~PrdrExpr(); + + private: + // Don't let us copy these things, we don't want to mess with the + // pointer tree. + PrdrExpr(const PrdrExpr & i_copy) {}; + }; + + class PrdrChip + { + public: + uint32_t cv_chipId; + TARGETING::TYPE cv_targetType; + uint32_t cv_signatureOffset; // Offset for error register ids. + uint32_t cv_dumpType; // default dump content type. + uint16_t cv_scomLen; // default scom length. + uint16_t cv_regCount; + PrdrRegister * cv_registers; + uint16_t cv_ruleCount; + PrdrExpr * cv_rules; + uint16_t cv_groupCount; + uint16_t cv_groupAttn[NUM_GROUP_ATTN]; + uint16_t * cv_groupSize; + uint8_t * cv_groupFlags; + PrdrExpr ** cv_groupPriorityBits; + PrdrExpr ** cv_groups; + uint16_t cv_actionCount; + uint16_t * cv_actionSize; + PrdrExpr ** cv_actions; + + PrdrChip() : cv_regCount(0), cv_registers(NULL), + cv_ruleCount(0), cv_rules(NULL), + cv_groupCount(0), cv_groupSize(NULL), + cv_groupFlags(NULL), cv_groupPriorityBits(NULL), + cv_groups(NULL), + cv_actionCount(0), cv_actionSize(NULL), + cv_actions(NULL) + { + }; + + ~PrdrChip() + { + if (NULL != cv_registers) delete[] cv_registers; + if (NULL != cv_rules) delete[] cv_rules; + for (int i = 0; i < cv_groupCount; i++) + { + if (NULL != cv_groupPriorityBits[i]) + delete cv_groupPriorityBits[i]; + if (NULL != cv_groups[i]) + delete[] cv_groups[i]; + } + if (NULL != cv_groups) delete[] cv_groups; + if (NULL != cv_groupSize) delete[] cv_groupSize; + if (NULL != cv_groupFlags) delete[] cv_groupFlags; + if (NULL != cv_groupPriorityBits) delete[] cv_groupPriorityBits; + for (int i = 0; i < cv_actionCount; i++) + if (NULL != cv_actions[i]) delete[] cv_actions[i]; + if (NULL != cv_actions) delete[] cv_actions; + if (NULL != cv_actionSize) delete[] cv_actionSize; + }; + }; + + errlHndl_t prdrLoadChip(UtilStream & i_stream, PrdrChip & o_chip); + +}; +#endif diff --git a/src/usr/diag/prdf/framework/rule/prdrLoadChipCache.C b/src/usr/diag/prdf/framework/rule/prdrLoadChipCache.C new file mode 100755 index 000000000..75918e4a1 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrLoadChipCache.C @@ -0,0 +1,170 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrLoadChipCache.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2006,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __HOSTBOOT_MODULE + +#include <utilreg.H> // for UtilReg + +#endif + + +#include <string.h> // for strncat +#include <prdrLoadChipCache.H> +#include <utilfile.H> +#include <prdfTrace.H> + +namespace Prdr +{ + // Declare private member instance. + LoadChipCache::Cache_t LoadChipCache::cv_cache; + + //--------------------------------------------------------------------- + void LoadChipCache::flushCache() + { + // Delete all objects within the cache. + for (Cache_t::iterator i = cv_cache.begin(); + i != cv_cache.end(); + ++i) + { + if (NULL != i->second) + delete (PrdrChip*)i->second; + } + + // Clear map. + cv_cache.clear(); + }; + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + errlHndl_t LoadChipCache::loadChip(const char * i_file, + PrdrChip ** o_chip) + { + errlHndl_t l_errl = NULL; + *o_chip = NULL; + + Cache_t::iterator i = cv_cache.find(i_file); + + if (cv_cache.end() != i) // Found object in cache. + { + (*o_chip) = (PrdrChip*)(*i).second; + l_errl = NULL; + } + else + { + (*o_chip) = new PrdrChip; + + do + { + // NOTE: to patch PRF files require rebuilding + // entire Hostboot image and put in a special + // location on FSP /nfs mount. + // FIXME: if we need to patch prf files directly + // on Hostboot, need to discuss with Patrick + // about a possibility of creating a new PNOR + // partition outside of the cryptographically + // signed area just for PRD. + +#ifdef __HOSTBOOT_MODULE + + char* l_filePathName; + size_t l_filePathSize = strlen(i_file) + 4 + 1; // 4 is for ".prf" + l_filePathName = new char[l_filePathSize]; + strcpy(l_filePathName, i_file); + strncat(l_filePathName, ".prf", l_filePathSize-1); + + UtilFile l_ruleFile(l_filePathName); + if (!l_ruleFile.exists()) + { + // FIXME: do we need to log and commit an error here? + PRDF_ERR("LoadChipCache::loadChip() failed to find %s", l_filePathName); + } + else + { + l_ruleFile.Open("r"); + } + + delete[] l_filePathName; + +#else + + // Read the correct directory path for flash. + size_t l_rootPathSize = 256; + char l_rootPath[256] = { '\0' }; + l_errl = UtilReg::read("fstp/RO_Root", + (void *) l_rootPath, + l_rootPathSize); + strncat(l_rootPath, "prdf/", 255); + strncat(l_rootPath, i_file, 255); + strncat(l_rootPath, ".prf", 255); + + if (NULL != l_errl) break; + + // Read /nfs/data/... directory path + size_t l_nfsPathSize = 256; + char l_nfsPath[256] = { '\0' }; + l_errl = UtilReg::read("fstp/NFS_Root", + (void *) l_nfsPath, + l_nfsPathSize); + + strncat(l_nfsPath, "prdf/", 255); + strncat(l_nfsPath, i_file, 255); + strncat(l_nfsPath, ".prf", 255); + + if (NULL != l_errl) break; + + // Open File to read chip. + UtilFile l_ruleFile(l_nfsPath); + if (!l_ruleFile.exists()) // check for NFS file. + { + l_ruleFile.Open(l_rootPath, "r"); + } + else + { + l_ruleFile.Open("r"); + } + +#endif + // Load chip object. + l_errl = Prdr::prdrLoadChip(l_ruleFile, *(*o_chip)); + + } while (0); + + if (NULL == l_errl) + { + // Add chip object to the cache. + cv_cache[i_file] = *o_chip; + } + else + { + PRDF_ERR("LoadChipCache::loadChip() l_errl is not null!"); + delete *o_chip; + (*o_chip) = NULL; + } + + } + + return l_errl; + + }; + //--------------------------------------------------------------------- +} diff --git a/src/usr/diag/prdf/framework/rule/prdrLoadChipCache.H b/src/usr/diag/prdf/framework/rule/prdrLoadChipCache.H new file mode 100755 index 000000000..6089bd426 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrLoadChipCache.H @@ -0,0 +1,82 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrLoadChipCache.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2006,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/** + * @file prdrLoadChipCache.H + * @brief Contains class information for a rule-chip loader cache. + */ + +#include <errlentry.H> +#include <prdrLoadChip.H> +#include <map> +#include <prdfPluginMap.H> + +namespace Prdr +{ + /** + * @class LoadChipCache + * @brief Creates a cache of the .prf rule-chips so the files only need to + * be parsed a single time. + */ + class LoadChipCache + { + public: + /** + * @fn flushCache + * @brief Clears any objects within the cache and frees all memory + * associated with them. + * + * @note After this call any pointers obtained from 'loadChip' are + * invalid. + */ + static void flushCache(); + + /** + * @fn loadChip + * @brief Loads a .prf file specified and returns a pointer to an + * associated chip object. + * + * This function will first look in NFS and then in flash for an + * associated chip file, assuming the object was not already in + * the cache. + * + * Any pointer returned should not be deleted. Its memory will be + * freed after the call to 'flushCache'. + * + * @param i_file - File name to open, eg. "SomeIoChip.prf". + * @param o_chip - Pointer to the object loaded from the file or + * retrieved from the cache. + * + * @note Caller must check o_chip for NULL pointers, indicating that + * the chip file could not be found / loaded. + * + * @retuns errlHndl_t - In the event of a registry or file failure. + */ + static errlHndl_t loadChip(const char * i_file, PrdrChip ** o_chip); + + private: + /** The file cache. */ + typedef std::map<const char *, PrdrChip *, PrdfStrCompare> Cache_t; + static Cache_t cv_cache; + }; +}; diff --git a/src/usr/diag/prdf/framework/rule/prdrRegister.H b/src/usr/diag/prdf/framework/rule/prdrRegister.H new file mode 100755 index 000000000..d635652f6 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrRegister.H @@ -0,0 +1,300 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrRegister.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDRREGISTER_H +#define __PRDRREGISTER_H + +#include <stdio.h> +#include <string.h> +#include <algorithm> + +#include <string> +#include <list> + +#include <stdint.h> + +#include <iostream> +#include <iomanip> +#include <netinet/in.h> + +// define needed to enable x86 rule parser code only +#define __PRD_RULE_COMPILE +#include <prdrCommon.H> +#include <UtilHash.H> + +#ifdef __HOSTBOOT_MODULE + #include <endian.h> + # define htonll(x) htobe64(x) +#else + #include <utilendian.H> +#endif + +extern Prdr::HashCollisionMap g_regsHashCollision; +extern bool g_hadError; + +struct PrdrResetOrMaskStruct +{ + uint8_t type; + uint64_t addr_r; + uint64_t addr_w; + + void output(FILE * l_file) + { + fwrite(&type, 1, 1, l_file); + + uint64_t l_tmp64; + + l_tmp64 = htonll(addr_r); + fwrite(&l_tmp64, sizeof (l_tmp64), 1, l_file); + + l_tmp64 = htonll(addr_w); + fwrite(&l_tmp64, sizeof (l_tmp64), 1, l_file); + } +}; + +struct PrdrCaptureReqStruct +{ + uint8_t type; + uint32_t data[2]; + std::string str; + + enum + { + PRDR_CAPTURE_GROUPID = 'G', + PRDR_CAPTURE_CONN = 'C', + PRDR_CAPTURE_FUNC = 'f', + PRDR_CAPTURE_TYPE = 'T', // Added this for storing a register's type in the capture struct. + }; + + void output(FILE * l_file) + { + fwrite(&type, 1, 1, l_file); + uint32_t l_tmp32; + + int loopMax = 0; + + switch (type) + { + case PRDR_CAPTURE_GROUPID: + case PRDR_CAPTURE_TYPE: + loopMax = 1; + break; + + case PRDR_CAPTURE_CONN: + loopMax = 2; + break; + + case PRDR_CAPTURE_FUNC: + loopMax = 0; + break; + } + + for (int i = 0; i < loopMax; i++) + { + l_tmp32 = htonl(data[i]); + fwrite(&l_tmp32, 4, 1, l_file); + } + if (type == PRDR_CAPTURE_FUNC) + { + if ('"' == (str)[0]) + str = str.substr(1, str.size() - 2); + fwrite(str.c_str(), str.size() + 1, 1, l_file); + } + }; +}; + +class PrdrRegister +{ + public: + + std::string * cv_sname; + std::string * cv_name; + + uint32_t cv_flags; + + uint64_t cv_scomaddr; + uint16_t cv_scomlen; + + std::string cv_name_default; + + std::list<PrdrResetOrMaskStruct> cv_resets; + std::list<PrdrResetOrMaskStruct> cv_masks; + + std::list<PrdrCaptureReqStruct> cv_captures; + + PrdrRegister() : + cv_sname(NULL), + cv_name(&cv_name_default), + cv_flags(0), + cv_scomaddr(0), + cv_scomlen(0), + cv_resets(0), cv_masks(0), cv_captures(0) + {}; + + static void merge(PrdrRegister * i_l, PrdrRegister * i_r) + { + if (NULL != i_r->cv_sname) + i_l->cv_sname = i_r->cv_sname; + if (&i_r->cv_name_default != i_r->cv_name) + i_l->cv_name = i_r->cv_name; + if (0 != i_r->cv_flags) + i_l->cv_flags = i_r->cv_flags; + if (0 != i_r->cv_scomaddr) + i_l->cv_scomaddr = i_r->cv_scomaddr; + if (0 != i_r->cv_scomlen) + i_l->cv_scomlen = i_r->cv_scomlen; + if (0 != i_r->cv_resets.size()) + { + std::copy( i_r->cv_resets.begin(), + i_r->cv_resets.end(), + std::back_inserter(i_l->cv_resets) ); + } + if (0 != i_r->cv_masks.size()) + { + std::copy( i_r->cv_masks.begin(), + i_r->cv_masks.end(), + std::back_inserter(i_l->cv_masks) ); + } + if (0 != i_r->cv_captures.size()) + { + std::copy( i_r->cv_captures.begin(), + i_r->cv_captures.end(), + std::back_inserter(i_l->cv_captures) ); + } + }; + + void print() + { + using std::cout; + using std::endl; + cout << "Register " << *cv_sname << ":" << endl; + cout << "\tLong Name: " << *cv_name << endl; + cout << "\tScom Addr: " << cv_scomaddr << endl; + cout << "\tScom Len: " << cv_scomlen << endl; + }; + + int output( FILE * l_file, uint16_t i_sigOff ) + { + // Check for hash collisions + uint16_t hash = Util::hashString( cv_sname->c_str() ) ^ i_sigOff; + Prdr::HashCollisionMap::iterator i = g_regsHashCollision.find(hash); + if ( g_regsHashCollision.end() != i ) + { + g_hadError = true; // Compile error + + std::cerr << "Register hash collision '" << *cv_sname << "' " + << std::hex << "[0x" + << std::setfill('0') << std::setw(4) + << hash << "]"; + + if ( 0 != cv_sname->compare(i->second) ) + { + std::cerr << ": previous register was '" << i->second << "'"; + } + + std::cerr << std::endl; + } + g_regsHashCollision[hash] = (*cv_sname); + + // Setup flags + if (0 != cv_resets.size()) + cv_flags |= Prdr::PRDR_REGISTER_RESETS; + if (0 != cv_masks.size()) + cv_flags |= Prdr::PRDR_REGISTER_MASKS; + if (0 != cv_captures.size()) + cv_flags |= Prdr::PRDR_REGISTER_CAPTURE; + + // output data + uint32_t l_temp; + uint16_t l_temp16; + + l_temp16 = htons(Util::hashString( cv_sname->c_str() )); + fwrite(&l_temp16, sizeof(l_temp16), 1, l_file); + + l_temp = htonl(cv_flags); + fwrite(&l_temp, sizeof(l_temp), 1, l_file); + + uint64_t l_temp64 = htonll(cv_scomaddr); + fwrite(&l_temp64, sizeof(l_temp64), 1, l_file); + + if (cv_flags & Prdr::PRDR_REGISTER_SCOMLEN) + { + l_temp16 = htons(cv_scomlen); + fwrite(&l_temp16, sizeof(l_temp16), 1, l_file); + } + + if (cv_flags & Prdr::PRDR_REGISTER_RESETS) + { + l_temp16 = htons(cv_resets.size()); + fwrite(&l_temp16, sizeof(l_temp16), 1, l_file); + + std::for_each( cv_resets.begin(), cv_resets.end(), + std::bind2nd( + std::mem_fun_ref(&PrdrResetOrMaskStruct::output), + l_file) ); + } + + if (cv_flags & Prdr::PRDR_REGISTER_MASKS) + { + l_temp16 = htons(cv_masks.size()); + fwrite(&l_temp16, sizeof(l_temp16), 1, l_file); + + std::for_each( cv_masks.begin(), cv_masks.end(), + std::bind2nd( + std::mem_fun_ref(&PrdrResetOrMaskStruct::output), + l_file) ); + } + + if (cv_flags & Prdr::PRDR_REGISTER_CAPTURE) + { + l_temp16 = htons(cv_captures.size()); + fwrite(&l_temp16, sizeof(l_temp16), 1, l_file); + + std::for_each( cv_captures.begin(), cv_captures.end(), + std::bind2nd( + std::mem_fun_ref(&PrdrCaptureReqStruct::output), + l_file) ); + } + + return 0; + }; + + void outputRegisterFile(std::ostream & o_file, uint16_t i_sigOff) + { + uint16_t hash = Util::hashString( cv_sname->c_str() ) ^ i_sigOff; + + o_file << "\tPRDR_REGISTER_ID ( " + << std::hex + << "0x" << std::setfill('0') << std::setw(4) + << hash << ", " + << *cv_sname << ", " << *cv_name << ", " + << "0x" << std::setfill('0') << std::setw(16) + << cv_scomaddr << "ULL )" + << std::endl; + }; +}; + +typedef std::list<PrdrRegister *> PrdrRegisterList; + +#endif + diff --git a/src/usr/diag/prdf/framework/rule/prdrSignatures.H b/src/usr/diag/prdf/framework/rule/prdrSignatures.H new file mode 100755 index 000000000..83debdbed --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrSignatures.H @@ -0,0 +1,36 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrSignatures.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2007,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include <stdint.h> + +// Create a constant integer for PRDR_ERROR_SIGNATURE( foo, 0x1, "asdf", "ASDF") +#define PRDR_ERROR_SIGNATURE(a,b,c,d) \ + const uint32_t PRDFSIG_##a = b + +// Change Log ********************************************************* +// +// Flag Reason Vers Date Coder Description +// ---- -------- ---- -------- -------- ------------------------------- +// D586213 f310 02/19/07 iawillia Add extra signature support. +// End Change Log ***************************************************** + diff --git a/src/usr/diag/prdf/framework/rule/prdrToken.H b/src/usr/diag/prdf/framework/rule/prdrToken.H new file mode 100755 index 000000000..859cacd76 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrToken.H @@ -0,0 +1,66 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/framework/rule/prdrToken.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2004,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __PRDRTOKEN_H +#define __PRDRTOKEN_H + +/** + * @file prdrToken.H + * @brief Collect of function defines and includes for prdrcompiler. + */ + +//-------------------------------------------------------------------- +// Includes +//-------------------------------------------------------------------- + +#include <string> +#include <stack> +#include <utility> + +#include <prdrRegister.H> +#include <prdrChip.H> +#include <prdrExpr.H> +#include <prdrGroup.H> + +//-------------------------------------------------------------------- +// Forward References +//-------------------------------------------------------------------- + +extern int yylex(); +extern int yyparse(); +extern void yyerror(const char *); + +extern int yyline; +extern std::stack<std::pair<std::string, int> > yyincfiles; + +extern PrdrChip * g_currentChip; + +#endif + +// Change Log ********************************************************* +// +// Flag Reason Vers Date Coder Description +// ---- -------- ---- -------- -------- ------------------------------- +// F494911 f310 03/04/05 iawillia Initial File Creation +// +// End Change Log ***************************************************** diff --git a/src/usr/diag/prdf/framework/rule/prdrpp b/src/usr/diag/prdf/framework/rule/prdrpp new file mode 100755 index 000000000..bbfc5e6fa --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/prdrpp @@ -0,0 +1,76 @@ +#!/usr/bin/perl +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/diag/prdf/framework/rule/prdrpp $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2004,2012 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG + +use strict; + +my @search_dirs = (); + +foreach my $arg (@ARGV) +{ + if ($arg =~ m/-I/) + { + $arg =~ s/-I//; + push @search_dirs, $arg; + } +} +read_file(\*STDIN); + +sub read_file +{ + my $file = shift; + while (my $line = <$file>) + { + if ($line =~ m/^\.include.*\".*\".*/) + { + my $include = $line; + chomp($include); + $include =~ s/.*\"(.*)\".*/$1/; + print ".included \"$include\"\n"; + open_file($include); + print ".end_included\n"; + } + else + { + print $line; + } + + } +} + +sub open_file +{ + my $filename = shift; + foreach my $dir (@search_dirs) + { + my $fileDirName = "$dir/$filename"; + if (-e $fileDirName) + { + open FILE, "< $fileDirName" || die "Error opening $fileDirName"; + read_file(\*FILE); + close FILE; + return; + } + } + print STDERR "prdrpp: $filename not found!\n"; +} diff --git a/src/usr/diag/prdf/framework/rule/tables.mk b/src/usr/diag/prdf/framework/rule/tables.mk new file mode 100755 index 000000000..200fff8e4 --- /dev/null +++ b/src/usr/diag/prdf/framework/rule/tables.mk @@ -0,0 +1,57 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/diag/prdf/framework/rule/tables.mk $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2005,2012 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG + +#------------------------------------------------------------------- +# To add a new chip, modify PRDR_RULE_TABLES line. +# To change system type, modify VPATH line in rule/Makefile +#------------------------------------------------------------------- + +# Add Rule tables here: +PRDR_RULE_TABLES = \ + Proc.prf \ + Ex.prf \ + Mcs.prf \ + Membuf.prf \ + Mba.prf + + +#------------------------------------------------------------------ +# Change nothing below this line unless you know what you're doing! +#------------------------------------------------------------------ + + + +# Stuff for errl plugin. + # Define required .o's +PRDR_ERRL_PLUGINS = ${PRDR_RULE_TABLES:S/\.prf/.prf.err.C/g} +PRDR_ERRL_PLUGINS += ${PRDR_RULE_TABLES:S/\.prf/.prf.reg.C/g} +PRDR_ERRL_PLUGINS_OFILES = ${PRDR_ERRL_PLUGINS:S/\.C/.o/g} + # Ensure that we'll use the latest .C's to build the .o's. +#${PRDR_ERRL_PLUGINS_OFILES} : ${.TARGET:S/\.o/\.C/g} +%.prf.err.o: %.prf.err.C +%.prf.reg.o: %.prf.reg.C +%.prf.err.C: %.prf +%.prf.reg.C: %.prf +%.prf: %.rule +# end errl plugin. + |