diff options
author | Jaymes Wilks <mjwilks@us.ibm.com> | 2017-06-16 11:22:44 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-07-18 09:54:30 -0400 |
commit | 45c8a43a7be3115a056b8fca842d158cae80cb3a (patch) | |
tree | 78fcc5885b818d4c51de2b5808f791ad347188fa /src/usr/targeting | |
parent | 986dd162063beef24cf9c28391ae19ead61a0116 (diff) | |
download | talos-hostboot-45c8a43a7be3115a056b8fca842d158cae80cb3a.tar.gz talos-hostboot-45c8a43a7be3115a056b8fca842d158cae80cb3a.zip |
Generate verification code for enum-based persistent r/w attributes
This updates xmltohb.pl to generate code to verify that all
enum-based persistent r/w attributes have valid values.
Change-Id: I07e2c99a6b2ca7afe1de20baffa16ad667bc9e79
RTC:163084
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/42374
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Reviewed-by: Stephen M. Cprek <smcprek@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/targeting')
-rw-r--r-- | src/usr/targeting/attrcheck_errl.C | 92 | ||||
-rw-r--r-- | src/usr/targeting/common/target.C | 7 | ||||
-rwxr-xr-x | src/usr/targeting/common/xmltohb/xmltohb.pl | 261 | ||||
-rw-r--r-- | src/usr/targeting/makefile | 3 | ||||
-rw-r--r-- | src/usr/targeting/runtime/makefile | 5 |
5 files changed, 335 insertions, 33 deletions
diff --git a/src/usr/targeting/attrcheck_errl.C b/src/usr/targeting/attrcheck_errl.C new file mode 100644 index 000000000..31a716779 --- /dev/null +++ b/src/usr/targeting/attrcheck_errl.C @@ -0,0 +1,92 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/targeting/attrcheck_errl.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file targeting/attrcheck_errl.C + * + * @brief Error handling for enum value and numeric range checking of + * persistent read/write attributes. + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +// This component +#include <targeting/common/attributes.H> +#include <targeting/attrrp.H> +#include <targeting/common/util.H> +#include <targeting/common/trace.H> +#include <targeting/common/predicates/predicateattrval.H> +#include <targeting/common/utilFilter.H> +#include <targeting/common/attributeTank.H> +#include <targeting/common/targreasoncodes.H> +#include <targeting/common/target.H> + +// Other components +#include <secureboot/service.H> + +namespace TARGETING +{ +#ifndef __HOSTBOOT_RUNTIME +void handleEnumCheckFailure(const Target* i_pTarget, + const ATTRIBUTE_ID i_attr, + const uint64_t i_invalidValue) +{ + TRACFCOMP(g_trac_targeting, + "ATTRIBUTE_ID enum check failed! Attribute ID = 0x%x with invalid value" + " 0x%llX", i_attr, i_invalidValue); + /*@ + * @errortype + * @moduleid TARGETING::TARG_HANDLE_ENUM_CHECK_FAILURE + * @reasoncode TARGETING::TARG_RC_ATTRIBUTE_ENUM_CHECK_FAIL + * @userdata1[00:31] Target's HUID + * @userdata1[32:63] Attribute ID + * @userdata2 Invalid value + * @devdesc Invalid enum value for attribute. + * @custdesc Unexpected internal firmware error. + */ + auto err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + TARGETING::TARG_HANDLE_ENUM_CHECK_FAILURE, + TARGETING::TARG_RC_ATTRIBUTE_ENUM_CHECK_FAIL, + TWO_UINT32_TO_UINT64( + get_huid(i_pTarget), + i_attr), + i_invalidValue, + true); + + // handle the secureboot failure in the normal secureboot way + // The 'true' below indicates that we want to wait for shutdown, which + // is advisable in most cases, including this one. + SECUREBOOT::handleSecurebootFailure(err, true); +} +#endif + +} // End namespace TARGETING diff --git a/src/usr/targeting/common/target.C b/src/usr/targeting/common/target.C index 4deb0603b..ec21890ec 100644 --- a/src/usr/targeting/common/target.C +++ b/src/usr/targeting/common/target.C @@ -73,10 +73,9 @@ Target::~Target() } //****************************************************************************** -// Target::_tryGetAttr +// Target::_tryGetAttrUnsafe //****************************************************************************** - -bool Target::_tryGetAttr( +bool Target::_tryGetAttrUnsafe( const ATTRIBUTE_ID i_attr, const uint32_t i_size, void* const io_pAttrData) const @@ -777,8 +776,6 @@ void setFrequencyAttributes( Target * i_sys, #undef TARG_FN } - - //****************************************************************************** // Attribute Tanks //****************************************************************************** diff --git a/src/usr/targeting/common/xmltohb/xmltohb.pl b/src/usr/targeting/common/xmltohb/xmltohb.pl index 72f38f9f9..75b6183dc 100755 --- a/src/usr/targeting/common/xmltohb/xmltohb.pl +++ b/src/usr/targeting/common/xmltohb/xmltohb.pl @@ -249,36 +249,11 @@ else handleTgtPtrAttributesHb(\$attributes, \%Target_t); } -# Output R/W attributes -my $rwAttrOutputDir = ""; -if (!($cfgSrcOutputDir =~ "none")) -{ - $rwAttrOutputDir = $cfgSrcOutputDir; -} -open(my $rwAttrFile, ">$rwAttrOutputDir"."PersistRwAttrList.csv") - or croak("R/W data file 'PersistRwAttrList.csv' could not be opened."); - -print $rwAttrFile "# PersistRwAttrList.csv\n" -. "# This file is generated by perl script xmltohb.pl\n" -. "# It lists all non-volatile read/write attributes that persist in PNOR\n" -. "# and can be manipulated at will.\n"; - -foreach my $attrs (@{$attributes->{attribute}}) -{ - if (exists $attrs->{readable} && - exists $attrs->{writeable} && - exists $attrs->{persistency} && - $attrs->{persistency} eq "non-volatile") - { - print $rwAttrFile "$attrs->{id}\n"; - } - -} -close $rwAttrFile; - # Open the output files and write them if( !($cfgSrcOutputDir =~ "none") ) { + # secureboot validation of RW persistent attributes + generateRWPersistValidations($cfgSrcOutputDir, $attributes); open(ATTR_TARG_MAP_FILE,">$cfgSrcOutputDir"."targAttrOverrideData.H") or croak("Target Attribute data file: \"$cfgSrcOutputDir" @@ -487,6 +462,238 @@ if( !($cfgImgOutputDir =~ "none") ) exit(0); +# sub generateRWPersistValidations +# Generates code to validate the values of persistent read/write attributes +# @param[in] rwAttrOutputDir - The directory to place the output files +# @param[in] attributes - The list of attributes to generate code from +# @return none +sub generateRWPersistValidations { + +#intentionally not indenting the top level of this function for readability +my ($rwAttrOutputDir, $attributes) = @_; + +# Begin secure boot verification codegen for R/W persistent attributes +# Set up csv output file R/W persistent attributes +open(my $rwAttrFile, ">$rwAttrOutputDir"."PersistRwAttrList.csv") + or croak("R/W data file 'PersistRwAttrList.csv' could not be opened."); + +print $rwAttrFile <<VERBATIM; +# PersistRwAttrList.csv +# This file is generated by perl script xmltohb.pl +# It lists all non-volatile read/write attributes that persist in PNOR +# and can be manipulated at will. +VERBATIM + +my @rwPersistAttrs; # store the persistent attributes in an array +my %attrEnumTypes; # store enum types in a hash table + +foreach my $attrs (@{$attributes->{attribute}}) +{ + if (exists $attrs->{readable} && + exists $attrs->{writeable} && + exists $attrs->{persistency} && + $attrs->{persistency} eq "non-volatile") + { + print $rwAttrFile "$attrs->{id}\n"; + push @rwPersistAttrs, $attrs; + } +} + +foreach my $atype (@{$attributes->{enumerationType}}) +{ + $attrEnumTypes{$atype->{id}}=$atype; +} + +close $rwAttrFile; + +# Set up header/cpp output file for secure boot verification codegen +open(my $rwAttrHFile, ">$rwAttrOutputDir"."persistrwattrcheck.H") + or croak("R/W H gen file 'persistrwattrcheck.H' could not be opened."); + +open(my $rwAttrCFile, ">$rwAttrOutputDir"."persistrwattrcheck.C") + or croak("R/W C gen file 'persistrwattrcheck.C' could not be opened."); + +print $rwAttrHFile <<VERBATIM; +/** + * \@file persistrwattrcheck.H + * + * \@brief Verify enum attribute values are correct. + */ + +#ifndef PERSISTRWATTRCHECK_H +#define PERSISTRWATTRCHECK_H + +VERBATIM + +print $rwAttrCFile <<VERBATIM; +/** + * \@file persistrwattrcheck.C + * + * \@brief Verify enum attribute values are correct. + */ + +#include <targeting/common/target.H> + +namespace TARGETING +{ + +#ifndef __HOSTBOOT_RUNTIME + +VERBATIM + +foreach my $attr (@rwPersistAttrs) +{ + if (exists $attr->{simpleType} && + exists $attr->{simpleType}->{enumeration}) + + { + my $typeId = $attr->{simpleType}->{enumeration}->{id}; + if (!exists $attrEnumTypes{$typeId}) + { + die "Attribute $attr->{id} is nonexistent enumerated type $typeId"; + } + my $atype = $attrEnumTypes{$typeId}; + + # forward declare in header file + print $rwAttrHFile "template<>\n" + . "bool Target::tryGetAttr<ATTR_$attr->{id}>(" + . "typename AttributeTraits<ATTR_$attr->{id}>::Type& o_attrValue)" + . " const;\n\n"; + + # implement in C file + print $rwAttrCFile "template<>\n" + . "bool Target::tryGetAttr<ATTR_$attr->{id}>(" + . "typename AttributeTraits<ATTR_$attr->{id}>::Type& o_attrValue)" + . " const\n" + . "{\n" + . " bool l_read = _tryGetAttrUnsafe(ATTR_$attr->{id}," + . "sizeof(o_attrValue),&o_attrValue);\n" + . " if (l_read)\n" + . " {\n"; + my $arrayPrefix = ""; + my $arraySuffix = ""; + my $isArrayType = exists $attr->{simpleType}->{array}; + if ($isArrayType) + { + my $arrayTag = "$attr->{simpleType}->{array}"; + my $arraySize = getArrayTagTotalSize($arrayTag); + my $numDimensions = getArrayNumDimensions($arrayTag); + $arraySuffix = "[i]"; + + for (my $i=0; $i < $numDimensions - 1; $i++) + { + $arrayPrefix = "$arrayPrefix*"; + } + + print $rwAttrCFile "" + . " for(int i=0; i<$arraySize; i++)\n" + . " {\n" + . " switch( (${arrayPrefix}o_attrValue)[i] )\n" + . " {\n"; + } + else + { + print $rwAttrCFile "" + . " switch( o_attrValue )\n" + . " {\n"; + } + foreach my $enumerations (@{$atype->{enumerator}}) + { + print $rwAttrCFile "" + . " case $atype->{id}_$enumerations->{name}:\n"; + } + print $rwAttrCFile " break;\n" + . " default:\n" + . " handleEnumCheckFailure(this, ATTR_$attr->{id}, " + . "(${arrayPrefix}o_attrValue)$arraySuffix);\n"; + if ($isArrayType) + { + printf $rwAttrCFile "" + . " }\n"; + } + printf $rwAttrCFile "" + . " }\n" + . " }\n" + . " return l_read;\n" + . "}\n\n"; + } +} +print $rwAttrHFile "#endif\n"; +print $rwAttrCFile "#endif // !__HOSTBOOT_RUNTIME\n"; +close $rwAttrHFile; + +print $rwAttrCFile <<VERBATIM; + +bool Target::_tryGetAttr(ATTRIBUTE_ID i_attr, uint32_t i_size, + void* io_attrData) const +{ + #ifndef __HOSTBOOT_RUNTIME + switch(i_attr) + { +VERBATIM +foreach my $attr (@rwPersistAttrs) +{ + if (exists $attr->{simpleType} && + exists $attr->{simpleType}->{enumeration}) + { + print $rwAttrCFile <<VERBATIM; + case (ATTR_$attr->{id}): + return tryGetAttr<ATTR_$attr->{id}>( + * reinterpret_cast< + typename AttributeTraits<ATTR_$attr->{id}>::Type* + >(io_attrData) + ); +VERBATIM + } +} +print $rwAttrCFile <<VERBATIM; + default: + return _tryGetAttrUnsafe(i_attr, i_size, io_attrData); + } + #else + return _tryGetAttrUnsafe(i_attr, i_size, io_attrData); + #endif +} + +} // namespace TARGETING + +VERBATIM + +close $rwAttrCFile; + +} + +# sub getArrayTagTotalSize +# Calculates the total array size from an array tag that contains individual +# sizes of each array dimension +# @param[in] thearray - an array of sizes for each dimension +# @return total size +sub getArrayTagTotalSize { + my ($thearray) = @_; + my $arraySize = 1; + my @bounds = split(/,/,$thearray); + + foreach my $bound (@bounds) + { + $arraySize *= $bound; + } + return $arraySize; +} + +# sub getArrayNumDimensions +# Calculates the number of array dimensions from an array tag that contains +# individual sizes of each array dimension +# @param[in] thearray - an array of sizes for each dimension +# @return number of dimensions +sub getArrayNumDimensions { + my ($thearray) = @_; + my @bounds = split(/,/,$thearray); + my $dims = scalar @bounds; + + return $dims; +} + + sub VALIDATION_FUNCTIONS { } ################################################################################ diff --git a/src/usr/targeting/makefile b/src/usr/targeting/makefile index 8be0fab05..cc2ed607b 100644 --- a/src/usr/targeting/makefile +++ b/src/usr/targeting/makefile @@ -51,6 +51,9 @@ HOSTBOOT_SPECIFIC_OBJS += ${DEBUG_OBJS} HOSTBOOT_SPECIFIC_OBJS += ${HOSTBOOT_RT_IPL_COMMON_OBJS} HOSTBOOT_SPECIFIC_OBJS += namedtarget.o HOSTBOOT_SPECIFIC_OBJS += errludattribute.o +HOSTBOOT_SPECIFIC_OBJS += attrcheck_errl.o +OBJS += persistrwattrcheck.o + # Indicates that targutilbase.o will be excluded from targeting and put in # the base image for hostboot builds only. See common/common.mk and grep diff --git a/src/usr/targeting/runtime/makefile b/src/usr/targeting/runtime/makefile index c5349952b..05a60a5e2 100644 --- a/src/usr/targeting/runtime/makefile +++ b/src/usr/targeting/runtime/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2013,2016 +# Contributors Listed Below - COPYRIGHT 2013,2017 # [+] International Business Machines Corp. # # @@ -43,9 +43,12 @@ HOSTBOOT_RUNTIME_SPECIFIC_OBJS += errludattribute.o OBJS += ${COMMON_TARGETING_OBJS} OBJS += ${HOSTBOOT_RT_IPL_COMMON_OBJS} OBJS += ${HOSTBOOT_RUNTIME_SPECIFIC_OBJS} +OBJS += persistrwattrcheck.o + include $(ROOTPATH)/config.mk + # To find errludattribute.[CH], etc. They are generated # by src/usr/targeting/common/xmltohb/xmltohb.pl vpath %.C ${GENDIR} |