summaryrefslogtreecommitdiffstats
path: root/src/usr/fapi2/plat_vpd_access.C
diff options
context:
space:
mode:
authorwhs <whs@us.ibm.com>2016-04-04 10:19:37 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-06-30 23:52:31 -0400
commitc9219373d4320bf513046e69903ce33243e84be6 (patch)
tree93494842bf5a673b00910edc756f19d3e1e1a026 /src/usr/fapi2/plat_vpd_access.C
parentf07603a9f2eab60e8e524ff487787086b9a5304e (diff)
downloadtalos-hostboot-c9219373d4320bf513046e69903ce33243e84be6.tar.gz
talos-hostboot-c9219373d4320bf513046e69903ce33243e84be6.zip
Changes related to packaging of memory vpd on Nimbus - part 2
Add the "upper" half of the NIMBUS direct memory support. Add ATTR_MEMVPD_FREQS_MHZ and ATTR_MEMVPD_POS attributes. Implement plat_vpd_access to call p9_getmem_vpd_keyword which decodes which vpd keyword to read for MR and MT. Update dvpd DD with record and keyword list. Update dvpd.dat simics vpd file to include MR and MT that map to J0 and X0. Change-Id: Ife00aa4266a7c16dcff2f0f72837f4d547988b82 RTC: 144519 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23245 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/fapi2/plat_vpd_access.C')
-rw-r--r--src/usr/fapi2/plat_vpd_access.C274
1 files changed, 274 insertions, 0 deletions
diff --git a/src/usr/fapi2/plat_vpd_access.C b/src/usr/fapi2/plat_vpd_access.C
new file mode 100644
index 000000000..91ea92506
--- /dev/null
+++ b/src/usr/fapi2/plat_vpd_access.C
@@ -0,0 +1,274 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/fapi2/plat_vpd_access.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file plat_vpd_access.C
+ *
+ * @brief Implements the GetVpd function
+ */
+
+#include <stdint.h>
+#include <fapi2.H>
+#include <vpd_access_defs.H>
+#include <vpd_access.H>
+#include <p9_get_mem_vpd_keyword.H>
+#include <attribute_service.H>
+#include <vpd/dvpdenums.H>
+
+//The following can be uncommented for unit testing
+//#undef FAPI_DBG
+//#define FAPI_DBG(args...) FAPI_INF(args)
+
+namespace fapi2
+{
+
+fapi2::ReturnCode platGetVPD(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
+ VPDInfo<fapi2::TARGET_TYPE_MCS>& io_vpd_info,
+ uint8_t* o_blob)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ errlHndl_t l_errl = nullptr;
+ keywordName_t l_keywordName = {0};
+ // 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
+ // the vpd DD the size of the keyword.
+ const size_t VPD_KEYWORD_SIZE = 255;
+
+ FAPI_DBG("platGetVPD: enter");
+
+ do
+ {
+ // null blob pointer requests blob size
+ if ( nullptr == o_blob) // just return size
+ {
+ io_vpd_info.iv_size = VPD_KEYWORD_SIZE;
+ FAPI_DBG("platGetVPD: return blob size of %d",
+ io_vpd_info.iv_size);
+ break; //return success
+ }
+
+ //Make sure passed blob buffer is big enough
+ if (VPD_KEYWORD_SIZE > io_vpd_info.iv_size)
+ {
+ FAPI_ERR("platGetVPD: blob size of %d too small, should be %d",
+ io_vpd_info.iv_size,
+ VPD_KEYWORD_SIZE);
+ /*@
+ * @errortype
+ * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD
+ * @reasoncode fapi2::RC_BUFFER_TOO_SMALL
+ * @userdata1 Buffer size
+ * @userdata2 Expected size
+ * @devdesc Passed buffer too small
+ * @custdesc Firmware Error
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi2::MOD_FAPI2_PLAT_GET_VPD,
+ fapi2::RC_BUFFER_TOO_SMALL,
+ io_vpd_info.iv_size,
+ VPD_KEYWORD_SIZE,
+ true); //software callout
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break; //return with error
+ }
+
+ // Get targeting MCS target
+ TARGETING::Target * l_pMcsTarget = nullptr;
+ l_errl = fapi2::platAttrSvc::getTargetingTarget(i_target, l_pMcsTarget);
+ if (l_errl)
+ {
+ FAPI_ERR("platGetVPD: Error from getTargetingTarget");
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break; //return with error
+ }
+
+ //Validate type and check for override
+ uint64_t l_mapKeyword = 0;
+ uint64_t l_keywordEnum = 0; //set this now to be used later
+ if ( fapi2::MT == io_vpd_info.iv_vpd_type )
+ {
+ if (1 ==
+ l_pMcsTarget->getAttr<TARGETING::ATTR_VPD_OVERRIDE_MT_ENABLE>() )
+ {
+ uint8_t l_override[VPD_KEYWORD_SIZE]={0};
+ assert(l_pMcsTarget->tryGetAttr<TARGETING::ATTR_VPD_OVERRIDE_MT>
+ (l_override),
+ "platGetVPD: getAttr ATTR_VPD_OVERRIDE_MT failed");
+ FAPI_DBG("platGetVPD: return MT override attr");
+ memcpy(o_blob,l_override,VPD_KEYWORD_SIZE);
+ break; //return with overriden keyword
+ }
+
+ // not overriden, continue
+ l_mapKeyword = DVPD::MT;
+ l_keywordEnum = DVPD::X0;
+ }
+ else if ( fapi2::MR == io_vpd_info.iv_vpd_type )
+ {
+ if (1==
+ l_pMcsTarget->getAttr<TARGETING::ATTR_VPD_OVERRIDE_MR_ENABLE>() )
+ {
+ uint8_t l_override[VPD_KEYWORD_SIZE]={0};
+ assert(l_pMcsTarget->tryGetAttr<TARGETING::ATTR_VPD_OVERRIDE_MR>
+ (l_override),
+ "platGetVPD: getAttr ATTR_VPD_OVERRIDE_MR failed");
+ FAPI_DBG("platGetVPD: return MR override attr");
+ memcpy(o_blob,l_override,VPD_KEYWORD_SIZE);
+ break; //return with overriden keyword
+ }
+
+ // not overriden, continue
+ l_mapKeyword = DVPD::MR;
+ l_keywordEnum = DVPD::J0;
+ }
+ else
+ {
+ FAPI_ERR("platGetVPD: invalid type = %d",
+ io_vpd_info.iv_vpd_type);
+ /*@
+ * @errortype
+ * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD
+ * @reasoncode fapi2::RC_INVALID_TYPE
+ * @userdata1 Vpd type
+ * @userdata2 HUID of MCS target
+ * @devdesc MR and MT types supported
+ * @custdesc Firmware Error
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi2::MOD_FAPI2_PLAT_GET_VPD,
+ fapi2::RC_BUFFER_TOO_SMALL,
+ 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
+ }
+
+ //Read mapping keyword
+ size_t l_buffSize = VPD_KEYWORD_SIZE;
+ uint8_t * l_pMapping = new uint8_t[VPD_KEYWORD_SIZE];
+ l_errl = deviceRead((TARGETING::Target *)l_pMcsTarget,
+ l_pMapping,
+ l_buffSize,
+ DEVICE_DVPD_ADDRESS(DVPD::MEMD,
+ l_mapKeyword));
+ if (l_errl)
+ {
+ delete l_pMapping;
+ 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,
+ i_target,
+ io_vpd_info,
+ l_pMapping,
+ VPD_KEYWORD_SIZE,
+ l_keywordName);
+ delete l_pMapping;
+ if (l_rc)
+ {
+ FAPI_ERR("platGetVPD: ERROR returned from p9_get_mem_vpd_keyword");
+ break; //return with error
+ }
+ FAPI_DBG("platGetVPD: keyword name = %s",
+ l_keywordName);
+
+ //Convert keyword name to keyword enumeration.
+ //ascii 0..9 runs from 0x30 to 0x39.
+ //The conversion assumes the input is valid (0..9,A..Z)
+ //and that the enumeration is in order and consecutive.
+ if ( '0' == (l_keywordName[1] & 0xf0)) //it is a digit (0..9)
+ {
+ l_keywordEnum += (l_keywordName[1] - '0');
+ }
+ else //it is a char (A..Z)
+ {
+ l_keywordEnum += (l_keywordName[1] - 'A') + 10;
+ }
+
+ //Read vpd blob
+ l_buffSize = io_vpd_info.iv_size;
+ 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
+ }
+
+ //Confirm all expected data was returned
+ if (VPD_KEYWORD_SIZE > l_buffSize)
+ {
+ FAPI_ERR("platGetVPD: insufficient vpd returned"
+ " for keyword %d;"
+ " %d returned, %d expected",
+ l_keywordEnum,
+ l_buffSize,
+ VPD_KEYWORD_SIZE);
+ /*@
+ * @errortype
+ * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD
+ * @reasoncode fapi2::RC_RETURNED_VPD_TOO_SMALL
+ * @userdata1[0:31] Returned vpd in bytes
+ * @userdata1[32:64] Expected number of vpd bytes
+ * @userdata2 Keyword
+ * @devdesc Less than expected number of bytes returned.
+ * @custdesc Firmware Error
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi2::MOD_FAPI2_PLAT_GET_VPD,
+ fapi2::RC_RETURNED_VPD_TOO_SMALL,
+ TWO_UINT32_TO_UINT64(
+ l_buffSize,
+ VPD_KEYWORD_SIZE),
+ l_keywordEnum);
+ l_errl->addHwCallout( l_pMcsTarget,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL );
+
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break; //return with error
+ }
+ }
+ while (0);
+
+ FAPI_DBG("platGetVPD: exit");
+
+ return l_rc;
+}
+
+} // namespace
OpenPOWER on IntegriCloud