summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
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