diff options
author | Adriana Kobylak <anoo@us.ibm.com> | 2014-09-28 18:41:51 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2014-12-02 18:07:13 -0600 |
commit | f722d8c15b0ffa1d7d57608b8cff4e2865961aa8 (patch) | |
tree | 730144ecc90386c0ad3fddc417d2628bbe8ba5a4 /src | |
parent | aeb70d93bba10dcddc9d4f8f35b460359cf864c2 (diff) | |
download | talos-hostboot-f722d8c15b0ffa1d7d57608b8cff4e2865961aa8.tar.gz talos-hostboot-f722d8c15b0ffa1d7d57608b8cff4e2865961aa8.zip |
Port HWSV FreqVoltageSvc functionality to HB for Habanero
Change-Id: I90abd08bb6abf042273da606c6241bd22c58fa29
RTC: 108816
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/13642
Tested-by: Jenkins Server
Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com>
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/usr/hwpf/fapi/fapiMvpdAccess.H | 65 | ||||
-rw-r--r-- | src/include/usr/hwpf/hwpf_reasoncodes.H | 10 | ||||
-rw-r--r-- | src/include/usr/isteps/istep06list.H | 3 | ||||
-rw-r--r-- | src/include/usr/isteps/istep15list.H | 4 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/pstate_attributes.xml | 332 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/pstates/makefile | 1 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.C | 398 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.H | 152 | ||||
-rwxr-xr-x | src/usr/hwpf/hwp/pstates/pstates/p8_build_pstate_datablock.C | 151 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/slave_sbe/makefile | 1 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/slave_sbe/slave_sbe.C | 14 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/start_payload/HBconfig | 1 | ||||
-rw-r--r-- | src/usr/hwpf/makefile | 1 | ||||
-rw-r--r-- | src/usr/hwpf/plat/fapiPlatMvpdAccess.C | 1513 | ||||
-rw-r--r-- | src/usr/hwpf/plat/plat.mk | 6 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/common.mk | 1 |
16 files changed, 2465 insertions, 188 deletions
diff --git a/src/include/usr/hwpf/fapi/fapiMvpdAccess.H b/src/include/usr/hwpf/fapi/fapiMvpdAccess.H index 902ab11ff..e1cbba54f 100644 --- a/src/include/usr/hwpf/fapi/fapiMvpdAccess.H +++ b/src/include/usr/hwpf/fapi/fapiMvpdAccess.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* [+] 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. */ @@ -124,6 +126,43 @@ namespace fapi MVPD_KEYWORD_PB = 0x21, MVPD_KEYWORD_CH = 0x22, }; + + typedef struct voltageBucketData + { + // bucket Id + uint8_t bucketId; + // Nominal + uint16_t nomFreq; + uint16_t VnestNomVltg; + uint16_t InestNomCurr; + uint16_t VcsNomVltg; + uint16_t IcsNomCurr; + // PowerSave + uint16_t PSFreq; + uint16_t VnestPSVltg; + uint16_t InestPSCurr; + uint16_t VcsPSVltg; + uint16_t IcsPSCurr; + // Turbo + uint16_t turboFreq; + uint16_t VnestTurboVltg; + uint16_t InestTurboCurr; + uint16_t VcsTurboVltg; + uint16_t IcsTurboCurr; + //Fvmin + uint16_t fvminFreq; + uint16_t VnestFvminVltg; + uint16_t InestFvminCurr; + uint16_t VcsFvminVltg; + uint16_t IcsFvminCurr; + //Lab + uint16_t labFreq; + uint16_t VnestLabVltg; + uint16_t InestLabCurr; + uint16_t VcsLabVltg; + uint16_t IcsLabCurr; + }voltageBucketData_t; + } extern "C" @@ -131,9 +170,9 @@ extern "C" /** * @brief Get Module VPD field. - * + * * A Module VPD field is specified using a record and keyword enumerator - * + * * Suggested way to call this routine is to call it once with a NULL buffer * pointer to to retrieve the size of the record, then allocate the proper * size of the buffer and call again. @@ -172,6 +211,26 @@ fapi::ReturnCode fapiSetMvpdField(const fapi::MvpdRecord i_record, const fapi::Target &i_procTarget, const uint8_t * const i_pBuffer, const uint32_t i_fieldSize); + +/** + * @brief Get #V bucket data from VPD + * + * @par Detailed Description: + * This function reads PR keyword from the VPD, parses PR keyword + * to get voltage bucket id, reads #V keyword (Voltage data) from VPD, + * parses #V keyword to get voltage data corresponding to the bucket id + * indicated by the PR keyword and returns data to the caller. + * + * @param[in] i_pTarget Pointer to proc chip target. + * @param[in] i_record VPD record number to read #V bucket data + * @param[out] o_data On success, structure with #V bucket data from VPD + * + * @return fapi::ReturnCode. FAPI_RC_SUCCESS, or failure value. + */ +fapi::ReturnCode fapiGetPoundVBucketData(const TARGETING::Target *i_pChipTarget, + const uint32_t i_record, + fapi::voltageBucketData_t & o_data); + } #endif diff --git a/src/include/usr/hwpf/hwpf_reasoncodes.H b/src/include/usr/hwpf/hwpf_reasoncodes.H index d9d0e8ae4..f4f5fc13b 100644 --- a/src/include/usr/hwpf/hwpf_reasoncodes.H +++ b/src/include/usr/hwpf/hwpf_reasoncodes.H @@ -74,6 +74,10 @@ namespace fapi MOD_GET_OCC_CHIP_TARGET = 0x20, MOD_ACCESS_OCB_INDIRECT_CHANNEL = 0x21, MOD_GET_RCD_CNTL_WORD = 0x22, + MOD_GET_SYS_FREQ = 0x23, + MOD_GET_POUNDV_BUCKET_DATA = 0x24, + MOD_GET_VER_ONE_VOLTAGE_BUCKET_DATA = 0x25, + MOD_PLAT_MVPD_GET_VLTG_BUCKET_ATTR = 0x26, }; @@ -126,6 +130,12 @@ namespace fapi RC_TARGET_UNSUPPORTED = HWPF_COMP_ID | 0x31, RC_INVALID_DATA_BUFFER_LENGTH = HWPF_COMP_ID | 0x32, RC_INVALID_DIMM_TYPE = HWPF_COMP_ID | 0x33, + RC_INVALID_DATA = HWPF_COMP_ID | 0x34, + RC_INVALID_SIZE = HWPF_COMP_ID | 0x35, + RC_INVALID_FREQ = HWPF_COMP_ID | 0x36, + RC_INVALID_PARAM = HWPF_COMP_ID | 0x37, + RC_DATA_MISMATCH = HWPF_COMP_ID | 0x38, + RC_DATA_NOT_SUPPORTED = HWPF_COMP_ID | 0x39, }; /** diff --git a/src/include/usr/isteps/istep06list.H b/src/include/usr/isteps/istep06list.H index e804df5f7..98ec2fd70 100644 --- a/src/include/usr/isteps/istep06list.H +++ b/src/include/usr/isteps/istep06list.H @@ -158,6 +158,9 @@ const DepModInfo g_istep06Dependancies = { DEP_LIB(libslave_sbe.so), DEP_LIB(libsbe.so), DEP_LIB(libporeve.so), +#ifdef CONFIG_HTMGT + DEP_LIB(libpstates.so), +#endif NULL } }; diff --git a/src/include/usr/isteps/istep15list.H b/src/include/usr/isteps/istep15list.H index f68187a44..d7774cad3 100644 --- a/src/include/usr/isteps/istep15list.H +++ b/src/include/usr/isteps/istep15list.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* [+] 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. */ diff --git a/src/usr/hwpf/hwp/pstate_attributes.xml b/src/usr/hwpf/hwp/pstate_attributes.xml new file mode 100644 index 000000000..1eb012cd9 --- /dev/null +++ b/src/usr/hwpf/hwp/pstate_attributes.xml @@ -0,0 +1,332 @@ +<!-- IBM_PROLOG_BEGIN_TAG --> +<!-- This is an automatically generated prolog. --> +<!-- --> +<!-- $Source: src/usr/hwpf/hwp/pstate_attributes.xml $ --> +<!-- --> +<!-- OpenPOWER HostBoot Project --> +<!-- --> +<!-- Contributors Listed Below - COPYRIGHT 2014 --> +<!-- [+] 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 --> +<attributes> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_NOM_FREQ_MHZ</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword Nominal Frequency in MHZ +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + + +<attribute> + <id>ATTR_OVERRIDE_MVPD_V_NEST_NOM_VOLTAGE</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword V-nest nominal voltage +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_I_NEST_NOM_CURRENT</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword I-nest nominal current +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_V_CS_NOM_VOLTAGE</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword V-cs nominal voltage +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_I_CS_NOM_CURRENT</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword I-cs nominal current +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_PS_FREQ_MHZ</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword PowerSave Frequency in MHZ +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + + +<attribute> + <id>ATTR_OVERRIDE_MVPD_V_NEST_PS_VOLTAGE</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword V-nest PowerSave voltage +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_I_NEST_PS_CURRENT</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword I-nest PowerSave current +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_V_CS_PS_VOLTAGE</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword V-cs PowerSave voltage +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_I_CS_PS_CURRENT</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword I-cs PowerSave current +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_TURBO_FREQ_MHZ</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword turbo Frequency in MHZ +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + + +<attribute> + <id>ATTR_OVERRIDE_MVPD_V_NEST_TURBO_VOLTAGE</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword V-nest turbo voltage +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_I_NEST_TURBO_CURRENT</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword I-nest turbo current +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_V_CS_TURBO_VOLTAGE</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword V-cs turbo voltage +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_I_CS_TURBO_CURRENT</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword I-cs turbo current +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_FVMIN_FREQ_MHZ</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword fvmin Frequency in MHZ +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + + +<attribute> + <id>ATTR_OVERRIDE_MVPD_V_NEST_FVMIN_VOLTAGE</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword V-nest fvmin voltage +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_I_NEST_FVMIN_CURRENT</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword I-nest fvmin current +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_V_CS_FVMIN_VOLTAGE</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword V-cs fvmin voltage +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_I_CS_FVMIN_CURRENT</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword I-cs fvmin current +consumer: p8_build_pstate_datablock, others +firmware notes: none</description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + + +<attribute> + <id>ATTR_OVERRIDE_MVPD_LAB_FREQ_MHZ</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword lab Frequency in MHZ +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + + +<attribute> + <id>ATTR_OVERRIDE_MVPD_V_NEST_LAB_VOLTAGE</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword V-nest lab voltage +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_I_NEST_LAB_CURRENT</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword I-nest lab current +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_V_CS_LAB_VOLTAGE</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword V-cs lab voltage +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>ATTR_OVERRIDE_MVPD_I_CS_LAB_CURRENT</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>Module VPD #V keyword I-cs lab current +consumer: p8_build_pstate_datablock, others +firmware notes: Used for over writing attributes in lab/debug + </description> + <valueType>uint32</valueType> + <readable/> + <writeable/> +</attribute> +</attributes> + diff --git a/src/usr/hwpf/hwp/pstates/makefile b/src/usr/hwpf/hwp/pstates/makefile index defe4b1e4..21a98b899 100644 --- a/src/usr/hwpf/hwp/pstates/makefile +++ b/src/usr/hwpf/hwp/pstates/makefile @@ -54,6 +54,7 @@ OBJS += p8_build_pstate_datablock.o OBJS += proc_get_voltage.o OBJS += pstates.o OBJS += pstate_tables.o +OBJS += $(if $(CONFIG_SET_NOMINAL_PSTATE)$(CONFIG_HTMGT),freqVoltageSvc.o) OBJS += proc_set_max_pstate.o diff --git a/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.C b/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.C new file mode 100644 index 000000000..cfda8a083 --- /dev/null +++ b/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.C @@ -0,0 +1,398 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2014 */ +/* [+] 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 freqVoltageSvc.C + * + * @brief Contains freqVoltage class definition + * + * This file contains implementation of frequency voltage service class. This + * class is used for reading/parsing/writing frequency and voltage related + * data. + * + */ + +#include <stdio.h> + +#include <freqVoltageSvc.H> + +#include <devicefw/userif.H> +#include <errl/errlentry.H> +#include <errl/errlmanager.H> +#include <fapiPlatHwpInvoker.H> +#include <hwpf/fapi/fapiMvpdAccess.H> +#include <hwpf/hwpf_reasoncodes.H> +#include <p8_build_pstate_datablock.H> +#include <proc_get_voltage.H> +#include <pstates.h> +#include <targeting/common/commontargeting.H> +#include <targeting/common/utilFilter.H> +#include <vpd/mvpdenums.H> + +extern trace_desc_t* g_fapiTd; + +using namespace TARGETING; + +namespace FREQVOLTSVC +{ + + //************************************************************************** + // FREQVOLTSVC::setSysFreq + //************************************************************************** + errlHndl_t setSysFreq() + { + errlHndl_t l_err = NULL; + uint32_t l_sysHighestPowerSaveFreq = 0x0; + TARGETING::ATTR_NOMINAL_FREQ_MHZ_type l_sysNomFreq = 0x0; + TARGETING::ATTR_FREQ_CORE_MAX_type l_sysLowestTurboFreq = 0x0; + + // Get system frequency + l_err = getSysFreq(l_sysHighestPowerSaveFreq, + l_sysNomFreq, + l_sysLowestTurboFreq); + if (l_err != NULL) + { + TRACFCOMP( g_fapiTd,ERR_MRK"Error getting system frequency"); + } + else + { + // Successfully got system frequency. Now update + // system attributes. + + //Get the top level (system) target handle + TARGETING::Target* l_pTopLevel = NULL; + (void)TARGETING::targetService().getTopLevelTarget(l_pTopLevel); + + // Assert on failure getting system target + assert( l_pTopLevel != NULL ); + + // Top level target successfully retrieved. + // Set nominal frequency attribute + (void)l_pTopLevel->setAttr + < TARGETING::ATTR_NOMINAL_FREQ_MHZ > (l_sysNomFreq); + + // Set max turbo frequency attribute + (void)l_pTopLevel->setAttr + < TARGETING::ATTR_FREQ_CORE_MAX > (l_sysLowestTurboFreq); + + // Set min freq attribute based on power save + (void)l_pTopLevel->setAttr<TARGETING::ATTR_MIN_FREQ_MHZ> + (l_sysHighestPowerSaveFreq); + + verifyBootFreq(l_pTopLevel); + } + + return l_err; + } + + //************************************************************************** + // FREQVOLTSVC::verifyBootFreq + //************************************************************************** + void verifyBootFreq(TARGETING::Target* const i_pTarget) + { + TARGETING::ATTR_MIN_FREQ_MHZ_type l_sysMinFreq = + i_pTarget->getAttr<TARGETING::ATTR_MIN_FREQ_MHZ>(); + TARGETING::ATTR_BOOT_FREQ_MHZ_type l_boot_freq_mhz = + i_pTarget->getAttr<TARGETING::ATTR_BOOT_FREQ_MHZ>(); + + l_boot_freq_mhz = (l_sysMinFreq > l_boot_freq_mhz) ? l_sysMinFreq: + l_boot_freq_mhz; + + i_pTarget->setAttr<TARGETING::ATTR_BOOT_FREQ_MHZ>(l_boot_freq_mhz); + } + + //************************************************************************** + // FREQVOLTSVC::getSysFreq + //************************************************************************** + errlHndl_t getSysFreq( + uint32_t & o_sysVPDPowerSaveMinFreqMhz, + TARGETING::ATTR_NOMINAL_FREQ_MHZ_type & o_sysNomFreqMhz, + TARGETING::ATTR_FREQ_CORE_MAX_type & o_sysVPDTurboMaxFreqMhz) + { + uint32_t l_minsysVPDTurboMaxFreqMhz = 0; + uint32_t l_maxsysVPDPowerSaveMinFreqMhz = 0; + fapi::ReturnCode l_rc; + errlHndl_t l_err = NULL; + + do + { + o_sysNomFreqMhz = 0; + o_sysVPDTurboMaxFreqMhz = 0; + o_sysVPDPowerSaveMinFreqMhz = 0; + + //Filter functional unit + TARGETING::PredicateIsFunctional l_isFunctional; + + // Filter core unit + TARGETING::PredicateCTM l_coreUnitFilter(TARGETING::CLASS_UNIT, + TARGETING::TYPE_CORE); + + //Filter functional cores + TARGETING::PredicatePostfixExpr l_funcCoreUnitFilter; + + // core units AND functional + l_funcCoreUnitFilter.push(&l_coreUnitFilter).push + (&l_isFunctional).And(); + + // Loop through all the targets, looking for functional core units. + TARGETING::TargetRangeFilter l_pFilter( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &l_funcCoreUnitFilter); + // Assert if no functional cores are found + assert(l_pFilter); + + bool l_copyOnce = true; + + // Loop through functional cores to get frequency + for(; l_pFilter; ++l_pFilter ) + { + TARGETING::Target * l_pTarget = *l_pFilter; + + fapi::voltageBucketData_t l_poundVdata = {0}; + + // Get Parent Chip target + const TARGETING::Target * l_pChipTarget = + getParentChip(l_pTarget); + + // Get core number for record number + TARGETING::ATTR_CHIP_UNIT_type l_coreNum = + l_pTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>(); + + uint32_t l_record = (uint32_t) MVPD::LRP0 + l_coreNum; + + // Get #V bucket data + l_rc = fapiGetPoundVBucketData(l_pChipTarget, + l_record, + l_poundVdata); + if(l_rc) + { + TRACFCOMP( g_fapiTd,ERR_MRK"Error getting #V data for HUID:" + "0x%08X", + l_pTarget->getAttr<TARGETING::ATTR_HUID>()); + + // Convert fapi returnCode to Error handle + l_err = fapiRcToErrl(l_rc); + + break; + } + + uint32_t l_sysVPDPowerSaveMinFreqMhz = l_poundVdata.PSFreq; + TARGETING::ATTR_NOMINAL_FREQ_MHZ_type l_sysNomFreqMhz = + l_poundVdata.nomFreq; + TARGETING::ATTR_FREQ_CORE_MAX_type l_sysVPDTurboMaxFreqMhz = + l_poundVdata.turboFreq; + TRACFCOMP(g_fapiTd,INFO_MRK"Nominal freq is: [0x%08X]. Turbo " + "freq is: [0x%08x]. PowerSave freq is: [0x%08X]", + l_sysNomFreqMhz, l_sysVPDTurboMaxFreqMhz, + l_sysVPDPowerSaveMinFreqMhz ); + + if( true == l_copyOnce) + { + o_sysNomFreqMhz = l_sysNomFreqMhz; + l_minsysVPDTurboMaxFreqMhz = l_sysVPDTurboMaxFreqMhz; + l_maxsysVPDPowerSaveMinFreqMhz = + l_sysVPDPowerSaveMinFreqMhz; + l_copyOnce = false; + } + + // frequency is never zero so create error if it is zero. + if( (l_sysNomFreqMhz == 0) || + (l_sysVPDTurboMaxFreqMhz == 0) || + (l_sysVPDPowerSaveMinFreqMhz == 0) ) + { + TRACFCOMP(g_fapiTd,ERR_MRK"Frequency is zero, " + "nominal freq: 0x%04X,turbo freq: 0x%08X", + "PowerSave freq is: [0x%08X]", + l_sysNomFreqMhz, + l_sysVPDTurboMaxFreqMhz, + l_sysVPDPowerSaveMinFreqMhz); + + /*@ + * @errortype + * @moduleid fapi::MOD_GET_SYS_FREQ + * @reasoncode fapi::RC_INVALID_DATA + * @userdata1[0:31] Proc HUID + * @userdata1[32:63] Nominal frequency + * @userdata2[0:31] Max Turbo frequency from VPD + * @userdata2[32:63] Min Power Save frequency from VPD + * @devdesc Either nominal, max turbo or min power + * save frequency for the processor HUID + * (userdata1) is zero + */ + l_err = + new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_GET_SYS_FREQ, + fapi::RC_INVALID_DATA, + TWO_UINT32_TO_UINT64( + l_pTarget->getAttr<TARGETING::ATTR_HUID>(), + l_sysNomFreqMhz), + TWO_UINT32_TO_UINT64(l_sysVPDTurboMaxFreqMhz, + l_sysVPDPowerSaveMinFreqMhz)); + + // Callout HW as VPD data is incorrect + l_err->addHwCallout(l_pTarget, HWAS::SRCI_PRIORITY_HIGH, + HWAS::DECONFIG, HWAS::GARD_NULL); + + break; + } + + // Validate nominal frequency. If differs, + // create error and stop processing further. + if( o_sysNomFreqMhz != l_sysNomFreqMhz ) + { + TRACFCOMP(g_fapiTd,ERR_MRK + "Nominal Frequency:[0x%04X] does not " + "match with other core nominal frequency:[0x%04X]", + l_sysNomFreqMhz, o_sysNomFreqMhz); + + /*@ + * @errortype + * @moduleid fapi::MOD_GET_SYS_FREQ + * @reasoncode fapi::RC_INVALID_FREQ + * @userdata1 Invalid frequency + * @userdata2 Expected frequency + * @devdesc Nominal frequency(userdata1) does not match + * nominal frequency(userdata2) on other cores. + * Should be the same for all chips. + */ + l_err = + new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_GET_SYS_FREQ, + fapi::RC_INVALID_FREQ, + l_sysNomFreqMhz, + o_sysNomFreqMhz); + + // Callout HW as VPD data is incorrect + l_err->addHwCallout(l_pTarget, HWAS::SRCI_PRIORITY_HIGH, + HWAS::DECONFIG, HWAS::GARD_NULL); + + break; + } + + // Save the min turbo freq + if (l_sysVPDTurboMaxFreqMhz < l_minsysVPDTurboMaxFreqMhz) + { + l_minsysVPDTurboMaxFreqMhz = l_sysVPDTurboMaxFreqMhz; + } + // Save the max powersave freq + if (l_sysVPDPowerSaveMinFreqMhz > + l_maxsysVPDPowerSaveMinFreqMhz) + { + l_maxsysVPDPowerSaveMinFreqMhz = + l_sysVPDPowerSaveMinFreqMhz; + } + + } // end for loop + if (l_err != NULL) + { + break; + } + + // Get min turbo freq + o_sysVPDTurboMaxFreqMhz = l_minsysVPDTurboMaxFreqMhz; + + // Get max powersave freq + o_sysVPDPowerSaveMinFreqMhz = l_maxsysVPDPowerSaveMinFreqMhz; + + } while (0); + + TRACFCOMP(g_fapiTd,EXIT_MRK"o_sysNomFreqMhz: 0x%08X, " + "o_sysVPDTurboMaxFreqMhz: 0x%08X, " + "o_sysVPDPowerSaveMinFreqMhz: 0x%08X", + o_sysNomFreqMhz, o_sysVPDTurboMaxFreqMhz, + o_sysVPDPowerSaveMinFreqMhz ); + + return l_err; + } + + //************************************************************************** + // FREQVOLTSVC::runP8BuildPstateDataBlock + //************************************************************************** + errlHndl_t runP8BuildPstateDataBlock( + const TARGETING::Target * i_procChip, + PstateSuperStructure * o_data) + { + errlHndl_t l_err = NULL; + + // Assert on NULL input target + assert(i_procChip != NULL); + + // convert to fapi target + fapi::Target l_fapiProcChip(fapi::TARGET_TYPE_PROC_CHIP, + reinterpret_cast<void *> + (const_cast<TARGETING::Target*>(i_procChip)) ); + + FAPI_INVOKE_HWP(l_err, p8_build_pstate_datablock,l_fapiProcChip,o_data); + + if( l_err != NULL) + { + TRACFCOMP( g_fapiTd,ERR_MRK"Error from HWP: " + "p8_build_pstate_datablock for target HUID: 0x%08X", + i_procChip->getAttr<TARGETING::ATTR_HUID>()); + } + + return l_err; + } + + //************************************************************************** + // FREQVOLTSVC::runProcGetVoltage + //************************************************************************** + errlHndl_t runProcGetVoltage( + const TARGETING::Target * i_procChip, + const uint32_t i_bootFreqMhz, + uint8_t & o_vdd_vid, + uint8_t & o_vcs_vid) + { + errlHndl_t l_err = NULL; + + TRACFCOMP(g_fapiTd,INFO_MRK"i_bootFreqMhz: 0x%08X",i_bootFreqMhz); + + // Assert on NULL input target + assert(i_procChip != NULL); + + // convert to fapi target + fapi::Target l_fapiProcChip(fapi::TARGET_TYPE_PROC_CHIP, + reinterpret_cast<void *> + (const_cast<TARGETING::Target*>(i_procChip))); + + // Invoke HW procedure + FAPI_INVOKE_HWP(l_err, proc_get_voltage,l_fapiProcChip,i_bootFreqMhz, + o_vdd_vid,o_vcs_vid); + + if( l_err != NULL) + { + TRACFCOMP( g_fapiTd,ERR_MRK"Error from HWP: proc_get_voltage: " + "i_bootFreq: 0x%08X, " + "HUID: 0x%08X", i_bootFreqMhz, + i_procChip->getAttr<TARGETING::ATTR_HUID>()); + } + + return l_err; + } + +} // end namespace FREQVOLTSVC + diff --git a/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.H b/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.H new file mode 100644 index 000000000..183f7be9e --- /dev/null +++ b/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.H @@ -0,0 +1,152 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2014 */ +/* [+] 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 freqVoltageSvc.H + * @brief Contains freqVoltage class declaration + * + * This file contains information about frequency voltage service class. This + * class is used for reading/parsing/writing frequency and voltage related + * data. + */ + +#ifndef __PSTATES_FREQVOLTAGESVC_H +#define __PSTATES_FREQVOLTAGESVC_H + +#include <errl/errlentry.H> +#include <hwpf/fapi/fapiMvpdAccess.H> +#include <pstates.h> + +namespace FREQVOLTSVC +{ + + /** + * @brief Set system frequency attribute + * + * @par Detailed Description: + * This function reads nominal, max turbo frequency, and min power + * save frequency from VPD and updates system target attributes. + * + * @return Error log handle indicating the status of the request + * + * @retval NULL Successfully set system frequency + * @retval !NULL Failed to set system frequency. + */ + errlHndl_t setSysFreq(); + + /** + * @brief Run p8_build_pstate_datablock HWP + * + * @par Detailed Description: + * This function is wrapper for executing p8_build_pstate_datablock + * HW procedure. + * + * @param[in] i_procChip + * Valid functional Processor Chip target pointer + * @param[out] o_data + * On success, holds pstate data + * + * @return Error log handle indicating the status of the request + * + * @retval NULL Successfully retrieved pstate data + * @retval !NULL Failed to get pstate data, ignore output + */ + errlHndl_t runP8BuildPstateDataBlock(const TARGETING::Target * i_procChip, + PstateSuperStructure * o_data); + + /** + * @brief Run proc_get_voltage HWP + * + * @par Detailed Description: + * This function is wrapper for executing proc_get_voltage + * HW procedure. + * + * @param[in] i_procChip + * Valid functional Processor Chip target pointer + * @param[in] i_bootFreqMhz + * Boot Frequency in MHZ + * @param[out] o_vdd_vid + * On success, holds VDD value + * @param[out] o_vcs_vid + * On success, holds VCS value + * + * @return Error log handle indicating the status of the request + * + * @retval NULL Successfully retrieved boot voltage data + * @retval !NULL Failed to get boot voltage, ignore output + */ + errlHndl_t runProcGetVoltage(const TARGETING::Target * i_procChip, + const uint32_t i_bootFreqMhz, + uint8_t & o_vdd_vid, + uint8_t & o_vcs_vid); + + /** + * @brief Get system frequency + * + * @par Detailed Description: + * This function reads nominal, max turbo and min PowerSave frequency + * from VPD. + * It also does validation (check if all functional core voltage data + * points to the same nominal frequency value). Returns error if + * validation fails. + * Max Turbo frequency returned is the lowest turbo freq of all the + * functional cores in the system, obtained from VPD. + * Min PowerSave frequency returned is the highest powersave freq of + * all the functional cores in the system, obtained from VPD. + * + * @param[out] o_sysNomFreqMhz + * On success, holds system nominal frequency + * On failure, set to zero. + * @param[out] o_sysVPDTurboMaxFreqMhz + * On success, holds lowest turbo frequency + * On failure, set to zero. + * @param[out] o_sysVPDPowerSaveMinFreqMhz + * On success, holds highest powersave frequency + * On failure, set to zero. + * + * @return Error log handle indicating the status of the request + * + * @retval NULL Successfully retrieved system frequency + * @retval !NULL Failed to get system frequency, ignore output + */ + errlHndl_t getSysFreq( + uint32_t & o_sysVPDPowerSaveMinFreqMhz, + TARGETING::ATTR_NOMINAL_FREQ_MHZ_type & o_sysNomFreqMhz, + TARGETING::ATTR_FREQ_CORE_MAX_type & o_sysVPDTurboMaxFreqMhz); + + /** + * @brief Verify the system boot frequency attribute + * + * @par Detailed Description: + * This method reads the system's boot frequency (ATTR_BOOT_FREQ_MHZ) + * and verifies that it is greater than or equal to the minimum + * power save frequency from VPD. + * + * @param[in] i_pTarget + * Pointer to system target. + */ + void verifyBootFreq(TARGETING::Target* const i_pTarget); + +}; // end namespace FREQVOLTSVC + +#endif // __PSTATES_FREQVOLTAGESVC_H diff --git a/src/usr/hwpf/hwp/pstates/pstates/p8_build_pstate_datablock.C b/src/usr/hwpf/hwp/pstates/pstates/p8_build_pstate_datablock.C index 54a2290d6..70b57df45 100755 --- a/src/usr/hwpf/hwp/pstates/pstates/p8_build_pstate_datablock.C +++ b/src/usr/hwpf/hwp/pstates/pstates/p8_build_pstate_datablock.C @@ -6,8 +6,8 @@ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2013,2014 */ -/* [+] International Business Machines Corp. */ /* [+] Google Inc. */ +/* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ @@ -23,7 +23,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_build_pstate_datablock.C,v 1.00039 2014/07/22 21:45:45 daviddu Exp $ +// $Id: p8_build_pstate_datablock.C,v 1.42 2014/11/18 18:08:49 anoo Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_build_pstate_datablock.C,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2012 @@ -99,7 +99,7 @@ p8_build_pstate_datablock(const Target& i_target, uint8_t i = 0; uint8_t present_chiplets = 0; uint8_t functional_chiplets = 0; - uint8_t poundm_ver = 0; + uint8_t poundm_ver = 0; uint8_t poundm_valid = 1; // assume valid until code determines invalid uint8_t lpst_valid = 1; // assume valid until code determines invalid uint8_t attr_pm_ivrms_enabled_wr = 0; @@ -116,7 +116,7 @@ p8_build_pstate_datablock(const Target& i_target, ivrm_mvpd_t ivrm_mvpd; FAPI_INF("Executing p8_build_pstate_datablock ...."); - + do { // ----------------------------------------------------------- @@ -138,21 +138,21 @@ p8_build_pstate_datablock(const Target& i_target, // -------------------------------- // check chip ec feature attributes - // -------------------------------- + // -------------------------------- if (attr.attr_proc_ec_core_hang_pulse_bug) { FAPI_INF("ATTR_PROC_EC_CORE_HANG_PULSE_BUG is set so disable iVRMs - setting PSTATE_NO_INSTALL_LPSA"); (*io_pss).gpst.options.options = revle32(revle32((*io_pss).gpst.options.options) | PSTATE_NO_INSTALL_LPSA); poundm_valid = 0; - lpst_valid = 0; + lpst_valid = 0; } - + if (! attr.attr_chip_ec_feature_resonant_clk_valid) { - FAPI_INF("ATTR_CHIP_EC_FEATURE_RESONANT_CLK_VALID is not set so disable resonant clocking - setting PSTATE_NO_INSTALL_RESCLK"); + FAPI_INF("ATTR_CHIP_EC_FEATURE_RESONANT_CLK_VALID is not set so disable resonant clocking - setting PSTATE_NO_INSTALL_RESCLK"); (*io_pss).gpst.options.options = revle32(revle32((*io_pss).gpst.options.options) | PSTATE_NO_INSTALL_RESCLK ); } - + // ---------------- // get #V & #M data // ---------------- @@ -173,9 +173,9 @@ p8_build_pstate_datablock(const Target& i_target, FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PSTATE_DATABLOCK_NO_CORES_PRESENT_ERROR); break; } - + if (!functional_chiplets || !poundm_valid) { - + if (!functional_chiplets) { FAPI_IMP("No FUNCTIONAL chiplets found - set PSTATE_NO_INSTALL_LPSA"); @@ -184,7 +184,7 @@ p8_build_pstate_datablock(const Target& i_target, { FAPI_IMP("Invalid #M found - set PSTATE_NO_INSTALL_LPSA"); } - + // indicate no LPST installed in PSS (*io_pss).gpst.options.options = revle32(revle32((*io_pss).gpst.options.options) | PSTATE_NO_INSTALL_LPSA); @@ -343,10 +343,10 @@ p8_build_pstate_datablock(const Target& i_target, // Create the Local Pstate table // ----------------------------- uint8_t vid_incr_gt7_nonreg = 0; - + if (! attr.attr_proc_ec_core_hang_pulse_bug) { FAPI_IMP("Creating Local Pstate Table"); - + rc = lpst_create( &((*io_pss).gpst), &((*io_pss).lpsa), DEAD_ZONE_5MV, volt_int_vdd_bias, volt_int_vcs_bias, &vid_incr_gt7_nonreg); int & LPST_RETURN_CODE = rc; @@ -364,28 +364,28 @@ p8_build_pstate_datablock(const Target& i_target, FAPI_ERR("**** ERROR : lpst_create encountered a vid increment > 7 in regulation"); FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PSTATE_DATABLOCK_LPST_CREATE_VID_INCR_CLIP_INREG_ERROR); break; - } + } else if (rc == -LPST_GPST_WARNING) { FAPI_IMP("No Local Pstate Generated - Global Pstate Table is completely within Deadzone - set PSTATE_NO_INSTALL_LPSA" ); // indicate no LPST installed in PSS (*io_pss).gpst.options.options = revle32(revle32((*io_pss).gpst.options.options) | PSTATE_NO_INSTALL_LPSA); - lpst_valid = 0; + lpst_valid = 0; } else if (rc) { FAPI_ERR("**** ERROR : lpst_create returned error rc = %d", rc ); FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PSTATE_DATABLOCK_LPST_CREATE_ERROR); break; } - + // display warning message if this condition occurs if (vid_incr_gt7_nonreg) { FAPI_IMP("Warning : vid increment field was > 7 in non-regulation - clipped to 7 in lpst"); } - + } - + // ----------------------- // Create VDS & VIN tables // ----------------------- @@ -458,7 +458,7 @@ p8_build_pstate_datablock(const Target& i_target, FAPI_INF(" Set PSTATE_FORCE_INITIAL_PMIN in GPST control options"); (*io_pss).gpst.options.options = revle32(revle32((*io_pss).gpst.options.options) | PSTATE_FORCE_INITIAL_PMIN); FAPI_INF(" GPST control options mask is now: [%x].", (*io_pss).gpst.options.options); - + // ------------------- // Attributes to write // ------------------- @@ -475,18 +475,18 @@ p8_build_pstate_datablock(const Target& i_target, attr_pm_ivrms_enabled_wr = 1; } else - { + { attr_pm_ivrms_enabled_wr = 0; FAPI_INF(" ATTR_PM_IVRMS_ENABLED will be set to 0 - set PSTATE_NO_INSTALL_LPSA"); // indicate no LPST installed in PSS (*io_pss).gpst.options.options = revle32(revle32((*io_pss).gpst.options.options) | - PSTATE_NO_INSTALL_LPSA); + PSTATE_NO_INSTALL_LPSA); } - + // write ATTR_PM_IVRMS_ENABLED - SETATTR(l_rc, ATTR_PM_IVRMS_ENABLED, "ATTR_PM_IVRMS_ENABLED", &i_target, attr_pm_ivrms_enabled_wr); + SETATTR(l_rc, ATTR_PM_IVRMS_ENABLED, "ATTR_PM_IVRMS_ENABLED", &i_target, attr_pm_ivrms_enabled_wr); - // Read back attribute to see if overridden + // Read back attribute to see if overridden GETATTR (l_rc, ATTR_PM_IVRMS_ENABLED, "ATTR_PM_IVRMS_ENABLED", &i_target, attr_pm_ivrms_enabled_rd); if (attr_pm_ivrms_enabled_rd && !attr_pm_ivrms_enabled_wr) { @@ -496,9 +496,9 @@ p8_build_pstate_datablock(const Target& i_target, FAPI_INF("WARNING : ATTR_PM_IVRMS_ENABLED was overriden to 0, but #V or #M data are valid - set PSTATE_NO_INSTALL_LPSA"); // indicate no LPST installed in PSS (*io_pss).gpst.options.options = revle32(revle32((*io_pss).gpst.options.options) | - PSTATE_NO_INSTALL_LPSA); + PSTATE_NO_INSTALL_LPSA); } - + } while(0); return l_rc; @@ -584,11 +584,11 @@ ReturnCode proc_get_attributes(const Target& i_target, DATABLOCK_GET_ATTR(ATTR_CHIP_EC_FEATURE_RESONANT_CLK_VALID, &i_target, attr_chip_ec_feature_resonant_clk_valid); DATABLOCK_GET_ATTR(ATTR_PROC_EC_CORE_HANG_PULSE_BUG , &i_target, attr_proc_ec_core_hang_pulse_bug); DATABLOCK_GET_ATTR(ATTR_CHIP_EC_FEATURE_IVRM_WINKLE_BUG , &i_target, attr_chip_ec_feature_ivrm_winkle_bug); - - // Read IVRM attributes + + // Read IVRM attributes DATABLOCK_GET_ATTR(ATTR_PM_SYSTEM_IVRMS_ENABLED , NULL, attr_pm_system_ivrms_enabled); DATABLOCK_GET_ATTR(ATTR_PM_SYSTEM_IVRM_VPD_MIN_LEVEL , NULL, attr_pm_system_ivrm_vpd_min_level); - + // -------------------------------------------------------------- // do basic attribute value checking and generate error if needed // -------------------------------------------------------------- @@ -706,36 +706,6 @@ ReturnCode proc_get_attributes(const Target& i_target, return l_rc; } -const uint8_t NON_ECO_VOLTAGE_BUCKET_OFFFSET = 0x04; -const uint8_t ALTERNATE_BUCKET_OFFSET = 0x05; -const uint8_t BUCKET_ID_MASK = 0x0F; -const uint8_t VPD_VINI_PR_DATA_LENGTH = 8; - -const uint8_t DEFAULT_BUCKET = 1; - -static int get_bucket_from_pr(const Target& i_target) -{ - ReturnCode l_rc; - uint8_t l_buffer[VPD_VINI_PR_DATA_LENGTH]; - uint32_t l_bufferSize = sizeof(l_buffer); - - l_rc = fapiGetMvpdField(fapi::MVPD_RECORD_VINI, - fapi::MVPD_KEYWORD_PR, - i_target, - l_buffer, - l_bufferSize); - - if (l_rc) - { - return DEFAULT_BUCKET; - } - - uint8_t l_bucketId = l_buffer[NON_ECO_VOLTAGE_BUCKET_OFFFSET] & - BUCKET_ID_MASK; - - return l_bucketId != 0 ? l_bucketId : DEFAULT_BUCKET; -} - /// ---------------------------------------------------------------- /// \brief Get #V data and put into array /// \param[in] i_target => Chip Target @@ -766,7 +736,6 @@ ReturnCode proc_get_mvpd_data(const Target& i_target, uint8_t ii = 0; uint8_t first_chplt = 1; uint8_t bucket_id = 0; - uint8_t pr_bucket_id = 0; uint16_t cal_data[4]; do @@ -803,10 +772,10 @@ ReturnCode proc_get_mvpd_data(const Target& i_target, // set l_record to appropriate lprx record (add core number to lrp0) l_record = (uint32_t)fapi::MVPD_RECORD_LRP0 + l_chipNum; - + // clear out buffer to known value before calling fapiGetMvpdField memset(l_buffer, 0, 512); - + // Get Chiplet MVPD data and put in chiplet_mvpd_data using accessor function l_rc = fapiGetMvpdField((fapi::MvpdRecord)l_record, fapi::MVPD_KEYWORD_PDV, @@ -827,16 +796,6 @@ ReturnCode proc_get_mvpd_data(const Target& i_target, break; } - // Get the correct bucket according to FRU PR data. - pr_bucket_id = get_bucket_from_pr(i_target); - if (l_bufferSize < PDV_BUFFER_SIZE * pr_bucket_id) { - const uint32_t &BUFFER_SIZE = l_bufferSize; - const Target &CHIP_TARGET= i_target; - FAPI_ERR("**** ERROR : Not enough buckets returned from fapiGetMvpdField for #V => %d", l_bufferSize ); - FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PSTATE_DATABLOCK_PDV_BUFFER_SIZE_ERROR); - break; - } - // clear array memset(chiplet_mvpd_data, 0, sizeof(chiplet_mvpd_data)); @@ -844,15 +803,9 @@ ReturnCode proc_get_mvpd_data(const Target& i_target, #define UINT16_GET(__uint8_ptr) ((uint16_t)( ( (*((const uint8_t *)(__uint8_ptr)) << 8) | *((const uint8_t *)(__uint8_ptr) + 1) ) )) // use copy of allocated buffer pointer to increment through buffer - // Skip version and 'PNP' from header. - l_buffer_inc = l_buffer + 4; + l_buffer_inc = l_buffer; bucket_id = *l_buffer_inc; - while (bucket_id != pr_bucket_id && - (l_buffer_inc - l_buffer) < l_bufferSize) { - l_buffer_inc += PDV_BUFFER_SIZE; - bucket_id = *l_buffer_inc; - } l_buffer_inc++; FAPI_INF("#V chiplet = %u bucket id = %u", l_chipNum, bucket_id); @@ -979,14 +932,14 @@ ReturnCode proc_get_mvpd_data(const Target& i_target, ivrm_mvpd->data.ex[j].point[i].drain_current = cal_data[3]; FAPI_INF("#M data (hex & dec) = 0x%04x 0x%04x 0x%04x 0x%04x %5u %5u %5u %5u", cal_data[0], cal_data[1], cal_data[2], cal_data[3], cal_data[0], cal_data[1], cal_data[2], cal_data[3]); - + // #M validity check - not valid if measurements are 0 (exception : cal_data[0](Vg) can be 0) if (cal_data[1] == 0 || cal_data[2] == 0 || cal_data[3] == 0 ) - { + { FAPI_INF("**** Warning : #M has zero valued measurements - IVRMs will not be enabled"); - *poundm_valid = 0; - } - + *poundm_valid = 0; + } + } // set number of samples to 13 @@ -1151,7 +1104,7 @@ ReturnCode proc_boost_gpst (PstateSuperStructure *pss, uint32_t pstate_diff; gpst_entry_t entry; uint8_t gpsi_max; - + const uint32_t MAXIMUM_BOOST_PERCENT_SUPPORTED = 20; const uint32_t MAXIMUM_PSTATE_RANGE = 255; // maximum represented by uint8_t @@ -1162,17 +1115,17 @@ ReturnCode proc_boost_gpst (PstateSuperStructure *pss, FAPI_INF("CPM Turbo Boost Attribute = 0 -- no boosting will be done"); break; } - + // check that percentage is rational. Note: attribute information is .1 percent units - if (attr_boost_percent > MAXIMUM_BOOST_PERCENT_SUPPORTED * 10) { + if (attr_boost_percent > MAXIMUM_BOOST_PERCENT_SUPPORTED * 10) { FAPI_ERR("Boost percentage is greater than maximum supported. Max: %u; Value: %u", - MAXIMUM_BOOST_PERCENT_SUPPORTED, attr_boost_percent); + MAXIMUM_BOOST_PERCENT_SUPPORTED, attr_boost_percent); const uint32_t& MAXBOOSTPERCENT = MAXIMUM_BOOST_PERCENT_SUPPORTED; const uint32_t& ATTRBOOSTPERCENT = attr_boost_percent; - FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PSTATE_DATABLOCK_INVALID_BOOST_PERCENTAGE_ERROR); - break; + FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PSTATE_DATABLOCK_INVALID_BOOST_PERCENTAGE_ERROR); + break; } - + // calculate percent to boost boosted_pct = 1.0 + (BOOST_PCT_UNIT * (double)attr_boost_percent); @@ -1199,7 +1152,7 @@ ReturnCode proc_boost_gpst (PstateSuperStructure *pss, FAPI_INF("CPM Turbo Boost Attribute resulted in no increase in pstates - boost_pct = %f turbo_freq_khz = %u boosted_freq_khz = %u", boosted_pct, pstate0_frequency_khz, boosted_freq_khz); break; - } + } else if (pstate_diff > MAXIMUM_PSTATE_RANGE) { FAPI_ERR("Percentage boost calculation overrun produced invalid Pstate Difference: %u", pstate_diff); const uint32_t& PSTATEDIFF = pstate_diff; @@ -1208,9 +1161,9 @@ ReturnCode proc_boost_gpst (PstateSuperStructure *pss, const uint32_t& FREQSTEPKHZ = frequency_step_khz; const uint32_t& ATTRBOOSTPERCENT = attr_boost_percent; const double& BOOSTEDPCT = boosted_pct; - FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PSTATE_DATABLOCK_PSTATE_DIFF_ERROR); - break; - } + FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PSTATE_DATABLOCK_PSTATE_DIFF_ERROR); + break; + } else { gpsi_max = pss->gpst.entries - 1; entry.value = revle64(pss->gpst.pstate[gpsi_max].value); @@ -1283,7 +1236,7 @@ ReturnCode proc_chk_valid_poundv(const Target& i_target, FAPI_INF("Checking for relationship between #V operating point (%s <= %s)", pv_op_str[pv_op_order[i-1]], pv_op_str[pv_op_order[i]]); FAPI_INF(" f=%u <= f=%u", poundv_data[pv_op_order[i-1]][0], poundv_data[pv_op_order[i]][0]); FAPI_INF(" v=%u <= v=%u i=%u <= i=%u", poundv_data[pv_op_order[i-1]][1], poundv_data[pv_op_order[i]][1], poundv_data[pv_op_order[i-1]][2], poundv_data[pv_op_order[i]][2]); - FAPI_INF(" v=%u <= v=%u i=%u <= i=%u", poundv_data[pv_op_order[i-1]][3], poundv_data[pv_op_order[i]][3], poundv_data[pv_op_order[i-1]][4], poundv_data[pv_op_order[i]][4]); + FAPI_INF(" v=%u <= v=%u i=%u <= i=%u", poundv_data[pv_op_order[i-1]][3], poundv_data[pv_op_order[i]][3], poundv_data[pv_op_order[i-1]][4], poundv_data[pv_op_order[i]][4]); if (poundv_data[pv_op_order[i-1]][0] > poundv_data[pv_op_order[i]][0] || poundv_data[pv_op_order[i-1]][1] > poundv_data[pv_op_order[i]][1] || @@ -1369,7 +1322,7 @@ ReturnCode proc_res_clock (PstateSuperStructure *pss, /// ------------------------------------------------------------ -/// \brief Update Psafe_pstate +/// \brief Update Psafe_pstate /// \param[inout] *pss => pointer to pstate superstructure /// \param[in] *attr => pointer to attribute list structure /// ------------------------------------------------------------ @@ -1424,7 +1377,7 @@ ReturnCode proc_upd_psafe_ps (PstateSuperStructure *pss, /// ------------------------------------------------------------ -/// \brief Update Floor_pstate +/// \brief Update Floor_pstate /// \param[inout] *pss => pointer to pstate superstructure /// \param[in] *attr => pointer to attribute list structure /// ------------------------------------------------------------ diff --git a/src/usr/hwpf/hwp/slave_sbe/makefile b/src/usr/hwpf/hwp/slave_sbe/makefile index 2ee5fe406..a29cb24ae 100644 --- a/src/usr/hwpf/hwp/slave_sbe/makefile +++ b/src/usr/hwpf/hwp/slave_sbe/makefile @@ -45,6 +45,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/slave_sbe/proc_cen_ref_clk_enable EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/slave_sbe/proc_spless_sbe_startWA EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/proc_mailbox_utils EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/slave_sbe/proc_tp_collect_dbg_data +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/pstates/pstates EXTRAINCDIR += ${ROOTPATH}/src/usr/pore/poreve/porevesrc EXTRAINCDIR += ${ROOTPATH}/src/usr/pore/poreve/model/ diff --git a/src/usr/hwpf/hwp/slave_sbe/slave_sbe.C b/src/usr/hwpf/hwp/slave_sbe/slave_sbe.C index 7b0a74447..9842d31da 100644 --- a/src/usr/hwpf/hwp/slave_sbe/slave_sbe.C +++ b/src/usr/hwpf/hwp/slave_sbe/slave_sbe.C @@ -65,6 +65,7 @@ #include "proc_getecid.H" #include "proc_spless_sbe_startWA.H" #include <sbe/sbeif.H> +#include <freqVoltageSvc.H> const uint64_t MS_TO_WAIT_FIRST = 2500; //(2.5 s) const uint64_t MS_TO_WAIT_OTHERS= 100; //(100 ms) @@ -143,6 +144,19 @@ void* call_host_slave_sbe_config(void *io_pArgs) // execute proc_read_nest_freq.C // execute proc_setup_sbe_config.C +#ifdef CONFIG_HTMGT + // Set system frequency attributes + errlHndl_t l_errl = FREQVOLTSVC::setSysFreq(); + if (l_errl ) + { + // Create IStep error log and cross reference error that occurred + l_stepError.addErrorDetails( l_errl ); + + // Commit Error + errlCommit( l_errl, HWPF_COMP_ID ); + } +#endif // CONFIG_HTMGT + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_slave_sbe_config exit" ); diff --git a/src/usr/hwpf/hwp/start_payload/HBconfig b/src/usr/hwpf/hwp/start_payload/HBconfig index 70fdcb55e..3cc6ed127 100644 --- a/src/usr/hwpf/hwp/start_payload/HBconfig +++ b/src/usr/hwpf/hwp/start_payload/HBconfig @@ -1,5 +1,6 @@ config SET_NOMINAL_PSTATE default n + depends on !HTMGT help Set the PState to Nominal just before starting the payload. config START_OCC_DURING_BOOT diff --git a/src/usr/hwpf/makefile b/src/usr/hwpf/makefile index 7493fd0af..b296803ca 100644 --- a/src/usr/hwpf/makefile +++ b/src/usr/hwpf/makefile @@ -218,6 +218,7 @@ HWP_ATTR_XML_FILES += hwp/dram_training/mem_pll_setup/memb_pll_ring_attributes.x HWP_ATTR_XML_FILES += hwp/proc_chip_ec_feature.xml HWP_ATTR_XML_FILES += hwp/proc_abus_dmi_xbus_scominit_attributes.xml HWP_ATTR_XML_FILES += hwp/runtime_attributes/memory_occ_attributes.xml +HWP_ATTR_XML_FILES += hwp/pstate_attributes.xml #------------------------------------------------------------------------------ # PLL Ring Data files diff --git a/src/usr/hwpf/plat/fapiPlatMvpdAccess.C b/src/usr/hwpf/plat/fapiPlatMvpdAccess.C index a0b7b3ba6..051719ab6 100644 --- a/src/usr/hwpf/plat/fapiPlatMvpdAccess.C +++ b/src/usr/hwpf/plat/fapiPlatMvpdAccess.C @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* [+] 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. */ @@ -28,15 +30,31 @@ #include <stdint.h> #include <errl/errlentry.H> +#include <freqVoltageSvc.H> // fapi support +#include <fapiAttributeService.H> #include <fapiMvpdAccess.H> +#include <fapiSystemConfig.H> #include <hwpf/hwpf_reasoncodes.H> // MVPD #include <devicefw/userif.H> #include <vpd/mvpdenums.H> +const uint8_t NON_ECO_VOLTAGE_BUCKET_OFFFSET = 0x04; +const uint8_t ALTERNATE_BUCKET_OFFSET = 0x05; +const uint8_t BUCKET_ID_MASK = 0x0F; +const uint8_t DEFAULT_BUCKET = 1; +const uint8_t VERSION_01_BUCKET_SZ = 0x33; // 51 decimal +const uint8_t POUND_V_VERSION_01 = 0x01; + +// Decimal 50 - 2 bytes for each 25 attributes. +const uint8_t MAX_MVPD_VOLTAGE_BUCKET_ATTR_SZ = 0x32; +// Two byte shift +const uint8_t MVPD_TWO_BYTE_ATTR_VAL_SHIFT = 0x10; +// Invalid chip unit +const uint8_t MVPD_INVALID_CHIP_UNIT = 0xFF; namespace fapi { @@ -47,56 +65,67 @@ namespace fapi // enumerator //****************************************************************************** fapi::ReturnCode MvpdRecordXlate(const fapi::MvpdRecord i_fapiRecord, - MVPD::mvpdRecord & o_hbRecord) + MVPD::mvpdRecord & o_hbRecord, + uint8_t & o_chipUnitNum) { // Create a lookup table for converting a FAPI MVPD record enumerator to a // Hostboot MVPD record enumerator. This is a simple array and relies on // the FAPI record enumerators starting at zero and incrementing. - static const MVPD::mvpdRecord mvpdFapiRecordToHbRecord[] = + + //Structure to map fapi::MVPD_RECORD to chiplet chip num position + struct mvpdRecordToChip + { + MVPD::mvpdRecord rec; + // This is the chip unit position. 0xFF means record associated to all + // chiplets, any other number means record associated to the ex chiplet + // corresponding to that number. + uint8_t exChipNum; + }; + static const mvpdRecordToChip mvpdFapiRecordToHbRecord[] = { - MVPD::CRP0, - MVPD::CP00, - MVPD::VINI, - MVPD::LRP0, - MVPD::LRP1, - MVPD::LRP2, - MVPD::LRP3, - MVPD::LRP4, - MVPD::LRP5, - MVPD::LRP6, - MVPD::LRP7, - MVPD::LRP8, - MVPD::LRP9, - MVPD::LRPA, - MVPD::LRPB, - MVPD::LRPC, - MVPD::LRPD, - MVPD::LRPE, - MVPD::LWP0, - MVPD::LWP1, - MVPD::LWP2, - MVPD::LWP3, - MVPD::LWP4, - MVPD::LWP5, - MVPD::LWP6, - MVPD::LWP7, - MVPD::LWP8, - MVPD::LWP9, - MVPD::LWPA, - MVPD::LWPB, - MVPD::LWPC, - MVPD::LWPD, - MVPD::LWPE, - MVPD::VWML, - MVPD::MER0, + {MVPD::CRP0,0xFF}, + {MVPD::CP00,0xFF}, + {MVPD::VINI,0xFF}, + {MVPD::LRP0,0x00}, + {MVPD::LRP1,0x01}, + {MVPD::LRP2,0x02}, + {MVPD::LRP3,0x03}, + {MVPD::LRP4,0x04}, + {MVPD::LRP5,0x05}, + {MVPD::LRP6,0x06}, + {MVPD::LRP7,0x07}, + {MVPD::LRP8,0x08}, + {MVPD::LRP9,0x09}, + {MVPD::LRPA,0x0A}, + {MVPD::LRPB,0x0B}, + {MVPD::LRPC,0x0C}, + {MVPD::LRPD,0x0D}, + {MVPD::LRPE,0x0E}, + {MVPD::LWP0,0x00}, + {MVPD::LWP1,0x01}, + {MVPD::LWP2,0x02}, + {MVPD::LWP3,0x03}, + {MVPD::LWP4,0x04}, + {MVPD::LWP5,0x05}, + {MVPD::LWP6,0x06}, + {MVPD::LWP7,0x07}, + {MVPD::LWP8,0x08}, + {MVPD::LWP9,0x09}, + {MVPD::LWPA,0x0A}, + {MVPD::LWPB,0x0B}, + {MVPD::LWPC,0x0C}, + {MVPD::LWPD,0x0D}, + {MVPD::LWPE,0x0E}, + {MVPD::VWML,0xFF}, + {MVPD::MER0,0xFF}, }; - const uint8_t NUM_MVPD_RECORDS = + const uint8_t NUM_MVPD_RECORDS = sizeof(mvpdFapiRecordToHbRecord)/sizeof(mvpdFapiRecordToHbRecord[0]); - + fapi::ReturnCode l_rc; - + uint8_t l_index = static_cast<uint8_t>(i_fapiRecord); - + if (l_index >= NUM_MVPD_RECORDS) { FAPI_ERR("MvpdRecordXlate: Invalid MVPD Record: 0x%x", i_fapiRecord); @@ -113,15 +142,16 @@ fapi::ReturnCode MvpdRecordXlate(const fapi::MvpdRecord i_fapiRecord, fapi::MOD_MVPD_ACCESS, fapi::RC_INVALID_RECORD, i_fapiRecord, 0, hbSwError); - + // Add the error log pointer as data to the ReturnCode l_rc.setPlatError(reinterpret_cast<void *> (l_errl)); } else { - o_hbRecord = mvpdFapiRecordToHbRecord[l_index]; + o_hbRecord = mvpdFapiRecordToHbRecord[l_index].rec; + o_chipUnitNum = mvpdFapiRecordToHbRecord[l_index].exChipNum; } - + return l_rc; } @@ -175,13 +205,13 @@ fapi::ReturnCode MvpdKeywordXlate(const fapi::MvpdKeyword i_fapiKeyword, MVPD::PB, MVPD::CH, }; - const uint8_t NUM_MVPD_KEYWORDS = + const uint8_t NUM_MVPD_KEYWORDS = sizeof(mvpdFapiKeywordToHbKeyword)/sizeof(mvpdFapiKeywordToHbKeyword[0]); - + fapi::ReturnCode l_rc; - + uint8_t l_index = static_cast<uint8_t>(i_fapiKeyword); - + if (l_index >= NUM_MVPD_KEYWORDS) { FAPI_ERR("MvpdKeywordXlate: Invalid MVPD Keyword: 0x%x", i_fapiKeyword); @@ -198,7 +228,7 @@ fapi::ReturnCode MvpdKeywordXlate(const fapi::MvpdKeyword i_fapiKeyword, fapi::MOD_MVPD_ACCESS, fapi::RC_INVALID_KEYWORD, i_fapiKeyword, 0, hbSwError); - + // Add the error log pointer as data to the ReturnCode l_rc.setPlatError(reinterpret_cast<void *> (l_errl)); } @@ -206,7 +236,1036 @@ fapi::ReturnCode MvpdKeywordXlate(const fapi::MvpdKeyword i_fapiKeyword, { o_hbKeyword = mvpdFapiKeywordToHbKeyword[l_index]; } - + + return l_rc; +} + +//****************************************************************************** +// getVoltageBucketAttr +//****************************************************************************** +fapi::ReturnCode getVoltageBucketAttr(const fapi::Target & i_exchplet, + const fapi::voltageBucketData_t & i_data, + uint8_t * io_pData, + uint32_t & io_dataSz) +{ + fapi::ReturnCode l_rc; + do + { + if( io_dataSz < MAX_MVPD_VOLTAGE_BUCKET_ATTR_SZ) + { + FAPI_ERR("getVltgBucketAttr: Invalid buffer size:0x%08X," + "expected:0x%08X",io_dataSz, + MAX_MVPD_VOLTAGE_BUCKET_ATTR_SZ); + errlHndl_t l_err = NULL; + + /*@ + * @errortype + * @moduleid fapi::MOD_PLAT_MVPD_GET_VLTG_BUCKET_ATTR + * @reasoncode fapi::RC_INVALID_SIZE + * @userdata1 Invalid input length + * @userdata2 Expected length + * @devdesc Input buffer size is smaller than expected length. + */ + l_err = + new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_PLAT_MVPD_GET_VLTG_BUCKET_ATTR, + fapi::RC_INVALID_SIZE, + io_dataSz, + MAX_MVPD_VOLTAGE_BUCKET_ATTR_SZ); + + // Add the error log pointer as data to the ReturnCode + l_rc.setPlatError(reinterpret_cast<void *> (l_err)); + break; + } + + //NOTE: Below attributes are read and value written to the output + // buffer as the VPD voltage bucket data layout. See MVPD documentation + // for more details + uint32_t l_data = 0; + uint32_t l_idx = 0; + // Write bucket id. This is written directly as this is not an + // override attribute (cannot be changed). + io_pData[l_idx] = i_data.bucketId; + l_idx++; + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_NOM_FREQ_MHZ, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_NOM_FREQ_MHZ"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_V_NEST_NOM_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_V_NEST_NOM_VOLTAGE"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_I_NEST_NOM_CURRENT, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_I_NEST_NOM_CURRENT"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_V_CS_NOM_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_V_CS_NOM_VOLTAGE"); + break; + } + + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_I_CS_NOM_CURRENT, + &i_exchplet, + l_data); + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_I_CS_NOM_CURRENT"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_PS_FREQ_MHZ,&i_exchplet, + l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_PS_FREQ_MHZ"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_V_NEST_PS_VOLTAGE,&i_exchplet, + l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_V_NEST_PS_VOLTAGE"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_I_NEST_PS_CURRENT,&i_exchplet, + l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_I_NEST_PS_CURRENT"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_V_CS_PS_VOLTAGE,&i_exchplet, + l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_V_CS_PS_VOLTAGE"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_I_CS_PS_CURRENT, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_I_CS_PS_CURRENT"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_TURBO_FREQ_MHZ, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_TURBO_FREQ_MHZ"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_V_NEST_TURBO_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_V_NEST_TURBO_VOLTAGE"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_I_NEST_TURBO_CURRENT, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_I_NEST_TURBO_CURRENT"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_V_CS_TURBO_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_V_CS_TURBO_VOLTAGE"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_I_CS_TURBO_CURRENT, + &i_exchplet, l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_I_CS_TURBO_CURRENT"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_FVMIN_FREQ_MHZ, + &i_exchplet,l_data); + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_FVMIN_FREQ_MHZ"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_V_NEST_FVMIN_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_V_NEST_FVMIN_VOLTAGE"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_I_NEST_FVMIN_CURRENT, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_I_NEST_FVMIN_CURRENT"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_V_CS_FVMIN_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_V_CS_FVMIN_VOLTAGE"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_I_CS_FVMIN_CURRENT, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_I_CS_FVMIN_CURRENT"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_LAB_FREQ_MHZ, + &i_exchplet,l_data); + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_LAB_FREQ_MHZ"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_V_NEST_LAB_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_V_NEST_LAB_VOLTAGE"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_I_NEST_LAB_CURRENT, + &i_exchplet, l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_I_NEST_LAB_CURRENT"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_V_CS_LAB_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_V_CS_LAB_VOLTAGE"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + l_rc = FAPI_ATTR_GET(ATTR_OVERRIDE_MVPD_I_CS_LAB_CURRENT, + &i_exchplet, l_data); + + if( l_rc ) + { + FAPI_ERR("getVltgBucketAttr:Err in get " + "ATTR_OVERRIDE_MVPD_I_CS_LAB_CURRENT"); + break; + } + + // Read value and put 2 bytes to the output buffer. FAPI ATTR cannot + // be 2 bytes by design so had to make it 4 bytes and do shift to + // return 2 bytes which is actual size of the data in the VPD. + l_data = l_data << MVPD_TWO_BYTE_ATTR_VAL_SHIFT; + memcpy(&io_pData[l_idx],&l_data,sizeof(uint16_t)); + l_idx += sizeof(uint16_t); + + //Return actual buffer size in output param + io_dataSz = l_idx; + + }while(false); + + if(l_rc) + { + // On error return 0 size + io_dataSz = 0; + } + + return l_rc; +} + +//****************************************************************************** +// setVoltageBucketAttr +//****************************************************************************** +fapi::ReturnCode setVoltageBucketAttr(const fapi::Target & i_exchplet, + const fapi::voltageBucketData_t & i_data) +{ + fapi::ReturnCode l_rc; + do + { + // local variable is used as i_data fields are 2 bytes (matching VPD + // data length) and FAPI attributes are 4 bytes long. FAPI attributes + // cannot be 2 bytes by design. + uint32_t l_data = i_data.nomFreq; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_NOM_FREQ_MHZ, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_NOM_FREQ_MHZ"); + break; + } + + l_data = i_data.VnestNomVltg; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_V_NEST_NOM_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_V_NEST_NOM_VOLTAGE"); + break; + } + + l_data = i_data.InestNomCurr; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_I_NEST_NOM_CURRENT, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_I_NEST_NOM_CURRENT"); + break; + } + + l_data = i_data.VcsNomVltg; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_V_CS_NOM_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_V_CS_NOM_VOLTAGE"); + break; + } + + l_data = i_data.IcsNomCurr; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_I_CS_NOM_CURRENT, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_I_CS_NOM_CURRENT"); + break; + } + + l_data = i_data.PSFreq; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_PS_FREQ_MHZ,&i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_PS_FREQ_MHZ"); + break; + } + + l_data = i_data.VnestPSVltg; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_V_NEST_PS_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_V_NEST_PS_VOLTAGE"); + break; + } + + l_data = i_data.InestPSCurr; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_I_NEST_PS_CURRENT, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_I_NEST_PS_CURRENT"); + break; + } + + l_data = i_data.VcsPSVltg; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_V_CS_PS_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_V_CS_PS_VOLTAGE"); + break; + } + + l_data = i_data.IcsPSCurr; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_I_CS_PS_CURRENT, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_I_CS_PS_CURRENT"); + break; + } + + l_data = i_data.turboFreq; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_TURBO_FREQ_MHZ, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_TURBO_FREQ_MHZ"); + break; + } + + l_data = i_data.VnestTurboVltg; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_V_NEST_TURBO_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_V_NEST_TURBO_VOLTAGE"); + break; + } + + l_data = i_data.InestTurboCurr; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_I_NEST_TURBO_CURRENT, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_I_NEST_TURBO_CURRENT"); + break; + } + + l_data = i_data.VcsTurboVltg; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_V_CS_TURBO_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_V_CS_TURBO_VOLTAGE"); + break; + } + + l_data = i_data.IcsTurboCurr; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_I_CS_TURBO_CURRENT, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_I_CS_TURBO_CURRENT"); + break; + } + l_data = i_data.fvminFreq; + + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_FVMIN_FREQ_MHZ, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_FVMIN_FREQ_MHZ"); + break; + } + + l_data = i_data.VnestFvminVltg; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_V_NEST_FVMIN_VOLTAGE, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_V_NEST_FVMIN_VOLTAGE"); + break; + } + + l_data = i_data.InestFvminCurr; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_I_NEST_FVMIN_CURRENT, + &i_exchplet,l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_I_NEST_FVMIN_CURRENT"); + break; + } + l_data = i_data.VcsFvminVltg; + + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_V_CS_FVMIN_VOLTAGE,&i_exchplet, + l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_V_CS_FVMIN_VOLTAGE"); + break; + } + + l_data = i_data.IcsFvminCurr; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_I_CS_FVMIN_CURRENT,&i_exchplet, + l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_I_CS_FVMIN_CURRENT"); + break; + } + + l_data = i_data.labFreq; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_LAB_FREQ_MHZ,&i_exchplet, + l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_LAB_FREQ_MHZ"); + break; + } + l_data = i_data.VnestLabVltg; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_V_NEST_LAB_VOLTAGE,&i_exchplet, + l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_V_NEST_LAB_VOLTAGE"); + break; + } + l_data = i_data.InestLabCurr; + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_I_NEST_LAB_CURRENT,&i_exchplet, + l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_I_NEST_LAB_CURRENT"); + break; + } + l_data = i_data.VcsLabVltg; + + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_V_CS_LAB_VOLTAGE,&i_exchplet, + l_data); + + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_V_CS_LAB_VOLTAGE"); + break; + } + l_data = i_data.IcsLabCurr; + + l_rc = FAPI_ATTR_SET(ATTR_OVERRIDE_MVPD_I_CS_LAB_CURRENT,&i_exchplet, + l_data); + if( l_rc ) + { + FAPI_ERR("setVltgBucketAttr:Err in set " + "ATTR_OVERRIDE_MVPD_I_CS_LAB_CURRENT"); + break; + } + + }while(false); + + return l_rc; +} + +/** + * @brief Parse and get #V version one bucket data + * + * @par Detailed Description: + * This function handles parsing of version one #V data and returns + * bucket data buffer. + * + * @param[in] i_prBucketId Bucket id to read data for + * @param[in] i_dataSz #V data buffer size + * @param[in] i_vDataPtr #V data buffer + * @param[out] o_data On success, structure with #V version one bucket + * data from VPD + * + * @return fapi::ReturnCode. FAPI_RC_SUCCESS, or failure value. + */ +fapi::ReturnCode fapiGetVerOneVoltageBucketData( + const TARGETING::Target * i_pChipTarget, + const uint8_t i_prBucketId, + const uint32_t i_dataSz, + const uint8_t *i_vDataPtr, + fapi::voltageBucketData_t & o_data) +{ + fapi::ReturnCode l_rc; + errlHndl_t l_err = NULL; + + do + { + memset (&o_data,0,sizeof (o_data)); + + // For version 0x01, valid bucket id is 1 through 5. + if( (i_prBucketId == 0 ) || + (i_prBucketId > 5) ) + { + FAPI_ERR("Found invalid bucket ID:0x%02X", i_prBucketId); + + /*@ + * @errortype + * @moduleid fapi::MOD_GET_VER_ONE_VOLTAGE_BUCKET_DATA + * @reasoncode fapi::RC_INVALID_PARAM + * @userdata1 Invalid bucket id + * @devdesc Invalid bucket id found for the voltage data. + */ + l_err = + new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_GET_VER_ONE_VOLTAGE_BUCKET_DATA, + fapi::RC_INVALID_PARAM, + i_prBucketId); + + // Callout HW as VPD data is incorrect + l_err->addHwCallout(i_pChipTarget, HWAS::SRCI_PRIORITY_HIGH, + HWAS::DECONFIG, HWAS::GARD_NULL); + + // Add the error log pointer as data to the ReturnCode + l_rc.setPlatError(reinterpret_cast<void *> (l_err)); + + break; + } + + // Documented in Module VPD document: mvpd-p8-100212.pdf Version 1.0 + // skip (1 byte version + 3 byte PNP + + // ((bucketId-1(as bucketId starts at 1)) * bucket data size ) + uint32_t l_bucketOffset = 4 + ((i_prBucketId -1)* VERSION_01_BUCKET_SZ); + + if( i_dataSz < (l_bucketOffset + VERSION_01_BUCKET_SZ)) + { + FAPI_ERR("Not enough data to get bucket data " + "Returned data length:[0x%08X],expected len:[0x%08X]", + i_dataSz, l_bucketOffset + VERSION_01_BUCKET_SZ); + + /*@ + * @errortype + * @moduleid fapi::MOD_GET_VER_ONE_VOLTAGE_BUCKET_DATA + * @reasoncode fapi::RC_INVALID_SIZE + * @userdata1 Voltage data length + * @userdata2 Expected length + * @devdesc Not enough voltage data to read bucket data. + */ + l_err = + new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_GET_VER_ONE_VOLTAGE_BUCKET_DATA, + fapi::RC_INVALID_SIZE, + i_dataSz, + (l_bucketOffset + VERSION_01_BUCKET_SZ)); + + // Callout HW as VPD data is incorrect + l_err->addHwCallout(i_pChipTarget, HWAS::SRCI_PRIORITY_HIGH, + HWAS::DECONFIG, HWAS::GARD_NULL); + + // Add the error log pointer as data to the ReturnCode + l_rc.setPlatError(reinterpret_cast<void *> (l_err)); + + break; + } + + // Got bucket data, now make sure input bucket id matches with the + // bucket id pointed to by the bucket data. Ignore default value + // since it means VPD is not initialized. + if( (i_prBucketId != i_vDataPtr[l_bucketOffset]) && + (i_prBucketId != DEFAULT_BUCKET) ) + { + FAPI_ERR("BucketId:[0x%02x] from PR data " + "does not match bucketId:[0x%02X] from the voltage " + "data for HUID:[0x%08X]", + i_prBucketId, i_vDataPtr[l_bucketOffset], + i_pChipTarget->getAttr<TARGETING::ATTR_HUID>()); + + /*@ + * @errortype + * @moduleid fapi::MOD_GET_VER_ONE_VOLTAGE_BUCKET_DATA + * @reasoncode fapi::RC_DATA_MISMATCH + * @userdata1[0:31] Voltage bucket id + * @userdata1[32:63] PR bucket id + * @userdata2 Voltage bucket id offset + * @devdesc Bucket id from PR keyword does not match + * bucket id in the voltage data + */ + l_err = + new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_GET_VER_ONE_VOLTAGE_BUCKET_DATA, + fapi::RC_DATA_MISMATCH, + TWO_UINT32_TO_UINT64(i_vDataPtr[l_bucketOffset], i_prBucketId), + l_bucketOffset); + + // Callout HW as VPD data is incorrect + l_err->addHwCallout(i_pChipTarget, HWAS::SRCI_PRIORITY_HIGH, + HWAS::DECONFIG, HWAS::GARD_NULL); + + // Add the error log pointer as data to the ReturnCode + l_rc.setPlatError(reinterpret_cast<void *> (l_err)); + + break; + } + + // Make sure bucket data is large enough to process output structure + if (sizeof(o_data) < (VERSION_01_BUCKET_SZ)) + { + FAPI_ERR("Not enough bucket data to fill o_data," + "bucket length:[0x%08X],o_data size:[0x%08X]", + VERSION_01_BUCKET_SZ,sizeof(o_data)); + + /*@ + * @errortype + * @moduleid fapi::MOD_GET_VER_ONE_VOLTAGE_BUCKET_DATA + * @reasoncode fapi::RC_INVALID_DATA + * @userdata1 Bucket data length + * @userdata2 Output Data size + * @devdesc Not enough bucket data to fill output data. + */ + l_err = + new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_GET_VER_ONE_VOLTAGE_BUCKET_DATA, + fapi::RC_INVALID_DATA, + VERSION_01_BUCKET_SZ, + (sizeof(o_data))); + + // Add the error log pointer as data to the ReturnCode + l_rc.setPlatError(reinterpret_cast<void *> (l_err)); + + break; + } + + // TODO RTC 116552 Clean up logic to map data to a struct + uint8_t l_idx = l_bucketOffset; + //Bucket id + o_data.bucketId = i_vDataPtr[l_idx]; + l_idx += sizeof(o_data.bucketId); + //Nominal + o_data.nomFreq = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.nomFreq); + o_data.VnestNomVltg = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.VnestNomVltg); + o_data.InestNomCurr = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.InestNomCurr); + o_data.VcsNomVltg = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.VcsNomVltg); + o_data.IcsNomCurr = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.IcsNomCurr); + + //PowerSave + o_data.PSFreq = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.PSFreq); + o_data.VnestPSVltg = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.VnestPSVltg); + o_data.InestPSCurr = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.InestPSCurr); + o_data.VcsPSVltg = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.VcsPSVltg); + o_data.IcsPSCurr = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.IcsPSCurr); + //Turbo + o_data.turboFreq = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.turboFreq); + o_data.VnestTurboVltg = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.VnestTurboVltg); + o_data.InestTurboCurr = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.InestTurboCurr); + o_data.VcsTurboVltg = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.VcsTurboVltg); + o_data.IcsTurboCurr = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.IcsTurboCurr); + + // Fvmin + o_data.fvminFreq = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.fvminFreq); + o_data.VnestFvminVltg = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.VnestFvminVltg); + o_data.InestFvminCurr = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.InestFvminCurr); + o_data.VcsFvminVltg = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.VcsFvminVltg); + o_data.IcsFvminCurr = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.IcsFvminCurr); + + //Lab + o_data.labFreq = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.labFreq); + o_data.VnestLabVltg = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.VnestLabVltg); + o_data.InestLabCurr = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.InestLabCurr); + o_data.VcsLabVltg = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.VcsLabVltg); + o_data.IcsLabCurr = *(reinterpret_cast<uint16_t*>( + const_cast<uint8_t*>(&i_vDataPtr[l_idx]))); + l_idx += sizeof(o_data.IcsLabCurr); + + } while(0); + return l_rc; } @@ -224,59 +1283,162 @@ fapi::ReturnCode fapiGetMvpdField(const fapi::MvpdRecord i_record, uint8_t * const i_pBuffer, uint32_t &io_fieldSize) { + uint8_t l_chipUnitNum = MVPD_INVALID_CHIP_UNIT; + errlHndl_t l_errl = NULL; fapi::ReturnCode l_rc; FAPI_DBG("fapiGetMvpdField entry"); do { + TARGETING::Target * l_pChipTarget = + reinterpret_cast<TARGETING::Target*>(i_procTarget.get()); + // Translate the FAPI record to a Hostboot record MVPD::mvpdRecord l_hbRecord = MVPD::MVPD_INVALID_RECORD; - - l_rc = fapi::MvpdRecordXlate(i_record, l_hbRecord); - + + l_rc = fapi::MvpdRecordXlate(i_record, l_hbRecord, l_chipUnitNum); + if (l_rc) { break; } - + // Translate the FAPI keyword to a Hostboot keyword MVPD::mvpdKeyword l_hbKeyword = MVPD::INVALID_MVPD_KEYWORD; - + l_rc = fapi::MvpdKeywordXlate(i_keyword, l_hbKeyword); - + if (l_rc) { break; } - - // Similarly to this function, deviceRead will return the size of the - // field if the pointer is NULL - size_t l_fieldLen = io_fieldSize; - errlHndl_t l_errl = deviceRead( - reinterpret_cast< TARGETING::Target*>(i_procTarget.get()), - i_pBuffer, - l_fieldLen, - DEVICE_MVPD_ADDRESS(l_hbRecord, l_hbKeyword)); - - if (l_errl) + // For #V keyword need to read the bucket id from the processor VPD + // and then read #V data to get the voltage bucket data. Use exsiting + // freq voltage service call to get the voltage bucket data + if(i_keyword == fapi::MVPD_KEYWORD_PDV) { - FAPI_ERR("fapiGetMvpdField: ERROR: deviceRead : errorlog PLID=0x%x", - l_errl->plid()); + fapi::voltageBucketData_t l_pVData; - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatError(reinterpret_cast<void *> (l_errl)); + // Get #V bucket data + l_rc = fapiGetPoundVBucketData(l_pChipTarget, + (uint32_t) l_hbRecord, + l_pVData); + if (l_rc) + { + FAPI_ERR("fapiGetMvpdField: Error getting #V bucket data " + "HUID: 0x%08X", + l_pChipTarget->getAttr<TARGETING::ATTR_HUID>()); + + break; + } + + // Get EX - CHPLET list and find the correct chiplet to read + // write attributes + std::vector<fapi::Target> l_exchiplets; + fapi::TargetState l_state = fapi::TARGET_STATE_PRESENT; + + l_rc = fapiGetChildChiplets( + i_procTarget,fapi::TARGET_TYPE_EX_CHIPLET, + l_exchiplets,l_state); + + if( l_rc) + { + FAPI_ERR("fapiGetMvpdField:Error getting exchiplet list"); + break; + } + + std::vector<fapi::Target>::iterator l_itr; + // Traverse through ex-chiplet and compare chip unit pos to find + // right ex chiplet + for(l_itr = l_exchiplets.begin();l_itr!=l_exchiplets.end();l_itr++) + { + uint8_t l_chipUnit = MVPD_INVALID_CHIP_UNIT; + // get chip unit + l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS,&(*(l_itr)),l_chipUnit); + + if( l_rc) + { + FAPI_ERR("fapiGetMvpdField:Err getting CHIP_UNIT_POS Attr"); + break; + } + + //Find correct chiplet + // If ex-chiplet chip unit pos does not match the one input + // record corresponds to then go to the next ex-chiplet + if( l_chipUnit != l_chipUnitNum) + { + continue; + } + // Matching ex-chiplet found. Write MVPD voltage bucket + // attributes associated to it. + l_rc = setVoltageBucketAttr(*l_itr,l_pVData); + + if( l_rc) + { + FAPI_ERR("fapiGetMvpdField:Error setting voltage bucket " + "attribute"); + break; + } + + // Read it back to get override value (if any) + l_rc = getVoltageBucketAttr(*l_itr,l_pVData,i_pBuffer, + io_fieldSize); + + if( l_rc) + { + FAPI_ERR("fapiGetMvpdField:Error reading voltage bucket " + "attribute"); + break; + } + // found correct core so we are done + break; + } //end for loop + + if( l_rc) + { + break; + } + + } + else // non-#V Module VPD data + { + // Similarly to this function, deviceRead will return the size of + // the field if the pointer is NULL + size_t l_fieldLen = io_fieldSize; + + l_errl = deviceRead( + reinterpret_cast< TARGETING::Target*>(i_procTarget.get()), + i_pBuffer, + l_fieldLen, + DEVICE_MVPD_ADDRESS(l_hbRecord, l_hbKeyword)); + + if (l_errl) + { + FAPI_ERR("fapiGetMvpdField: ERROR: deviceRead : errorlog PLID=0x%x", + l_errl->plid()); + + // Add the error log pointer as data to the ReturnCode + l_rc.setPlatError(reinterpret_cast<void *> (l_errl)); + + break; + } + + // Success, update callers io_fieldSize for the case where the + // pointer is NULL and deviceRead returned the actual size + io_fieldSize = l_fieldLen; - break; } - // Success, update callers io_fieldSize for the case where the pointer - // is NULL and deviceRead returned the actual size - io_fieldSize = l_fieldLen; FAPI_DBG("fapiGetMvpdField: returning field len=0x%x", io_fieldSize); } while(0); + if( l_rc) + { + io_fieldSize = 0; + } + FAPI_DBG( "fapiGetMvpdField: exit" ); return l_rc; @@ -292,30 +1454,31 @@ fapi::ReturnCode fapiSetMvpdField(const fapi::MvpdRecord i_record, const uint32_t i_fieldSize) { fapi::ReturnCode l_rc; + uint8_t l_chipUnitNum = MVPD_INVALID_CHIP_UNIT; FAPI_DBG("fapiSetMvpdField entry"); do { // Translate the FAPI record to a Hostboot record MVPD::mvpdRecord l_hbRecord = MVPD::MVPD_INVALID_RECORD; - - l_rc = fapi::MvpdRecordXlate(i_record, l_hbRecord); - + + l_rc = fapi::MvpdRecordXlate(i_record, l_hbRecord, l_chipUnitNum); + if (l_rc) { break; } - + // Translate the FAPI keyword to a Hostboot keyword MVPD::mvpdKeyword l_hbKeyword = MVPD::INVALID_MVPD_KEYWORD; - + l_rc = fapi::MvpdKeywordXlate(i_keyword, l_hbKeyword); - + if (l_rc) { break; } - + size_t l_fieldLen = i_fieldSize; errlHndl_t l_errl = deviceWrite( @@ -323,7 +1486,7 @@ fapi::ReturnCode fapiSetMvpdField(const fapi::MvpdRecord i_record, const_cast<uint8_t *>(i_pBuffer), l_fieldLen, DEVICE_MVPD_ADDRESS(l_hbRecord, l_hbKeyword)); - + if (l_errl) { FAPI_ERR("fapiSetMvpdField: ERROR: deviceWrite : errorlog PLID=0x%x", @@ -342,4 +1505,186 @@ fapi::ReturnCode fapiSetMvpdField(const fapi::MvpdRecord i_record, return l_rc; } +fapi::ReturnCode fapiGetPoundVBucketData( + const TARGETING::Target * i_pChipTarget, + const uint32_t i_record, + fapi::voltageBucketData_t & o_data) +{ + fapi::ReturnCode l_rc; + size_t l_vpdSize = 0; + uint8_t *l_prDataPtr = NULL; + uint8_t *l_vDataPtr = NULL; + errlHndl_t l_err = NULL; + + do + { + // Read PR keyword size + l_err = deviceRead( (TARGETING::Target *)i_pChipTarget, + NULL, + l_vpdSize, + DEVICE_MVPD_ADDRESS( MVPD::VINI, + MVPD::PR ) ); + if (l_err) + { + FAPI_ERR("Error getting PR keyword size for HUID: " + "0x%08X, errorlog PLID=0x%x", + i_pChipTarget->getAttr<TARGETING::ATTR_HUID>(), + l_err->plid()); + + // Add the error log pointer as data to the ReturnCode + l_rc.setPlatError(reinterpret_cast<void *> (l_err)); + + break; + } + + // Assert if deviceRead returned success but size is 0 + assert(l_vpdSize != 0); + + l_prDataPtr = new uint8_t [l_vpdSize]; + + // Read PR keyword data + l_err = deviceRead( (TARGETING::Target *)i_pChipTarget, + l_prDataPtr, + l_vpdSize, + DEVICE_MVPD_ADDRESS( MVPD::VINI, + MVPD::PR ) ); + if (l_err) + { + FAPI_ERR("Error getting PR keyword data for HUID: " + "0x%08X, errorlog PLID=0x%x", + i_pChipTarget->getAttr<TARGETING::ATTR_HUID>(), + l_err->plid()); + + // Add the error log pointer as data to the ReturnCode + l_rc.setPlatError(reinterpret_cast<void *> (l_err)); + + break; + } + + // Get non-ECO mode bucket id - bits 4-7 + uint8_t l_bucketId = + (l_prDataPtr[NON_ECO_VOLTAGE_BUCKET_OFFFSET] & BUCKET_ID_MASK); + if( l_bucketId == 0) + { + FAPI_INF("bucketId is zero, using alternate offset"); + l_bucketId = l_prDataPtr[ALTERNATE_BUCKET_OFFSET]; + } + if( l_bucketId == 0) // VPD is not initialized / programmed correctly + { + FAPI_INF("bucketId is zero, invalid VPD, using default value 0x%x", + DEFAULT_BUCKET); + l_bucketId = DEFAULT_BUCKET; + } + + l_vpdSize = 0; + l_err = deviceRead( (TARGETING::Target *)i_pChipTarget, + NULL, + l_vpdSize, + DEVICE_MVPD_ADDRESS( i_record, + MVPD::pdV ) ); + if (l_err) + { + FAPI_ERR("Error getting #V keyword size for HUID: " + "0x%08X, errorlog PLID=0x%x", + i_pChipTarget->getAttr<TARGETING::ATTR_HUID>(), + l_err->plid()); + + // Add the error log pointer as data to the ReturnCode + l_rc.setPlatError(reinterpret_cast<void *> (l_err)); + + break; + } + + // Assert if deviceRead returned success but size is 0 + assert(l_vpdSize != 0); + + l_vDataPtr = new uint8_t [l_vpdSize]; + + l_err = deviceRead( (TARGETING::Target *)i_pChipTarget, + l_vDataPtr, + l_vpdSize, + DEVICE_MVPD_ADDRESS( i_record, + MVPD::pdV ) ); + if (l_err) + { + FAPI_ERR("Error getting #V keyword data for HUID: " + "0x%08X, errorlog PLID=0x%x", + i_pChipTarget->getAttr<TARGETING::ATTR_HUID>(), + l_err->plid()); + + // Add the error log pointer as data to the ReturnCode + l_rc.setPlatError(reinterpret_cast<void *> (l_err)); + + break; + } + + uint8_t l_version = 0x0; + + l_version = l_vDataPtr[0]; + + if( l_version != POUND_V_VERSION_01) + { + FAPI_ERR("Found unsupported version:[0x%02X] of " + "the #V data", l_version); + + /*@ + * @errortype + * @moduleid fapi::MOD_GET_POUNDV_BUCKET_DATA + * @reasoncode fapi::RC_DATA_NOT_SUPPORTED + * @userdata1[0:31] Unsupported version + * @userdata1[32:63] Expected version + * @userdata2 #V KW data size + * @devdesc Unsupported #V keyword data version found. + */ + l_err = + new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_GET_POUNDV_BUCKET_DATA, + fapi::RC_DATA_NOT_SUPPORTED, + TWO_UINT32_TO_UINT64(l_version, POUND_V_VERSION_01), + l_vpdSize); + + // Callout HW as VPD data is incorrect + l_err->addHwCallout(i_pChipTarget, HWAS::SRCI_PRIORITY_HIGH, + HWAS::DECONFIG, HWAS::GARD_NULL); + + // Code (SW) callout in case this is downlevel VPD version + l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_MED); + + // Add the error log pointer as data to the ReturnCode + l_rc.setPlatError(reinterpret_cast<void *> (l_err)); + + break; + } + + // Parse #V Version one data to get bucket data + l_rc = fapiGetVerOneVoltageBucketData(i_pChipTarget, + l_bucketId, + l_vpdSize, + l_vDataPtr, + o_data); + if (l_rc) + { + FAPI_ERR("Error getting voltage bucket data for version 0x%x, " + "PR KW bucketId:[0x%02X], errorlog PLID=0x%x", + POUND_V_VERSION_01, l_bucketId, l_err->plid()); + + break; + } + + } while(0); + + if (l_prDataPtr != NULL) + { + delete [] l_prDataPtr; + } + if (l_vDataPtr != NULL) + { + delete [] l_vDataPtr; + } + + return l_rc; +} + } // extern "C" diff --git a/src/usr/hwpf/plat/plat.mk b/src/usr/hwpf/plat/plat.mk index 0c378aa32..4a6e3e098 100644 --- a/src/usr/hwpf/plat/plat.mk +++ b/src/usr/hwpf/plat/plat.mk @@ -5,7 +5,9 @@ # # OpenPOWER HostBoot Project # -# COPYRIGHT International Business Machines Corp. 2014 +# Contributors Listed Below - COPYRIGHT 2014 +# [+] 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. @@ -25,6 +27,8 @@ EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/include +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/pstates/pstates OBJS += fapiPlatHwAccess.o OBJS += fapiPlatHwpInvoker.o diff --git a/src/usr/targeting/common/xmltohb/common.mk b/src/usr/targeting/common/xmltohb/common.mk index 191ac983e..bdc529f20 100644 --- a/src/usr/targeting/common/xmltohb/common.mk +++ b/src/usr/targeting/common/xmltohb/common.mk @@ -87,6 +87,7 @@ FAPI_ATTR_SOURCES += erepair_thresholds.xml FAPI_ATTR_SOURCES += dram_training/mem_pll_setup/memb_pll_ring_attributes.xml FAPI_ATTR_SOURCES += runtime_attributes/memory_occ_attributes.xml FAPI_ATTR_SOURCES += proc_abus_dmi_xbus_scominit_attributes.xml +FAPI_ATTR_SOURCES += pstate_attributes.xml XMLTOHB_GENERIC_XML += generic.xml XMLTOHB_FAPI_XML += fapiattrs.xml |