summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2018-06-18 23:05:31 -0500
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2018-07-03 09:18:52 -0400
commite5dfc3ab0ec51ee63205c7064b7b4a4c4b8ba46f (patch)
tree76ccf82718d46c0bb7bbb5cbcf451d2bbd03aaf6 /src
parent691894a135de3e81f4318a5498c4a964fdebb8ae (diff)
downloadtalos-hostboot-e5dfc3ab0ec51ee63205c7064b7b4a4c4b8ba46f.tar.gz
talos-hostboot-e5dfc3ab0ec51ee63205c7064b7b4a4c4b8ba46f.zip
Allow SPDX override as part of FW load
Memory VPD contents have changed since the cards have been built so we need to provide a method to override the data as part of a FW build. We have done the same thing previously for the MEMD record on the Nimbus machines so will use the same design here for SPDX. As part of this change, the previous MEMD support was refactored to be completely generic so a single code path can be used for any arbitrary record. Change-Id: I5af5e965429c881be3de0d18c82b1d7918ac9c22 CQ: SW430659 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/61190 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: Michael Baiocchi <mbaiocch@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60980
Diffstat (limited to 'src')
-rwxr-xr-xsrc/build/buildpnor/memd_creation.pl8
-rwxr-xr-xsrc/build/mkrules/hbfw/img/makefile20
-rw-r--r--src/include/usr/devicefw/userif.H26
-rw-r--r--src/include/usr/fapi2/plat_vpd_access.H17
-rw-r--r--src/include/usr/runtime/runtime_reasoncodes.H1
-rw-r--r--src/include/usr/util/utilrsvdmem.H20
-rw-r--r--src/include/usr/vpd/memd_vpdenums.H201
-rw-r--r--src/include/usr/vpd/vpd_if.H42
-rw-r--r--src/include/usr/vpd/vpdreasoncodes.H1
-rw-r--r--src/kernel/exception.C1
-rw-r--r--src/usr/devicefw/test/associatortest.H8
-rw-r--r--src/usr/fapi2/plat_vpd_access.C226
-rw-r--r--src/usr/isteps/istep11/call_host_prd_hwreconfig.C24
-rw-r--r--src/usr/isteps/istep14/call_proc_exit_cache_contained.C12
-rw-r--r--src/usr/pnor/spnorrp.C3
-rw-r--r--src/usr/runtime/populate_hbruntime.C98
-rw-r--r--src/usr/util/runtime/util_rt.C2
-rw-r--r--src/usr/util/utilrsvdmem.C1
-rw-r--r--src/usr/vpd/cvpd.C148
-rw-r--r--src/usr/vpd/cvpd.H32
-rw-r--r--src/usr/vpd/dvpd.C164
-rw-r--r--src/usr/vpd/dvpd.H32
-rw-r--r--src/usr/vpd/ipvpd.C458
-rw-r--r--src/usr/vpd/ipvpd.H125
-rw-r--r--src/usr/vpd/memd_vpd.C228
-rw-r--r--src/usr/vpd/memd_vpd.H227
-rwxr-xr-xsrc/usr/vpd/test/dvpdtest.H54
-rwxr-xr-xsrc/usr/vpd/vpd.C26
-rw-r--r--src/usr/vpd/vpd.H34
-rw-r--r--src/usr/vpd/vpd.mk3
-rw-r--r--src/usr/vpd/vpd_common.C8
31 files changed, 1195 insertions, 1055 deletions
diff --git a/src/build/buildpnor/memd_creation.pl b/src/build/buildpnor/memd_creation.pl
index 4144a0ddf..c4f551b03 100755
--- a/src/build/buildpnor/memd_creation.pl
+++ b/src/build/buildpnor/memd_creation.pl
@@ -29,7 +29,7 @@ use strict;
use File::Basename;
### CONSTANTS ###
-use constant ROUNDING_DIVISOR => 1000;
+use constant ROUNDING_DIVISOR => 1000; # 1K (not 1KB)
use constant HEADER_INPUT_LOCATION => 12;
print "Creating MEMD binary...\n";
@@ -44,6 +44,7 @@ print "Creating MEMD binary...\n";
my $memd_dir = "";
my $memd_output = "";
my @memd_files = "";
+my $record_name = "01.0"; #legacy support
my $help = 0;
my $man = 0;
@@ -51,6 +52,7 @@ GetOptions(
"memd_dir=s" => \$memd_dir,
"memd_output=s" => \$memd_output,
"memd_files=s" => \@memd_files,
+ "record=s" => \$record_name,
"help" => \$help,
"man" => \$man) || pod2usage(-verbose=>0);
@@ -92,8 +94,8 @@ my $number_of_files = scalar(@memd_files);
# Generate header - add to file
my $header = "OKOK"; # shows that the memd partition is valid
$header .= "01.0"; # current metadata header version
-$header .= "01.0"; # current memd version
-$header .= "0000"; # expected size of each memd blob (in KB's) placeholder
+$header .= $record_name; # vpd record
+$header .= "0000"; # expected size of each memd blob (in 1000's) placeholder
$header .= "00"; # number of memd instances placeholder
$header .= "00000000"; # padding for the future
$header .= "000000"; # rounding up to 16 bytes
diff --git a/src/build/mkrules/hbfw/img/makefile b/src/build/mkrules/hbfw/img/makefile
index cf2aab233..5cf263bc2 100755
--- a/src/build/mkrules/hbfw/img/makefile
+++ b/src/build/mkrules/hbfw/img/makefile
@@ -202,9 +202,9 @@ BUILD_TYPE_PARAMS = --build-type fspbuild
.if (${FAKEPNOR} == "")
# Parameters passed into GEN_PNOR_IMAGE_SCRIPT.
.if (${DEFAULT_PNOR} == 1)
- GEN_DEFAULT_BIN_FILES = HBBL=${HBBL_IMG},HBB=${HBB_IMG},HBI=${HBI_IMG},HBRT=${HBRT_IMG},TEST=EMPTY,TESTRO=EMPTY,TESTLOAD=EMPTY,HBEL=EMPTY,GUARD=EMPTY,GLOBAL=EMPTY,PAYLOAD=EMPTY,CVPD=EMPTY,MVPD=EMPTY,DJVPD=EMPTY,RINGOVD=EMPTY,SBKT=EMPTY,FIRDATA=EMPTY,MEMD=EMPTY
+ GEN_DEFAULT_BIN_FILES = HBBL=${HBBL_IMG},HBB=${HBB_IMG},HBI=${HBI_IMG},HBRT=${HBRT_IMG},TEST=EMPTY,TESTRO=EMPTY,TESTLOAD=EMPTY,HBEL=EMPTY,GUARD=EMPTY,GLOBAL=EMPTY,PAYLOAD=EMPTY,CVPD=EMPTY,MVPD=EMPTY,DJVPD=EMPTY,RINGOVD=EMPTY,SBKT=EMPTY,FIRDATA=EMPTY,MEMD=${${ZZ_MEMD_IMG}:P}
.else
- GEN_DEFAULT_BIN_FILES = HBBL=${HBBL_IMG},HBB=${HBB_IMG},HBI=${HBI_IMG},HBRT=${HBRT_IMG},HBEL=EMPTY,GUARD=EMPTY,GLOBAL=EMPTY,CVPD=EMPTY,MVPD=EMPTY,DJVPD=EMPTY,RINGOVD=EMPTY,SBKT=EMPTY,MEMD=EMPTY
+ GEN_DEFAULT_BIN_FILES = HBBL=${HBBL_IMG},HBB=${HBB_IMG},HBI=${HBI_IMG},HBRT=${HBRT_IMG},HBEL=EMPTY,GUARD=EMPTY,GLOBAL=EMPTY,CVPD=EMPTY,MVPD=EMPTY,DJVPD=EMPTY,RINGOVD=EMPTY,SBKT=EMPTY,MEMD=${${ZZ_MEMD_IMG}:P}
.endif
DEFAULT_PARAMS = --build-all --emit-eccless ${TARGET_TEST:b--test} ${HB_STANDALONE:b--hb-standalone} \
${CONFIG_SECUREBOOT:b--secureboot} --systemBinFiles ${GEN_DEFAULT_BIN_FILES} \
@@ -442,15 +442,15 @@ gen_system_specific_images: build_sbe_partitions .PMAKE
@${MAKE:T:R} gen_system_specific_images_bypass_cache
.if (${DEFAULT_PNOR} == 1)
- HOSTBOOT_DEFAULT_SECTIONS = HBBL=${HBBL_FINAL_IMG},HBB=${HBB_FINAL_IMG},HBI=${HBI_FINAL_IMG},HBRT=${HBRT_FINAL_IMG},TEST=${TEST_FINAL_IMG},TESTRO=${TESTRO_FINAL_IMG},TESTLOAD=${TESTLOAD_FINAL_IMG},HBEL=${HBEL_FINAL_IMG},GUARD=${GUARD_FINAL_IMG},GLOBAL=${GLOBAL_FINAL_IMG},PAYLOAD=${PAYLOAD_FINAL_IMG},CVPD=${CVPD_FINAL_IMG},MVPD=${MVPD_FINAL_IMG},DJVPD=${DJVPD_FINAL_IMG},RINGOVD=${RINGOVD_FINAL_IMG},SBKT=${SBKT_FINAL_IMG},FIRDATA=${FIRDATA_FINAL_IMG},MEMD=${MEMD_FINAL_IMG}
- NIMBUS_SECT = HBD=${NIMBUS_HBD_FINAL_IMG},SBE=${NIMBUS_SBE_FINAL_IMG},HCODE=${NIMBUS_HCODE_FINAL_IMG},OCC=${NIMBUS_OCC_FINAL_IMG},WOFDATA=${ZZ_WOFDATA_FINAL_IMG},CENHWIMG=${NIMBUS_CENHWIMG_FINAL_IMG}
- CUMULUS_SECT = HBD=${CUMULUS_HBD_FINAL_IMG},SBE=${CUMULUS_SBE_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},OCC=${CUMULUS_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG}
- CUMULUS_CDIMM_SECT = HBD=${CUMULUS_CDIMM_HBD_FINAL_IMG},SBE=${CUMULUS_SBE_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},OCC=${CUMULUS_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG}
+ HOSTBOOT_DEFAULT_SECTIONS = HBBL=${HBBL_FINAL_IMG},HBB=${HBB_FINAL_IMG},HBI=${HBI_FINAL_IMG},HBRT=${HBRT_FINAL_IMG},TEST=${TEST_FINAL_IMG},TESTRO=${TESTRO_FINAL_IMG},TESTLOAD=${TESTLOAD_FINAL_IMG},HBEL=${HBEL_FINAL_IMG},GUARD=${GUARD_FINAL_IMG},GLOBAL=${GLOBAL_FINAL_IMG},PAYLOAD=${PAYLOAD_FINAL_IMG},CVPD=${CVPD_FINAL_IMG},MVPD=${MVPD_FINAL_IMG},DJVPD=${DJVPD_FINAL_IMG},RINGOVD=${RINGOVD_FINAL_IMG},SBKT=${SBKT_FINAL_IMG},FIRDATA=${FIRDATA_FINAL_IMG}
+ NIMBUS_SECT = HBD=${NIMBUS_HBD_FINAL_IMG},SBE=${NIMBUS_SBE_FINAL_IMG},HCODE=${NIMBUS_HCODE_FINAL_IMG},OCC=${NIMBUS_OCC_FINAL_IMG},WOFDATA=${ZZ_WOFDATA_FINAL_IMG},CENHWIMG=${NIMBUS_CENHWIMG_FINAL_IMG},MEMD=${ZZ_MEMD_FINAL_IMG}
+ CUMULUS_SECT = HBD=${CUMULUS_HBD_FINAL_IMG},SBE=${CUMULUS_SBE_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},OCC=${CUMULUS_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG},MEMD=${MEMD_FINAL_IMG}
+ CUMULUS_CDIMM_SECT = HBD=${CUMULUS_CDIMM_HBD_FINAL_IMG},SBE=${CUMULUS_SBE_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},OCC=${CUMULUS_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG},MEMD=${MEMD_FINAL_IMG}
.else
- HOSTBOOT_DEFAULT_SECTIONS = HBBL=${HBBL_FINAL_IMG},HBB=${HBB_FINAL_IMG},HBI=${HBI_FINAL_IMG},HBRT=${HBRT_FINAL_IMG},HBEL=${HBEL_FINAL_IMG},GUARD=${GUARD_FINAL_IMG},GLOBAL=${GLOBAL_FINAL_IMG},CVPD=${CVPD_FINAL_IMG},MVPD=${MVPD_FINAL_IMG},DJVPD=${DJVPD_FINAL_IMG},RINGOVD=${RINGOVD_FINAL_IMG},SBKT=${SBKT_FINAL_IMG},MEMD=${MEMD_FINAL_IMG}
- NIMBUS_SECT = HBD=${NIMBUS_HBD_FINAL_IMG},SBE=${NIMBUS_SBE_FINAL_IMG},HCODE=${NIMBUS_HCODE_FINAL_IMG},OCC=${NIMBUS_OCC_FINAL_IMG},WOFDATA=${ZZ_WOFDATA_FINAL_IMG},CENHWIMG=${NIMBUS_CENHWIMG_FINAL_IMG}
- CUMULUS_SECT = HBD=${CUMULUS_HBD_FINAL_IMG},SBE=${CUMULUS_SBE_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},OCC=${CUMULUS_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG}
- CUMULUS_CDIMM_SECT = HBD=${CUMULUS_CDIMM_HBD_FINAL_IMG},SBE=${CUMULUS_SBE_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},OCC=${CUMULUS_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG}
+ HOSTBOOT_DEFAULT_SECTIONS = HBBL=${HBBL_FINAL_IMG},HBB=${HBB_FINAL_IMG},HBI=${HBI_FINAL_IMG},HBRT=${HBRT_FINAL_IMG},HBEL=${HBEL_FINAL_IMG},GUARD=${GUARD_FINAL_IMG},GLOBAL=${GLOBAL_FINAL_IMG},CVPD=${CVPD_FINAL_IMG},MVPD=${MVPD_FINAL_IMG},DJVPD=${DJVPD_FINAL_IMG},RINGOVD=${RINGOVD_FINAL_IMG},SBKT=${SBKT_FINAL_IMG}
+ NIMBUS_SECT = HBD=${NIMBUS_HBD_FINAL_IMG},SBE=${NIMBUS_SBE_FINAL_IMG},HCODE=${NIMBUS_HCODE_FINAL_IMG},OCC=${NIMBUS_OCC_FINAL_IMG},WOFDATA=${ZZ_WOFDATA_FINAL_IMG},CENHWIMG=${NIMBUS_CENHWIMG_FINAL_IMG},MEMD=${ZZ_MEMD_FINAL_IMG}
+ CUMULUS_SECT = HBD=${CUMULUS_HBD_FINAL_IMG},SBE=${CUMULUS_SBE_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},OCC=${CUMULUS_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG},MEMD=${MEMD_FINAL_IMG}
+ CUMULUS_CDIMM_SECT = HBD=${CUMULUS_CDIMM_HBD_FINAL_IMG},SBE=${CUMULUS_SBE_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},OCC=${CUMULUS_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG},MEMD=${MEMD_FINAL_IMG}
.endif
PNOR_IMG_INFO = \
nimbus.pnor:${PNOR_LAYOUT}:${NIMBUS_SECT},${HOSTBOOT_DEFAULT_SECTIONS} \
diff --git a/src/include/usr/devicefw/userif.H b/src/include/usr/devicefw/userif.H
index 4df37c8a8..68f923f95 100644
--- a/src/include/usr/devicefw/userif.H
+++ b/src/include/usr/devicefw/userif.H
@@ -67,7 +67,7 @@ namespace DeviceFW
SIO,
AHB_SIO,
DVPD, // Direct access memory VPD
- MEMD_VPD,
+ DEPRECATED_MEMD_VPD,
NODECOMM,
LAST_ACCESS_TYPE,
@@ -256,30 +256,6 @@ namespace DeviceFW
static_cast<uint64_t>(( i_location ))
/**
- * Construct the device addressing parameters for the DVPD (Direct access
- * memory VPD) device ops.
- * @param[in] i_record - The enumeration of the DVPD record to access.
- * @param[in] i_keyword - The enumeration of the DVPD keyword, located
- * within the i_record Record to access.
- */
- #define DEVICE_MEMD_VPD_ADDRESS( i_record, i_keyword )\
- DEVICE_MEMD_VPD_FORCE_ADDRESS( i_record, i_keyword, VPD::PNOR )
-
- /**
- * Construct the device addressing parameters for the DVPD device ops.
- * @param[in] i_record - The enumeration of the DVPD record to access.
- * @param[in] i_keyword - The enumeration of the DVPD keyword, located
- * within the i_record Record to access.
- * @param[in] i_location - The location of the data (PNOR/SEEPROM)
- see vpd_if.H
- */
- #define DEVICE_MEMD_VPD_FORCE_ADDRESS( i_record, i_keyword, i_location )\
- DeviceFW::MEMD_VPD, static_cast<uint64_t>(( i_record )),\
- static_cast<uint64_t>(( i_keyword )),\
- static_cast<uint64_t>(( i_location ))
-
-
- /**
* Construct the device addressing parameters for the SCAN device ops.
* @param[in] i_ring - The ring address to scan
* @param[in] i_ringlen - The length of the ring to scan in bits
diff --git a/src/include/usr/fapi2/plat_vpd_access.H b/src/include/usr/fapi2/plat_vpd_access.H
index f28317df9..0bde2f363 100644
--- a/src/include/usr/fapi2/plat_vpd_access.H
+++ b/src/include/usr/fapi2/plat_vpd_access.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -31,7 +31,6 @@
#define _FAPI2_PLAT_VPDACCESS_H_
#include <fapi2_vpd_access.H>
-#include <vpd/memd_vpdenums.H>
namespace fapi2
{
@@ -52,19 +51,5 @@ fapi2::ReturnCode platGetVPD(
VPDInfo<fapi2::TARGET_TYPE_MCS>& io_vpd_info,
uint8_t* o_blob);
-/**
- * @brief Search through the PNOR::MEMD section to find the copy with
- * a matching VM keyword compared to the EEPROM's VM.
- *
- * @param[in] i_eepromVM - The EEPROM's copy of the VM keyword
- * @param[in] i_header - The header from PNOR::MEMD
- * @param[in] i_target - A valid fapi2 MCS target
- * @param[in] i_vm_size - Size of the VM keyword
- *
- * @return boolean - true if a matching MEMD was found, false if not
- */
-bool find_memd_in_pnor(uint8_t* i_eepromVM, MemdHeader_t i_header,
- TARGETING::Target * i_target, size_t i_vm_size);
-
};
#endif // _FAPI2_PLAT_VPDACCESS_H_
diff --git a/src/include/usr/runtime/runtime_reasoncodes.H b/src/include/usr/runtime/runtime_reasoncodes.H
index 79ebe37a8..6b77d621a 100644
--- a/src/include/usr/runtime/runtime_reasoncodes.H
+++ b/src/include/usr/runtime/runtime_reasoncodes.H
@@ -138,6 +138,7 @@ namespace RUNTIME
RC_RT_RES_TRACE_BUF_INVALID = RUNTIME_COMP_ID | 0x41,
RC_SP_ATTN_AREA_OVERFLOW = RUNTIME_COMP_ID | 0x42,
RC_SP_ATTN_AREA1_SIZE_OVERFLOW = RUNTIME_COMP_ID | 0x43,
+ RC_UNKNOWN_LABEL = RUNTIME_COMP_ID | 0x44,
};
enum UserDetailsTypes
diff --git a/src/include/usr/util/utilrsvdmem.H b/src/include/usr/util/utilrsvdmem.H
index ed4d0e4f5..d93819b7b 100644
--- a/src/include/usr/util/utilrsvdmem.H
+++ b/src/include/usr/util/utilrsvdmem.H
@@ -35,23 +35,33 @@ namespace Util
typedef uint64_t hbrt_mem_label_t;
// Ascii label "VPD " in hex
- constexpr hbrt_mem_label_t HBRT_MEM_LABEL_VPD = 0x5650442020202020;
+ constexpr hbrt_mem_label_t HBRT_MEM_LABEL_VPD = 0x5650442020202020;
// Ascii label "ATTR " in hex
- constexpr hbrt_mem_label_t HBRT_MEM_LABEL_ATTR = 0x4154545220202020;
+ constexpr hbrt_mem_label_t HBRT_MEM_LABEL_ATTR = 0x4154545220202020;
// Ascii label "ATTROVER" in hex
- constexpr hbrt_mem_label_t HBRT_MEM_LABEL_ATTROVER = 0x415454524F564552;
+ constexpr hbrt_mem_label_t HBRT_MEM_LABEL_ATTROVER = 0x415454524F564552;
// Ascii label "PADDING " in hex
- constexpr hbrt_mem_label_t HBRT_MEM_LABEL_PADDING = 0x50414444494E4720;
+ constexpr hbrt_mem_label_t HBRT_MEM_LABEL_PADDING = 0x50414444494E4720;
// Ascii label "HYPCOMM " in hex
- constexpr hbrt_mem_label_t HBRT_MEM_LABEL_HYPCOMM = 0x485950434f4d4d20;
+ constexpr hbrt_mem_label_t HBRT_MEM_LABEL_HYPCOMM = 0x485950434f4d4d20;
// Ascii label "TRACEBUF" in hex
constexpr hbrt_mem_label_t HBRT_MEM_LABEL_TRACEBUF = 0x5452414345425546;
+ // Note : may be several sections of the format 'VPD_xxxx' if support
+ // other overrides in the future
+ // Ascii label "VPD_"<blank> in hex
+ constexpr hbrt_mem_label_t HBRT_MEM_LABEL_VPD_XXXX = 0x5650445F00000000;
+ // Mask off specific VPD label
+ constexpr hbrt_mem_label_t HBRT_MEM_LABEL_VPD_MASK = 0x00000000FFFFFFFF;
+ // Ascii label "VPD_MEMD in hex
+ constexpr hbrt_mem_label_t HBRT_MEM_LABEL_VPD_MEMD = 0x5650445F4D454D44;
+
+
/** @brief A 32 byte table of contents entry */
struct hbrtTableOfContentsEntry_t
{
diff --git a/src/include/usr/vpd/memd_vpdenums.H b/src/include/usr/vpd/memd_vpdenums.H
deleted file mode 100644
index ecd20ef04..000000000
--- a/src/include/usr/vpd/memd_vpdenums.H
+++ /dev/null
@@ -1,201 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/include/usr/vpd/memd_vpdenums.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2013,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 */
-#ifndef __MEMD_VPDENUMS_H
-#define __MEMD_VPDENUMS_H
-
-#include <vpd/ipvpdenums.H>
-
-/**
- * @brief Define the set of information included at the beginning of the
- * MEMD PNOR section
- */
-struct MemdHeader_t
-{
- uint32_t eyecatch; /* Eyecatch to determine validity. "OKOK" */
- uint32_t header_version; /* What version of the header this is in */
- uint32_t memd_version; /* What version of the MEMD this includes */
- uint32_t expected_size_kb; /* Size in kilobytes of each MEMD instance */
- uint16_t expected_num; /* Number of MEMD instances in this section */
- uint8_t padding[14]; /* Padding for future changes */
-}__attribute__((packed));
-
-enum MEMD_valid_constants
-{
- MEMD_VALID_HEADER = 0x4f4b4f4b, // "OKOK"
- MEMD_VALID_HEADER_VERSION = 0x30312e30, // "01.0";
- MEMD_VALID_MEMD_VERSION = 0x30312e30, //"01.0";
-};
-
-namespace MEMD_VPD
-{
-
- /**
- * @brief Enumeration for the MEMD_VPD Records that contain
- * the keyword enumerations below.
- */
- enum MEMD_VPDRecord
- {
- MEMD_VPD_FIRST_RECORD = 0x00,
- VINI = MEMD_VPD_FIRST_RECORD,
- MEMD = 0x01,
-
- // Last Record
- MEMD_VPD_LAST_RECORD,
- MEMD_VPD_TEST_RECORD, // Test purposes ONLY!
-
- //Start common IPVPD enums
- MEMD_VPD_INVALID_RECORD = IPVPD::INVALID_RECORD,
- };
-
- /**
- * @brief Enumerations for MEMD_VPD keywords that can be
- * accessed in the MEMD_VPD.
- */
- enum MEMD_VPDKeyword
- {
- MEMD_VPD_FIRST_KEYWORD = 0x00,
- B3 = MEMD_VPD_FIRST_KEYWORD,
- B4 = 0x01,
- B7 = 0x02,
- CC = 0x03,
- CE = 0x04,
- CT = 0x05,
- DR = 0x06,
- FC = 0x07,
- FN = 0x08,
- HE = 0x09,
- HW = 0x0a,
- I2 = 0x0b,
- IN = 0x0c,
- J0 = 0x0d,
- J1 = 0x0e,
- J2 = 0x0f,
- J3 = 0x10,
- J4 = 0x11,
- J5 = 0x12,
- J6 = 0x13,
- J7 = 0x14,
- J8 = 0x15,
- J9 = 0x16,
- JA = 0x17,
- JB = 0x18,
- JC = 0x19,
- JD = 0x1a,
- JE = 0x1b,
- JF = 0x1c,
- JG = 0x1d,
- JH = 0x1e,
- JI = 0x1f,
- JJ = 0x20,
- JK = 0x21,
- JL = 0x22,
- JM = 0x23,
- JN = 0x24,
- JO = 0x25,
- JP = 0x26,
- JQ = 0x27,
- JR = 0x28,
- JS = 0x29,
- JT = 0x2a,
- JU = 0x2b,
- JV = 0x2c,
- JW = 0x2d,
- JX = 0x2e,
- JY = 0x2f,
- JZ = 0x30,
- LX = 0x31,
- MR = 0x32,
- MT = 0x33,
- PF = 0x34,
- PN = 0x35,
- PR = 0x36,
- RB = 0x37,
- RG = 0x38,
- RT = 0x39,
- SE = 0x3a,
- SN = 0x3b,
- SO = 0x3c,
- TM = 0x3d,
- VM = 0x3e,
- VZ = 0x3f,
- X0 = 0x40,
- X1 = 0x41,
- X2 = 0x42,
- X3 = 0x43,
- X4 = 0x44,
- X5 = 0x45,
- X6 = 0x46,
- X7 = 0x47,
- X8 = 0x48,
- X9 = 0x49,
- XA = 0x4a,
- XB = 0x4b,
- XC = 0x4c,
- XD = 0x4d,
- XE = 0x4e,
- XF = 0x4f,
- XG = 0x50,
- XH = 0x51,
- XI = 0x52,
- XJ = 0x53,
- XK = 0x54,
- XL = 0x55,
- XM = 0x56,
- XN = 0x57,
- XO = 0x58,
- XP = 0x59,
- XQ = 0x5a,
- XR = 0x5b,
- XS = 0x5c,
- XT = 0x5d,
- XU = 0x5e,
- XV = 0x5f,
- XW = 0x60,
- XX = 0x61,
- XY = 0x62,
- XZ = 0x63,
- Q0 = 0x64,
- Q1 = 0x65,
- Q2 = 0x66,
- Q3 = 0x67,
- Q4 = 0x68,
- Q5 = 0x69,
- Q6 = 0x6A,
- Q7 = 0x6B,
- Q8 = 0x6C,
- CK = 0X6D,
-
- // Last Keyword
- MEMD_VPD_LAST_KEYWORD,
- MEMD_VPD_TEST_KEYWORD, // Test purposes ONLY!
-
- //Start common IPVPD enums
- FULL_RECORD = IPVPD::FULL_RECORD,
- MEMD_VPD_INVALID_KEYWORD = IPVPD::INVALID_KEYWORD,
- };
-
-}; // end MEMD_VPD
-
-#endif
diff --git a/src/include/usr/vpd/vpd_if.H b/src/include/usr/vpd/vpd_if.H
index 0d8cc4a2d..4e63a0965 100644
--- a/src/include/usr/vpd/vpd_if.H
+++ b/src/include/usr/vpd/vpd_if.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -25,6 +25,8 @@
#if !defined(__VPD_IF_H)
#define __VPD_IF_H
+#include <pnor/pnorif.H>
+#include <map>
namespace VPD
{
@@ -41,9 +43,18 @@ namespace VPD
*/
enum vpdCmdTarget
{
- AUTOSELECT,
- PNOR,
- SEEPROM,
+ AUTOSELECT = 0x0000,
+
+ // Use our cache or read the eeprom
+ PNOR = 0x0001,
+ SEEPROM = 0x0002,
+ LOCATION_MASK = 0x000F,
+
+ // Use the real vpd or a firmware override
+ USEVPD = 0x0010,
+ USEOVERRIDE = 0x0020,
+ OVERRIDE_MASK = 0x00F0,
+
INVALID_LOCATION = 0xFFFF,
};
@@ -137,6 +148,29 @@ namespace VPD
*/
errlHndl_t goldenCacheInvalidate ( void );
+ /**
+ * @brief Structure used to specify VPD overrides for runtime
+ * reserved memory usage
+ */
+ struct OverrideSpecifier_t
+ {
+ PNOR::SectionId pnorId;
+ size_t size; // size in bytes
+ };
+
+ /**
+ * @brief Map of override labels to sections
+ * index : uint64_t label = right-justified 4-digit ASCII string
+ * result : OverrideSpecifier_t
+ */
+ typedef std::map<uint64_t,OverrideSpecifier_t> OverrideRsvMemMap_t;
+
+ /**
+ * @brief Get a list of all overridden sections
+ * @param[out] List of known override sections
+ */
+ void getListOfOverrideSections( OverrideRsvMemMap_t& o_overrides );
+
}; //end vpd namespace
#endif
diff --git a/src/include/usr/vpd/vpdreasoncodes.H b/src/include/usr/vpd/vpdreasoncodes.H
index 45652bf05..8c7402158 100644
--- a/src/include/usr/vpd/vpdreasoncodes.H
+++ b/src/include/usr/vpd/vpdreasoncodes.H
@@ -147,6 +147,7 @@ enum vpdReasonCode
VPD_TARGET_CHIP_NOT_FOUND = VPD_COMP_ID | 0x39,
VPD_EEPROM_VPD_PRIMARY_INFO_MISSING = VPD_COMP_ID | 0x3a,
VPD_RT_NODE_TOO_LARGE = VPD_COMP_ID | 0x3b,
+ VPD_CANNOT_WRITE_OVERRIDDEN_VPD = VPD_COMP_ID | 0x3c,
};
diff --git a/src/kernel/exception.C b/src/kernel/exception.C
index ca05bf3a1..8dc4b53e3 100644
--- a/src/kernel/exception.C
+++ b/src/kernel/exception.C
@@ -110,6 +110,7 @@ void kernel_execute_data_storage()
"Instruction where it occurred: %p\n",
t->tid, getDAR(), getDSISR(), t->context.nip);
KernelMisc::printkBacktrace(t);
+ MAGIC_INSTRUCTION(MAGIC_BREAK_ON_ERROR);
TaskManager::endTask(t, NULL, TASK_STATUS_CRASHED);
}
}
diff --git a/src/usr/devicefw/test/associatortest.H b/src/usr/devicefw/test/associatortest.H
index a9d87534e..98eb3edba 100644
--- a/src/usr/devicefw/test/associatortest.H
+++ b/src/usr/devicefw/test/associatortest.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* [+] 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. */
@@ -164,7 +166,7 @@ public:
// Reverse the wildcard test
l_errl = as.registerRoute(WILDCARD,
- PNOR,
+ DeviceFW::PNOR,
TYPE_NODE,
&performOperation);
if (l_errl)
@@ -172,7 +174,7 @@ public:
TS_FAIL("testDoubleRegistration> Error received from registerRoute (2).");
}
l_errl = as.registerRoute(WRITE,
- PNOR,
+ DeviceFW::PNOR,
TYPE_NODE,
&performOperation);
if (l_errl)
diff --git a/src/usr/fapi2/plat_vpd_access.C b/src/usr/fapi2/plat_vpd_access.C
index 164062c9d..f5a6c92e2 100644
--- a/src/usr/fapi2/plat_vpd_access.C
+++ b/src/usr/fapi2/plat_vpd_access.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -35,7 +35,6 @@
#include <p9_get_mem_vpd_keyword.H>
#include <attribute_service.H>
#include <vpd/dvpdenums.H>
-#include <vpd/memd_vpdenums.H>
#include <errl/errlmanager.H>
//The following can be uncommented for unit testing
//#undef FAPI_DBG
@@ -52,8 +51,6 @@ fapi2::ReturnCode platGetVPD(
fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
errlHndl_t l_errl = nullptr;
keywordInfo_t l_keywordInfo;
- uint8_t* l_dvpd_vm = nullptr;
- uint32_t* l_full_dvpdVM = nullptr;
// Assume that all memory keywords (MR,MT,J0..JZ,X0...XZ) are all the
// same size of 255. This avoids going through the decode and asking
@@ -96,7 +93,6 @@ fapi2::ReturnCode platGetVPD(
io_vpd_info.iv_size,
VPD_KEYWORD_SIZE,
true); //software callout
- l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
break; //return with error
}
@@ -106,7 +102,6 @@ fapi2::ReturnCode platGetVPD(
if (l_errl)
{
FAPI_ERR("platGetVPD: Error from getTargetingTarget");
- l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
break; //return with error
}
@@ -203,121 +198,24 @@ fapi2::ReturnCode platGetVPD(
io_vpd_info.iv_vpd_type,
TARGETING::get_huid(l_pMcsTarget),
true); //software callout
- l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
break; //return with error
}
- // The PNOR::MEMD section potentially contains multiple copies of the
- // MEMD VPD. This next section searches through the PNOR copy for a
- // valid copy if it exists and uses that instead of the DVPD section.
-
//Read mapping keyword
size_t l_buffSize = VPD_KEYWORD_SIZE;
uint8_t * l_pMapping = new uint8_t[VPD_KEYWORD_SIZE]();
- // MEMD Processing
- PNOR::SectionInfo_t l_memd_info;
- l_errl = PNOR::getSectionInfo(PNOR::MEMD,l_memd_info);
- bool l_memd_found = false;
- MemdHeader_t l_header;
-
+ l_errl = deviceRead((TARGETING::Target *)l_pMcsTarget,
+ l_pMapping,
+ l_buffSize,
+ DEVICE_DVPD_ADDRESS(DVPD::MEMD,
+ l_mapKeyword));
if( l_errl )
{
- FAPI_INF("platGetVPD: Optional MEMD section not found.");
- delete l_errl;
- l_errl = NULL;
- }
- else
- {
- do
- {
- const uint8_t * vaddr = reinterpret_cast<const uint8_t *>(
- l_memd_info.vaddr);
- // Get and process the header
- memcpy(&l_header, vaddr, sizeof(l_header));
-
- size_t theSize = 0;
-
- // Get the VM keyword size
- l_errl = deviceRead( l_pMcsTarget, nullptr,
- theSize, DEVICE_DVPD_ADDRESS(
- DVPD::MEMD, DVPD::VM));
-
- if( l_errl )
- {
- FAPI_ERR("platGetVPD: ERROR getting MEMD VM size");
- l_rc.setPlatDataPtr(reinterpret_cast<void *>( l_errl ));
- break;
- }
-
- // Get the VM keyword from the real VPD
- l_dvpd_vm = static_cast<uint8_t*>(malloc( theSize ));
-
- l_errl = deviceRead( l_pMcsTarget, l_dvpd_vm,
- theSize, DEVICE_DVPD_ADDRESS(
- DVPD::MEMD, DVPD::VM));
- if( l_errl )
- {
- FAPI_ERR("platGetVPD: ERROR getting DVPD VM keyword");
- l_rc.setPlatDataPtr(reinterpret_cast<void *>( l_errl ));
- break;
- }
- l_full_dvpdVM = (reinterpret_cast<uint32_t*>(l_dvpd_vm));
-
- l_memd_found = find_memd_in_pnor(l_dvpd_vm,
- l_header, l_pMcsTarget, theSize);
- uint64_t l_memd_offset_bytes = l_pMcsTarget->getAttr<
- TARGETING::ATTR_MEMD_OFFSET>();
-
- if(l_memd_found)
- {
- FAPI_INF("platGetVPD: Matching MEMD data was found in the "
- "PNOR section, VM value is %llx. Reading in at "
- "offset %llx",l_full_dvpdVM[0], l_memd_offset_bytes);
- l_errl = deviceRead((TARGETING::Target *)l_pMcsTarget,
- l_pMapping,
- l_buffSize,
- DEVICE_MEMD_VPD_ADDRESS(MEMD_VPD::MEMD,
- l_mapKeyword) + l_memd_offset_bytes );
- break;
- }else
- {
- FAPI_INF("platGetVPD: Matching MEMD data was not found in "
- "the PNOR section, DVPD VM value is %llx",
- l_full_dvpdVM[0]);
- }
-
- }while(0);
-
- }
- if(l_errl)
- {
- FAPI_ERR("find_memd_in_pnor: ERROR getting the PNOR MEMD information");
- l_rc.setPlatDataPtr(reinterpret_cast<void *>(l_errl));
+ FAPI_ERR("platGetVPD: ERROR returned from deviceRead(MEMD,%d)",l_mapKeyword);
break;
}
- if( !(l_memd_found) )
- {
- FAPI_INF("platGetVPD: MEMD data was not found in the PNOR "
- "section. Using EEPROM. VM value is: %llx",
- l_full_dvpdVM[0]);
-
- l_errl = deviceRead((TARGETING::Target *)l_pMcsTarget,
- l_pMapping,
- l_buffSize,
- DEVICE_DVPD_ADDRESS(DVPD::MEMD,
- l_mapKeyword));
- if (l_errl)
- {
- delete l_pMapping;
- l_pMapping = nullptr;
- FAPI_ERR("platGetVPD: ERROR reading mapping keyword");
- l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
- break; //return with error
- }
- }
-
// Find vpd keyword name based on VPDInfo
FAPI_EXEC_HWP(l_rc,
p9_get_mem_vpd_keyword,
@@ -377,28 +275,15 @@ fapi2::ReturnCode platGetVPD(
//Read vpd blob
l_buffSize = l_keywordInfo.kwBlobSize;
- if(l_memd_found)
- {
- l_errl = deviceRead((TARGETING::Target *)l_pMcsTarget,
- o_blob,
- l_buffSize,
- DEVICE_MEMD_VPD_ADDRESS(MEMD_VPD::MEMD,
- l_keywordEnum));
-
- }
- else
- {
- l_errl = deviceRead((TARGETING::Target *)l_pMcsTarget,
+ l_errl = deviceRead((TARGETING::Target *)l_pMcsTarget,
o_blob,
l_buffSize,
DEVICE_DVPD_ADDRESS(DVPD::MEMD,
l_keywordEnum));
- }
if (l_errl)
{
FAPI_ERR("platGetVPD: ERROR reading keyword");
- l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
break; //return with error
}
@@ -434,106 +319,19 @@ fapi2::ReturnCode platGetVPD(
HWAS::NO_DECONFIG,
HWAS::GARD_NULL );
- l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
break; //return with error
}
}
}
while (0);
- free(l_dvpd_vm);
- l_dvpd_vm = nullptr;
- l_full_dvpdVM = nullptr;
-
- FAPI_DBG("platGetVPD: exit");
-
- return l_rc;
-}
-
-bool find_memd_in_pnor(uint8_t* i_eepromVM, MemdHeader_t i_header,
- TARGETING::Target * i_target, size_t i_vm_size)
-{
- errlHndl_t l_errl = nullptr;
-
- bool memdFoundInPnor = false;
- bool l_valid_memd = ((i_header.eyecatch == MEMD_VALID_HEADER) &
- (i_header.header_version == MEMD_VALID_HEADER_VERSION) &
- (i_header.memd_version == MEMD_VALID_MEMD_VERSION) );
-
- uint8_t* l_memd_vm = nullptr;
- uint32_t l_memd_iteration = 0;
- bool l_retValue = false;
-
- if(l_valid_memd && !memdFoundInPnor)
+ if( l_errl )
{
- FAPI_INF("find_memd_in_pnor: MEMD is valid!");
- // Reset memd offset before we start the first iteration
- i_target->setAttr<TARGETING::ATTR_MEMD_OFFSET>(0);
-
- //do-while loop (needs to be executed at least once)
- // while VM keywods don't match, and we haven't gone
- // through all the MEMD copies
- do
- {
- // Get the VM keyword from the copy in PNOR
- l_memd_vm = static_cast<uint8_t*>(malloc( i_vm_size ));
-
- uint64_t l_memd_offset = i_target->getAttr<
- TARGETING::ATTR_MEMD_OFFSET>();
-
- FAPI_INF("find_memd_in_pnor: attempting to read MEMD VM keyword");
- l_errl = deviceRead( i_target, l_memd_vm, i_vm_size,
- DEVICE_MEMD_VPD_ADDRESS(
- MEMD_VPD::MEMD, MEMD_VPD::VM));
- if(l_errl)
- {
- FAPI_ERR("find_memd_in_pnor: ERROR getting MEMD VM keyword");
- errlCommit(l_errl, FAPI2_COMP_ID);
- break;
- }
-
- assert(i_vm_size != 0);
-
- // Compare the last nibbles
- if( !((i_eepromVM[i_vm_size-1] & 0x0F) ==
- (l_memd_vm[i_vm_size-1] & 0x0F)) )
- {
- // VM's don't match, we need to keep looking
- FAPI_INF("find_memd_in_pnor: DVPD and MEMD VM's last nibble"
- " don't match: %llx and %llx",
- (reinterpret_cast<uint32_t*>(i_eepromVM))[0],
- (reinterpret_cast<uint32_t*>(l_memd_vm))[0] );
- i_target->setAttr<TARGETING::ATTR_MEMD_OFFSET
- >(l_memd_offset +
- (i_header.expected_size_kb * 1000));
- }
- else
- {
- FAPI_INF("find_memd_in_pnor: Matching MEMD data was found in "
- "the PNOR section. VM value is: %llx. Offset "
- "is %llx, DVPD VM is %llx",
- (reinterpret_cast<uint32_t*>(l_memd_vm))[0],
- l_memd_offset,
- (reinterpret_cast<uint32_t*>(i_eepromVM))[0]);
- memdFoundInPnor = true;
- l_retValue = true;
- break;
- }
-
- l_memd_iteration = l_memd_iteration + 1;
- free(l_memd_vm);
- l_memd_vm = nullptr;
-
- }while(l_memd_iteration < i_header.expected_num);
-
- free(l_memd_vm);
- l_memd_vm = nullptr;
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
}
+ FAPI_DBG("platGetVPD: exit");
- return l_retValue;
-
+ return l_rc;
}
-
-
} // namespace
diff --git a/src/usr/isteps/istep11/call_host_prd_hwreconfig.C b/src/usr/isteps/istep11/call_host_prd_hwreconfig.C
index 81eede957..0df8a468e 100644
--- a/src/usr/isteps/istep11/call_host_prd_hwreconfig.C
+++ b/src/usr/isteps/istep11/call_host_prd_hwreconfig.C
@@ -23,6 +23,11 @@
/* */
/* IBM_PROLOG_END_TAG */
#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <isteps/hwpisteperror.H>
+#include <pnor/pnorif.H>
+#include <config.h>
+#include <initservice/isteps_trace.H>
using namespace ERRORLOG;
@@ -30,9 +35,26 @@ namespace ISTEP_11
{
void* call_host_prd_hwreconfig (void *io_pArgs)
{
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, ENTER_MRK"call_host_prd_hwreconfig");
+
errlHndl_t l_err = NULL;
+ ISTEP_ERROR::IStepError l_StepError;
//@TODO-RTC:158411 call p9_enable_reconfig.C
- return l_err;
+
+
+#ifdef CONFIG_SECUREBOOT
+ // Load the MEMD section here as the first part of step11, it
+ // will stay loaded until the end of step14
+ l_err = loadSecureSection(PNOR::MEMD);
+ if( l_err )
+ {
+ l_StepError.addErrorDetails(l_err);
+ ERRORLOG::errlCommit(l_err, HWPF_COMP_ID);
+ }
+#endif
+
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, EXIT_MRK"call_host_prd_hwreconfig");
+ return l_StepError.getErrorHandle();
}
};
diff --git a/src/usr/isteps/istep14/call_proc_exit_cache_contained.C b/src/usr/isteps/istep14/call_proc_exit_cache_contained.C
index 45d4bbf73..7b5e86d46 100644
--- a/src/usr/isteps/istep14/call_proc_exit_cache_contained.C
+++ b/src/usr/isteps/istep14/call_proc_exit_cache_contained.C
@@ -461,6 +461,7 @@ void* call_proc_exit_cache_contained (void *io_pArgs)
}
}
}
+
if ( l_errl )
{
// Create IStep error log and cross reference to error that occurred
@@ -470,6 +471,17 @@ void* call_proc_exit_cache_contained (void *io_pArgs)
errlCommit( l_errl, HWPF_COMP_ID );
}
+#ifdef CONFIG_SECUREBOOT
+ // Unload the MEMD section that was loaded at the beginning of step11
+ l_errl = unloadSecureSection(PNOR::MEMD);
+ if (l_errl)
+ {
+ l_stepError.addErrorDetails(l_errl);
+ errlCommit(l_errl, HWPF_COMP_ID);
+ }
+#endif
+
+
TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_proc_exit_cache_contained exit" );
// @@@@@ END CUSTOM BLOCK: @@@@@
diff --git a/src/usr/pnor/spnorrp.C b/src/usr/pnor/spnorrp.C
index f3e67d202..5b1ef5b03 100644
--- a/src/usr/pnor/spnorrp.C
+++ b/src/usr/pnor/spnorrp.C
@@ -884,12 +884,14 @@ void SPnorRP::waitForMessage()
}
else
{
+ TRACDCOMP(g_trac_pnor,"Loading %s for the first time", PNOR::SectionIdToString(l_id));
l_record = new LoadRecord;
}
TRACDCOMP(g_trac_pnor, "SPnorRP::waitForMessage> MSG_LOAD_SECTION refCount is %i",l_record->refCount);
if (l_record->refCount == 0)
{
+ TRACDCOMP(g_trac_pnor,"Loading %s fresh", PNOR::SectionIdToString(l_id));
uint32_t loadPlid=0;
l_rc = verifySections(l_id,
l_loadedPreviously,
@@ -1027,6 +1029,7 @@ void SPnorRP::waitForMessage()
// 2 or more
break;
}
+ TRACDCOMP(g_trac_pnor,"Completely unloading %s", PNOR::SectionIdToString(l_id));
l_errhdl = removePages(l_rec->secAddr,
l_sizeWithHdr);
diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C
index 4d26bce26..bf891b09c 100644
--- a/src/usr/runtime/populate_hbruntime.C
+++ b/src/usr/runtime/populate_hbruntime.C
@@ -443,9 +443,12 @@ errlHndl_t setNextHbRsvMemEntry(const HDAT::hdatMsVpdRhbAddrRangeType i_type,
* ----- HB Data Layout -------
* io_start_address
* -- HB Table of Contents
- * -- ATTR Override Data
+ * -- ATTR Override Data (optional)
* -- ATTR Data
* -- VPD
+ * -- HYPCOMM
+ * -- VPD Overrides
+ * -- HBRT Trace Area (master node only)
* -- Padding
* io_end_address
*
@@ -564,6 +567,21 @@ errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address,
ALIGN_PAGE(l_hbTOC.entry[l_hbTOC.total_entries].size);
l_hbTOC.total_entries++;
+ // Fill in VPD_XXXX sizes (if there are any)
+ VPD::OverrideRsvMemMap_t l_vpdOverrides;
+ VPD::getListOfOverrideSections( l_vpdOverrides );
+ for( auto l_over : l_vpdOverrides )
+ {
+ // Or in the specific label with the "VPD_" prefix
+ l_hbTOC.entry[l_hbTOC.total_entries].label =
+ Util::HBRT_MEM_LABEL_VPD_XXXX | l_over.first;
+ l_hbTOC.entry[l_hbTOC.total_entries].offset = 0;
+ l_hbTOC.entry[l_hbTOC.total_entries].size = l_over.second.size;
+ l_totalSectionSize +=
+ ALIGN_PAGE(l_hbTOC.entry[l_hbTOC.total_entries].size);
+ l_hbTOC.total_entries++;
+ }
+
// Fill in the TRACEBUF only for Master Node
if(i_master_node == true )
{
@@ -778,7 +796,84 @@ errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address,
memset(reinterpret_cast<uint8_t*>(l_prevDataAddr),0,aligned_size);
break;
+ case Util::HBRT_MEM_LABEL_VPD_MEMD:
+ {
+ TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> VPD_MEMD v address 0x%.16llX, size: %lld", l_prevDataAddr, aligned_size);
+
+ VPD::OverrideSpecifier_t l_over =
+ l_vpdOverrides[l_hbTOC.entry[i].label
+ & Util::HBRT_MEM_LABEL_VPD_MASK];
+
+#ifdef CONFIG_SECUREBOOT
+ // load the section in, copy the data, then unload it
+ l_elog = PNOR::loadSecureSection(l_over.pnorId);
+ if(l_elog)
+ {
+ TRACFCOMP( g_trac_runtime,
+ "fill_RsvMem_hbData> failed secure load call" );
+ break;
+ }
+#endif
+
+ PNOR::SectionInfo_t l_memd_info;
+ l_elog = PNOR::getSectionInfo(l_over.pnorId,l_memd_info);
+ if( l_elog )
+ {
+ TRACFCOMP( g_trac_runtime,
+ "fill_RsvMem_hbData> failed getSectionInfo call" );
+ break;
+ }
+
+#ifdef CONFIG_SECUREBOOT
+ memcpy(reinterpret_cast<uint8_t*>(l_prevDataAddr),
+ reinterpret_cast<uint8_t *>(l_memd_info.vaddr),
+ l_memd_info.secureProtectedPayloadSize);
+#else
+ memcpy(reinterpret_cast<uint8_t*>(l_prevDataAddr),
+ reinterpret_cast<uint8_t *>(l_memd_info.vaddr),
+ l_memd_info.size);
+#endif
+
+
+#ifdef CONFIG_SECUREBOOT
+ l_elog = PNOR::unloadSecureSection(l_over.pnorId);
+ if(l_elog)
+ {
+ TRACFCOMP( g_trac_runtime,
+ "fill_RsvMem_hbData> failed secure unload call" );
+ break;
+ }
+#endif
+
+ TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> VPD v address 0x%.16llX, size: %lld done", l_prevDataAddr, aligned_size);
+ break;
+ }
+
+ case(Util::HBRT_MEM_LABEL_PADDING):
+ // NOOP
+ break;
+
default:
+ TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData> Unrecognized label 0x%.ll16X", l_hbTOC.entry[i].label );
+ /*@
+ * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid RUNTIME::MOD_FILL_RSVMEM_HBDATA
+ * @reasoncode RUNTIME::RC_UNKNOWN_LABEL
+ * @userdata1 Unknown Label
+ * @userdata2 <unused>
+ *
+ * @devdesc Unknown reserved memory label attempted
+ * @custdesc Firmware error initializing system
+ * data structures during boot
+ */
+ l_elog = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_FILL_RSVMEM_HBDATA,
+ RUNTIME::RC_UNKNOWN_LABEL,
+ l_hbTOC.entry[i].label,
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
+ l_elog->collectTrace(RUNTIME_COMP_NAME);
break;
}
i++;
@@ -3138,6 +3233,7 @@ errlHndl_t populate_hbRuntimeData( void )
if(l_elog != nullptr)
{
TRACFCOMP( g_trac_runtime, "fill_RsvMem_hbData failed" );
+ break;
}
// Get list of processor chips
diff --git a/src/usr/util/runtime/util_rt.C b/src/usr/util/runtime/util_rt.C
index 3dc3935f3..468db6ee7 100644
--- a/src/usr/util/runtime/util_rt.C
+++ b/src/usr/util/runtime/util_rt.C
@@ -28,7 +28,6 @@
#include <util/utilrsvdmem.H>
#include <util/runtime/util_rt.H>
-
/**
* @brief Get the address of a reserved hostboot memory region by its label
* @param[in] i_label HBRT_MEM_LABEL_ constant
@@ -55,6 +54,7 @@ uint64_t hb_get_rt_rsvd_mem(Util::hbrt_mem_label_t i_label,
case Util::HBRT_MEM_LABEL_PADDING:
case Util::HBRT_MEM_LABEL_HYPCOMM:
case Util::HBRT_MEM_LABEL_TRACEBUF:
+ case Util::HBRT_MEM_LABEL_VPD_MEMD:
if( (g_hostInterfaces != NULL) &&
(g_hostInterfaces->get_reserved_mem) )
{
diff --git a/src/usr/util/utilrsvdmem.C b/src/usr/util/utilrsvdmem.C
index 32859f311..e0a788b33 100644
--- a/src/usr/util/utilrsvdmem.C
+++ b/src/usr/util/utilrsvdmem.C
@@ -62,6 +62,7 @@ namespace Util
case HBRT_MEM_LABEL_PADDING:
case HBRT_MEM_LABEL_HYPCOMM:
case HBRT_MEM_LABEL_TRACEBUF:
+ case HBRT_MEM_LABEL_VPD_MEMD:
// Find offset of label section
for (uint16_t i = 0; i < toc_ptr->total_entries; i++)
{
diff --git a/src/usr/vpd/cvpd.C b/src/usr/vpd/cvpd.C
index 7576009eb..fe203dd50 100644
--- a/src/usr/vpd/cvpd.C
+++ b/src/usr/vpd/cvpd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2018 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -115,10 +115,38 @@ namespace CVPD
TRACSSCOMP( g_trac_vpd,
ENTER_MRK"cvpdRead()" );
- err = Singleton<CvpdFacade>::instance().read(i_target,
- io_buffer,
- io_buflen,
- args);
+#ifdef CONFIG_SECUREBOOT
+ // Load the secure section just in case if we're using it
+ bool l_didload = false;
+ err = Singleton<CvpdFacade>::instance().
+ loadUnloadSecureSection( args, i_target, true, l_didload );
+#endif
+
+ if( !err )
+ {
+ err = Singleton<CvpdFacade>::instance().read(i_target,
+ io_buffer,
+ io_buflen,
+ args);
+ }
+
+#ifdef CONFIG_SECUREBOOT
+ if( l_didload )
+ {
+ errlHndl_t err2 = Singleton<CvpdFacade>::instance().
+ loadUnloadSecureSection( args, i_target, false, l_didload );
+ if( err2 && !err )
+ {
+ err = err2;
+ err2 = nullptr;
+ }
+ else if( err2 )
+ {
+ err2->plid(err->plid());
+ errlCommit( err2, VPD_COMP_ID );
+ }
+ }
+#endif
return err;
}
@@ -288,3 +316,113 @@ void CvpdFacade::getRecordLists(
#endif
}
+/**
+ * @brief Callback function to check for a record override and
+ * set iv_overridePtr appropriately
+ */
+errlHndl_t CvpdFacade::checkForRecordOverride( const char* i_record,
+ TARGETING::Target* i_target,
+ uint8_t*& o_ptr )
+{
+ TRACFCOMP(g_trac_vpd,ENTER_MRK"CvpdFacade::checkForRecordOverride( %s, 0x%.8X )",
+ i_record, get_huid(i_target));
+ errlHndl_t l_errl = nullptr;
+ o_ptr = nullptr;
+
+ assert( i_record != nullptr, "CvpdFacade::checkForRecordOverride() i_record is null" );
+ assert( i_target != nullptr, "CvpdFacade::checkForRecordOverride() i_target is null" );
+
+ VPD::RecordTargetPair_t l_recTarg =
+ VPD::makeRecordTargetPair(i_record,i_target);
+
+ do
+ {
+ // We only support overriding SPDX
+ if( strcmp( i_record, "SPDX" ) )
+ {
+ TRACFCOMP(g_trac_vpd,"Record %s has no override", i_record);
+ iv_overridePtr[l_recTarg] = nullptr;
+ break;
+ }
+
+ // Compare the 5th nibble
+ constexpr uint32_t l_vmMask = 0x00000F00;
+ input_args_t l_args = { CVPD::SPDX, CVPD::VM, VPD::AUTOSELECT };
+ l_errl = getMEMDFromPNOR( l_args,
+ i_target,
+ l_vmMask );
+ if( l_errl )
+ {
+ TRACFCOMP(g_trac_vpd,ERR_MRK"ERROR from getMEMDFromPNOR.");
+ break;
+ }
+
+ } while(0);
+
+ // For any error, we should reset the override map so that we'll
+ // attempt everything again the next time we want VPD
+ if( l_errl )
+ {
+ iv_overridePtr.erase(l_recTarg);
+ }
+ else
+ {
+ o_ptr = iv_overridePtr[l_recTarg];
+ }
+
+ return l_errl;
+}
+
+#ifdef CONFIG_SECUREBOOT
+/**
+ * @brief Load/unload the appropriate secure section for
+ * an overriden PNOR section
+ */
+errlHndl_t CvpdFacade::loadUnloadSecureSection( input_args_t i_args,
+ TARGETING::Target* i_target,
+ bool i_load,
+ bool& o_loaded )
+{
+ errlHndl_t l_err = nullptr;
+ o_loaded = false;
+
+#ifndef __HOSTBOOT_RUNTIME
+ // Only relevant for SPDX
+ if( i_args.record != CVPD::SPDX )
+ {
+ return nullptr;
+ }
+
+ const char* l_record = nullptr;
+ l_err = translateRecord( i_args.record, l_record );
+ if( l_err )
+ {
+ return l_err;
+ }
+
+ // Jump out if we don't have an override
+ VPD::RecordTargetPair_t l_recTarg =
+ VPD::makeRecordTargetPair(l_record,i_target);
+ VPD::OverrideMap_t::iterator l_overItr = iv_overridePtr.find(l_recTarg);
+ if( l_overItr == iv_overridePtr.end() )
+ {
+ return nullptr;
+ }
+
+ if( i_load )
+ {
+ l_err = loadSecureSection(PNOR::MEMD);
+ if( !l_err )
+ {
+ o_loaded = true;
+ }
+ }
+ else
+ {
+ l_err = unloadSecureSection(PNOR::MEMD);
+ }
+#endif
+
+ return l_err;
+}
+#endif
diff --git a/src/usr/vpd/cvpd.H b/src/usr/vpd/cvpd.H
index 73c54128d..31f89b29f 100644
--- a/src/usr/vpd/cvpd.H
+++ b/src/usr/vpd/cvpd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -176,6 +176,22 @@ class CvpdFacade: public IpVpdFacade
*/
CvpdFacade( );
+#ifdef CONFIG_SECUREBOOT
+ /**
+ * @brief Load/unload the appropriate secure section for
+ * an overriden PNOR section
+ * @param[in] i_args Record/keyword
+ * @param[in] i_target Target pointer
+ * @param[in] i_load true=load, false=unload
+ * @param[out] o_loaded true=section loaded, false=section not loaded
+ * @return Error log
+ */
+ virtual errlHndl_t loadUnloadSecureSection( input_args_t i_args,
+ TARGETING::Target* i_target,
+ bool i_load,
+ bool& o_loaded );
+#endif
+
private:
/**
@@ -197,5 +213,19 @@ class CvpdFacade: public IpVpdFacade
const recordInfo* & o_altVpdRecords,
uint64_t & o_altRecSize);
+ protected:
+ /**
+ * @brief Callback function to check for a record override and
+ * set iv_overridePtr appropriately
+ * @param[in] i_record Record name
+ * @param[in] i_target Target pointer
+ * @param[out] o_ptr Pointer to location of record in PNOR,
+ * ==nullptr if there is no override
+ * @return Error log
+ */
+ virtual errlHndl_t checkForRecordOverride( const char* i_record,
+ TARGETING::Target* i_target,
+ uint8_t*& o_ptr );
+
};
#endif // __CVPD_H
diff --git a/src/usr/vpd/dvpd.C b/src/usr/vpd/dvpd.C
index 8adf670f7..9e5e7fbf4 100644
--- a/src/usr/vpd/dvpd.C
+++ b/src/usr/vpd/dvpd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -113,12 +113,44 @@ namespace DVPD
args.location = ((VPD::vpdCmdTarget)va_arg( i_args, uint64_t ));
TRACSSCOMP( g_trac_vpd,
- ENTER_MRK"dvpdRead()" );
+ ENTER_MRK"dvpdRead(0x%.8X):rec=%d,kw=%d,loc=%d",
+ TARGETING::get_huid(i_target),
+ args.record,
+ args.keyword,
+ args.location);
+
+#ifdef CONFIG_SECUREBOOT
+ // Load the secure section just in case if we're using it
+ bool l_didload = false;
+ err = Singleton<DvpdFacade>::instance().
+ loadUnloadSecureSection( args, i_target, true, l_didload );
+#endif
- err = Singleton<DvpdFacade>::instance().read(i_target,
- io_buffer,
- io_buflen,
- args);
+ if( !err )
+ {
+ err = Singleton<DvpdFacade>::instance().read(i_target,
+ io_buffer,
+ io_buflen,
+ args);
+ }
+
+#ifdef CONFIG_SECUREBOOT
+ if( l_didload )
+ {
+ errlHndl_t err2 = Singleton<DvpdFacade>::instance().
+ loadUnloadSecureSection( args, i_target, false, l_didload );
+ if( err2 && !err )
+ {
+ err = err2;
+ err2 = nullptr;
+ }
+ else if( err2 )
+ {
+ err2->plid(err->plid());
+ errlCommit( err2, VPD_COMP_ID );
+ }
+ }
+#endif
return err;
}
@@ -166,7 +198,11 @@ namespace DVPD
args.location = ((VPD::vpdCmdTarget)va_arg( i_args, uint64_t ));
TRACSSCOMP( g_trac_vpd,
- ENTER_MRK"dvpdWrite()" );
+ ENTER_MRK"dvpdWrite(0x%.8X):rec=%d,kw=%d,loc=%d",
+ TARGETING::get_huid(i_target),
+ args.record,
+ args.keyword,
+ args.location);
err = Singleton<DvpdFacade>::instance().write(i_target,
@@ -337,9 +373,8 @@ IpVpdFacade(DVPD::dvpdRecords,
iv_configInfo.vpdWriteHW = false;
#endif
-iv_vpdSectionSize = DVPD::SECTION_SIZE;
-iv_vpdMaxSections = DVPD::MAX_SECTIONS;
-
+ iv_vpdSectionSize = DVPD::SECTION_SIZE;
+ iv_vpdMaxSections = DVPD::MAX_SECTIONS;
}
// Retrun lists of records that should be copied to pnor.
void DvpdFacade::getRecordLists(
@@ -367,3 +402,112 @@ void DvpdFacade::getRecordLists(
#endif
}
+/**
+ * @brief Callback function to check for a record override
+ */
+errlHndl_t DvpdFacade::checkForRecordOverride( const char* i_record,
+ TARGETING::Target* i_target,
+ uint8_t*& o_ptr )
+{
+ TRACFCOMP(g_trac_vpd,ENTER_MRK"DvpdFacade::checkForRecordOverride( %s, 0x%.8X )",
+ i_record, get_huid(i_target));
+ errlHndl_t l_errl = nullptr;
+ o_ptr = nullptr;
+
+ assert( i_record != nullptr, "DvpdFacade::checkForRecordOverride() i_record is null" );
+ assert( i_target != nullptr, "DvpdFacade::checkForRecordOverride() i_target is null" );
+
+ VPD::RecordTargetPair_t l_recTarg =
+ VPD::makeRecordTargetPair(i_record,i_target);
+
+ do
+ {
+ // We only support overriding MEMD
+ if( strcmp( i_record, "MEMD" ) )
+ {
+ TRACFCOMP(g_trac_vpd,"Record %s has no override", i_record);
+ iv_overridePtr[l_recTarg] = nullptr;
+ break;
+ }
+
+ // Compare the last nibble
+ constexpr uint32_t l_vmMask = 0x0000000F;
+ input_args_t l_args = { DVPD::MEMD, DVPD::VM, VPD::AUTOSELECT };
+ l_errl = getMEMDFromPNOR( l_args,
+ i_target,
+ l_vmMask );
+ if( l_errl )
+ {
+ TRACFCOMP(g_trac_vpd,ERR_MRK"ERROR from getMEMDFromPNOR.");
+ break;
+ }
+
+ } while(0);
+
+ // For any error, we should reset the override map so that we'll
+ // attempt everything again the next time we want VPD
+ if( l_errl )
+ {
+ iv_overridePtr.erase(l_recTarg);
+ }
+ else
+ {
+ o_ptr = iv_overridePtr[l_recTarg];
+ }
+
+ return l_errl;
+}
+
+#ifdef CONFIG_SECUREBOOT
+/**
+ * @brief Load/unload the appropriate secure section for
+ * an overriden PNOR section
+ */
+errlHndl_t DvpdFacade::loadUnloadSecureSection( input_args_t i_args,
+ TARGETING::Target* i_target,
+ bool i_load,
+ bool& o_loaded )
+{
+ errlHndl_t l_err = nullptr;
+ o_loaded = false;
+
+#ifndef __HOSTBOOT_RUNTIME
+ // Only relevant for MEMD
+ if( i_args.record != DVPD::MEMD )
+ {
+ return nullptr;
+ }
+
+ const char* l_record = nullptr;
+ l_err = translateRecord( i_args.record, l_record );
+ if( l_err )
+ {
+ return l_err;
+ }
+
+ // Jump out if we don't have an override
+ VPD::RecordTargetPair_t l_recTarg =
+ VPD::makeRecordTargetPair(l_record,i_target);
+ VPD::OverrideMap_t::iterator l_overItr = iv_overridePtr.find(l_recTarg);
+ if( l_overItr == iv_overridePtr.end() )
+ {
+ return nullptr;
+ }
+
+ if( i_load )
+ {
+ l_err = loadSecureSection(PNOR::MEMD);
+ if( !l_err )
+ {
+ o_loaded = true;
+ }
+ }
+ else
+ {
+ l_err = unloadSecureSection(PNOR::MEMD);
+ }
+#endif
+
+ return l_err;
+}
+#endif
diff --git a/src/usr/vpd/dvpd.H b/src/usr/vpd/dvpd.H
index 73279e844..92985aebe 100644
--- a/src/usr/vpd/dvpd.H
+++ b/src/usr/vpd/dvpd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2016 */
+/* Contributors Listed Below - COPYRIGHT 2013,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -225,6 +225,22 @@ class DvpdFacade: public IpVpdFacade
*/
DvpdFacade( );
+#ifdef CONFIG_SECUREBOOT
+ /**
+ * @brief Load/unload the appropriate secure section for
+ * an overriden PNOR section
+ * @param[in] i_args Record/keyword
+ * @param[in] i_target Target pointer
+ * @param[in] i_load true=load, false=unload
+ * @param[out] o_loaded true=section loaded, false=section not loaded
+ * @return Error log
+ */
+ virtual errlHndl_t loadUnloadSecureSection( input_args_t i_args,
+ TARGETING::Target* i_target,
+ bool i_load,
+ bool& o_loaded );
+#endif
+
private:
/**
@@ -246,5 +262,19 @@ class DvpdFacade: public IpVpdFacade
const recordInfo* & o_altVpdRecords,
uint64_t & o_altRecSize);
+ protected:
+ /**
+ * @brief Callback function to check for a record override and
+ * set iv_overridePtr appropriately
+ * @param[in] i_record Record name
+ * @param[in] i_target Target pointer
+ * @param[out] o_ptr Pointer to location of record in PNOR,
+ * ==nullptr if there is no override
+ * @return Error log
+ */
+ virtual errlHndl_t checkForRecordOverride( const char* i_record,
+ TARGETING::Target* i_target,
+ uint8_t*& o_ptr );
+
};
#endif // __DVPD_H
diff --git a/src/usr/vpd/ipvpd.C b/src/usr/vpd/ipvpd.C
index c62c8355f..25b7970f2 100644
--- a/src/usr/vpd/ipvpd.C
+++ b/src/usr/vpd/ipvpd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2018 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -41,7 +41,8 @@
#include <vpd/vpd_if.H>
#include <config.h>
#include <vpd/ipvpdenums.H>
-#include <vpd/memd_vpdenums.H>
+#include <util/utilrsvdmem.H>
+#include <util/runtime/util_rt.H>
#include "vpd.H"
#include "cvpd.H"
@@ -68,7 +69,6 @@ extern trace_desc_t* g_trac_vpd;
static const uint64_t IPVPD_TOC_SIZE = 0x100; //256
static const uint64_t IPVPD_TOC_ENTRY_SIZE = 8;
static const uint64_t IPVPD_TOC_INVALID_DATA = 0xFFFFFFFFFFFFFFFF;
-uint64_t MEMD_HEADER_SIZE = sizeof(MemdHeader_t);
/**
* @brief Constructor
@@ -88,7 +88,6 @@ IpVpdFacade::IpVpdFacade(const recordInfo* i_vpdRecords,
,iv_mutex(i_mutex)
,iv_cachePnorAddr(0x0)
,iv_vpdMsgType(i_vpdMsgType)
-,iv_memdAccessed(false)
{
iv_configInfo.vpdReadPNOR = false;
iv_configInfo.vpdReadHW = false;
@@ -243,11 +242,9 @@ errlHndl_t IpVpdFacade::write ( TARGETING::Target * i_target,
// write() recursively for each location
if ( iv_configInfo.vpdWritePNOR &&
iv_configInfo.vpdWriteHW &&
- i_args.location == VPD::AUTOSELECT )
+ ((i_args.location & VPD::LOCATION_MASK) == VPD::AUTOSELECT) )
{
- input_args_t l_args;
- l_args.record = i_args.record;
- l_args.keyword = i_args.keyword;
+ input_args_t l_args = i_args;
l_args.location = VPD::SEEPROM;
err = write( i_target,
@@ -615,7 +612,8 @@ errlHndl_t IpVpdFacade::loadPnor ( TARGETING::Target * i_target )
sRecLength,
pRecPtr,
i_target,
- sRecArgs.location );
+ sRecArgs.location,
+ (*it).record_name );
if( err )
{
TRACFCOMP(g_trac_vpd,"IpVpdFacade::loadPnor() Error reading record %s",(*it).record_name);
@@ -858,6 +856,43 @@ errlHndl_t IpVpdFacade::findRecordOffset ( const char * i_record,
{
errlHndl_t err = NULL;
+ // Look for a record override in our image unless explicitly told not to
+ if( (i_args.location & VPD::OVERRIDE_MASK) != VPD::USEVPD )
+ {
+ uint8_t* l_overridePtr = nullptr;
+ VPD::RecordTargetPair_t l_recTarg =
+ VPD::makeRecordTargetPair(i_record,i_target);
+
+ // Check if we already figured out where to get this record from
+ VPD::OverrideMap_t::iterator l_overItr = iv_overridePtr.find(l_recTarg);
+ if( l_overItr != iv_overridePtr.end() )
+ {
+ l_overridePtr = l_overItr->second;
+ }
+ else
+ {
+ // Now go see if we should be using the override and if so
+ // where we find the right copy
+ err = checkForRecordOverride(i_record,i_target,l_overridePtr);
+ if( err )
+ {
+ TRACFCOMP( g_trac_vpd, ERR_MRK"findRecordOffset> failure calling checkForRecordOverride for %s on %.8X",
+ i_record, get_huid(i_target) );
+ return err;
+ }
+
+ TRACFCOMP( g_trac_vpd, INFO_MRK" Record %s for target 0x%.8X exists at %p in PNOR",
+ i_record, get_huid(i_target), l_overridePtr );
+ }
+
+ // If we have an override, the record is already pointed at directly
+ if( l_overridePtr != nullptr )
+ {
+ o_offset = 0;
+ return nullptr;
+ }
+ }
+
// Determine the VPD source (PNOR/SEEPROM)
VPD::vpdCmdTarget vpdSource = VPD::AUTOSELECT;
bool configError = false;
@@ -940,17 +975,17 @@ bool IpVpdFacade::hasVpdPresent( TARGETING::Target * i_target,
uint16_t recordOffset = 0x0;
input_args_t i_args;
bool vpdPresent = false;
- const char * recordName = NULL;
- const char * keywordName = NULL;
+ const char * l_recordName = NULL;
+ const char * l_keywordName = NULL;
i_args.record = i_record;
i_args.keyword = i_keyword;
do
{
- //get the Recod/Keyword names
+ //get the Record/Keyword names
err = translateRecord( i_args.record,
- recordName );
+ l_recordName );
if( err )
{
@@ -960,7 +995,7 @@ bool IpVpdFacade::hasVpdPresent( TARGETING::Target * i_target,
}
err = translateKeyword( i_args.keyword,
- keywordName );
+ l_keywordName );
if( err )
{
@@ -969,10 +1004,10 @@ bool IpVpdFacade::hasVpdPresent( TARGETING::Target * i_target,
break;
}
- vpdPresent = recordPresent( recordName,
+ vpdPresent = recordPresent( l_recordName,
recordOffset,
i_target,
- VPD::AUTOSELECT );
+ VPD::USEVPD );
}while( 0 );
@@ -996,7 +1031,7 @@ bool IpVpdFacade::recordPresent( const char * i_record,
{
errlHndl_t err = NULL;
uint64_t tmpOffset = 0x0;
- char record[RECORD_BYTE_SIZE] = { '\0' };
+ char l_record[RECORD_BYTE_SIZE] = { '\0' };
bool matchFound = false;
do
@@ -1018,9 +1053,10 @@ bool IpVpdFacade::recordPresent( const char * i_record,
//Read Record Name
err = fetchData( tmpOffset,
RECORD_BYTE_SIZE,
- record,
+ l_record,
i_target,
- i_location );
+ i_location,
+ i_record );
tmpOffset += RECORD_BYTE_SIZE;
if( err )
@@ -1028,7 +1064,7 @@ bool IpVpdFacade::recordPresent( const char * i_record,
break;
}
- if( !(memcmp(record, i_record, RECORD_BYTE_SIZE )) )
+ if( !(memcmp(l_record, i_record, RECORD_BYTE_SIZE )) )
{
matchFound = true;
@@ -1037,7 +1073,8 @@ bool IpVpdFacade::recordPresent( const char * i_record,
RECORD_ADDR_BYTE_SIZE,
&o_offset,
i_target,
- i_location );
+ i_location,
+ i_record );
if( err )
{
break;
@@ -1485,7 +1522,8 @@ errlHndl_t IpVpdFacade::retrieveKeyword ( const char * i_keywordName,
keywordSize,
io_buffer,
i_target,
- i_args.location );
+ i_args.location,
+ i_recordName );
if( err )
{
break;
@@ -1525,7 +1563,8 @@ errlHndl_t IpVpdFacade::retrieveRecord( const char * i_recordName,
sizeof(l_size),
&l_size,
i_target,
- i_args.location );
+ i_args.location,
+ i_recordName );
if( err )
{
@@ -1557,7 +1596,8 @@ errlHndl_t IpVpdFacade::retrieveRecord( const char * i_recordName,
l_size,
io_buffer,
i_target,
- i_args.location );
+ i_args.location,
+ i_recordName );
if( err )
{
break;
@@ -1581,7 +1621,8 @@ errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr,
size_t i_numBytes,
void * o_data,
TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location )
+ VPD::vpdCmdTarget i_location,
+ const char* i_record )
{
errlHndl_t err = NULL;
@@ -1594,12 +1635,58 @@ errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr,
i_location,
vpdSource );
+ // Look for a record override in our image unless explicitly told not to
+ bool l_foundOverride = false;
+ if( (i_location & VPD::OVERRIDE_MASK) != VPD::USEVPD )
+ {
+ uint8_t* l_overridePtr = nullptr;
+ VPD::RecordTargetPair_t l_recTarg =
+ VPD::makeRecordTargetPair(i_record,i_target);
+
+ // At this point we can assume that the pointer is set into our
+ // map if we need it
+ VPD::OverrideMap_t::iterator l_overItr = iv_overridePtr.find(l_recTarg);
+ if( l_overItr != iv_overridePtr.end() )
+ {
+ l_overridePtr = l_overItr->second;
+
+ // Just do a simple memcpy
+ if( l_overridePtr != nullptr )
+ {
+ memcpy( o_data, l_overridePtr+i_byteAddr, i_numBytes );
+ l_foundOverride = true;
+ }
+ }
+ // Automatically populate a bunch of infrastructure records that
+ // we would never override (makes the error checks pass cleaner)
+ else if( (0 == memcmp( i_record, "VHDR", 4 ))
+ || (0 == memcmp( i_record, "VTOC", 4 )) )
+ {
+ iv_overridePtr[l_recTarg] = nullptr;
+ }
+ else
+ {
+ TRACFCOMP( g_trac_vpd, ERR_MRK"IpVpdFacade::fetchData: "
+ "iv_overridePtr is not set as expected for %s on %.8X",
+ i_record, TARGETING::get_huid(i_target) );
+ for( auto l_over : iv_overridePtr )
+ {
+ TRACFCOMP( g_trac_vpd, "%.8X : %.8X = %p",
+ TARGETING::get_huid((l_over.first).second),
+ (l_over.first).first,
+ l_over.second );
+ }
+ assert( false,
+ "iv_overridePtr is not set inside IpVpdFacade::fetchData" );
+ }
+ }
+
// Get the data
- if ( vpdSource == VPD::PNOR )
+ if ( (vpdSource == VPD::PNOR) && !l_foundOverride )
{
err = fetchDataFromPnor( i_byteAddr, i_numBytes, o_data, i_target );
}
- else if ( vpdSource == VPD::SEEPROM )
+ else if ( (vpdSource == VPD::SEEPROM) && !l_foundOverride )
{
err = fetchDataFromEeprom( i_byteAddr, i_numBytes, o_data, i_target );
}
@@ -1608,7 +1695,7 @@ errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr,
configError = true;
}
- if( configError )
+ if( configError && !l_foundOverride )
{
TRACFCOMP( g_trac_vpd, ERR_MRK"IpVpdFacade::fetchData: "
"Error resolving VPD source (PNOR/SEEPROM)");
@@ -1738,9 +1825,12 @@ errlHndl_t IpVpdFacade::findKeywordAddr ( const char * i_keywordName,
int matchesFound = 0;
TRACSSCOMP( g_trac_vpd,
- ENTER_MRK"IpVpdFacade::findKeywordAddr(%s, %s, . . .)",
+ ENTER_MRK"IpVpdFacade::findKeywordAddr(%s, %s, %d, %d, %.8X )",
i_keywordName,
- i_recordName );
+ i_recordName,
+ i_offset,
+ i_index,
+ TARGETING::get_huid(i_target) );
do
{
@@ -1749,31 +1839,14 @@ errlHndl_t IpVpdFacade::findKeywordAddr ( const char * i_keywordName,
RECORD_ADDR_BYTE_SIZE,
&recordSize,
i_target,
- i_args.location );
+ i_args.location,
+ i_recordName );
offset += RECORD_ADDR_BYTE_SIZE;
if( err )
{
break;
}
- if((iv_pnorSection == PNOR::MEMD))
- {
- static uint64_t l_basePnorAddr = 0;//getPnorAddr(*this);
- uint64_t l_cache_address = 0;
-
- if((iv_cachePnorAddr !=0) && !(iv_memdAccessed))
- {
- l_basePnorAddr = getPnorAddr(*this);
- iv_memdAccessed = true;
- }
-
- TARGETING::ATTR_MEMD_OFFSET_type l_memd_offset =
- i_target->getAttr<TARGETING::ATTR_MEMD_OFFSET>();
- l_cache_address = l_basePnorAddr +
- MEMD_HEADER_SIZE + l_memd_offset;
- setPnorAddr(l_cache_address);
- }
-
// Byte Swap
recordSize = le16toh( recordSize );
@@ -1784,7 +1857,8 @@ errlHndl_t IpVpdFacade::findKeywordAddr ( const char * i_keywordName,
RECORD_BYTE_SIZE,
record,
i_target,
- i_args.location );
+ i_args.location,
+ i_recordName );
// If we were looking for the Record Type (RT) keyword, we are done.
if (memcmp( i_keywordName, "RT", KEYWORD_BYTE_SIZE ) == 0) {
@@ -1809,10 +1883,11 @@ errlHndl_t IpVpdFacade::findKeywordAddr ( const char * i_keywordName,
if( memcmp( record, i_recordName, RECORD_BYTE_SIZE ) )
{
TRACFCOMP( g_trac_vpd, ERR_MRK"IpVpdFacade::findKeywordAddr: "
- "Record(%s) for offset (0x%04x) did not match "
+ "Record(%s) for offset (0x%04x->0x%04x) did not match "
"expected record(%s)!",
record,
i_offset,
+ offset,
i_recordName );
/*@
@@ -1866,7 +1941,8 @@ errlHndl_t IpVpdFacade::findKeywordAddr ( const char * i_keywordName,
KEYWORD_BYTE_SIZE,
keyword,
i_target,
- i_args.location );
+ i_args.location,
+ i_recordName );
offset += KEYWORD_BYTE_SIZE;
if( err )
@@ -1894,7 +1970,8 @@ errlHndl_t IpVpdFacade::findKeywordAddr ( const char * i_keywordName,
keywordLength,
&keywordSize,
i_target,
- i_args.location );
+ i_args.location,
+ i_recordName );
offset += keywordLength;
if( err )
@@ -2055,6 +2132,52 @@ errlHndl_t IpVpdFacade::writeKeyword ( const char * i_keywordName,
i_args.location,
vpdDest );
+ // Look for a record override in our image unless explicitly told not to
+ if( (i_args.location & VPD::OVERRIDE_MASK) != VPD::USEVPD )
+ {
+ uint8_t* l_overridePtr = nullptr;
+ VPD::RecordTargetPair_t l_recTarg
+ = VPD::makeRecordTargetPair(i_recordName,i_target);
+
+ // At this point we can assume that the pointer is set into our
+ // map if we need it
+ VPD::OverrideMap_t::iterator l_overItr = iv_overridePtr.find(l_recTarg);
+ if( l_overItr != iv_overridePtr.end() )
+ {
+ // If we are using an override, we can't write to it
+ if( l_overridePtr != nullptr )
+ {
+ uint32_t l_kw = 0;
+ memcpy( &l_kw, i_keywordName, KEYWORD_BYTE_SIZE );
+ /*@
+ * @errortype
+ * @reasoncode VPD::VPD_CANNOT_WRITE_OVERRIDDEN_VPD
+ * @moduleid VPD::VPD_IPVPD_WRITE_KEYWORD
+ * @userdata1[0:31] Target HUID
+ * @userdata1[32:63] <unused>
+ * @userdata2[0:31] VPD Record (ASCII)
+ * @userdata2[32:63] VPD Keyword (ASCII)
+ * @devdesc Attempting to write to a VPD record
+ * that has been overridden by firmware
+ * @custdesc Firmware error writing VPD
+ */
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_IPVPD_WRITE_KEYWORD,
+ VPD::VPD_WRITE_DEST_UNRESOLVED,
+ TWO_UINT32_TO_UINT64(
+ TARGETING::get_huid(i_target),
+ 0 ),
+ TWO_UINT32_TO_UINT64(
+ l_recTarg.first,
+ l_kw),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
+ err->collectTrace( "VPD", 256 );
+ break;
+ }
+ }
+ }
+
// Write the data
if ( vpdDest == VPD::PNOR )
{
@@ -2119,7 +2242,7 @@ errlHndl_t IpVpdFacade::writeKeyword ( const char * i_keywordName,
if( configError )
{
- TRACFCOMP( g_trac_vpd, ERR_MRK"IpVpdFacade::fetchData: "
+ TRACFCOMP( g_trac_vpd, ERR_MRK"IpVpdFacade::writeKeyword: "
"Error resolving VPD source (PNOR/SEEPROM)");
/*@
@@ -2270,3 +2393,230 @@ void IpVpdFacade::getRecordLists(
o_altRecSize = 0;
}
+/**
+ * @brief Callback function to check for a record override
+ */
+errlHndl_t IpVpdFacade::checkForRecordOverride( const char* i_record,
+ TARGETING::Target* i_target,
+ uint8_t*& o_ptr )
+{
+ // by default there is not an override
+ o_ptr = nullptr;
+ TRACDCOMP( g_trac_vpd, "No override for %s on %.8X", i_record, TARGETING::get_huid(i_target) );
+ VPD::RecordTargetPair_t l_recTarg =
+ VPD::makeRecordTargetPair(i_record,i_target);
+ iv_overridePtr[l_recTarg] = nullptr;
+ return nullptr;
+}
+
+/**
+ * @brief Retrieves the MEMD record from PNOR, finds a matching
+ * set of data, and sets up sets up the override pointer.
+ */
+errlHndl_t IpVpdFacade::getMEMDFromPNOR( input_args_t i_recKw,
+ TARGETING::Target* i_target,
+ uint32_t i_vmMask )
+{
+ TRACFCOMP(g_trac_vpd,ENTER_MRK"IpVpdFacade::getMEMDFromPNOR( %d, %.8X )",
+ i_recKw.record, get_huid(i_target));
+ errlHndl_t l_errl = nullptr;
+
+ /**
+ * @brief Define the set of information included at the beginning of the
+ * MEMD PNOR section
+ */
+ struct MemdHeader_t
+ {
+ uint32_t eyecatch; /* Eyecatch to determine validity. "OKOK" */
+ uint32_t header_version; /* What version of the header this is in */
+ uint32_t memd_version; /* What version of the MEMD this includes */
+ uint32_t expected_size_k; /* Size in thousands (not KB) of each MEMD instance */
+ uint16_t expected_num; /* Number of MEMD instances in this section */
+ uint8_t padding[14]; /* Padding for future changes */
+ }__attribute__((packed));
+
+ enum MEMD_valid_constants
+ {
+ MEMD_VALID_HEADER = 0x4f4b4f4b, // "OKOK"
+ MEMD_VALID_HEADER_VERSION = 0x30312e30, // "01.0";
+ };
+
+ do
+ {
+ // Get the Record/keyword names
+ const char* l_record = nullptr;
+ l_errl = translateRecord( i_recKw.record,
+ l_record );
+ if( l_errl )
+ {
+ break;
+ }
+
+ const char* l_keyword = nullptr;
+ l_errl = translateKeyword( i_recKw.keyword,
+ l_keyword );
+ if( l_errl )
+ {
+ break;
+ }
+
+ VPD::RecordTargetPair_t l_recTarg =
+ VPD::makeRecordTargetPair(l_record,i_target);
+
+ // MEMD Processing
+#ifdef __HOSTBOOT_RUNTIME
+ uint64_t l_memdSize = 0;
+ uint64_t l_memd_addr = hb_get_rt_rsvd_mem(
+ Util::HBRT_MEM_LABEL_VPD_MEMD,
+ 0,
+ l_memdSize );
+ if( (l_memd_addr == 0) || (l_memdSize == 0) )
+ {
+ TRACFCOMP(g_trac_vpd,"Optional MEMD section not found in reserved mem.");
+ break;
+ }
+
+ uint8_t* l_memd_vaddr
+ = reinterpret_cast<uint8_t *>(l_memd_addr);
+#else
+ PNOR::SectionInfo_t l_memd_info;
+ l_errl = PNOR::getSectionInfo(PNOR::MEMD,l_memd_info);
+ if( l_errl )
+ {
+ TRACFCOMP(g_trac_vpd,"Optional MEMD section not found in PNOR.");
+ delete l_errl;
+ l_errl = nullptr;
+ iv_overridePtr[l_recTarg] = nullptr;
+ break;
+ }
+
+ uint8_t* l_memd_vaddr
+ = reinterpret_cast<uint8_t *>(l_memd_info.vaddr);
+#endif
+
+ TRACFCOMP(g_trac_vpd,"MEMD is at %p", l_memd_vaddr);
+
+ // Get and process the header
+ MemdHeader_t l_header;
+ memcpy(&l_header, l_memd_vaddr, sizeof(l_header));
+ TRACFBIN(g_trac_vpd,"MEMD Header", &l_header, sizeof(l_header));
+
+ // See if we have any valid override records
+ bool l_valid_memd = ((l_header.eyecatch == MEMD_VALID_HEADER) &
+ (l_header.header_version == MEMD_VALID_HEADER_VERSION) &
+ ( (l_header.memd_version == l_recTarg.first)
+ // also handle old version to avoid coreqs
+ || (l_header.memd_version == MEMD_VALID_HEADER_VERSION) ));
+ if( !l_valid_memd )
+ {
+ TRACFCOMP(g_trac_vpd,"MEMD is not valid, ignoring it");
+ iv_overridePtr[l_recTarg] = nullptr;
+ break;
+ }
+
+ // Get the VM keyword size from the real VPD
+ size_t l_vm_size = 0;
+ input_args_t l_vm_args = i_recKw;
+ l_vm_args.location = VPD::USEVPD;
+ l_errl = read( i_target, nullptr, l_vm_size, l_vm_args );
+ if( l_errl )
+ {
+ TRACFCOMP(g_trac_vpd,"ERROR getting MEMD VM size");
+ break;
+ }
+
+ // VM should be exactly 4 bytes long
+ uint32_t l_vm_kw = 0;
+ assert( l_vm_size == sizeof(l_vm_kw) );
+
+ // Get the VM keyword from the real VPD
+ l_errl = read( i_target, &l_vm_kw, l_vm_size, l_vm_args );
+ if( l_errl )
+ {
+ TRACFCOMP(g_trac_vpd,"ERROR getting DVPD VM keyword");
+ break;
+ }
+ TRACFCOMP(g_trac_vpd,"VPD VM = %.8X", l_vm_kw);
+
+ // Offset past the header to start with
+ uint16_t l_memd_offset = sizeof(MemdHeader_t);
+ bool l_found_match = false;
+
+ // Loop through each possible instance until we find a match or run out
+ for( auto l_inst = 0; l_inst < l_header.expected_num; ++l_inst )
+ {
+ // Get the VM keyword from the copy in PNOR
+ TRACFCOMP(g_trac_vpd,"Attempting to read MEMD VM keyword from override");
+ input_args_t l_pnor_args = i_recKw;
+ l_pnor_args.location = VPD::USEOVERRIDE;
+
+ // Set the ptr in the map to allow the lookups inside
+ // IpVpdFacade to work
+ iv_overridePtr[l_recTarg] = l_memd_vaddr + l_memd_offset;
+
+ uint32_t l_memd_vm = 0;
+ l_errl = retrieveKeyword( l_keyword, l_record,
+ 0, 0,
+ i_target,
+ &l_memd_vm, l_vm_size,
+ l_pnor_args );
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_vpd,"getMEMDFromPNOR: ERROR getting %s:%s keyword in slot %d", l_record, l_keyword, l_inst);
+ // if we got this using the legacy header version then it is
+ // because we are looking at a bunch of the wrong record
+ // type, so just move on
+ if( l_header.memd_version == MEMD_VALID_HEADER_VERSION )
+ {
+ delete l_errl;
+ l_errl = nullptr;
+ }
+ break;
+ }
+
+ // Compare the appropriate portion of VM
+ if( (l_memd_vm != 0) &&
+ ((l_vm_kw & i_vmMask) == (l_memd_vm & i_vmMask)) )
+ {
+ TRACFCOMP(g_trac_vpd,"Matching data was found in PNOR at %.llX. VM: PNOR=%.8X, VPD=%.8X",
+ l_memd_offset,
+ l_memd_vm,
+ l_vm_kw);
+ l_found_match = true;
+ break;
+ }
+
+ // VM's don't match, we need to keep looking
+ TRACFCOMP(g_trac_vpd,"No match. VM: PNOR=%.8X, VPD=%.8X",
+ l_memd_vm,
+ l_vm_kw );
+ l_memd_offset += (l_header.expected_size_k * 1000);
+ }
+ if( l_errl ) { break; }
+
+ // If we did not find a match, set our map back to a nullptr
+ if( !l_found_match )
+ {
+ iv_overridePtr[l_recTarg] = nullptr;
+ }
+ } while(0);
+
+ TRACFCOMP(g_trac_vpd,EXIT_MRK"getMEMDFromPNOR()");
+ return l_errl;
+}
+
+#ifdef CONFIG_SECUREBOOT
+/**
+ * @brief Load/unload the appropriate secure section for
+ * an overriden PNOR section
+ */
+errlHndl_t IpVpdFacade::loadUnloadSecureSection( input_args_t i_args,
+ TARGETING::Target* i_target,
+ bool i_load,
+ bool& o_loaded )
+{
+ // nothing to do by default
+ o_loaded = false;
+ return nullptr;
+}
+#endif
diff --git a/src/usr/vpd/ipvpd.H b/src/usr/vpd/ipvpd.H
index 4797cb317..597c6e256 100644
--- a/src/usr/vpd/ipvpd.H
+++ b/src/usr/vpd/ipvpd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2018 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -28,10 +28,13 @@
#include <list>
+#include <map>
#include <pnor/pnorif.H>
#include <devicefw/driverif.H>
+#include <config.h>
#include "vpd.H"
+
/** @file ipvpd.H
* @brief Provides base support for i/p-Series style IBM VPD
*/
@@ -84,8 +87,7 @@ class IpVpdFacade
} input_args_t;
/**
- * @brief Structure of information needed to access requested
- * record/keyword combinations.
+ * @brief Mapping from keyword enum into 4 character string
*/
typedef struct
{
@@ -94,6 +96,7 @@ class IpVpdFacade
} recordInfo;
/**
+ * @brief Mapping from keyword enum into 2 character string
*/
typedef struct
{
@@ -102,6 +105,16 @@ class IpVpdFacade
} keywordInfo;
/**
+ * @brief Mapping from record enum into PNOR section
+ * where override might be
+ */
+ typedef struct
+ {
+ VPD::vpdRecord record;
+ PNOR::SectionId section;
+ } recordOverrideInfo_t;
+
+ /**
* @brief Structure defining where to read/write VPD data
*/
typedef struct
@@ -138,7 +151,7 @@ class IpVpdFacade
*
* @param[in] i_vpdKeywords - Pointer to array of VPD Keywords to use
*
- * @param[in] i_keyCount - size of i_vpdKeywords array
+ * @param[in] i_keySize - size of i_vpdKeywords array
*
* @param[in] i_pnorSection - PNOR Section containing VPD for current
* chip
@@ -293,6 +306,23 @@ class IpVpdFacade
*/
void setConfigFlagsHW ( );
+#ifdef CONFIG_SECUREBOOT
+ /**
+ * @brief Load/unload the appropriate secure section for
+ * an overriden PNOR section
+ * @param[in] i_args Record/keyword
+ * @param[in] i_target Target pointer
+ * @param[in] i_load true=load, false=unload
+ * @param[out] o_loaded true=section loaded, false=section not loaded
+ * @return Error log
+ */
+ virtual errlHndl_t loadUnloadSecureSection( input_args_t i_args,
+ TARGETING::Target* i_target,
+ bool i_load,
+ bool& o_loaded );
+#endif
+
+
protected:
/**
@@ -578,6 +608,8 @@ class IpVpdFacade
*
* @param[in] i_location - VPD location to fetch data from (PNOR/SEEPROM)
*
+ * @param[in] i_record - String representation of the record.
+ *
* @return errHndl_t - NULL if successful, otherwise a pointer to the
* error log.
*/
@@ -585,7 +617,8 @@ class IpVpdFacade
size_t i_numBytes,
void * o_data,
TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location );
+ VPD::vpdCmdTarget i_location,
+ const char* i_record );
/**
* @brief This function actually reads the data from PNOR
@@ -625,8 +658,7 @@ class IpVpdFacade
void * o_data,
TARGETING::Target * i_target );
-
- /**
+ /**
* @brief This function compares 2 ipvpd record values. Used for binary
* search to find a match.
*
@@ -688,6 +720,51 @@ class IpVpdFacade
const recordInfo* & o_altVpdRecords,
uint64_t & o_altRecSize);
+ /**
+ * @brief Returns the cached pnor address
+ *
+ */
+ inline static uint64_t getPnorAddr(const IpVpdFacade& x)
+ {
+ return x.iv_cachePnorAddr;
+ };
+
+ /**
+ * @brief Set the cached pnor address to the given value
+ *
+ */
+ inline void setPnorAddr(uint64_t i_pnorAddr)
+ {
+ this->iv_cachePnorAddr = i_pnorAddr;
+ };
+
+
+ /**
+ * @brief Retrieves the MEMD record from PNOR, finds a matching
+ * set of data, and sets up sets up the override pointer.
+ * @param[in] i_recKw Record/Keyword values
+ * @param[in] i_target Relevant Target
+ * @param[in] i_vmMask Specific bits to compare with EEPROM
+ * @return Error log
+ */
+ errlHndl_t getMEMDFromPNOR( input_args_t i_recKw,
+ TARGETING::Target* i_target,
+ uint32_t i_vmMask );
+
+ /**
+ * @brief Callback function to check for a record override and
+ * set iv_overridePtr appropriately
+ * @param[in] i_record Record name
+ * @param[in] i_target Target pointer
+ * @param[out] o_ptr Pointer to location of record in PNOR,
+ * ==nullptr if there is no override
+ * @return Error log
+ */
+ virtual errlHndl_t checkForRecordOverride( const char* i_record,
+ TARGETING::Target* i_target,
+ uint8_t*& o_ptr );
+
+
protected: // Variables
/**
@@ -702,8 +779,7 @@ class IpVpdFacade
*/
uint64_t iv_vpdMaxSections;
-
- public: // Variables
+ public: //Used by static function
/**
* @brief Pointer to array of VPD Record information
*
@@ -711,30 +787,12 @@ class IpVpdFacade
const recordInfo* iv_vpdRecords;
/**
- * @brief Returns the cached pnor address
- *
- */
- inline static uint64_t getPnorAddr(const IpVpdFacade& x)
- {
- return x.iv_cachePnorAddr;
- }
-
- /**
- * @brief Set the cached pnor address to the given value
- *
- */
- inline void setPnorAddr(uint64_t i_pnorAddr)
- {
- this->iv_cachePnorAddr = i_pnorAddr;
- }
-
- /**
* @brief Number of VPD Records for current chip
*
*/
- uint64_t iv_recSize;
+ const uint64_t iv_recSize;
- protected: // Variables
+ protected:
/**
* @brief Pointer to array of VPD Keyword information
*
@@ -745,7 +803,7 @@ class IpVpdFacade
* @brief Number of VPD Keywords for current chip
*
*/
- uint64_t iv_keySize;
+ const uint64_t iv_keySize;
/**
* @brief PNOR section enum for vpd type
@@ -778,10 +836,11 @@ class IpVpdFacade
configInfo iv_configInfo;
/**
- * @brief Boolean variable to denote if the pnor section was
- * accessed for the MEMD section
+ * @brief Used to denote if a record is being
+ * fetched from a copy in our code image versus the
+ * real VPD EEPROM (or cache)
*/
- bool iv_memdAccessed;
+ VPD::OverrideMap_t iv_overridePtr;
};
diff --git a/src/usr/vpd/memd_vpd.C b/src/usr/vpd/memd_vpd.C
deleted file mode 100644
index 08f122d03..000000000
--- a/src/usr/vpd/memd_vpd.C
+++ /dev/null
@@ -1,228 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/vpd/memd_vpd.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2013,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 */
-// ----------------------------------------------
-// Includes
-// ----------------------------------------------
-#include <string.h>
-#include <endian.h>
-#include <trace/interface.H>
-#include <errl/errlentry.H>
-#include <errl/errlmanager.H>
-#include <targeting/common/targetservice.H>
-#include <targeting/common/util.H>
-#include <targeting/common/utilFilter.H>
-#include <devicefw/driverif.H>
-#include <vfs/vfs.H>
-#include <vpd/vpdreasoncodes.H>
-#include <vpd/memd_vpdenums.H>
-#include <vpd/vpd_if.H>
-#include <i2c/eepromif.H>
-#include <config.h>
-#include "memd_vpd.H"
-#include "cvpd.H"
-#include "vpd.H"
-#include "pvpd.H"
-#include <initservice/initserviceif.H>
-
-// ----------------------------------------------
-// Trace definitions
-// ----------------------------------------------
-extern trace_desc_t* g_trac_vpd;
-
-
-// ------------------------
-// Macros for unit testing
-//#define TRACUCOMP(args...) TRACFCOMP(args)
-#define TRACUCOMP(args...)
-//#define TRACSSCOMP(args...) TRACFCOMP(args)
-#define TRACSSCOMP(args...)
-
-namespace MEMD_VPD
-{
- // ----------------------------------------------
- // Globals
- // ----------------------------------------------
- mutex_t g_mutex = MUTEX_INITIALIZER;
-
-
- /**
- * @brief This function will perform the steps required to do a read from
- * the Hostboot MEMD_VPD data.
- *
- * @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
- * driververif.H
- *
- * @param[in] i_target - Processor Target device
- *
- * @param [in/out] io_buffer - Pointer to the data that was read from
- * the target device. This parameter, when set to NULL, will return
- * the keyword size value in io_buflen.
- *
- * @param [in/out] io_buflen - Length of the buffer to be read or written
- * to/from the target. This value should indicate the size of the
- * io_buffer parameter that has been allocated. Being returned it
- * will indicate the number of valid bytes in the buffer being
- * returned. This parameter will contain the size of a keyword when
- * the io_buffer parameter is passed in NULL.
- *
- * @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
- * usrif.H
- *
- * @param [in] i_args - This is an argument list for the device driver
- * framework.
- *
- * @return errlHndl_t - NULL if successful, otherwise a pointer to the
- * error log.
- */
- errlHndl_t MEMD_VPDRead ( DeviceFW::OperationType i_opType,
- TARGETING::Target * i_target,
- void * io_buffer,
- size_t & io_buflen,
- int64_t i_accessType,
- va_list i_args )
- {
- errlHndl_t err = NULL;
- IpVpdFacade::input_args_t args;
- args.record = ((MEMD_VPDRecord)va_arg( i_args, uint64_t ));
- args.keyword = ((MEMD_VPDKeyword)va_arg( i_args, uint64_t ));
- args.location = ((VPD::vpdCmdTarget)va_arg( i_args, uint64_t ));
-
- TRACSSCOMP( g_trac_vpd,
- ENTER_MRK"MEMD_VPDRead()" );
-
- err = Singleton<MEMD_VpdFacade>::instance().read(i_target,
- io_buffer,
- io_buflen,
- args);
-
- return err;
- }
-
-
- /**
- * @brief This function will perform the steps required to do a write to
- * the Hostboot MEMD_VPD data.
- *
- * @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
- * driververif.H
- *
- * @param[in] i_target - Processor Target device
- *
- * @param [in/out] io_buffer - Pointer to the data that was read from
- * the target device. It will also be used to contain data to
- * be written to the device.
- *
- * @param [in/out] io_buflen - Length of the buffer to be read or written
- * to/from the target. This value should indicate the size of the
- * io_buffer parameter that has been allocated. Being returned it
- * will indicate the number of valid bytes in the buffer being
- * returned.
- *
- * @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
- * usrif.H
- *
- * @param [in] i_args - This is an argument list for the device driver
- * framework.
- *
- * @return errlHndl_t - NULL if successful, otherwise a pointer to the
- * error log.
- */
- errlHndl_t MEMD_VPDWrite ( DeviceFW::OperationType i_opType,
- TARGETING::Target * i_target,
- void * io_buffer,
- size_t & io_buflen,
- int64_t i_accessType,
- va_list i_args )
- {
- errlHndl_t err = NULL;
- IpVpdFacade::input_args_t args;
- args.record = ((MEMD_VPDRecord)va_arg( i_args, uint64_t ));
- args.keyword = ((MEMD_VPDKeyword)va_arg( i_args, uint64_t ));
- args.location = ((VPD::vpdCmdTarget)va_arg( i_args, uint64_t ));
-
- TRACSSCOMP( g_trac_vpd,
- ENTER_MRK"MEMD_VPDWrite()" );
-
-
- err = Singleton<MEMD_VpdFacade>::instance().write(i_target,
- io_buffer,
- io_buflen,
- args);
-
- return err;
- }
-
- // Register with the routing code
- DEVICE_REGISTER_ROUTE( DeviceFW::READ,
- DeviceFW::MEMD_VPD,
- TARGETING::TYPE_MCS,
- MEMD_VPDRead );
- DEVICE_REGISTER_ROUTE( DeviceFW::WRITE,
- DeviceFW::MEMD_VPD,
- TARGETING::TYPE_MCS,
- MEMD_VPDWrite );
-
-}; // end namespace MEMD_VPD
-
-
-//MEMD_VpdFacade Class Functions
-/**
- * @brief Constructor
- * Planar VPD is included in the Centaur PNOR section.
- * Including with Centaur vpd minimizes the number of PNOR sections.
- */
-MEMD_VpdFacade::MEMD_VpdFacade() :
-IpVpdFacade(MEMD_VPD::MEMD_VPDRecords,
- (sizeof(MEMD_VPD::MEMD_VPDRecords)/sizeof(
- MEMD_VPD::MEMD_VPDRecords[0])),
- MEMD_VPD::MEMD_VPDKeywords,
- (sizeof(MEMD_VPD::MEMD_VPDKeywords)/sizeof(
- MEMD_VPD::MEMD_VPDKeywords[0])),
- PNOR::MEMD, // note use of MEMD
- MEMD_VPD::g_mutex,
- VPD::VPD_INVALID) // Direct access memory
-{
- TRACUCOMP(g_trac_vpd, "MEMD_VpdFacade::MEMD_VpdFacade> " );
-
- iv_configInfo.vpdReadPNOR = true;
- iv_configInfo.vpdReadHW = false;
- iv_configInfo.vpdWritePNOR = false;
- iv_configInfo.vpdWriteHW = false;
- iv_vpdSectionSize = MEMD_VPD::SECTION_SIZE;
- iv_vpdMaxSections = MEMD_VPD::MAX_SECTIONS;
-}
-
-/**
- * @brief returns true if the record is present in this facade.
- * this will always return true in this function
- */
-bool MEMD_VpdFacade::recordPresent( const char * i_record,
- uint16_t & offset,
- TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location )
-{
- offset = 0;
- return true;
-}
diff --git a/src/usr/vpd/memd_vpd.H b/src/usr/vpd/memd_vpd.H
deleted file mode 100644
index d94532b4a..000000000
--- a/src/usr/vpd/memd_vpd.H
+++ /dev/null
@@ -1,227 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/vpd/memd_vpd.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2013,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 */
-#ifndef __MEMD_VPD_H
-#define __MEMD_VPD_H
-
-
-/**
- * @file MEMD_VPD.H
- *
- * @brief Provides the interfaces for the MEMD_VPD device driver
- *
- */
-
-// ----------------------------------------------
-// Includes
-// ----------------------------------------------
-#include <errl/errlentry.H>
-#include <vpd/memd_vpdenums.H>
-
-#include "ipvpd.H"
-#include <config.h>
-
-namespace MEMD_VPD
-{
-
- enum
- {
- MAX_SECTIONS = 1,
- SECTION_SIZE = 0x6000,
- };
-
-
- /**
- * @brief Conversion of MEMD_VPD Records to corresponding character
- * representation.
- */
- const IpVpdFacade::recordInfo MEMD_VPDRecords[] =
- {
- // -------------------------------------------------------------------
- // NOTE: This list must remain an ordered list! There is a
- // testcase that checks this. When adding new entries to the
- // list, be sure that the keyword in each entry (value 0)
- // are in ascending order.
- // -------------------------------------------------------------------
- { MEMD, "MEMD" },
-
- // -------------------------------------------------------------------
- // DO NOT USE!! This is for test purposes ONLY!
- { MEMD_VPD_TEST_RECORD, "TEST" },
- // -------------------------------------------------------------------
- };
-
- /**
- * @brief Conversion of MEMD_VPD Keywords to corresponding character
- * representation.
- */
- const IpVpdFacade::keywordInfo MEMD_VPDKeywords[] =
- {
- // -------------------------------------------------------------------
- // NOTE: This list must remain an ordered list! There is a
- // testcase that checks this. When adding new entries to
- // the list, be sure that the keyword in each entry (value 0)
- // are in ascending order.
- // -------------------------------------------------------------------
- { B3, "B3" },
- { B4, "B4" },
- { B7, "B7" },
- { CC, "CC" },
- { CE, "CE" },
- { CT, "CT" },
- { DR, "DR" },
- { FC, "FC" },
- { FN, "FN" },
- { HE, "HE" },
- { HW, "HW" },
- { I2, "I2" },
- { IN, "IN" },
- { J0, "J0" },
- { J1, "J1" },
- { J2, "J2" },
- { J3, "J3" },
- { J4, "J4" },
- { J5, "J5" },
- { J6, "J6" },
- { J7, "J7" },
- { J8, "J8" },
- { J9, "J9" },
- { JA, "JA" },
- { JB, "JB" },
- { JC, "JC" },
- { JD, "JD" },
- { JE, "JE" },
- { JF, "JF" },
- { JG, "JG" },
- { JH, "JH" },
- { JI, "JI" },
- { JJ, "JJ" },
- { JK, "JK" },
- { JL, "JL" },
- { JM, "JM" },
- { JN, "JN" },
- { JO, "JO" },
- { JP, "JP" },
- { JQ, "JQ" },
- { JR, "JR" },
- { JS, "JS" },
- { JT, "JT" },
- { JU, "JU" },
- { JV, "JV" },
- { JW, "JW" },
- { JX, "JX" },
- { JY, "JY" },
- { JZ, "JZ" },
- { LX, "LX" },
- { MR, "MR" },
- { MT, "MT" },
- { PF, "PF" },
- { PN, "PN" },
- { PR, "PR" },
- { RB, "RB" },
- { RG, "RG" },
- { RT, "RT" },
- { SE, "SE" },
- { SN, "SN" },
- { SO, "SO" },
- { TM, "TM" },
- { VM, "VM" },
- { VZ, "VZ" },
- { X0, "X0" },
- { X1, "X1" },
- { X2, "X2" },
- { X3, "X3" },
- { X4, "X4" },
- { X5, "X5" },
- { X6, "X6" },
- { X7, "X7" },
- { X8, "X8" },
- { X9, "X9" },
- { XA, "XA" },
- { XB, "XB" },
- { XC, "XC" },
- { XD, "XD" },
- { XE, "XE" },
- { XF, "XF" },
- { XG, "XG" },
- { XH, "XH" },
- { XI, "XI" },
- { XJ, "XJ" },
- { XK, "XK" },
- { XL, "XL" },
- { XM, "XM" },
- { XN, "XN" },
- { XO, "XO" },
- { XP, "XP" },
- { XQ, "XQ" },
- { XR, "XR" },
- { XS, "XS" },
- { XT, "XT" },
- { XU, "XU" },
- { XV, "XV" },
- { XW, "XW" },
- { XX, "XX" },
- { XY, "XY" },
- { XZ, "XZ" },
- { Q0, "Q0" },
- { Q1, "Q1" },
- { Q2, "Q2" },
- { Q3, "Q3" },
- { Q4, "Q4" },
- { Q5, "Q5" },
- { Q6, "Q6" },
- { Q7, "Q7" },
- { Q8, "Q8" },
- { CK, "CK" },
-
- // -------------------------------------------------------------------
- // DO NOT USE!! This is for test purposes ONLY!
- { MEMD_VPD_TEST_KEYWORD, "ZZ" },
- // -------------------------------------------------------------------
-
- //Common ipvpd
- { FULL_RECORD, "FL"},
- };
-
-}; // end MEMD_VPD namespace
-
-class MEMD_VpdFacade: public IpVpdFacade
-{
- public:
-
- /**
- * @brief Constructor
- */
- MEMD_VpdFacade( );
-
-
- protected:
- virtual bool recordPresent( const char * i_record,
- uint16_t & offset,
- TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location );
-
-
-};
-#endif // __MEMD_VPD_H
diff --git a/src/usr/vpd/test/dvpdtest.H b/src/usr/vpd/test/dvpdtest.H
index e7c61cdd2..b0d62a062 100755
--- a/src/usr/vpd/test/dvpdtest.H
+++ b/src/usr/vpd/test/dvpdtest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2016 */
+/* Contributors Listed Below - COPYRIGHT 2013,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,6 +37,7 @@
#include <errl/errlentry.H>
#include <devicefw/driverif.H>
#include <targeting/common/predicates/predicatectm.H>
+#include <config.h>
#include <vpd/dvpdenums.H>
#include <vpd/vpdreasoncodes.H>
@@ -204,6 +205,7 @@ class DVPDTest: public CxxTest::TestSuite
/**
* @brief This function will test DVPD writes.
+ * Note: this forces the path to not use the FW override
*/
void testDvpdWrite ( void )
{
@@ -234,7 +236,9 @@ class DVPDTest: public CxxTest::TestSuite
err = deviceRead( theTarget,
testData,
theSize,
- DEVICE_DVPD_ADDRESS(DVPD::MEMD,TSTKEYWD) );
+ DEVICE_DVPD_FORCE_ADDRESS(DVPD::MEMD,
+ TSTKEYWD,
+ VPD::USEVPD) );
if( err )
{
fails++;
@@ -254,7 +258,9 @@ class DVPDTest: public CxxTest::TestSuite
err = deviceRead( theTarget,
origData,
theSize,
- DEVICE_DVPD_ADDRESS(DVPD::MEMD,TSTKEYWD) );
+ DEVICE_DVPD_FORCE_ADDRESS(DVPD::MEMD,
+ TSTKEYWD,
+ VPD::USEVPD) );
if( err )
{
fails++;
@@ -282,7 +288,9 @@ class DVPDTest: public CxxTest::TestSuite
err = deviceWrite( theTarget,
testData,
theSize,
- DEVICE_DVPD_ADDRESS(DVPD::MEMD,TSTKEYWD) );
+ DEVICE_DVPD_FORCE_ADDRESS(DVPD::MEMD,
+ TSTKEYWD,
+ VPD::USEVPD) );
if( err )
{
fails++;
@@ -302,7 +310,9 @@ class DVPDTest: public CxxTest::TestSuite
err = deviceRead( theTarget,
verifyData,
theSize,
- DEVICE_DVPD_ADDRESS(DVPD::MEMD,TSTKEYWD) );
+ DEVICE_DVPD_FORCE_ADDRESS(DVPD::MEMD,
+ TSTKEYWD,
+ VPD::USEVPD) );
if( err )
{
fails++;
@@ -334,7 +344,9 @@ class DVPDTest: public CxxTest::TestSuite
err = deviceWrite( theTarget,
origData,
theSize,
- DEVICE_DVPD_ADDRESS(DVPD::MEMD,TSTKEYWD) );
+ DEVICE_DVPD_FORCE_ADDRESS(DVPD::MEMD,
+ TSTKEYWD,
+ VPD::USEVPD) );
if( err )
{
fails++;
@@ -716,6 +728,36 @@ class DVPDTest: public CxxTest::TestSuite
"testDvpdCheckStructOrder - %d fails",
fails );
}
+
+ DVPDTest() : CxxTest::TestSuite()
+ {
+ TRACFCOMP( g_trac_vpd, "Starting DVPDTest" );
+#ifdef CONFIG_SECUREBOOT
+#ifndef __HOSTBOOT_RUNTIME
+ errlHndl_t l_err = loadSecureSection(PNOR::MEMD);
+ if(l_err)
+ {
+ TS_FAIL( "DVPDTest : loadSecureSection" );
+ delete l_err;
+ }
+#endif
+#endif
+ }
+
+ ~DVPDTest()
+ {
+#ifdef CONFIG_SECUREBOOT
+#ifndef __HOSTBOOT_RUNTIME
+ errlHndl_t l_err = unloadSecureSection(PNOR::MEMD);
+ TRACFCOMP( g_trac_vpd, "Ending DVPDTest" );
+ if(l_err)
+ {
+ TS_FAIL( "DVPDTest : unloadSecureSection" );
+ delete l_err;
+ }
+#endif
+#endif
+ }
};
#endif
diff --git a/src/usr/vpd/vpd.C b/src/usr/vpd/vpd.C
index 585c168fa..a9bc590b5 100755
--- a/src/usr/vpd/vpd.C
+++ b/src/usr/vpd/vpd.C
@@ -1106,4 +1106,30 @@ errlHndl_t validateSharedPnorCache()
return errl;
}
+/**
+ * @brief Get a list of all overridden sections
+ */
+void getListOfOverrideSections( OverrideRsvMemMap_t& o_overrides )
+{
+ // Note - any new sections need to be added here
+
+ PNOR::SectionInfo_t l_memd_info;
+ errlHndl_t l_elog = PNOR::getSectionInfo(PNOR::MEMD,l_memd_info);
+ if( l_elog )
+ {
+ TRACFCOMP( g_trac_vpd,
+ "getListOfOverrideSections> failed getSectionInfo call" );
+ delete l_elog;
+ return;
+ }
+
+ // Add MEMD section
+ OverrideSpecifier_t l_memd = {
+ PNOR::MEMD,
+ l_memd_info.size
+ };
+
+ o_overrides[0x4D454D44/*MEMD*/] = l_memd;
+}
+
}; //end VPD namespace
diff --git a/src/usr/vpd/vpd.H b/src/usr/vpd/vpd.H
index 2753a476d..7446dc491 100644
--- a/src/usr/vpd/vpd.H
+++ b/src/usr/vpd/vpd.H
@@ -27,6 +27,7 @@
#include <pnor/pnorif.H>
#include <vpd/vpd_if.H>
+#include <map>
namespace VPD
{
@@ -83,6 +84,35 @@ union VpdWriteMsg_t
} PACKED;
};
+/**
+ * first = 4-character record name as a 4-byte uint
+ * second = Target pointer
+ */
+typedef std::pair<uint32_t, TARGETING::Target*> RecordTargetPair_t;
+
+/**
+ * @brief Helper function to convert record string to uint
+ * @param[in] 4-character record string
+ * @param[in] Target pointer
+ * @return Fully formed RecordTargetPair_t
+ */
+inline RecordTargetPair_t makeRecordTargetPair( const char* i_rec,
+ TARGETING::Target* i_targ )
+{
+ uint32_t l_rec = 0;
+ memcpy( &l_rec, i_rec, sizeof(l_rec) );
+ return std::make_pair(l_rec,i_targ);
+};
+
+
+/**
+ * Indexed by RecordTargetPair_t
+ * Returns a pointer to this record within the override section
+ * if it is being used, or nullptr if not.
+ */
+typedef std::map<RecordTargetPair_t,uint8_t*> OverrideMap_t;
+
+
/**
* @brief This function is used to query the attribute code to get the VPD
@@ -258,6 +288,10 @@ errlHndl_t getPnAndSnRecordAndKeywords( TARGETING::Target * i_target,
vpdKeyword & io_partKeyword,
vpdKeyword & io_serialKeyword);
+/**
+ * @brief Read data from the BMC to update the system serial number
+ * @param[in] i_target - node target to update vpd of
+ */
void updateSerialNumberFromBMC( TARGETING::Target * i_nodetarget );
}; //end VPD namespace
diff --git a/src/usr/vpd/vpd.mk b/src/usr/vpd/vpd.mk
index d07a2bbea..b8337b989 100644
--- a/src/usr/vpd/vpd.mk
+++ b/src/usr/vpd/vpd.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2017
+# Contributors Listed Below - COPYRIGHT 2013,2018
# [+] International Business Machines Corp.
#
#
@@ -29,6 +29,5 @@ OBJS += mvpd.o
OBJS += cvpd.o
OBJS += pvpd.o
OBJS += dvpd.o
-OBJS += memd_vpd.o
OBJS += spd.o
OBJS += errlud_vpd.o
diff --git a/src/usr/vpd/vpd_common.C b/src/usr/vpd/vpd_common.C
index d11dc8743..3c657acb5 100644
--- a/src/usr/vpd/vpd_common.C
+++ b/src/usr/vpd/vpd_common.C
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/usr/vpd/vpd.C $ */
+/* $Source: src/usr/vpd/vpd_common.C $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2015 */
+/* Contributors Listed Below - COPYRIGHT 2013,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -77,7 +77,7 @@ bool resolveVpdSource( TARGETING::Target * i_target,
bool badConfig = false;
o_vpdSource = VPD::INVALID_LOCATION;
- if( i_vpdCmdTarget == VPD::PNOR )
+ if( (i_vpdCmdTarget & VPD::LOCATION_MASK) == VPD::PNOR )
{
if( i_rwPnorEnabled )
{
@@ -89,7 +89,7 @@ bool resolveVpdSource( TARGETING::Target * i_target,
TRACFCOMP(g_trac_vpd,"resolveVpdSource: VpdCmdTarget=PNOR but READ/WRITE PNOR CONFIG is disabled");
}
}
- else if( i_vpdCmdTarget == VPD::SEEPROM )
+ else if( (i_vpdCmdTarget & VPD::LOCATION_MASK) == VPD::SEEPROM )
{
if( i_rwHwEnabled )
{
OpenPOWER on IntegriCloud