diff options
author | Doug Gilbert <dgilbert@us.ibm.com> | 2013-10-15 13:55:28 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-11-13 14:49:38 -0600 |
commit | dd2a474b7fc3a8937f45d1278e887b370ad81192 (patch) | |
tree | 00595698a572529ddcd00fc3c975b588b4ea67dc /src | |
parent | 1aa8f7551005dd48078b91be173e8bcc7e339061 (diff) | |
download | talos-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.h | 5 | ||||
-rw-r--r-- | src/include/usr/devtree/devtree_reasoncodes.H | 2 | ||||
-rw-r--r-- | src/include/usr/vmmconst.h | 18 | ||||
-rw-r--r-- | src/include/usr/vpd/vpd_if.H | 35 | ||||
-rw-r--r-- | src/include/usr/vpd/vpdreasoncodes.H | 13 | ||||
-rw-r--r-- | src/makefile | 5 | ||||
-rw-r--r-- | src/usr/devtree/bld_devtree.C | 61 | ||||
-rw-r--r-- | src/usr/testcore/rtloader/loader.H | 44 | ||||
-rw-r--r-- | src/usr/vpd/makefile | 8 | ||||
-rw-r--r-- | src/usr/vpd/rtvpd_load.C | 148 | ||||
-rw-r--r-- | src/usr/vpd/runtime/makefile | 39 | ||||
-rw-r--r-- | src/usr/vpd/runtime/rt_vpd.C | 327 | ||||
-rw-r--r-- | src/usr/vpd/runtime/test/makefile | 29 | ||||
-rwxr-xr-x | src/usr/vpd/spd.C | 3 | ||||
-rwxr-xr-x | src/usr/vpd/test/cvpdtest.H | 2 | ||||
-rwxr-xr-x | src/usr/vpd/test/dimmPrestest.H | 6 | ||||
-rwxr-xr-x | src/usr/vpd/test/mvpdtest.H | 14 | ||||
-rwxr-xr-x | src/usr/vpd/test/spdtest.H | 7 | ||||
-rw-r--r-- | src/usr/vpd/vpd.C | 3 | ||||
-rw-r--r-- | src/usr/vpd/vpd.mk | 24 |
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 |