summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDoug Gilbert <dgilbert@us.ibm.com>2013-10-15 13:55:28 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-11-13 14:49:38 -0600
commitdd2a474b7fc3a8937f45d1278e887b370ad81192 (patch)
tree00595698a572529ddcd00fc3c975b588b4ea67dc /src
parent1aa8f7551005dd48078b91be173e8bcc7e339061 (diff)
downloadtalos-hostboot-dd2a474b7fc3a8937f45d1278e887b370ad81192.tar.gz
talos-hostboot-dd2a474b7fc3a8937f45d1278e887b370ad81192.zip
Add VPD support to HBRT
RTC: 79419 Change-Id: I6d00e52026084a68925691b96d7a491faaffb4ef Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/7004 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/runtime/interface.h5
-rw-r--r--src/include/usr/devtree/devtree_reasoncodes.H2
-rw-r--r--src/include/usr/vmmconst.h18
-rw-r--r--src/include/usr/vpd/vpd_if.H35
-rw-r--r--src/include/usr/vpd/vpdreasoncodes.H13
-rw-r--r--src/makefile5
-rw-r--r--src/usr/devtree/bld_devtree.C61
-rw-r--r--src/usr/testcore/rtloader/loader.H44
-rw-r--r--src/usr/vpd/makefile8
-rw-r--r--src/usr/vpd/rtvpd_load.C148
-rw-r--r--src/usr/vpd/runtime/makefile39
-rw-r--r--src/usr/vpd/runtime/rt_vpd.C327
-rw-r--r--src/usr/vpd/runtime/test/makefile29
-rwxr-xr-xsrc/usr/vpd/spd.C3
-rwxr-xr-xsrc/usr/vpd/test/cvpdtest.H2
-rwxr-xr-xsrc/usr/vpd/test/dimmPrestest.H6
-rwxr-xr-xsrc/usr/vpd/test/mvpdtest.H14
-rwxr-xr-xsrc/usr/vpd/test/spdtest.H7
-rw-r--r--src/usr/vpd/vpd.C3
-rw-r--r--src/usr/vpd/vpd.mk24
20 files changed, 774 insertions, 19 deletions
diff --git a/src/include/runtime/interface.h b/src/include/runtime/interface.h
index b5d55acaa..0b7382b61 100644
--- a/src/include/runtime/interface.h
+++ b/src/include/runtime/interface.h
@@ -103,6 +103,11 @@ typedef struct hostInterfaces
*/
int (*lid_unload)(void*);
+ /** Get address of VPD image
+ * @return physical address of VPD image
+ */
+ uint64_t (*get_vpd_image_addr)();
+
} hostInterfaces_t;
typedef struct runtimeInterfaces
diff --git a/src/include/usr/devtree/devtree_reasoncodes.H b/src/include/usr/devtree/devtree_reasoncodes.H
index c996ebca3..bbd44674d 100644
--- a/src/include/usr/devtree/devtree_reasoncodes.H
+++ b/src/include/usr/devtree/devtree_reasoncodes.H
@@ -31,12 +31,14 @@ namespace DEVTREE
{
MOD_DEVTREE_INVALID = 0x00, /**< Zero is invalid module id */
MOD_DEVTREE_BLD_MEM = 0x01,
+ MOD_BLD_VPD_IMAGE = 0x02,
};
enum DevtreeReasonCode
{
RC_ATTR_MEMSIZE_GET_FAIL = DEVTREE_COMP_ID | 0x01,
RC_ATTR_MEMBASE_GET_FAIL = DEVTREE_COMP_ID | 0x02,
+ RC_INSUFFICIENT_SPACE_FOR_RT_VPD = DEVTREE_COMP_ID | 0x03,
};
};
diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h
index d1d0d38a8..c93e62148 100644
--- a/src/include/usr/vmmconst.h
+++ b/src/include/usr/vmmconst.h
@@ -140,6 +140,24 @@ enum BlockPriority
(VMM_OCC_COMMON_SIZE+VMM_HOMER_REGION_SIZE)
+/** Reserved runtime VPD sizes in bytes */
+// must be page aligned
+#define VMM_MODULE_VPD_SIZE 0x80000
+#define VMM_CENTAUR_VPD_SIZE 0x40000
+#define VMM_DIMM_JEDEC_VPD_SIZE 0x40000
+
+/** Total VPD image size */
+#define VMM_RT_VPD_SIZE (VMM_MODULE_VPD_SIZE + \
+ VMM_CENTAUR_VPD_SIZE + \
+ VMM_DIMM_JEDEC_VPD_SIZE)
+
+/** Memory offset for runtime VPD image */
+// Given value is number of bytes BELOW the top of memory to store
+// the runtime image(s) Currently below the OCC HOMER IMAGE
+#define VMM_RT_VPD_OFFSET (VMM_RT_VPD_SIZE + \
+ VMM_ALL_HOMER_OCC_MEMORY_SIZE)
+
+
/**
* Test Constants
*/
diff --git a/src/include/usr/vpd/vpd_if.H b/src/include/usr/vpd/vpd_if.H
new file mode 100644
index 000000000..184d84d40
--- /dev/null
+++ b/src/include/usr/vpd/vpd_if.H
@@ -0,0 +1,35 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/vpd/vpd_if.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#if !defined(__VPD_IF_H)
+#define __VPD_IF_H
+
+namespace VPD
+{
+ /**
+ * Load the runtime VPD image into memory
+ * @param[out] The physical address of the VPD image
+ * @return error handle if there was an error
+ */
+ errlHndl_t vpd_load_rt_image(uint64_t & o_vpd_addr);
+};
+#endif
diff --git a/src/include/usr/vpd/vpdreasoncodes.H b/src/include/usr/vpd/vpdreasoncodes.H
index 20be0e0f6..ac1b13c56 100644
--- a/src/include/usr/vpd/vpdreasoncodes.H
+++ b/src/include/usr/vpd/vpdreasoncodes.H
@@ -70,6 +70,12 @@ enum vpdModuleId
// Centaur FRU VPD
+ // Runtime VPD
+ VPD_RT_GET_ADDR = 0x80,
+ VPD_RT_WRITE_PNOR = 0x81,
+ VPD_BLD_RT_IMAGE = 0x82,
+ VPD_SEND_MBOX_WRITE_MESSAGE = 0x83,
+
};
/**
@@ -102,6 +108,13 @@ enum vpdReasonCode
VPD_INVALID_WRITE_METHOD = VPD_COMP_ID | 0x13,
VPD_NULL_ENTRY = VPD_COMP_ID | 0x14,
VPD_UNSUPPORTED_WRITE = VPD_COMP_ID | 0x15,
+ VPD_RT_INVALID_TYPE = VPD_COMP_ID | 0x16,
+ VPD_RT_CALL_TO_HYPR_FAILED = VPD_COMP_ID | 0x17,
+ VPD_RT_WRITE_NOT_SUPPORTED = VPD_COMP_ID | 0x18,
+ VPD_RT_NOT_INITIALIZED = VPD_COMP_ID | 0x19,
+ VPD_RT_NULL_VPD_PTR = VPD_COMP_ID | 0x1a,
+ VPD_INSUFFICIENT_SPACE_FOR_IMAGE = VPD_COMP_ID | 0x1b,
+ VPD_MBOX_NOT_SUPPORTED_RT = VPD_COMP_ID | 0x1c,
};
}; // end MVPD
diff --git a/src/makefile b/src/makefile
index fe32d003b..79abda197 100644
--- a/src/makefile
+++ b/src/makefile
@@ -73,12 +73,13 @@ RUNTIME_OBJECTS = rt_start.o rt_main.o rt_console.o rt_stdlib.o rt_sync.o \
rt_assert.o rt_vfs.o rt_task.o
RUNTIME_MODULES = trace_rt errl_rt targeting_rt util_rt devicefw_rt \
- xscom_rt scom_rt
+ xscom_rt scom_rt vpd_rt
RUNTIME_DATA_MODULES =
RUNTIME_TESTCASE_MODULES = cxxtest_rt testsyslib_rt testtargeting_rt \
testxscom_rt testerrl_rt testdevicefw_rt \
- testscom_rt testutil_rt
+ testscom_rt testutil_rt testvpd_rt
+
RELOCATABLE_IMAGE_LDFLAGS = -pie --export-dynamic
diff --git a/src/usr/devtree/bld_devtree.C b/src/usr/devtree/bld_devtree.C
index 3dc7f96d6..a79057680 100644
--- a/src/usr/devtree/bld_devtree.C
+++ b/src/usr/devtree/bld_devtree.C
@@ -44,6 +44,7 @@ $ */
#include "devtree.H"
#include <sys/mmio.h> //THIRTYTWO_GB
#include <intr/interrupt.H>
+#include <vpd/vpd_if.H>
trace_desc_t *g_trac_devtree = NULL;
@@ -428,7 +429,11 @@ uint32_t bld_intr_node(devTree * i_dt, dtOffset_t & i_parentNode,
return i_dt->getPhandle(intNode);
}
-void add_reserved_mem(devTree * i_dt, uint64_t i_homerAddr[], size_t i_num)
+
+void add_reserved_mem(devTree * i_dt,
+ uint64_t i_homerAddr[],
+ size_t i_num,
+ uint64_t i_vpd_addr)
{
/*
* The reserved-names and reserve-names properties work hand in hand.
@@ -454,21 +459,48 @@ void add_reserved_mem(devTree * i_dt, uint64_t i_homerAddr[], size_t i_num)
dtOffset_t rootNode = i_dt->findNode("/");
const char* homerStr = "ibm,slw-occ-image";
- const char* reserve_strs[i_num+1];
- uint64_t homerRanges[i_num][2];
+ const char* vpdStr = "ibm,hbrt-vpd-image";
+ const char* reserve_strs[i_num+2];
+ uint64_t ranges[i_num+1][2];
+ uint64_t cell_count = sizeof(ranges) / sizeof(uint64_t);
+ uint64_t res_mem_addrs[i_num+1];
+ uint64_t res_mem_sizes[i_num+1];
+
for(size_t i = 0; i<i_num; i++)
{
reserve_strs[i] = homerStr;
- homerRanges[i][0] = i_homerAddr[i];
- homerRanges[i][1] = VMM_HOMER_INSTANCE_SIZE;
+ ranges[i][0] = i_homerAddr[i];
+ ranges[i][1] = VMM_HOMER_INSTANCE_SIZE;
+ res_mem_addrs[i] = i_homerAddr[i];
+ res_mem_sizes[i] = VMM_HOMER_INSTANCE_SIZE;
}
- reserve_strs[i_num] = NULL;
+ if(i_vpd_addr)
+ {
+ reserve_strs[i_num] = vpdStr;
+ ranges[i_num][0] = i_vpd_addr;
+ ranges[i_num][1] = VMM_RT_VPD_SIZE;
+
+ res_mem_addrs[i_num] = i_vpd_addr;
+ res_mem_sizes[i_num] = VMM_RT_VPD_SIZE;
+
+ reserve_strs[i_num+1] = NULL;
+ }
+ else
+ {
+ reserve_strs[i_num] = NULL;
+ cell_count -= sizeof(ranges[0]);
+ }
i_dt->addPropertyStrings(rootNode, "reserved-names", reserve_strs);
i_dt->addPropertyCells64(rootNode, "reserved-ranges",
- reinterpret_cast<uint64_t*>(homerRanges),
- sizeof(homerRanges) / sizeof(uint64_t));
+ reinterpret_cast<uint64_t*>(ranges),
+ cell_count);
+
+ // added per comment from Dean Sanner
+ // cell_count has limit of DT_MAX_MEM_RESERVE = 16. Is this enough
+ // for all processors + 1 vpd area?
+ i_dt->populateReservedMem(res_mem_addrs, res_mem_sizes, cell_count);
}
@@ -538,8 +570,17 @@ errlHndl_t bld_fdt_cpu(devTree * i_dt)
}
}
- //Add in reserved memory for HOMER images
- add_reserved_mem(i_dt, l_homerAddr, l_cpuTargetList.size());
+ // VPD
+ uint64_t l_vpd_addr = 0;
+
+ errhdl = VPD::vpd_load_rt_image(l_vpd_addr);
+
+
+ //Add in reserved memory for HOMER images and VPD image
+ add_reserved_mem(i_dt,
+ l_homerAddr,
+ l_cpuTargetList.size(),
+ l_vpd_addr);
return errhdl;
}
diff --git a/src/usr/testcore/rtloader/loader.H b/src/usr/testcore/rtloader/loader.H
index 89bc0d436..b60c830e2 100644
--- a/src/usr/testcore/rtloader/loader.H
+++ b/src/usr/testcore/rtloader/loader.H
@@ -32,8 +32,8 @@
#include <errl/errlmanager.H>
#include <util/utillidmgr.H>
#include <map>
-
#include <runtime/interface.h>
+#include <vpd/vpd_if.H>
trace_desc_t* g_trac_hbrt = NULL;
TRAC_INIT(&g_trac_hbrt, "HBRT_TEST", 2*KILOBYTE);
@@ -112,6 +112,7 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
intf->scom_write = rt_scom_write;
intf->lid_load = rt_lid_load;
intf->lid_unload = rt_lid_unload;
+ intf->get_vpd_image_addr = rt_get_vpd;
// Call init.
runtimeInterfaces_t* rtInterface =
@@ -296,11 +297,52 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
return 0;
}
+
+ //--------------------------------------------------------------------
+ static uint64_t rt_get_vpd()
+ {
+ if(cv_vpd_addr != 0)
+ {
+ return cv_vpd_addr;
+ }
+
+ // runtime VPD area not setup yet.
+ // Need to map the area into virtual memory
+
+ uint64_t phys_addr = 0;
+ errlHndl_t err = VPD::vpd_load_rt_image(phys_addr);
+
+ if(!err)
+ {
+
+ uint8_t * vpd_ptr =
+ reinterpret_cast<uint8_t *>(phys_addr);
+
+ void * vptr = mm_block_map(vpd_ptr, VMM_RT_VPD_SIZE);
+
+ assert(vptr != NULL,"rt_get_vpd. Could not map VPD memory");
+
+
+ // Store the address in a class variable so we only
+ // need to load vpd once.
+ cv_vpd_addr = reinterpret_cast<uint64_t>(vptr);
+ }
+ else
+ {
+ errlCommit(err,CXXTEST_COMP_ID);
+ }
+
+ return cv_vpd_addr;
+
+ }
+
+ static uint64_t cv_vpd_addr;
};
RuntimeLoaderTest::SCOM_MAP RuntimeLoaderTest::cv_scomMap;
std::map<void*, UtilLidMgr*> RuntimeLoaderTest::cv_loadedLids;
+uint64_t RuntimeLoaderTest::cv_vpd_addr = 0;
#endif
diff --git a/src/usr/vpd/makefile b/src/usr/vpd/makefile
index 3a8a59154..d48c209e9 100644
--- a/src/usr/vpd/makefile
+++ b/src/usr/vpd/makefile
@@ -23,9 +23,13 @@
ROOTPATH = ../../..
MODULE = vpd
-OBJS = vpd.o spd.o ipvpd.o mvpd.o dimmPres.o cvpd.o
+#include common objects between hb and runtime
+include vpd.mk
-SUBDIRS = test.d
+#include unique objects
+OBJS += vpd.o dimmPres.o rtvpd_load.o
+
+SUBDIRS = test.d runtime.d
BINARY_FILES = $(IMGDIR)/dimmspd.dat:3a9f53e3684e57401ed0aed75f25980fca99f40b
BINARY_FILES += $(IMGDIR)/procmvpd.dat:7dabbe4879dcdd19ed236573aa68e8671fa8c3c7
diff --git a/src/usr/vpd/rtvpd_load.C b/src/usr/vpd/rtvpd_load.C
new file mode 100644
index 000000000..cb393e996
--- /dev/null
+++ b/src/usr/vpd/rtvpd_load.C
@@ -0,0 +1,148 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/vpd/rtvpd_load.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <errl/errlentry.H>
+#include <targeting/common/target.H>
+#include <targeting/common/targetservice.H>
+#include <targeting/common/utilFilter.H>
+#include <sys/mm.h>
+#include <vmmconst.h>
+#include <pnor/pnorif.H>
+#include <vpd/vpdreasoncodes.H>
+#include <vpd/vpd_if.H>
+
+// ----------------------------------------------
+// Trace definitions
+// ----------------------------------------------
+extern trace_desc_t* g_trac_vpd;
+
+
+/**
+ * Copy a VPD image from PNOR into MEMORY
+ * @param[in] vpd type (pnor section id)
+ * @param[in] destination memory location
+ * @param[in] Max size of image.
+ * @return error handle if error
+ */
+errlHndl_t bld_vpd_image(PNOR::SectionId vpd_type,
+ void * i_dest,
+ uint64_t i_size)
+{
+ errlHndl_t err = NULL;
+ PNOR::SectionInfo_t info;
+ err = PNOR::getSectionInfo( vpd_type,
+ PNOR::CURRENT_SIDE,
+ info );
+
+ if(!err)
+ {
+ if(info.size <= i_size)
+ {
+ memcpy(i_dest,
+ reinterpret_cast<void *>(info.vaddr),
+ info.size);
+ }
+ else
+ {
+ TRACFCOMP( g_trac_vpd, ERR_MRK
+ "bld_vpd_image: Reserved size in memory insufficient "
+ "for VPD type %d. Size provided: %d Size needed: %d",
+ (uint32_t)vpd_type,
+ i_size,
+ info.size );
+
+
+ /*@
+ * @errortype
+ * @reasoncode VPD::VPD_INSUFFICIENT_SPACE_FOR_IMAGE
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_BLD_RT_IMAGE
+ * @userdata1 Size provided
+ * @userdata2 vpd_type | Size required
+ * @devdesc Reserved size in memory insufficient
+ * for runtime VPD
+ */
+ err = new ERRORLOG::ErrlEntry
+ (ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_BLD_RT_IMAGE,
+ VPD::VPD_INSUFFICIENT_SPACE_FOR_IMAGE,
+ i_size,
+ (((uint64_t)vpd_type) << 32) + info.size );
+
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ }
+ }
+
+ return err;
+
+}
+
+// External function see vpd_if.H
+errlHndl_t VPD::vpd_load_rt_image(uint64_t & o_vpd_addr)
+{
+ errlHndl_t err = NULL;
+
+ uint64_t vpd_addr = TARGETING::get_top_mem_addr();
+
+ assert (vpd_addr != 0,
+ "bld_devtree: Top of memory was 0!");
+
+ vpd_addr -= VMM_RT_VPD_OFFSET;
+
+ o_vpd_addr = vpd_addr;
+
+ uint8_t * vpd_ptr = reinterpret_cast<uint8_t*>(vpd_addr);
+
+ void * vptr = mm_block_map(vpd_ptr, VMM_RT_VPD_SIZE);
+
+ assert(vptr != NULL,"bld_devtree: Could not map VPD memory");
+
+ vpd_ptr = static_cast<uint8_t*>(vptr);
+
+ err = bld_vpd_image(PNOR::DIMM_JEDEC_VPD,
+ vpd_ptr,
+ VMM_DIMM_JEDEC_VPD_SIZE);
+
+ vpd_ptr += VMM_DIMM_JEDEC_VPD_SIZE;
+
+ if(!err)
+ {
+ err = bld_vpd_image(PNOR::MODULE_VPD,
+ vpd_ptr,
+ VMM_MODULE_VPD_SIZE);
+
+ vpd_ptr += VMM_MODULE_VPD_SIZE;
+ }
+
+ if(!err)
+ {
+ err = bld_vpd_image(PNOR::CENTAUR_VPD,
+ vpd_ptr,
+ VMM_CENTAUR_VPD_SIZE);
+ }
+
+ mm_block_unmap(vptr);
+
+ return err;
+}
diff --git a/src/usr/vpd/runtime/makefile b/src/usr/vpd/runtime/makefile
new file mode 100644
index 000000000..bb8d04ffe
--- /dev/null
+++ b/src/usr/vpd/runtime/makefile
@@ -0,0 +1,39 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/vpd/runtime/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2013
+#
+# p1
+#
+# Object Code Only (OCO) source materials
+# Licensed Internal Code Source Materials
+# IBM HostBoot Licensed Internal Code
+#
+# The source code for this program is not published or otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+# common objects with runtime
+HOSTBOOT_RUNTIME = 1
+ROOTPATH = ../../../..
+MODULE = vpd_rt
+
+#include common objects between hostboot and runtime hostboot
+include ../vpd.mk
+
+#add unique object modules
+OBJS += rt_vpd.o
+
+SUBDIRS = test.d
+
+VPATH += ..
+
+include $(ROOTPATH)/config.mk
+
diff --git a/src/usr/vpd/runtime/rt_vpd.C b/src/usr/vpd/runtime/rt_vpd.C
new file mode 100644
index 000000000..a80ad0ed8
--- /dev/null
+++ b/src/usr/vpd/runtime/rt_vpd.C
@@ -0,0 +1,327 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/vpd/runtime/rt_vpd.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <vpd/vpdreasoncodes.H>
+#include <initservice/initserviceif.H>
+#include "../vpd.H"
+#include <runtime/interface.h>
+#include <targeting/common/util.H>
+
+// ----------------------------------------------
+// Trace definitions
+// ----------------------------------------------
+trace_desc_t* g_trac_vpd = NULL;
+TRAC_INIT( & g_trac_vpd, "VPD", KILOBYTE );
+
+// ------------------------
+// Macros for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+//#define TRACSSCOMP(args...) TRACFCOMP(args)
+#define TRACSSCOMP(args...)
+
+namespace VPD
+{
+
+// ------------------------------------------------------------------
+// getVpdLocation
+// ------------------------------------------------------------------
+errlHndl_t getVpdLocation ( int64_t & o_vpdLocation,
+ TARGETING::Target * i_target )
+{
+ errlHndl_t err = NULL;
+
+ TRACSSCOMP( g_trac_vpd,
+ ENTER_MRK"getVpdLocation()" );
+
+ o_vpdLocation = i_target->getAttr<TARGETING::ATTR_VPD_REC_NUM>();
+ TRACUCOMP( g_trac_vpd,
+ INFO_MRK"Using VPD location: %d",
+ o_vpdLocation );
+
+ TRACSSCOMP( g_trac_vpd,
+ EXIT_MRK"getVpdLocation()" );
+
+ return err;
+}
+
+// ------------------------------------------------------------------
+// Fake getPnorAddr - VPD image is in memory
+// ------------------------------------------------------------------
+errlHndl_t getPnorAddr( pnorInformation & i_pnorInfo,
+ uint64_t &io_cachedAddr,
+ mutex_t * i_mutex )
+{
+ errlHndl_t err = NULL;
+ uint64_t vpd_addr = 0;
+
+ if(
+ g_hostInterfaces != NULL &&
+ g_hostInterfaces->get_vpd_image_addr)
+ {
+ vpd_addr = g_hostInterfaces->get_vpd_image_addr();
+ if(vpd_addr == 0)
+ {
+ TRACFCOMP(g_trac_vpd,ERR_MRK"rt_vpd: Failed to get VPD addr. "
+ "vpd_type: %d",
+ i_pnorInfo.pnorSection);
+ /*@
+ * @errortype
+ * @moduleid VPD::VPD_RT_GET_ADDR
+ * @reasoncode VPD::VPD_RT_NULL_VPD_PTR
+ * @userdata1 VPD type
+ * @userdata2 0
+ * @devdesc Hypervisor returned NULL address for VPD
+ */
+ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ VPD::VPD_RT_GET_ADDR,
+ VPD::VPD_RT_NULL_VPD_PTR,
+ i_pnorInfo.pnorSection,
+ 0);
+
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ }
+ }
+ else // interface not set
+ {
+ TRACFCOMP(g_trac_vpd,ERR_MRK"Hypervisor vpd interface not linked");
+ /*@
+ * @errortype
+ * @moduleid VPD::VPD_RT_GET_ADDR
+ * @reasoncode VPD::VPD_RT_NOT_INITIALIZED
+ * @userdata1 VPD type
+ * @userdata2 0
+ * @devdesc Runtime VPD interface not linked.
+ */
+ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ VPD::VPD_RT_GET_ADDR,
+ VPD::VPD_RT_NOT_INITIALIZED,
+ i_pnorInfo.pnorSection,
+ 0);
+
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ }
+
+ if(!err)
+ {
+
+ switch(i_pnorInfo.pnorSection)
+ {
+ case PNOR::DIMM_JEDEC_VPD:
+ break;
+
+ case PNOR::MODULE_VPD:
+ vpd_addr += VMM_DIMM_JEDEC_VPD_SIZE;
+ break;
+
+ case PNOR::CENTAUR_VPD:
+ vpd_addr += (VMM_DIMM_JEDEC_VPD_SIZE + VMM_MODULE_VPD_SIZE);
+ break;
+
+ default: // Huh?
+ TRACFCOMP(g_trac_vpd, ERR_MRK
+ "RT getPnorAddr: Invalid VPD type: 0x%x",
+ i_pnorInfo.pnorSection);
+
+ /*@
+ * @errortype
+ * @reasoncode VPD::VPD_RT_INVALID_TYPE
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_RT_GET_ADDR
+ * @userdata1 Requested VPD TYPE
+ * @userdata2 0
+ * @devdesc Requested VPD type is invalid or not
+ * supported at runtime
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_RT_GET_ADDR,
+ VPD::VPD_RT_INVALID_TYPE,
+ i_pnorInfo.pnorSection,
+ 0 );
+
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ break;
+ }
+ }
+
+ if(!err)
+ {
+ io_cachedAddr = vpd_addr;
+ }
+
+ return err;
+}
+
+// ------------------------------------------------------------------
+// Fake readPNOR - image is in memory
+// ------------------------------------------------------------------
+errlHndl_t readPNOR ( uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target,
+ pnorInformation & i_pnorInfo,
+ uint64_t &io_cachedAddr,
+ mutex_t * i_mutex )
+{
+ errlHndl_t err = NULL;
+ int64_t vpdLocation = 0;
+ uint64_t addr = 0x0;
+ const char * readAddr = NULL;
+
+ TRACSSCOMP( g_trac_vpd,
+ ENTER_MRK"RT fake readPNOR()" );
+
+ do
+ {
+ // fake getPnorAddr gets memory address of VPD
+ err = getPnorAddr(i_pnorInfo,
+ io_cachedAddr,
+ i_mutex );
+ if(err)
+ {
+ break;
+ }
+
+ addr = io_cachedAddr;
+
+ err = getVpdLocation( vpdLocation,
+ i_target);
+
+ if(err)
+ {
+ break;
+ }
+
+ // Add Offset for target vpd location
+ addr += (vpdLocation * i_pnorInfo.segmentSize);
+
+ // Add keyword offset
+ addr += i_byteAddr;
+
+ TRACUCOMP( g_trac_vpd,
+ INFO_MRK"Address to read: 0x%08x",
+ addr );
+
+ readAddr = reinterpret_cast<const char *>( addr );
+ memcpy( o_data,
+ readAddr,
+ i_numBytes );
+ } while(0);
+
+ TRACSSCOMP( g_trac_vpd,
+ EXIT_MRK"RT fake readPNOR()" );
+
+ return err;
+}
+
+// ------------------------------------------------------------------
+// Fake writePNOR - image is in memory
+// ------------------------------------------------------------------
+errlHndl_t writePNOR ( uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * i_data,
+ TARGETING::Target * i_target,
+ pnorInformation & i_pnorInfo,
+ uint64_t &io_cachedAddr,
+ mutex_t * i_mutex )
+{
+ errlHndl_t err = NULL;
+ // Does VPD write ever need to be supported at runtime?
+ TRACFCOMP(g_trac_vpd, ERR_MRK
+ "RT writePNOR: VPD write not supported at runtime.");
+
+ /*@
+ * @errortype
+ * @reasoncode VPD::VPD_RT_WRITE_NOT_SUPPORTED
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_RT_WRITE_PNOR
+ * @userdata1 target huid
+ * @userdata2 VPD type
+ * @devdesc VPD write not suported at runtime
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_RT_WRITE_PNOR,
+ VPD::VPD_RT_WRITE_NOT_SUPPORTED,
+ get_huid(i_target),
+ i_pnorInfo.pnorSection);
+
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ return err;
+}
+
+// ------------------------------------------------------------------
+// sendMboxWriteMsg - not supported at runtime
+// Treat the same way HB does if mbox is not available
+// ------------------------------------------------------------------
+errlHndl_t sendMboxWriteMsg ( size_t i_numBytes,
+ void * i_data,
+ TARGETING::Target * i_target,
+ VPD_MSG_TYPE i_type,
+ VpdWriteMsg_t& i_record )
+{
+ errlHndl_t err = NULL;
+ TRACFCOMP( g_trac_vpd, INFO_MRK
+ "sendMboxWriteMsg: Send msg to FSP to write VPD type %.8X, "
+ "record %d, offset 0x%X",
+ i_type,
+ i_record.rec_num,
+ i_record.offset );
+
+ // mimic the behavior of hostboot when mbox is not available.
+ TRACFCOMP( g_trac_vpd, ERR_MRK
+ "No SP Base Services available at runtime.");
+
+ /*@
+ * @errortype
+ * @reasoncode VPD::VPD_MBOX_NOT_SUPPORTED_RT
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_SEND_MBOX_WRITE_MESSAGE
+ * @userdata1 VPD message type
+ * @userdata2 0
+ * @devdesc MBOX send not supported in HBRT
+ */
+ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_SEND_MBOX_WRITE_MESSAGE,
+ VPD::VPD_MBOX_NOT_SUPPORTED_RT,
+ i_type,
+ 0);
+
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+
+
+ return err;
+}
+
+}; // end namepsace VPD
diff --git a/src/usr/vpd/runtime/test/makefile b/src/usr/vpd/runtime/test/makefile
new file mode 100644
index 000000000..8cfee9d53
--- /dev/null
+++ b/src/usr/vpd/runtime/test/makefile
@@ -0,0 +1,29 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/vpd/runtime/test/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2013
+#
+# p1
+#
+# Object Code Only (OCO) source materials
+# Licensed Internal Code Source Materials
+# IBM HostBoot Licensed Internal Code
+#
+# The source code for this program is not published or otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+HOSTBOOT_RUNTIME = 1
+ROOTPATH = ../../../../..
+
+MODULE = testvpd_rt
+TESTS = ../../test/*.H
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/vpd/spd.C b/src/usr/vpd/spd.C
index 3db5af0f5..772d7f083 100755
--- a/src/usr/vpd/spd.C
+++ b/src/usr/vpd/spd.C
@@ -1068,6 +1068,7 @@ errlHndl_t spdReadBinaryFile ( uint64_t i_byteAddr,
void * o_data )
{
errlHndl_t err = NULL;
+#ifndef __HOSTBOOT_RUNTIME
const char * fileName = "dimmspd.dat";
const char * startAddr = NULL;
size_t fileSize;
@@ -1164,7 +1165,7 @@ errlHndl_t spdReadBinaryFile ( uint64_t i_byteAddr,
TRACSSCOMP( g_trac_spd,
EXIT_MRK"spdReadBinaryFile()" );
-
+#endif
return err;
}
diff --git a/src/usr/vpd/test/cvpdtest.H b/src/usr/vpd/test/cvpdtest.H
index 90f91a660..461bb6d15 100755
--- a/src/usr/vpd/test/cvpdtest.H
+++ b/src/usr/vpd/test/cvpdtest.H
@@ -247,6 +247,7 @@ class CVPDTest: public CxxTest::TestSuite
*/
void testCvpdWrite ( void )
{
+#ifndef __HOSTBOOT_RUNTIME
errlHndl_t err = NULL;
uint64_t cmds = 0x0;
uint64_t fails = 0x0;
@@ -409,6 +410,7 @@ class CVPDTest: public CxxTest::TestSuite
TRACFCOMP( g_trac_vpd,
"testCvpdWrite - %d/%d fails",
fails, cmds );
+#endif
}
/**
diff --git a/src/usr/vpd/test/dimmPrestest.H b/src/usr/vpd/test/dimmPrestest.H
index ff8c3e4cb..91146199b 100755
--- a/src/usr/vpd/test/dimmPrestest.H
+++ b/src/usr/vpd/test/dimmPrestest.H
@@ -55,6 +55,7 @@ class DIMMPresTest: public CxxTest::TestSuite
*/
void testDimmPres ( void )
{
+#ifndef __HOSTBOOT_RUNTIME
errlHndl_t err = NULL;
uint64_t cmds = 0x0;
uint64_t fails = 0x0;
@@ -115,6 +116,7 @@ class DIMMPresTest: public CxxTest::TestSuite
TRACFCOMP( g_trac_spd,
"testDimmPres - %d/%d fails",
fails, cmds );
+#endif
}
@@ -124,6 +126,7 @@ class DIMMPresTest: public CxxTest::TestSuite
*/
void testDimmPresInvalidSize ( void )
{
+#ifndef __HOSTBOOT_RUNTIME
errlHndl_t err = NULL;
uint64_t cmds = 0x0;
uint64_t fails = 0x0;
@@ -180,9 +183,8 @@ class DIMMPresTest: public CxxTest::TestSuite
TRACFCOMP( g_trac_spd,
"testDimmPresInvalidSize() - %d/%d fails",
fails, cmds );
+#endif
}
-
};
-
#endif
diff --git a/src/usr/vpd/test/mvpdtest.H b/src/usr/vpd/test/mvpdtest.H
index d40ea22d3..3ca7415ce 100755
--- a/src/usr/vpd/test/mvpdtest.H
+++ b/src/usr/vpd/test/mvpdtest.H
@@ -460,6 +460,7 @@ class MVPDTest: public CxxTest::TestSuite
testData,
theSize,
DEVICE_MVPD_ADDRESS(MVPD::VWML,MVPD::pdI) );
+#ifndef __HOSTBOOT_RUNTIME
if( err )
{
fails++;
@@ -521,6 +522,19 @@ class MVPDTest: public CxxTest::TestSuite
VPD_COMP_ID );
continue;
}
+#else
+ if(!err)
+ {
+ fails++;
+ TRACFCOMP( g_trac_vpd, ERR_MRK
+ "testMvpdWrite() at runtime did not fail");
+ TS_FAIL( "testMvpdWrite() - VPD write did not fail at runtime");
+ }
+ else
+ {
+ delete err;
+ }
+#endif
} while( 0 );
diff --git a/src/usr/vpd/test/spdtest.H b/src/usr/vpd/test/spdtest.H
index d2c28d2e1..ce1372c2f 100755
--- a/src/usr/vpd/test/spdtest.H
+++ b/src/usr/vpd/test/spdtest.H
@@ -255,6 +255,7 @@ class SPDTest: public CxxTest::TestSuite
*/
void testSpdWriteDQ ( void )
{
+#ifndef __HOSTBOOT_RUNTIME
errlHndl_t err = NULL;
uint64_t cmds = 0x0;
uint64_t fails = 0x0;
@@ -445,6 +446,7 @@ class SPDTest: public CxxTest::TestSuite
TRACFCOMP( g_trac_spd,
"testSpdWriteDQ - %d/%d fails",
fails, cmds );
+#endif
}
/**
@@ -456,6 +458,7 @@ class SPDTest: public CxxTest::TestSuite
*/
void _testSpdWriteSmall ( void )
{
+#ifndef __HOSTBOOT_RUNTIME
errlHndl_t err = NULL;
uint64_t cmds = 0x0;
uint64_t fails = 0x0;
@@ -642,6 +645,7 @@ class SPDTest: public CxxTest::TestSuite
TRACFCOMP( g_trac_spd,
"testSpdWriteSmall - %d/%d fails",
fails, cmds );
+#endif
}
/**
* @brief Test an invalid Keyword to a DIMM target.
@@ -761,6 +765,7 @@ class SPDTest: public CxxTest::TestSuite
*/
void testSpdInvalidWrite ( void )
{
+#ifndef __HOSTBOOT_RUNTIME
errlHndl_t err = NULL;
uint64_t cmds = 0x0;
uint64_t fails = 0x0;
@@ -819,9 +824,9 @@ class SPDTest: public CxxTest::TestSuite
TRACFCOMP( g_trac_spd,
"testSpdInvalidWrite - %d/%d fails",
fails, cmds );
+#endif
}
-
/**
* @brief This test will test reading the Module specific keywords.
*/
diff --git a/src/usr/vpd/vpd.C b/src/usr/vpd/vpd.C
index 782960ad0..78314a400 100644
--- a/src/usr/vpd/vpd.C
+++ b/src/usr/vpd/vpd.C
@@ -286,6 +286,9 @@ errlHndl_t sendMboxWriteMsg ( size_t i_numBytes,
TRACFCOMP(g_trac_vpd, INFO_MRK "No SP Base Services, skipping VPD write");
TRACFBIN( g_trac_vpd, "msg=", msg, sizeof(msg_t) );
TRACFBIN( g_trac_vpd, "extra=", msg->extra_data, i_numBytes );
+ free (msg->extra_data);
+ msg_free( msg );
+
break;
}
diff --git a/src/usr/vpd/vpd.mk b/src/usr/vpd/vpd.mk
new file mode 100644
index 000000000..b893b94e8
--- /dev/null
+++ b/src/usr/vpd/vpd.mk
@@ -0,0 +1,24 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/vpd/vpd.mk $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2013
+#
+# p1
+#
+# Object Code Only (OCO) source materials
+# Licensed Internal Code Source Materials
+# IBM HostBoot Licensed Internal Code
+#
+# The source code for this program is not published or otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+# common objects with runtime
+OBJS = ipvpd.o mvpd.o cvpd.o spd.o
OpenPOWER on IntegriCloud