summaryrefslogtreecommitdiffstats
path: root/src/usr/hdat/hdatmsvpd.C
diff options
context:
space:
mode:
authornagurram-in <nagendra.g@in.ibm.com>2016-10-03 07:26:30 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-11-14 21:29:58 -0500
commit2da4b3794cb7ee133d1c4db6640aad99748ebf4b (patch)
tree0ce57c885d1ae2c2c33743681fbcc98012d6958b /src/usr/hdat/hdatmsvpd.C
parent3d95d418377ac2ede6d9ab217637cd53158736e9 (diff)
downloadtalos-hostboot-2da4b3794cb7ee133d1c4db6640aad99748ebf4b.tar.gz
talos-hostboot-2da4b3794cb7ee133d1c4db6640aad99748ebf4b.zip
HDAT changes for Witherspoon
Change-Id: I942362604938fe4f7511e21da9246236a939c176 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/30905 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/hdat/hdatmsvpd.C')
-rwxr-xr-xsrc/usr/hdat/hdatmsvpd.C2015
1 files changed, 2015 insertions, 0 deletions
diff --git a/src/usr/hdat/hdatmsvpd.C b/src/usr/hdat/hdatmsvpd.C
new file mode 100755
index 000000000..a83669a71
--- /dev/null
+++ b/src/usr/hdat/hdatmsvpd.C
@@ -0,0 +1,2015 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hdat/hdatmsvpd.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 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 hdatmsvpd.C
+ *
+ * @brief This file contains the implementation of the HdatMsVpd class.
+ *
+ */
+
+/*----------------------------------------------------------------------------*/
+/* Includes */
+/*----------------------------------------------------------------------------*/
+#include "hdatmsvpd.H" // HdatMsVpd class definition
+#include "hdathdif.H"
+#include <sys/mm.h>
+#include <sys/mmio.h>
+#include <assert.h>
+#include <util/align.H>
+#include <limits.h>
+
+
+namespace HDAT
+{
+/*----------------------------------------------------------------------------*/
+/* Global variables */
+/*----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------*/
+/* Macros */
+/*----------------------------------------------------------------------------*/
+// macro to compute the address of a main store area
+#define HDAT_MS_AREA(_i_idx_) *((HdatMsArea **)((char *)iv_msAreaPtrs + \
+_i_idx_ * sizeof(HdatMsArea *)))
+
+
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+HdatMsVpd::HdatMsVpd(errlHndl_t &o_errlHndl,
+ const hdatMsAddr_t &i_msAddr
+ ):HdatHdif(o_errlHndl,
+ HDAT_MSVPD_STRUCT_NAME, HDAT_MS_VPD_LAST, HDAT_START_INSTANCE,
+ HDAT_MS_CHILD_LAST, HDAT_MS_VPD_VERSION),
+ iv_actMsAreaCnt(0), iv_maxMsAreaCnt(0), iv_msAreaPtrs(NULL),
+ iv_IMTaddrRangeArray(NULL), iv_maxIMTAddrRngCnt(0),
+ iv_UEaddrRangeArray(NULL), iv_maxUEAddrRngCnt(0)
+{
+ memcpy(&iv_msAddr, &i_msAddr, sizeof(hdatMsAddr_t));
+}
+
+
+
+void HdatMsVpd::hdatInit(hdatMsAddr_t &i_maxMsAddr,
+ hdatMsAddr_t &i_maxMsCcmAddr,
+ uint32_t i_msSize,
+ uint32_t i_msAreaCnt,
+ uint32_t i_MostSigAffinityDomain,
+ uint32_t i_ueAreaCnt,
+ uint64_t i_MirrMemStartAddr)
+{
+ iv_maxUEAddrRngCnt = i_ueAreaCnt;
+ iv_maxMsAreaCnt = i_msAreaCnt;
+ iv_maxIMTAddrRngCnt = i_msAreaCnt;
+ memcpy(&iv_maxAddr.hdatMaxAddr, &i_maxMsAddr, sizeof(hdatMsAddr_t));
+ memcpy(&iv_maxAddr.hdatMaxCcmAddr, &i_maxMsCcmAddr, sizeof(hdatMsAddr_t));
+ iv_maxAddr.hdatMstSigAffntyDom = i_MostSigAffinityDomain;
+ memcpy(&iv_maxAddr.hdatMirrMemStartAddr, &i_MirrMemStartAddr,
+ sizeof(hdatMsAddr_t));
+ iv_maxSize.hdatReserved1 = 0;
+ iv_maxSize.hdatTotSize = i_msSize;
+ memset(&iv_mover, 0x00, sizeof(hdatMsVpdPageMover_t));
+ iv_IMTaddrRngArrayHdr.hdatOffset = sizeof(hdatHDIFDataArray_t);
+ iv_IMTaddrRngArrayHdr.hdatArrayCnt = 0;
+ iv_IMTaddrRngArrayHdr.hdatAllocSize = sizeof(hdatMsVpdImtAddrRange_t);
+ iv_IMTaddrRngArrayHdr.hdatActSize = sizeof(hdatMsVpdImtAddrRange_t);
+ iv_UEaddrRngArrayHdr.hdatOffset = sizeof(hdatHDIFDataArray_t);
+ iv_UEaddrRngArrayHdr.hdatArrayCnt = 0;
+ iv_UEaddrRngArrayHdr.hdatAllocSize = sizeof(hdatMsVpdUEAddrRange_t);
+ iv_UEaddrRngArrayHdr.hdatActSize = sizeof(hdatMsVpdUEAddrRange_t);
+ iv_RHBaddrRngArrayHdr.hdatOffset = sizeof(hdatHDIFDataArray_t);
+ iv_RHBaddrRngArrayHdr.hdatArrayCnt = 0;
+ iv_RHBaddrRngArrayHdr.hdatAllocSize = sizeof(hdatMsVpdRhbAddrRange_t);
+ iv_RHBaddrRngArrayHdr.hdatActSize = sizeof(hdatMsVpdRhbAddrRange_t);
+
+ iv_maxRHBAddrRngCnt = hdatGetMaxCecNodes();
+
+ // Allocate space for the mainstore area entries and IMT Addr Range array
+ iv_msAreaPtrs = new HdatMsArea*[iv_maxMsAreaCnt];
+ iv_IMTaddrRangeArray = new hdatMsVpdImtAddrRange_t[iv_maxIMTAddrRngCnt];
+ iv_UEaddrRangeArray = new hdatMsVpdUEAddrRange_t[iv_maxUEAddrRngCnt];
+ // Allocate space for the host boot memory reserve range
+ iv_RHBaddrRangeArray = new hdatMsVpdRhbAddrRange_t[iv_maxRHBAddrRngCnt];
+
+ // Update the base class internal data pointers.
+ // When the data is written to the file by commit(), it must be done in the
+ // same order as these addData() calls
+ this->addData(HDAT_MS_VPD_MAX_ADDR, sizeof(hdatMsVpdAddr_t));
+ this->addData(HDAT_MS_VPD_MAX_SIZE, sizeof(hdatMsVpdSize_t));
+ this->addData(HDAT_MS_VPD_PAGE_MOVER, sizeof(hdatMsVpdPageMover_t));
+
+ this->addData(HDAT_MS_VPD_IMT_ADDR_RNG, (sizeof(hdatHDIFDataArray_t) +
+ (iv_maxIMTAddrRngCnt * sizeof(hdatMsVpdImtAddrRange_t))));
+ this->addData(HDAT_MS_VPD_UE_ADDR_RNG, (sizeof(hdatHDIFDataArray_t) +
+ (iv_maxUEAddrRngCnt * sizeof(hdatMsVpdUEAddrRange_t))));
+
+ this->addData(HDAT_MS_VPD_HB_ADDR_RNG, (sizeof(hdatHDIFDataArray_t) +
+ (iv_maxRHBAddrRngCnt * sizeof(hdatMsVpdRhbAddrRange_t))));
+ this->align();
+
+ return;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+HdatMsVpd::~HdatMsVpd()
+{
+
+ uint32_t l_cnt;
+ HdatMsArea *l_obj, **l_curPtr;
+
+ // Delete mainstore area objects (which in turn delete RAM objects)
+ l_curPtr = iv_msAreaPtrs;
+ for (l_cnt = 0; l_cnt < iv_actMsAreaCnt; l_cnt++)
+ {
+ l_obj = *l_curPtr;
+ delete l_obj;
+ l_curPtr = reinterpret_cast<HdatMsArea**>(reinterpret_cast<char*>
+ (l_curPtr) + sizeof(HdatMsArea *));
+ }
+
+ delete[] iv_msAreaPtrs;
+
+ // Delete IMT Address Range Array
+ delete[] iv_IMTaddrRangeArray;
+
+ // Delete UE Address Range Array
+ delete[] iv_UEaddrRangeArray;
+
+ delete[] iv_RHBaddrRangeArray;
+
+ uint64_t l_addr = reinterpret_cast<uint64_t> (iv_virtAddr);
+ l_addr = ALIGN_PAGE_DOWN(l_addr);
+
+ iv_virtAddr = reinterpret_cast<void*>(l_addr);
+
+ int rc = mm_block_unmap(iv_virtAddr);
+ if( rc != 0)
+ {
+ errlHndl_t l_errl = NULL;
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_MSVPD_DESTRUCTOR
+ * @reasoncode HDAT::RC_DEV_MAP_FAIL
+ * @devdesc Unmap a mapped region failed
+ * @custdesc Firmware encountered an internal error.
+ */
+ hdatBldErrLog(l_errl,
+ MOD_MSVPD_DESTRUCTOR,
+ RC_DEV_MAP_FAIL,
+ 0,0,0,0,
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ HDAT_VERSION1,
+ true);
+ }
+
+ return;
+}
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+errlHndl_t HdatMsVpd::addIMTAddrRange(hdatMsAddr_t &i_start,
+ hdatMsAddr_t &i_end)
+{
+
+ errlHndl_t l_errlHndl = NULL;
+ hdatMsVpdImtAddrRange_t *l_addr;
+
+ if (iv_IMTaddrRngArrayHdr.hdatArrayCnt < iv_maxIMTAddrRngCnt)
+ {
+ l_addr = reinterpret_cast<hdatMsVpdImtAddrRange_t*>(reinterpret_cast
+ <char*>(iv_IMTaddrRangeArray) + (iv_IMTaddrRngArrayHdr.hdatArrayCnt *
+ sizeof(hdatMsVpdImtAddrRange_t)));
+
+ l_addr->hdatImtAddrRngStrAddr = i_start;
+ l_addr->hdatImtAddrRngEndAddr = i_end;
+ iv_IMTaddrRngArrayHdr.hdatArrayCnt++;
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @refcode LIC_REFCODE
+ * @subsys EPUB_FIRMWARE_SP
+ * @reasoncode RC_ERC_MAX_EXCEEDED
+ * @moduleid MOD_ADD_IMT_ADDR_RANGE
+ * @userdata1 current number of array entries
+ * @userdata2 maximum number of array entries
+ * @userdata3 none
+ * @userdata4 none
+ * @devdesc Exceeded limit of number of mainstore VPD
+ * In Memory Trace array entries
+ */
+ hdatBldErrLog(l_errlHndl,
+ MOD_ADD_IMT_ADDR_RANGE, // SRC module ID
+ RC_ERC_MAX_EXCEEDED, // SRC extended reference code
+ iv_IMTaddrRngArrayHdr.hdatArrayCnt, // SRC hex word 1
+ iv_maxIMTAddrRngCnt); // SRC hex word 2
+ }
+
+ return l_errlHndl;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+errlHndl_t HdatMsVpd::addUEAddrRange(hdatMsAddr_t &i_addr)
+{
+
+ errlHndl_t l_errlHndl = NULL;
+ hdatMsVpdUEAddrRange_t *l_addr;
+
+ if (iv_UEaddrRngArrayHdr.hdatArrayCnt < iv_maxUEAddrRngCnt)
+ {
+ l_addr = reinterpret_cast<hdatMsVpdUEAddrRange_t*>(reinterpret_cast
+ <char*>(iv_UEaddrRangeArray) + (iv_UEaddrRngArrayHdr.hdatArrayCnt *
+ sizeof(hdatMsVpdUEAddrRange_t)));
+
+ l_addr->hdatUEAddr = i_addr;
+ iv_UEaddrRngArrayHdr.hdatArrayCnt++;
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @refcode LIC_REFCODE
+ * @subsys EPUB_FIRMWARE_SP
+ * @reasoncode RC_ERC_MAX_EXCEEDED
+ * @moduleid MOD_ADD_UE_ADDR_RANGE
+ * @userdata1 current number of array entries
+ * @userdata2 maximum number of array entries
+ * @userdata3 none
+ * @userdata4 none
+ * @devdesc Exceeded limit of number of mainstore
+ * VPD In Memory Trace array entries
+ */
+ hdatBldErrLog(l_errlHndl,
+ MOD_ADD_UE_ADDR_RANGE, // SRC module ID
+ RC_ERC_MAX_EXCEEDED, // SRC extended reference code
+ iv_UEaddrRngArrayHdr.hdatArrayCnt, // SRC hex word 1
+ iv_maxUEAddrRngCnt); // SRC hex word 2
+ }
+
+ return l_errlHndl;
+}
+
+
+errlHndl_t HdatMsVpd::addRHBAddrRange(uint32_t i_dbob_id, hdatMsAddr_t &i_start,
+ hdatMsAddr_t &i_end, uint32_t i_labelSize,
+ uint8_t* &i_labelStringPtr)
+{
+ errlHndl_t l_errlHndl = NULL;
+ hdatMsVpdRhbAddrRange_t *l_addr;
+
+ if (iv_RHBaddrRngArrayHdr.hdatArrayCnt < iv_maxRHBAddrRngCnt)
+ {
+ l_addr = reinterpret_cast<hdatMsVpdRhbAddrRange_t*>(reinterpret_cast
+ <char*>(iv_RHBaddrRangeArray) + (iv_RHBaddrRngArrayHdr.hdatArrayCnt *
+ sizeof(hdatMsVpdRhbAddrRange_t)));
+
+ l_addr->hdatDbobID = i_dbob_id;
+ l_addr->hdatRhbAddrRngStrAddr = i_start;
+ l_addr->hdatRhbAddrRngEndAddr = i_end;
+ //TODO : : RTC Story 159684
+ //Need to verify the correct data for label size and string
+ if (i_labelSize <= HDAT_MS_RHB_LABEL_LEN)
+ {
+ l_addr->hdatRhbLabelSize = i_labelSize;
+ }
+ else
+ {
+ l_addr->hdatRhbLabelSize = HDAT_MS_RHB_LABEL_LEN;
+ }
+
+ memset(l_addr->hdatRhbLabelString, 0x00, HDAT_MS_RHB_LABEL_LEN);
+
+ if (i_labelStringPtr != NULL)
+ {
+ for(uint8_t l_idx = 0; l_idx < l_addr->hdatRhbLabelSize; l_idx++)
+ {
+ l_addr->hdatRhbLabelString[l_idx] = i_labelStringPtr[l_idx];
+ }
+ }
+ else
+ {
+ HDAT_INF("hdatmsvpd:addRHBAddrRange "
+ "i_labelStringPtr is NULL");
+ }
+ iv_RHBaddrRngArrayHdr.hdatArrayCnt++;
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @refcode LIC_REFCODE
+ * @subsys EPUB_FIRMWARE_SP
+ * @reasoncode RC_ERC_MAX_EXCEEDED
+ * @moduleid MOD_ADD_RES_HB_ADDR_RANGE
+ * @userdata1 current number of array entries
+ * @userdata2 maximum number of array entries
+ * @userdata3 none
+ * @userdata4 none
+ * @devdesc Exceeded limit of number of mainstore VPD Reserved
+ * Hostboot array entries
+ */
+ hdatBldErrLog(l_errlHndl,
+ MOD_ADD_RES_HB_ADDR_RANGE, // SRC module ID
+ RC_ERC_MAX_EXCEEDED, // SRC extended reference code
+ iv_RHBaddrRngArrayHdr.hdatArrayCnt, // SRC hex word 1
+ iv_maxRHBAddrRngCnt); // SRC hex word 2
+ }
+
+ return l_errlHndl;
+
+}
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+void HdatMsVpd::setBSR(const hdatMsAddr_t &i_bsrAddr,
+ hdatBsrMode i_bsrMode)
+{
+ const uint32_t HDAT_BSR_ENABLED = 0x20000000;
+
+ iv_mover.hdatFlags |= (HDAT_BSR_ENABLED | i_bsrMode);
+
+ memcpy(&iv_mover.hdatBSRAddr, &i_bsrAddr, sizeof(hdatMsAddr_t));
+
+ return;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+void HdatMsVpd::setXSCOM(const hdatMsAddr_t &i_xscomAddr)
+{
+
+ const uint32_t HDAT_XSCOM_ENABLED = 0x10000000;
+
+ iv_mover.hdatFlags |= HDAT_XSCOM_ENABLED;
+
+ memcpy(&iv_mover.hdatXSCOMAddr, &i_xscomAddr, sizeof(hdatMsAddr_t));
+
+ return;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+errlHndl_t HdatMsVpd::addMsAreaFru(uint32_t i_resourceId,
+ uint32_t i_slcaIndex,
+ TARGETING::Target * i_target,
+ uint16_t i_msAreaId,
+ uint32_t i_ramCnt,
+ uint32_t i_chipEcCnt,
+ uint32_t i_addrRngCnt)
+{
+ errlHndl_t l_errlHndl = NULL;
+ HdatMsArea *l_msArea, *l_prevMsArea, **l_arrayEntry;
+ uint32_t l_slcaIdx, l_kwdSize, l_resourceId, l_prevIdx;
+ char *l_kwd;
+
+ l_msArea = NULL;
+ l_kwd = NULL;
+ l_slcaIdx = i_slcaIndex;
+ l_kwdSize = 0;
+
+ // Ensure we are not over max mainstore areas that we were told this object
+ // could handle on the constructor.
+ if (iv_actMsAreaCnt < iv_maxMsAreaCnt)
+ {
+
+ // Determine if the resource ID associated with this mainstore area is
+ // the same as the resoruce id of the previous mainstore area.If it is,
+ // we can gain a performance advantage (translates into a smaller IPL
+ // time for the builddata step) by using the ASCII keyword data we
+ // already have rather than going to svpd to get it again.
+ if (iv_actMsAreaCnt > 0)
+ {
+ l_prevIdx = iv_actMsAreaCnt - 1;
+ l_prevMsArea = HDAT_MS_AREA(l_prevIdx);
+ l_prevMsArea->getKwdInfo(l_resourceId, l_slcaIdx, l_kwdSize, l_kwd);
+ if (l_resourceId != i_resourceId)
+ {
+ l_kwd = NULL;
+ l_slcaIdx = 0;
+ l_kwdSize = 0;
+ }
+ }
+
+ // Create a mainstore area object and add it to the array of objects we
+ // are managing
+ l_msArea = new HdatMsArea(l_errlHndl,
+ i_target,
+ i_msAreaId,
+ i_ramCnt,
+ i_chipEcCnt,
+ i_addrRngCnt,
+ i_resourceId,
+ l_slcaIdx,
+ l_kwdSize,
+ l_kwd);
+ if (NULL == l_errlHndl)
+ {
+ l_arrayEntry = reinterpret_cast<HdatMsArea**>(reinterpret_cast
+ <char*>(iv_msAreaPtrs) + iv_actMsAreaCnt * sizeof(HdatMsArea *));
+
+ *l_arrayEntry = l_msArea;
+ iv_actMsAreaCnt++;
+ }
+ else
+ {
+ delete l_msArea;
+ }
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @refcode LIC_REFCODE
+ * @subsys EPUB_FIRMWARE_SP
+ * @reasoncode RC_ERC_MAX_EXCEEDED
+ * @moduleid MOD_ADD_MS_AREA_FRU
+ * @userdata1 current array entry count
+ * @userdata2 maximum array entry count
+ * @userdata3 ID number of mainstore area that wasn't added
+ * @userdata4 none
+ * @devdesc Exceeded limit of number of mainstore area array entries
+ */
+ hdatBldErrLog(l_errlHndl,
+ MOD_ADD_MS_AREA_FRU, // SRC module ID
+ RC_ERC_MAX_EXCEEDED, // SRC extended reference code
+ iv_actMsAreaCnt, // SRC hex word 1
+ iv_maxMsAreaCnt, // SRC hex word 2
+ i_msAreaId); // SRC hex word 3
+ }
+
+ return l_errlHndl;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+void HdatMsVpd::setMsAreaType(uint16_t i_msAreaId,
+ hdatMemParentType i_type)
+{
+ HdatMsArea *l_obj;
+
+ if (i_msAreaId < iv_actMsAreaCnt)
+ {
+ l_obj = HDAT_MS_AREA(i_msAreaId);
+ l_obj->setParentType(i_type);
+ }
+
+ return;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+void HdatMsVpd::setMsAreaStat(uint16_t i_msAreaId,
+ uint16_t i_status)
+{
+
+ HdatMsArea *l_obj;
+
+ if (i_msAreaId < iv_actMsAreaCnt)
+ {
+ l_obj = HDAT_MS_AREA(i_msAreaId);
+ l_obj->setStatus(i_status);
+ }
+ else
+ {
+ HDAT_ERR( "hdatmsvpd:setMsAreaStat - invalid i_msAreadId parameter");
+ }
+
+ return;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+void HdatMsVpd::setMsAreaInterleavedId(uint16_t i_msAreaId,
+ uint16_t i_id)
+{
+ HdatMsArea *l_obj;
+
+ if (i_msAreaId < iv_actMsAreaCnt)
+ {
+ l_obj = HDAT_MS_AREA(i_msAreaId);
+ l_obj->setInterleavedId(i_id);
+ }
+ else
+ {
+ HDAT_ERR( "hdatmsvpd:setMsAreaInterleavedId-invalid i_msAreadId "
+ "parameter");
+ }
+
+ return;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+void HdatMsVpd::setMsAreaSize(uint16_t i_msAreaId,
+ uint32_t i_size)
+{
+ HdatMsArea *l_obj;
+
+ if (i_msAreaId < iv_actMsAreaCnt)
+ {
+ l_obj = HDAT_MS_AREA(i_msAreaId);
+ l_obj->setSize(i_size);
+ }
+ else
+ {
+ HDAT_ERR( "hdatmsvpd:setMsAreaSize - invalid i_msAreadId parameter");
+ }
+
+ return;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+void HdatMsVpd::setMsAreaModuleId(uint16_t i_msAreaId,
+ uint32_t i_moduleId)
+{
+ HdatMsArea *l_obj;
+
+ if (i_msAreaId < iv_actMsAreaCnt)
+ {
+ l_obj = HDAT_MS_AREA(i_msAreaId);
+ l_obj->setModuleId(i_moduleId);
+ }
+ else
+ {
+ HDAT_ERR( "hdatmsvpd:setMsAreaModuleId - invalid i_msAreadId"
+ " parameter");
+ }
+
+ return;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+void HdatMsVpd::setMsAreaAffinityDomain(uint16_t i_msAreaId,
+ uint32_t i_affinityDomain)
+{
+ HdatMsArea *l_obj;
+
+ if (i_msAreaId < iv_actMsAreaCnt)
+ {
+ l_obj = HDAT_MS_AREA(i_msAreaId);
+ l_obj->setAffinityDomain(i_affinityDomain);
+ }
+ else
+ {
+ HDAT_ERR("hdatmsvpd:setMsAreaAffinityDomain-invalid "
+ "i_msAreadId parameter");
+ }
+
+ return;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+errlHndl_t HdatMsVpd::addMsAreaAddr(uint16_t i_msAreaId,
+ hdatMsAddr_t &i_start,
+ hdatMsAddr_t &i_end,
+ uint32_t i_procChipId,
+ bool i_rangeIsMirrorable,
+ uint8_t i_mirroringAlgorithm,
+ uint64_t i_startMirrAddr)
+{
+ errlHndl_t l_errlHndl = NULL;
+ HdatMsArea *l_obj;
+ hdatMsAddr_t l_startMirrAddr;
+
+ memcpy(&l_startMirrAddr, &i_startMirrAddr, sizeof(hdatMsAddr_t));
+
+ if (i_msAreaId < iv_actMsAreaCnt)
+ {
+ l_obj = HDAT_MS_AREA(i_msAreaId);
+ l_errlHndl = l_obj->addAddrRange(i_start, i_end, i_procChipId,
+ i_rangeIsMirrorable, i_mirroringAlgorithm, l_startMirrAddr);
+ }
+ else
+ {
+ HDAT_INF( "hdatmsvpd:addMsAreaAddr - invalid i_msAreadId parameter");
+ }
+
+ return l_errlHndl;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+errlHndl_t HdatMsVpd::addEcEntry(uint16_t i_msAreaId,
+ uint32_t i_manfId,
+ uint32_t i_ecLvl)
+{
+ errlHndl_t l_errlHndl = NULL;
+ HdatMsArea *l_obj;
+
+ if (i_msAreaId < iv_actMsAreaCnt)
+ {
+ l_obj = HDAT_MS_AREA(i_msAreaId);
+ l_errlHndl = l_obj->addEcEntry(i_manfId, i_ecLvl);
+ }
+ else
+ {
+ HDAT_ERR( "hdatmsvpd:addEcEntry - invalid i_msAreadId parameter");
+ }
+
+ return l_errlHndl;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+errlHndl_t HdatMsVpd::addRamFru(uint16_t i_msAreaId,
+ TARGETING::Target * i_target,
+ uint32_t i_resourceId,
+ uint32_t i_slcaIndex,
+ uint16_t i_ramId,
+ uint16_t i_status,
+ uint32_t i_size)
+{
+ errlHndl_t l_errlHndl = NULL;
+
+ HdatMsArea *l_msArea;;
+ HdatRam *l_ram;
+
+ // Ensure we are not over the current mainstore area count
+ if (i_msAreaId < iv_actMsAreaCnt)
+ {
+ l_ram = NULL;
+ l_msArea = HDAT_MS_AREA(i_msAreaId);
+
+ // Create a RAM object
+ l_ram = new HdatRam(l_errlHndl, i_target, i_resourceId,i_slcaIndex);
+ if (NULL == l_errlHndl)
+ {
+ l_ram->iv_ramArea.hdatRamAreaId = i_ramId;
+ l_ram->iv_ramArea.hdatRamStatus = i_status;
+ l_ram->iv_ramSize.hdatRamTotalSize = i_size;
+
+ // Add the RAM object to the mainstore area object
+ if (l_msArea)
+ {
+ l_errlHndl = l_msArea->addRam(*l_ram);
+ }
+ }
+
+ if (NULL != l_errlHndl)
+ {
+ delete l_ram;
+ }
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @refcode LIC_REFCODE
+ * @subsys EPUB_FIRMWARE_SP
+ * @reasoncode RC_ERC_NO_PARENT
+ * @moduleid MOD_ADD_RAM_FRU
+ * @userdata1 main store area id
+ * @userdata2 current count of main store areas
+ * @userdata3 none
+ * @userdata4 none
+ * @devdesc Attempted to add a RAM FRU for an invalid mainstore area
+ */
+ HDAT_INF("Attempted to add a RAM FRU for an invalid mainstore area %d",
+ i_msAreaId);
+
+ hdatBldErrLog(l_errlHndl,
+ MOD_ADD_RAM_FRU, // SRC module ID
+ RC_ERC_NO_PARENT, // SRC extended reference code
+ i_msAreaId, // SRC hex word 1
+ iv_actMsAreaCnt); // SRC hex word 2
+ }
+
+ return l_errlHndl;
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+void HdatMsVpd::adjustMsAreaObjects()
+{
+ HdatMsArea *l_msEntry;
+ uint32_t l_idx, l_maxSize, l_tempSize;
+ bool l_adjust;
+
+ l_maxSize = 0;
+ l_adjust = false;
+
+ // Finalize the object size for each MS area object. Also, determine if
+ // the objects differ in size. If they do, an extra step is needed to make
+ // them all the same size.
+ for (l_idx = 0; l_idx < iv_actMsAreaCnt; l_idx++)
+ {
+ l_msEntry = *(reinterpret_cast<HdatMsArea**>(reinterpret_cast
+ <char*>(iv_msAreaPtrs) + l_idx * sizeof(HdatMsArea *)));
+
+ l_msEntry->finalizeObjSize(); // Get the MS area sizes updated before
+ // size() method is used
+ l_tempSize = l_msEntry->size();
+ if (l_maxSize != l_tempSize)
+ {
+ if (l_maxSize != 0)
+ {
+ l_adjust = true;
+ }
+ if (l_maxSize < l_tempSize)
+ {
+ l_maxSize = l_tempSize;
+ }
+ }
+ }
+
+ // Do we need to adjust some of the MS area objects to make them all the
+ // same size?
+ if (l_adjust)
+ {
+ for (l_idx = 0; l_idx < iv_actMsAreaCnt; l_idx++)
+ {
+ l_msEntry = *(reinterpret_cast<HdatMsArea**>(reinterpret_cast
+ <char*>(iv_msAreaPtrs) + l_idx * sizeof(HdatMsArea *)));
+
+ // If too small, adjust its size
+ if (l_msEntry->size() < l_maxSize)
+ {
+ l_msEntry->maxSiblingSize(l_maxSize);
+ }
+ }
+ }
+
+ // Tell the base class about child and grandchild structures.
+ for (l_idx = 0; l_idx < iv_actMsAreaCnt; l_idx++)
+ {
+ l_msEntry = *(reinterpret_cast<HdatMsArea**>(reinterpret_cast
+ <char*>(iv_msAreaPtrs) + l_idx * sizeof(HdatMsArea *)));
+
+ this->addChild(HDAT_MS_AREAS, l_msEntry->size(),1);//1st parm is 0 based
+ this->addGrandChild(l_msEntry->ramObjSizes());
+ }
+
+ return;
+}
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+void HdatMsVpd::getTotalSize(uint32_t &o_size)
+{
+
+ HdatMsArea *l_msEntry;
+ // Since MS area objects could be different sizes at this point (different
+ // size for the VPD, for example) and since PHYP traverses the MS areas
+ // as an array, we may need to adjust the MS areas so they are all the same
+ // size.
+ this->adjustMsAreaObjects();
+
+ o_size = this->getSize();
+
+ o_size += sizeof(hdatMsVpdAddr_t);
+
+ o_size += sizeof(hdatMsVpdSize_t);
+
+ o_size += sizeof(hdatMsVpdPageMover_t);
+
+ o_size += sizeof(hdatHDIFDataArray_t);
+
+ o_size += (iv_maxIMTAddrRngCnt * sizeof(hdatMsVpdImtAddrRange_t));
+
+ o_size += sizeof(hdatHDIFDataArray_t);
+
+ o_size += (iv_maxUEAddrRngCnt * sizeof(hdatMsVpdUEAddrRange_t));
+
+ o_size += sizeof(hdatHDIFDataArray_t);
+
+ o_size += (iv_maxRHBAddrRngCnt * sizeof(hdatMsVpdRhbAddrRange_t));
+
+ o_size += this->endCommitSize();
+
+ // Write the MS area structures and RAM structures
+ if (iv_actMsAreaCnt > 0)
+ {
+ // All of the mainstore areas must be written first so that can be
+ // processed as an array of mainstore areas.
+ uint32_t l_ramSizes = 0;
+ uint8_t l_cnt = 0;
+ uint8_t l_currOffset = 0;
+
+ while (l_cnt < iv_actMsAreaCnt)
+ {
+ l_msEntry = *(reinterpret_cast<HdatMsArea**>(reinterpret_cast
+ <char*>(iv_msAreaPtrs) + l_cnt * sizeof(HdatMsArea *)));
+
+ // Since we don't know what order mainstore areas and RAM
+ // areas were created, update the offset in the HdatMsArea
+ // child structure triple so it points to the first RAM area.
+
+ l_currOffset = (iv_actMsAreaCnt - l_cnt) * l_msEntry->size()
+ + l_ramSizes;
+ l_msEntry->chgChildOffset(HDAT_MS_AREA_RAM_AREAS, l_currOffset);
+ o_size += l_msEntry->getMsAreaSize();
+
+ // Now compute the size of the RAM areas associated with this
+ // mainstore area. These will have to be added to the child offset
+ // for the next mainstore area to skip over them.
+ l_ramSizes += l_msEntry->ramObjSizes();
+
+ l_cnt++;
+ }
+
+ // Now the children (RAM areas) of each mainstore area must be committed
+ l_cnt = 0;
+
+ while (l_cnt < iv_actMsAreaCnt)
+ {
+ l_msEntry = *(reinterpret_cast<HdatMsArea**>(reinterpret_cast
+ <char*>(iv_msAreaPtrs) + l_cnt * sizeof(HdatMsArea *)));
+
+ o_size += l_msEntry->getRamAreaSize();
+ l_cnt++;
+ }
+ }
+
+}
+
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+void HdatMsVpd::prt()
+{
+ uint32_t l_cnt;
+ HdatMsArea *l_obj;
+
+ HDAT_INF(" **** HdatMsVpd start ****");
+ HDAT_INF(" iv_msAddr = 0X %08X %08X ", iv_msAddr.hi, iv_msAddr.lo);
+ HDAT_INF(" iv_actMsAreaCnt = %u", iv_actMsAreaCnt);
+ HDAT_INF(" iv_maxMsAreaCnt = %u", iv_maxMsAreaCnt);
+ this->print();
+
+ HDAT_INF(" **hdatMsVpdAddr_t**");
+ HDAT_INF(" hdatMaxAddr = 0X %08X %08X ", iv_maxAddr.hdatMaxAddr.hi,
+ iv_maxAddr.hdatMaxAddr.lo);
+ HDAT_INF(" hdatMaxCcmAddr = 0X %08X %08X ", iv_maxAddr.hdatMaxCcmAddr.hi,
+ iv_maxAddr.hdatMaxCcmAddr.lo);
+ HDAT_INF(" hdatMstSigAffntyDom = 0X %08X ", iv_maxAddr.hdatMstSigAffntyDom);
+
+ HDAT_INF(" **hdatMsVpdSize_t**");
+ HDAT_INF(" hdatReserved1 = %u", iv_maxSize.hdatReserved1);
+ HDAT_INF(" hdatTotSize = %u", iv_maxSize.hdatTotSize);
+
+ HDAT_INF(" **hdatMsVpdPageMover_t**");
+ HDAT_INF(" hdatFlags = %u", iv_mover.hdatFlags);
+ HDAT_INF(" hdatLockCnt = %u", iv_mover.hdatLockCnt);
+ HDAT_INF(" hdatLockAddr = 0X %08X %08X ", iv_mover.hdatLockAddr.hi,
+ iv_mover.hdatLockAddr.lo);
+ HDAT_INF(" hdatMoverAddr = 0X %08X %08X ", iv_mover.hdatMoverAddr.hi,
+ iv_mover.hdatMoverAddr.lo);
+ HDAT_INF(" hdatBSRAddr = 0X %08X %08X ", iv_mover.hdatBSRAddr.hi,
+ iv_mover.hdatBSRAddr.lo);
+
+ HDAT_INF(" **hdatMsVpdImtAddrRange_t**");
+ hdatPrintHdrs(NULL, NULL, &iv_IMTaddrRngArrayHdr, NULL);
+{
+ hdatMsVpdImtAddrRange_t *l_addr = iv_IMTaddrRangeArray;
+ for (l_cnt = 0; l_cnt < iv_IMTaddrRngArrayHdr.hdatArrayCnt; l_cnt++)
+ {
+ HDAT_INF(" hdatImtAddrRngStrAddr = 0X %08X %08X ",
+ l_addr->hdatImtAddrRngStrAddr.hi,
+ l_addr->hdatImtAddrRngStrAddr.lo);
+ HDAT_INF(" hdatImtAddrRngEndAddr = 0X %08X %08X ",
+ l_addr->hdatImtAddrRngEndAddr.hi,
+ l_addr->hdatImtAddrRngEndAddr.lo);
+ l_addr++;
+ l_cnt++;
+ }
+}
+ HDAT_INF(" **hdatMsVpdUEAddrRange_t**");
+ hdatPrintHdrs(NULL, NULL, &iv_UEaddrRngArrayHdr, NULL);
+ {
+ hdatMsVpdUEAddrRange_t *l_addr = iv_UEaddrRangeArray;
+ for (l_cnt = 0; l_cnt < iv_UEaddrRngArrayHdr.hdatArrayCnt; l_cnt++)
+ {
+ HDAT_INF(" hdatUEAddrRngStrAddr = 0X %08X %08X ",
+ l_addr->hdatUEAddr.hi,
+ l_addr->hdatUEAddr.lo);
+ l_addr++;
+ l_cnt++;
+ }
+ }
+ HDAT_INF(" **hdatMsVpdRhbAddrRange_t**");
+ hdatPrintHdrs(NULL, NULL, &iv_RHBaddrRngArrayHdr, NULL);
+ {
+ hdatMsVpdRhbAddrRange_t *l_addr = iv_RHBaddrRangeArray;
+ for (l_cnt = 0; l_cnt < iv_RHBaddrRngArrayHdr.hdatArrayCnt; l_cnt++)
+ {
+ HDAT_INF(" hdatRhbAddrRngStrAddr = 0X %08X %08X ",
+ l_addr->hdatRhbAddrRngStrAddr.hi,
+ l_addr->hdatRhbAddrRngStrAddr.lo);
+ HDAT_INF(" hdatRhbAddrRngEndAddr = 0X %08X %08X ",
+ l_addr->hdatRhbAddrRngEndAddr.hi,
+ l_addr->hdatRhbAddrRngEndAddr.lo);
+ l_addr++;
+ l_cnt++;
+ }
+
+ }
+ HDAT_INF("");;
+
+ HDAT_INF(" **** HdatMsVpd end ****");
+
+ HDAT_INF(" **main store areas and their associated RAM areas**");
+ for (l_cnt = 0; l_cnt < iv_actMsAreaCnt; l_cnt++)
+ {
+ l_obj = *(HdatMsArea **)((char *)iv_msAreaPtrs + l_cnt *
+ sizeof(HdatMsArea *));
+ l_obj->prt();
+ }
+
+ return;
+}
+
+
+
+
+/*******************************************************************************
+* hdatLoadMsData
+*******************************************************************************/
+errlHndl_t HdatMsVpd::hdatLoadMsData(uint32_t &o_size, uint32_t &o_count)
+{
+ errlHndl_t l_err = NULL;
+ HDAT_ENTER();
+
+ do
+ {
+ //Find the system target
+ TARGETING::Target *l_pSysTarget = NULL;
+ (void) TARGETING::targetService().getTopLevelTarget(l_pSysTarget);
+
+ assert(l_pSysTarget != NULL);
+
+ hdatMsAddr_t l_addr_range;
+ hdatMsAddr_t l_end;
+ l_addr_range.hi = 0x0;
+ l_addr_range.lo = 0x0;
+ l_end = l_addr_range;
+
+ uint32_t l_sizeConfigured = 0;
+ uint64_t l_maxMsAddr = hdatGetMaxMemConfiguredAddress();
+
+ hdatMsAddr_t l_tmpMaxMsAddr;
+ l_tmpMaxMsAddr.hi = (l_maxMsAddr & 0xFFFFFFFF00000000ull) >> 32;
+ l_tmpMaxMsAddr.lo = l_maxMsAddr & 0x00000000FFFFFFFFull;
+
+ HDAT_INF("MaxMsAddr high:0x%.8X 0x%.8X",
+ l_tmpMaxMsAddr.hi,l_tmpMaxMsAddr.lo);
+
+ uint32_t l_mostSigAffinityDomain_x = 0;
+ uint32_t l_ueCount = 1;
+
+ TARGETING::ATTR_MIRROR_BASE_ADDRESS_type l_mirroringBaseAddress_x =
+ l_pSysTarget->getAttr<TARGETING::ATTR_MIRROR_BASE_ADDRESS>();
+ l_mirroringBaseAddress_x |= HDAT_REAL_ADDRESS_MASK64;
+
+ TARGETING::ATTR_MAX_MCS_PER_SYSTEM_type l_maxMsAreas =
+ l_pSysTarget->getAttr<TARGETING::ATTR_MAX_MCS_PER_SYSTEM>();
+
+ // Initialize the MS vpd class
+ hdatInit(l_tmpMaxMsAddr,l_tmpMaxMsAddr,l_sizeConfigured,l_maxMsAreas,
+ l_mostSigAffinityDomain_x,l_ueCount,l_mirroringBaseAddress_x);
+
+ TARGETING::ATTR_XSCOM_BASE_ADDRESS_type l_xscomAddr =
+ l_pSysTarget->getAttr<TARGETING::ATTR_XSCOM_BASE_ADDRESS>();
+ assert(l_xscomAddr != 0);
+ {
+ hdatMsAddr_t l_hdatXscomAddr;
+ l_hdatXscomAddr.hi = (l_xscomAddr & 0xFFFFFFFF00000000ull) >> 32;
+ l_hdatXscomAddr.lo = l_xscomAddr & 0x00000000FFFFFFFFull;
+
+ l_hdatXscomAddr.hi |= HDAT_REAL_ADDRESS_MASK;
+
+ setXSCOM(l_hdatXscomAddr);
+ }
+
+ uint32_t l_index = 0;
+ //for each proc/ memory controller in the system
+ TARGETING::PredicateCTM l_procPred(TARGETING::CLASS_CHIP,
+ TARGETING::TYPE_PROC);
+ TARGETING::PredicateHwas l_predHwasPresent;
+ l_predHwasPresent.present(true);
+ TARGETING::PredicateHwas l_predHwasFunc;
+ l_predHwasFunc.functional(true);
+ TARGETING::PredicatePostfixExpr l_funcProc;
+ l_funcProc.push(&l_procPred).push(&l_predHwasFunc).And();
+
+ TARGETING::TargetRangeFilter l_procs(
+ TARGETING::targetService().begin(),
+ TARGETING::targetService().end(),
+ &l_funcProc);
+
+ uint32_t l_nxtSharingGroupId = 0;
+
+ for(;l_procs;++l_procs)
+ {
+ TARGETING::Target *l_pProcTarget = *(l_procs);
+ TARGETING::ATTR_ORDINAL_ID_type l_procChipId
+ = l_pProcTarget->getAttr<TARGETING::ATTR_ORDINAL_ID>();
+
+ // TODO : RTC Story 159682
+ // Further CHTM support needs to be added which contains the trace
+ // array for 24 cores
+ hdatMsAddr_t l_hdatNhtmStartAddr;
+ hdatMsAddr_t l_hdatNhtmEndAddr;
+
+ TARGETING::ATTR_PROC_NHTM_BAR_BASE_ADDR_type l_nhtmStartAddr =
+ l_pProcTarget->getAttr<TARGETING::ATTR_PROC_NHTM_BAR_BASE_ADDR>();
+ TARGETING::ATTR_PROC_NHTM_BAR_SIZE_type l_nhtmSize =
+ l_pProcTarget->getAttr<TARGETING::ATTR_PROC_NHTM_BAR_SIZE>();
+
+ if( 0 != l_nhtmSize )
+ {
+ l_hdatNhtmStartAddr.hi =
+ (l_nhtmStartAddr & 0xFFFFFFFF00000000ull) >> 32;
+ l_hdatNhtmStartAddr.lo =
+ l_nhtmStartAddr & 0x00000000FFFFFFFFull;
+ l_hdatNhtmStartAddr.hi |= HDAT_REAL_ADDRESS_MASK;
+
+ l_nhtmSize = l_nhtmStartAddr + l_nhtmSize;
+ l_hdatNhtmEndAddr.hi =
+ (l_nhtmSize & 0xFFFFFFFF00000000ull) >> 32;
+ l_hdatNhtmEndAddr.lo = l_nhtmSize & 0x00000000FFFFFFFFull;
+ l_hdatNhtmEndAddr.hi |= HDAT_REAL_ADDRESS_MASK;
+
+ HDAT_INF("hdatNhtmStartAddr = 0x%08X 0x%08X ",
+ l_hdatNhtmStartAddr.hi, l_hdatNhtmStartAddr.lo);
+ HDAT_INF("hdatNhtmEndAddr = 0x%08X 0x%08X ",
+ l_hdatNhtmEndAddr.hi, l_hdatNhtmEndAddr.lo);
+
+ addIMTAddrRange(l_hdatNhtmStartAddr, l_hdatNhtmEndAddr);
+ }
+ else
+ {
+ HDAT_INF("NHTM Bar size value = 0x%016llX",
+ l_nhtmSize);
+ }
+
+ TARGETING::ATTR_PROC_MEM_BASES_type l_procMemBases = {0};
+ assert(l_pProcTarget->
+ tryGetAttr<TARGETING::ATTR_PROC_MEM_BASES>(l_procMemBases));
+
+ //Sharing count for each group
+ TARGETING::ATTR_MSS_MEM_MC_IN_GROUP_type l_mcsSharingCount = {0};
+
+ //Group ID for each group, group id will be assigned only
+ //if the group is shared
+ TARGETING::ATTR_MSS_MEM_MC_IN_GROUP_type l_mcsSharingGrpIds = {0};
+
+ //Size configured under each group
+ TARGETING::ATTR_PROC_MEM_SIZES_type l_procMemSizesBytes = {0};
+
+ assert(l_pProcTarget->tryGetAttr<TARGETING::ATTR_PROC_MEM_SIZES>
+ (l_procMemSizesBytes));
+
+ TARGETING::PredicateCTM l_mcbistPredicate(TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MCBIST);
+
+ TARGETING::PredicatePostfixExpr l_presentMcbist;
+ l_presentMcbist.push(&l_mcbistPredicate).
+ push(&l_predHwasFunc).And();
+
+ TARGETING::TargetHandleList l_mcbistList;
+
+ // Find Associated MCBIST list
+ TARGETING::targetService().getAssociated(l_mcbistList,
+ l_pProcTarget,
+ TARGETING::TargetService::CHILD_BY_AFFINITY,
+ TARGETING::TargetService::ALL,
+ &l_presentMcbist);
+
+ //scan all mcbist in this proc
+ for(uint32_t l_mcbistIdx =0;
+ l_mcbistIdx < l_mcbistList.size();
+ ++l_mcbistIdx)
+ {
+ TARGETING::Target *l_pMcbistTarget = l_mcbistList[l_mcbistIdx];
+
+ TARGETING::PredicateCTM l_mcsPredicate(TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MCS);
+
+ TARGETING::PredicatePostfixExpr l_funcMcs;
+ l_funcMcs.push(&l_mcsPredicate).push(&l_predHwasFunc).And();
+
+ TARGETING::TargetHandleList l_mcsList;
+
+ // Find Associated memory controllers
+ TARGETING::targetService().getAssociated(l_mcsList,
+ l_pMcbistTarget,
+ TARGETING::TargetService::CHILD,
+ TARGETING::TargetService::ALL,
+ &l_funcMcs);
+
+ //scan all mcs in this proc to get sharing counit
+ for(uint32_t l_idx = 0; l_idx<l_mcsList.size(); ++l_idx)
+ {
+ TARGETING::Target *l_pMcsTarget = l_mcsList[l_idx];
+
+ uint32_t l_mcsInGrp = 0;
+ if(!hdatFindGroupForMc(l_pProcTarget,
+ l_pMcsTarget,
+ l_mcsInGrp))
+ {
+ //Skip this MCS is not in any group
+ continue;
+ }
+
+ //Increment sharing count if mem configured under group.
+ if(l_procMemSizesBytes[l_mcsInGrp] > 0)
+ {
+ l_mcsSharingCount[l_mcsInGrp]++;
+
+ //Assign sharing group id only if shared
+ //And only when first instance of sharing is found
+ if(l_mcsSharingCount[l_mcsInGrp] ==
+ HDAT_MIN_NUM_FOR_SHARING)
+ {
+ l_mcsSharingGrpIds[l_mcsInGrp] =
+ l_nxtSharingGroupId;
+ l_nxtSharingGroupId++;
+ }
+ }
+ }
+
+ for(uint32_t l_mcsIdx = 0; l_mcsIdx<l_mcsList.size();
+ ++l_mcsIdx)
+ {
+ TARGETING::Target *l_pMcsTarget =
+ l_mcsList[l_mcsIdx];
+
+ //Group which this MCS is belonging
+ uint32_t l_mcsInGrp = 0;
+
+ if(!hdatFindGroupForMc(l_pProcTarget,
+ l_pMcsTarget,
+ l_mcsInGrp))
+ {
+ HDAT_INF("No group found for MCS");
+ //Skip this MCS is not under any group
+ continue;
+ }
+
+ uint32_t l_mcaFruId = 0;
+ hdatMemParentType l_parentType = HDAT_MEM_PARENT_CEC_FRU;
+
+ std::list<hdatRamArea> l_areas;
+ l_areas.clear();
+ uint32_t l_areaSizeInMB = 0;
+ bool l_areaFunctional = false;
+ uint32_t l_numDimms =0;
+
+ l_err = hdatScanDimms(l_pMcsTarget,
+ l_mcaFruId,
+ l_areas,
+ l_areaSizeInMB,
+ l_numDimms,
+ l_areaFunctional,
+ l_parentType);
+
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in calling Scan Dimms");
+ break;
+ }
+
+ HDAT_INF("l_areaSizeInMB:0x%.8X l_numDimms:0x%.8X"
+ " l_areas.size():0x%.8X", l_areaSizeInMB, l_numDimms,
+ l_areas.size());
+
+ //Skip if no memory configured under this MCS
+ if(l_areaSizeInMB == 0)
+ {
+ continue;
+ }
+
+ uint32_t l_maxMemBlocks = 0;
+ l_err = hdatGetMaxMemoryBlocks(l_pMcsTarget,l_maxMemBlocks);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error error in get max blocks");
+ break;
+ }
+
+ TARGETING::ATTR_SLCA_RID_type l_procRid =
+ l_pProcTarget->getAttr<TARGETING::ATTR_SLCA_RID>();
+
+ TARGETING::ATTR_SLCA_INDEX_type l_procSlcaIndex =
+ l_pProcTarget->getAttr<TARGETING::ATTR_SLCA_INDEX>();
+
+ l_err = addMsAreaFru(l_procRid,
+ l_procSlcaIndex,
+ l_pProcTarget,
+ l_index,
+ l_numDimms,
+ MAX_CHIP_EC_CNT_PER_MSAREA,
+ l_maxMemBlocks);
+
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error adding MSArea %d"
+ "Number of Dimms: %d Max Blocks: %d",
+ l_index,
+ l_numDimms,l_maxMemBlocks);
+ break;
+ }
+
+ uint32_t l_memStatus = 0;
+ //If group is shared with more than one area
+ if(l_mcsSharingCount[l_mcsInGrp] >=
+ HDAT_MIN_NUM_FOR_SHARING)
+ {
+ l_memStatus = HDAT_MEM_SHARED;
+ setMsAreaInterleavedId(l_index,
+ l_mcsSharingGrpIds[l_mcsInGrp]);
+ }
+
+ setMsAreaType(l_index,l_parentType);
+ setMsAreaSize(l_index,l_areaSizeInMB);
+
+ iv_maxSize.hdatTotSize += l_areaSizeInMB;
+
+ l_memStatus |= l_areaFunctional ?
+ (HDAT_MEM_INSTALLED | HDAT_MEM_FUNCTIONAL) :
+ HDAT_MEM_INSTALLED;
+
+ setMsAreaStat(l_index, l_memStatus);
+
+ //Add MCS ec level
+ uint32_t l_mcsEcLevel = 0;
+ uint32_t l_mcsChipId = 0;
+ l_err = hdatGetIdEc(l_pMcsTarget,
+ l_mcsEcLevel,
+ l_mcsChipId);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in getting MCS ID "
+ "and EC HUID:[0x%08X]",
+ l_pMcsTarget->getAttr<TARGETING::ATTR_HUID>());
+ break;
+ }
+
+ l_err = addEcEntry(l_index,
+ l_mcsChipId,
+ l_mcsEcLevel);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in adding"
+ " ID[0x%08X] and EC[0x%08X] to ms area"
+ " HUID:[0x%08X]",l_mcsChipId,
+ l_mcsEcLevel,
+ l_pMcsTarget->getAttr<TARGETING::ATTR_HUID>());
+ break;
+ }
+
+ std::list<hdatRamArea>::iterator l_area = l_areas.begin();
+
+ for (uint32_t l_ramId = 0;
+ l_area != l_areas.end();
+ ++l_ramId, ++l_area)
+ {
+ uint32_t l_status = (l_area)->ivFunctional ?
+ (HDAT_RAM_INSTALLED | HDAT_RAM_FUNCTIONAL)
+ : HDAT_RAM_INSTALLED;
+
+ TARGETING::Target *l_pDimmTarget =
+ TARGETING::Target::getTargetFromHuid(l_area->ivHuid);
+
+ TARGETING::ATTR_SLCA_RID_type l_dimmRid =
+ l_pDimmTarget->getAttr<TARGETING::ATTR_SLCA_RID>();
+
+ TARGETING::ATTR_SLCA_INDEX_type l_dimmSlcaIndex =
+ l_pDimmTarget->getAttr<TARGETING::ATTR_SLCA_INDEX>();
+
+ l_err = addRamFru(l_index,
+ l_pDimmTarget,
+ l_dimmRid,
+ l_dimmSlcaIndex,
+ l_ramId,
+ l_status,
+ (l_area)->ivSize);
+
+ if (l_err) // Failed to add ram fru information
+ {
+ HDAT_ERR("Error in adding RAM FRU"
+ "Index:%d Rid:[0x%08X] status:[0x%08X]"
+ "Size:[0x%08X] RamID:[0x%08X]",
+ l_index,(l_area)->ivHuid,
+ l_status,(l_area)->ivSize,l_ramId);
+ ERRORLOG::errlCommit(l_err,HDAT_COMP_ID);
+
+ delete l_err;
+ l_err = NULL;
+ continue;
+ }
+ }//end of RAM list
+
+ l_addr_range.hi = (l_procMemBases[l_mcsInGrp] &
+ 0xFFFFFFFF00000000ull) >> 32;
+ l_addr_range.lo = l_procMemBases[l_mcsInGrp] &
+ 0x00000000FFFFFFFFull;
+
+ l_end = l_addr_range;
+
+ //Update the range
+ l_end.hi += (l_procMemSizesBytes[l_mcsInGrp] &
+ 0xFFFFFFFF00000000ull) >> 32;
+ l_end.lo += l_procMemSizesBytes[l_mcsInGrp] &
+ 0x00000000FFFFFFFFull;
+
+ HDAT_INF("MCS:0x%08X l_addr_range:0x%08X 0x%08X"
+ " l_end:0x%08X 0x%08X",
+ l_pMcsTarget->getAttr<TARGETING::ATTR_HUID>(),
+ l_addr_range.hi, l_addr_range.lo,
+ l_end.hi,l_end.lo);
+
+ uint64_t l_hdatMirrorAddr_x = 0x0ull;
+ uint64_t l_hdatMirrorAddr = 0x0ull;
+ uint8_t l_hdatMirrorAlogrithm = 0xFF;
+ bool l_rangeIsMirrorable = false;
+
+ TARGETING::ATTR_PROC_MIRROR_BASES_type l_MirrorAddr = {0};
+ assert(l_pProcTarget->tryGetAttr<
+ TARGETING::ATTR_PROC_MIRROR_BASES>(l_MirrorAddr));
+
+ TARGETING::ATTR_PROC_MIRROR_SIZES_type l_MirrorSize = {0};
+ assert(l_pProcTarget->tryGetAttr<
+ TARGETING::ATTR_PROC_MIRROR_SIZES>(l_MirrorSize));
+
+ TARGETING::ATTR_MIRROR_BASE_ADDRESS_type l_mirrorBaseAddress_x =
+ l_pSysTarget->getAttr<TARGETING::ATTR_MIRROR_BASE_ADDRESS>();
+
+ uint64_t l_startAddr = (((uint64_t)(l_addr_range.hi) << 32 )
+ | (uint64_t)(l_addr_range.lo));
+ l_hdatMirrorAddr_x = (l_startAddr / 2) + l_mirrorBaseAddress_x;
+
+ TARGETING::ATTR_PAYLOAD_IN_MIRROR_MEM_type l_payLoadMirrorMem =
+ l_pSysTarget->getAttr<TARGETING::ATTR_PAYLOAD_IN_MIRROR_MEM>();
+
+ HDAT_INF(
+ "Start add : 0x%016llX MirrorBase : 0x%016llX"
+ " MirrorAddr : 0x%016llX PayLoadMirrorMem : 0x%X",
+ l_startAddr, l_mirrorBaseAddress_x,
+ l_hdatMirrorAddr_x, l_payLoadMirrorMem);
+
+ if ( 0 != l_payLoadMirrorMem )
+ {
+ for ( int idx=0 ; idx <
+ (int)(sizeof(TARGETING::ATTR_PROC_MIRROR_SIZES_type)
+ / sizeof(uint64_t)) ; idx++ )
+ {
+ HDAT_INF("Mirror size : 0x%016llX"
+ " MirrorAddr[idx] : 0x%016llX"
+ " hdatMirrorAddr_x : 0x%016llX",
+ l_MirrorSize[idx], l_MirrorAddr[idx],
+ l_hdatMirrorAddr_x);
+
+ if( (0 != l_MirrorSize[idx]) &&
+ (l_MirrorAddr[idx] == l_hdatMirrorAddr_x) )
+ {
+ l_rangeIsMirrorable = true;
+ l_hdatMirrorAddr = l_MirrorAddr[idx]
+ | HDAT_REAL_ADDRESS_MASK64;
+ break;
+ }
+ }
+ }
+ l_err = addMsAreaAddr(l_index,
+ l_addr_range,
+ l_end,
+ l_procChipId,
+ l_rangeIsMirrorable,
+ l_hdatMirrorAlogrithm,
+ l_hdatMirrorAddr);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in adding addMsAreaAddr"
+ " to ms area index[%d]",
+ l_index);
+ break;
+ }
+
+ // TODO : RTC Story 159682
+ // Further CHTM support needs to be added which contains the
+ // trace array for 24 cores
+ // Reinitializing the NHTM size
+ l_nhtmSize =
+ l_pProcTarget->getAttr
+ <TARGETING::ATTR_PROC_NHTM_BAR_SIZE>();
+
+ uint64_t l_end_addr =
+ (((uint64_t)(l_end.hi) << 32 ) | (uint64_t)(l_end.lo));
+ uint64_t l_start_addr = (((uint64_t)(l_addr_range.hi) << 32 )
+ | (uint64_t)(l_addr_range.lo));
+ uint64_t l_size_bytes = (l_areaSizeInMB) * 1024 * 1024;
+
+ if((0 != l_nhtmSize) &&
+ (l_size_bytes != (l_end_addr - l_start_addr)))
+ {
+ HDAT_INF("NHTM Bar size = 0x%016llX "
+ " MS area size = 0x%016llX"
+ " l_end_addr = 0x%016llX"
+ " l_start_addr = 0x%016llX",
+ l_nhtmSize,l_size_bytes, l_end_addr, l_start_addr);
+
+ l_addr_range.lo = l_hdatNhtmStartAddr.lo;
+ l_addr_range.hi = l_hdatNhtmStartAddr.hi;
+
+ l_end.lo = l_hdatNhtmEndAddr.lo;
+ l_end.hi = l_hdatNhtmEndAddr.hi;
+
+ l_err = addMsAreaAddr(l_index,
+ l_addr_range,
+ l_end,
+ l_procChipId,
+ false, 0, 0);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in adding "
+ " addMsAreaAddr to ms area index[%d]",
+ l_index);
+ break;
+ }
+ l_nhtmSize=0; //only add 1 entry
+ }
+ l_addr_range = l_end;
+ l_index++;
+ } //end of MCS list
+ } //end of MCBIST list
+ if(l_err)
+ {
+ // Error message recorded above
+ break;
+ }
+ } //end of proc list
+
+ TARGETING::PredicateCTM l_nodePred(TARGETING::CLASS_ENC,
+ TARGETING::TYPE_NODE);
+ TARGETING::PredicateHwas l_predFunctional;
+ l_predFunctional.functional(true);
+ TARGETING::PredicatePostfixExpr l_functionalnode;
+ l_functionalnode.push(&l_nodePred).push(&l_predFunctional).And();
+
+ TARGETING::TargetRangeFilter l_nodes(TARGETING::targetService().begin(),
+ TARGETING::targetService().end(),
+ &l_functionalnode);
+
+ TARGETING::ATTR_HB_RSV_MEM_SIZE_MB_type l_rhbSize =
+ l_pSysTarget->getAttr<TARGETING::ATTR_HB_RSV_MEM_SIZE_MB>();
+ if( 0 != l_rhbSize )
+ {
+ for(;l_nodes;++l_nodes)
+ {
+ TARGETING::ATTR_HB_HRMOR_NODAL_BASE_type l_rhbStartAddr =
+ l_pSysTarget->getAttr<TARGETING::ATTR_HB_HRMOR_NODAL_BASE>();
+
+ TARGETING::Target *l_pNodeTarget = *(l_nodes);
+ uint32_t l_dbobId =
+ l_pNodeTarget->getAttr<TARGETING::ATTR_ORDINAL_ID>();
+
+ hdatMsAddr_t l_hdatRhbStartAddr;
+ hdatMsAddr_t l_hdatRhbEndAddr;
+
+ l_rhbStartAddr = l_rhbStartAddr * l_dbobId;
+ l_hdatRhbStartAddr.hi =
+ (l_rhbStartAddr & 0xFFFFFFFF00000000ull) >> 32;
+ l_hdatRhbStartAddr.lo = l_rhbStartAddr & 0x00000000FFFFFFFFull;
+ l_hdatRhbStartAddr.hi |= HDAT_REAL_ADDRESS_MASK;
+
+ // need to store a 64 bit range
+ uint64_t l_hbSize=0;
+ // in bytes
+ uint64_t l_size_bytes = (l_rhbSize * 1024 * 1024) -1;
+ l_hbSize = l_rhbStartAddr + l_size_bytes;
+ l_hdatRhbEndAddr.hi = (l_hbSize & 0xFFFFFFFF00000000ull) >> 32;
+ l_hdatRhbEndAddr.lo = l_hbSize & 0x00000000FFFFFFFFull;
+ l_hdatRhbEndAddr.hi |= HDAT_REAL_ADDRESS_MASK;
+
+ //TODO : : RTC Story 159684
+ //Need to populate correct label size and label string
+ uint32_t l_rhbLabelSize = 0;
+ uint8_t* l_rhbLabelStringPtr = NULL;
+
+ addRHBAddrRange(l_dbobId, l_hdatRhbStartAddr,
+ l_hdatRhbEndAddr, l_rhbLabelSize,
+ l_rhbLabelStringPtr);
+ }
+ }
+ else
+ {
+ HDAT_INF("Reserve HB mem size 0x%08X",l_rhbSize);
+ }
+
+ if(l_err)
+ {
+ // Error message recorded above
+ break;
+ }
+
+ o_size = 0;
+ o_count = 1; // Only 1 of these structures is ever built
+
+ getTotalSize (o_size);
+
+
+ uint64_t l_base_addr = ((uint64_t) iv_msAddr.hi << 32) | iv_msAddr.lo;
+ uint64_t l_base_addr_down = ALIGN_PAGE_DOWN(l_base_addr);
+ iv_virtAddr = mm_block_map ( reinterpret_cast<void*>(l_base_addr_down),
+ (ALIGN_PAGE(o_size) + PAGESIZE));
+
+ uint64_t l_final_addr = reinterpret_cast<uint64_t>(iv_virtAddr);
+
+ l_final_addr += l_base_addr - l_base_addr_down;
+
+
+ iv_virtAddr = reinterpret_cast<void *> (l_final_addr);
+
+
+ commit(iv_virtAddr,o_size);
+
+ prt();
+ }
+ while(0);
+
+ HDAT_EXIT();
+
+ return l_err;
+}
+
+/** @brief See the prologue in hdatmsvpd.H
+ */
+void HdatMsVpd::commit(void * i_addr,
+ uint32_t i_size)
+{
+
+ uint32_t l_cnt,l_currOffset, l_ramSizes;
+ HdatMsArea *l_msEntry;
+ UtilMem l_data(i_addr, i_size);
+
+ // Start committing the base class data
+ this->startCommit(l_data);
+
+ l_data.write(&iv_maxAddr, sizeof(hdatMsVpdAddr_t));
+
+ l_data.write(&iv_maxSize, sizeof(hdatMsVpdSize_t));
+
+ // Page mover is called 'Misc Addr Structure' on OPAL but still exists
+ l_data.write(&iv_mover, sizeof(hdatMsVpdPageMover_t));
+
+ l_data.write(&iv_IMTaddrRngArrayHdr,sizeof(hdatHDIFDataArray_t));
+
+ l_data.write(iv_IMTaddrRangeArray,
+ iv_maxIMTAddrRngCnt * sizeof(hdatMsVpdImtAddrRange_t));
+
+ l_data.write(&iv_UEaddrRngArrayHdr, sizeof(hdatHDIFDataArray_t));
+
+ l_data.write(iv_UEaddrRangeArray,
+ iv_maxUEAddrRngCnt * sizeof(hdatMsVpdUEAddrRange_t));
+
+ l_data.write(&iv_RHBaddrRngArrayHdr,sizeof(hdatHDIFDataArray_t));
+
+ l_data.write (iv_RHBaddrRangeArray,iv_maxRHBAddrRngCnt
+ * sizeof(hdatMsVpdRhbAddrRange_t));
+
+ this->endCommit(l_data);
+
+
+ // Write the MS area structures and RAM structures
+ if (iv_actMsAreaCnt > 0)
+ {
+ // All of the mainstore areas must be written first so that can be
+ // processed as an array of mainstore areas.
+ l_ramSizes = 0;
+ l_cnt = 0;
+
+ while (l_cnt < iv_actMsAreaCnt)
+ {
+ l_msEntry = *(reinterpret_cast<HdatMsArea **>(
+ reinterpret_cast<char *>(iv_msAreaPtrs) + l_cnt
+ * sizeof(HdatMsArea *)));
+
+ // Since we don't know what order mainstore areas and RAM
+ // areas were created, update the offset in the HdatMsArea
+ // child structure triple so it points to the first RAM area.
+
+ l_currOffset = (iv_actMsAreaCnt - l_cnt) * l_msEntry->size()
+ + l_ramSizes;
+ l_msEntry->chgChildOffset(HDAT_MS_AREA_RAM_AREAS, l_currOffset);
+ l_msEntry->commit(l_data);
+
+ // Now compute the size of the RAM areas associated with this
+ // mainstore area. These will have to be added to the child
+ // offset for the next mainstore area to skip over them.
+ l_ramSizes += l_msEntry->ramObjSizes();
+
+ l_cnt++;
+ }
+
+ // Now the children (RAM areas) of each mainstore area must be committed
+ l_cnt = 0;
+
+ while (l_cnt < iv_actMsAreaCnt)
+ {
+ l_msEntry = *(reinterpret_cast<HdatMsArea **>(reinterpret_cast<char *>
+ (iv_msAreaPtrs) + l_cnt
+ * sizeof(HdatMsArea *)));
+ l_msEntry->commitRamAreas(l_data);
+ l_cnt++;
+ }
+ }
+}
+
+/*******************************************************************************
+* hdatGetMaxMemConfiguredAddress
+*******************************************************************************/
+uint64_t HdatMsVpd::hdatGetMaxMemConfiguredAddress()
+{
+ //For each processor in the system
+ TARGETING::PredicateCTM l_procChipPred(TARGETING::CLASS_CHIP,
+ TARGETING::TYPE_PROC);
+
+ TARGETING::PredicateHwas l_predFunctional;
+ l_predFunctional.functional(true);
+ TARGETING::PredicatePostfixExpr l_functionalProc;
+ l_functionalProc.push(&l_procChipPred).push(&l_predFunctional).And();
+
+ TARGETING::TargetRangeFilter l_procs(
+ TARGETING::targetService().begin(),
+ TARGETING::targetService().end(),
+ &l_functionalProc);
+
+ uint64_t l_maxBase = 0x0ull;
+ uint64_t l_maxMsAddress = 0x0ull;
+ bool l_processedAnyGroup = false;
+ uint64_t l_hdatMaxImtAddr = 0x0ull;
+
+ for(;l_procs;++l_procs)
+ {
+ TARGETING::Target *l_pProcTarget = (*l_procs);
+
+ TARGETING::ATTR_PROC_MEM_BASES_type l_procMemBases = {0};
+ TARGETING::ATTR_PROC_MEM_SIZES_type l_procMemSizesBytes = {0};
+
+ assert(l_pProcTarget->tryGetAttr<TARGETING::ATTR_PROC_MEM_SIZES>
+ (l_procMemSizesBytes));
+
+ assert(l_pProcTarget->
+ tryGetAttr<TARGETING::ATTR_PROC_MEM_BASES>(l_procMemBases));
+
+ //For each MCS
+ TARGETING::PredicateCTM l_allMcs(TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MCS);
+ TARGETING::PredicateHwas l_funcMcs;
+ l_funcMcs.functional(true);
+ TARGETING::PredicatePostfixExpr l_allFuncMcs;
+ l_allFuncMcs.push(&l_allMcs).push(&l_funcMcs).And();
+
+ TARGETING::TargetHandleList l_mcsList;
+
+ TARGETING::targetService().
+ getAssociated(l_mcsList, l_pProcTarget,
+ TARGETING::TargetService::CHILD,
+ TARGETING::TargetService::ALL, &l_allFuncMcs);
+
+ for(uint32_t i=0; i < l_mcsList.size(); i++)
+ {
+
+ TARGETING::Target *l_pMcsTarget = l_mcsList[i];
+
+ uint32_t l_mcsInGroup = 0;
+ if(!hdatFindGroupForMc(l_pProcTarget,
+ l_pMcsTarget,
+ l_mcsInGroup))
+ {
+ //Skip this MC not part of any group
+ continue;
+ }
+
+ if(!l_processedAnyGroup ||
+ (l_procMemBases[l_mcsInGroup] > l_maxBase))
+ {
+ l_maxBase = l_procMemBases[l_mcsInGroup];
+ l_processedAnyGroup = true;
+ l_maxMsAddress = l_maxBase + l_procMemSizesBytes[l_mcsInGroup];
+ }
+ }
+
+ // TODO : RTC Story 159682
+ // Further CHTM support needs to be added which contains the trace array
+ // for 24 cores
+ hdatMsAddr_t l_hdatNhtmStartAddr;
+ hdatMsAddr_t l_hdatNhtmEndAddr;
+
+ TARGETING::ATTR_PROC_NHTM_BAR_BASE_ADDR_type l_nhtmStartAddr =
+ l_pProcTarget->getAttr<TARGETING::ATTR_PROC_NHTM_BAR_BASE_ADDR>();
+ TARGETING::ATTR_PROC_NHTM_BAR_SIZE_type l_nhtmSize =
+ l_pProcTarget->getAttr<TARGETING::ATTR_PROC_NHTM_BAR_SIZE>();
+
+ if( 0 != l_nhtmSize )
+ {
+ l_hdatNhtmStartAddr.hi =
+ (l_nhtmStartAddr & 0xFFFFFFFF00000000ull) >> 32;
+ l_hdatNhtmStartAddr.lo = l_nhtmStartAddr & 0x00000000FFFFFFFFull;
+ l_hdatNhtmStartAddr.hi |= HDAT_REAL_ADDRESS_MASK;
+
+ l_nhtmSize = l_nhtmStartAddr + l_nhtmSize;
+ l_hdatNhtmEndAddr.hi =
+ (l_nhtmSize & 0xFFFFFFFF00000000ull) >> 32;
+ l_hdatNhtmEndAddr.lo = l_nhtmSize & 0x00000000FFFFFFFFull;
+ l_hdatNhtmEndAddr.hi |= HDAT_REAL_ADDRESS_MASK;
+
+ if( l_hdatMaxImtAddr <
+ (((uint64_t)l_hdatNhtmEndAddr.hi << 32) |l_hdatNhtmEndAddr.lo))
+ {
+ l_hdatMaxImtAddr =
+ (((uint64_t)l_hdatNhtmEndAddr.hi << 32) |l_hdatNhtmEndAddr.lo);
+ HDAT_INF("NHTM Max Addr: = 0x%016llX", l_hdatMaxImtAddr);
+ }
+ }
+ else
+ {
+ HDAT_INF("NHTM Bar size value = 0x%016llX ", l_nhtmSize);
+ }
+ }
+ // Set MSB to 1 for PHYP
+ l_maxMsAddress |= HDAT_REAL_ADDRESS_MASK64;
+
+ if(l_hdatMaxImtAddr > l_maxMsAddress)
+ {
+ l_maxMsAddress = l_hdatMaxImtAddr;
+ HDAT_INF("IMT Max MS Addr: = 0x%016llX",l_maxMsAddress);
+ }
+ // We now have to subtract 1 since the address range starts at 0
+ if(l_maxMsAddress != 0)
+ {
+ l_maxMsAddress -= 1;
+ }
+
+ return l_maxMsAddress;
+}
+
+//******************************************************************************
+//* hdatFindGroupForMc
+//******************************************************************************
+bool HdatMsVpd::hdatFindGroupForMc(const TARGETING::Target *i_pProcTarget,
+ const TARGETING::Target *i_pMcsTarget,
+ uint32_t& o_groupOfMc)
+{
+ bool l_foundGroup = false;
+ TARGETING::ATTR_MSS_MEM_MC_IN_GROUP_type l_mcsGroups = {0};
+ assert(i_pProcTarget != NULL || i_pMcsTarget != NULL);
+
+ assert(!(i_pProcTarget->getAttr<TARGETING::ATTR_TYPE>()
+ != TARGETING::TYPE_PROC)||
+ !(i_pProcTarget->getAttr<TARGETING::ATTR_CLASS>()
+ != TARGETING::CLASS_CHIP));
+
+ assert(i_pProcTarget->
+ tryGetAttr<TARGETING::ATTR_MSS_MEM_MC_IN_GROUP>(l_mcsGroups));
+
+ assert(!(i_pMcsTarget->getAttr<TARGETING::ATTR_TYPE>()
+ != TARGETING::TYPE_MCS)||
+ !(i_pMcsTarget->getAttr<TARGETING::ATTR_CLASS>()
+ != TARGETING::CLASS_UNIT));
+ TARGETING::ATTR_CHIP_UNIT_type l_chipUnit =
+ i_pMcsTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+ uint32_t l_sizeOfArray = sizeof(l_mcsGroups)/sizeof(l_mcsGroups[0]);
+
+ assert(!(sizeof( l_mcsGroups[0] ) != sizeof(uint8_t)));
+
+
+ assert(!( l_chipUnit >= ( sizeof( l_mcsGroups[0] ) * HDAT_BITS_PER_BYTE )));
+
+
+ const uint8_t MC_IN_GROUP_MCS_0 = 0x80;
+ for(uint32_t l_idx =0; l_idx < l_sizeOfArray;++l_idx)
+ {
+ //Attribute ATTR_MSS_MEM_MC_IN_GROUP is an array of bitmask
+ //bit 0 of bitmask corresponds to mcs 0, bit 7 to mcs7
+ if((l_mcsGroups[l_idx] & (MC_IN_GROUP_MCS_0 >> l_chipUnit)) ==
+ (MC_IN_GROUP_MCS_0 >> l_chipUnit))
+ {
+ HDAT_INF("hdatFindGroupForMc::: Found group : %d",l_idx);
+ o_groupOfMc = l_idx;
+ l_foundGroup = true;
+ break;
+ }
+ }
+
+ return l_foundGroup;
+}
+/*******************************************************************************
+* hdatScanDimms
+*******************************************************************************/
+errlHndl_t HdatMsVpd::hdatScanDimms(const TARGETING::Target *i_pTarget,
+ uint32_t i_mcaFruid,
+ std::list<hdatRamArea>& o_areas,
+ uint32_t& o_areaSize,
+ uint32_t& o_dimmNum,
+ bool& o_areaFunctional,
+ hdatMemParentType& o_parentType)
+{
+ errlHndl_t l_err = NULL;
+
+ do
+ {
+ if(i_pTarget->getAttr<TARGETING::ATTR_TYPE>() != TARGETING::TYPE_MCS)
+ {
+ HDAT_ERR("Input Target is type not supported.");
+ break;
+ }
+
+ TARGETING::ATTR_EFF_DIMM_SIZE_type l_dimSizes = {{0}};
+ //Get configured memory size
+ if(!i_pTarget->
+ tryGetAttr<TARGETING::ATTR_EFF_DIMM_SIZE>(l_dimSizes))
+ {
+ HDAT_ERR("DIMM size should be available with MCS");
+ }
+
+ //for each MCA connected to this this MCS
+ TARGETING::PredicateCTM l_mcaPredicate(TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MCA);
+
+ TARGETING::PredicateHwas l_predMca;
+ l_predMca.present(true);
+ TARGETING::PredicatePostfixExpr l_presentMca;
+ l_presentMca.push(&l_mcaPredicate).push(&l_predMca).And();
+ TARGETING::TargetHandleList l_mcaList;
+
+ // Get associated MCAs
+ TARGETING::targetService().
+ getAssociated(l_mcaList, i_pTarget,
+ TARGETING::TargetService::CHILD_BY_AFFINITY,
+ TARGETING::TargetService::ALL, &l_presentMca);
+
+ o_dimmNum = 0;
+ for (uint32_t i = 0; i < l_mcaList.size(); ++i)
+ {
+
+ TARGETING::Target *l_pMcaTarget = l_mcaList[i];
+
+ //for each DIMM connected to this this MCA
+ TARGETING::PredicateCTM l_dimmPredicate(TARGETING::
+ CLASS_LOGICAL_CARD,
+ TARGETING::TYPE_DIMM);
+ TARGETING::PredicateHwas l_predDimm;
+ l_predDimm.present(true);
+ TARGETING::PredicatePostfixExpr l_presentDimm;
+ l_presentDimm.push(&l_dimmPredicate).push(&l_predDimm).And();
+
+ TARGETING::TargetHandleList l_dimmList;
+
+ // Get associated dimms
+ TARGETING::targetService().
+ getAssociated(l_dimmList, l_pMcaTarget,
+ TARGETING::TargetService::CHILD_BY_AFFINITY,
+ TARGETING::TargetService::ALL, &l_presentDimm);
+
+
+ for(uint32_t j=0; j < l_dimmList.size(); ++j)
+ {
+ //fetch each dimm
+ TARGETING::Target *l_pDimmTarget = l_dimmList[j];
+
+ uint32_t l_dimmfru = 0;
+ l_dimmfru = l_pDimmTarget->getAttr<TARGETING::ATTR_FRU_ID>();
+
+ uint8_t l_mcaDimm = 0;
+ uint8_t l_mcaPort = 0;
+ TARGETING::ATTR_REL_POS_type l_dimmRelPos = 0;
+
+ if(l_pDimmTarget->
+ tryGetAttr<TARGETING::ATTR_REL_POS>(l_dimmRelPos))
+ {
+ l_mcaDimm = l_dimmRelPos%2; //2 DIMMs per MCA
+ l_dimmRelPos = 0;
+ if(!l_pMcaTarget->
+ tryGetAttr<TARGETING::ATTR_REL_POS>(l_dimmRelPos))
+ {
+ HDAT_ERR("Attribute REL_POS in MCA is not "
+ "present");
+ }
+ else
+ {
+ l_mcaPort = l_dimmRelPos%2; //2 MCAs per MCS
+ }
+ }
+ else
+ {
+ HDAT_ERR("Attribute REL_POS in DIMM "
+ "is not present");
+ }
+
+ //Convert GB to MB
+ uint32_t l_dimmSizeInMB =
+ l_dimSizes[l_mcaPort][l_mcaDimm] * HDAT_MB_PER_GB;
+ uint32_t l_huid = TARGETING::get_huid(l_pDimmTarget);
+
+
+ bool foundArea = false;
+ for (std::list<hdatRamArea>::iterator l_area = o_areas.begin();
+ l_area != o_areas.end();
+ ++l_area)
+ {
+ //we do not need to compare each dimm fru id with mca fru id
+ //to create ram area, by the below logic
+ //dimms with same fruid will fall into same ram area
+ //even if they have fru id same with mca
+ if (l_area->ivfruId == l_dimmfru)//this means soldered dimms
+ {
+ foundArea = true;
+ l_area->ivFunctional = (l_area)->ivFunctional ||
+ isFunctional(l_pDimmTarget);
+ (l_area)->ivFunctional = true;
+ (l_area)->ivSize += l_dimmSizeInMB;
+ break;
+ }
+ }
+
+ //Search in the list of RAM Areas if not
+ //present create a new ram area
+ if (!foundArea)
+ {
+ o_dimmNum++;
+ o_areas.push_back(hdatRamArea(l_huid,
+ isFunctional(l_pDimmTarget),
+ l_dimmSizeInMB,l_dimmfru));
+ }
+ o_areaSize += l_dimmSizeInMB;
+ o_areaFunctional = o_areaFunctional ||
+ isFunctional(l_pDimmTarget);
+ }
+ if(l_err != NULL)
+ {
+ //Break of error
+ break;
+ }
+ }
+ o_parentType = HDAT_MEM_PARENT_CEC_FRU;
+
+ if(l_err != NULL)
+ {
+ //break if error
+ break;
+ }
+ }
+ while(0);
+ return l_err;
+}
+/*******************************************************************************
+* hdatGetMaxMemoryBlocks
+*******************************************************************************/
+errlHndl_t HdatMsVpd::hdatGetMaxMemoryBlocks(const TARGETING::Target *i_pTarget,
+ uint32_t &o_maxMemoryBlocks)
+{
+ errlHndl_t l_err = NULL;
+ do
+ {
+ //One Memctrl connected to only one membuf in P8
+ o_maxMemoryBlocks = 1;
+ }
+ while(0);
+ return l_err;
+}
+} //namespace HDAT
OpenPOWER on IntegriCloud