summaryrefslogtreecommitdiffstats
path: root/src/usr/targeting
diff options
context:
space:
mode:
authorJaymes Wilks <mjwilks@us.ibm.com>2017-06-16 11:22:44 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-07-18 09:54:30 -0400
commit45c8a43a7be3115a056b8fca842d158cae80cb3a (patch)
tree78fcc5885b818d4c51de2b5808f791ad347188fa /src/usr/targeting
parent986dd162063beef24cf9c28391ae19ead61a0116 (diff)
downloadtalos-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.C92
-rw-r--r--src/usr/targeting/common/target.C7
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/xmltohb.pl261
-rw-r--r--src/usr/targeting/makefile3
-rw-r--r--src/usr/targeting/runtime/makefile5
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}
OpenPOWER on IntegriCloud