diff options
author | Shakeeb <shakeebbk@in.ibm.com> | 2016-08-27 10:50:49 -0500 |
---|---|---|
committer | Sachin Gupta <sgupta2m@in.ibm.com> | 2016-08-30 06:01:06 -0400 |
commit | f2d94b5f809410300fe10dc9d0786790018463a0 (patch) | |
tree | 467f90297b0eb7c5c6672653d778ed4734c0d5a3 /src/hwpf/src/plat_ring_traverse.C | |
parent | 49b557dcae32250e8e06c4de895c0b7ba0e8009e (diff) | |
download | talos-sbe-f2d94b5f809410300fe10dc9d0786790018463a0.tar.gz talos-sbe-f2d94b5f809410300fe10dc9d0786790018463a0.zip |
SBE code restructure: sbe -> src rename
Change-Id: I6e4378d0e71a00ed2b239658d43f180df2a9b748
RTC:159709
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28875
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: RAJA DAS <rajadas2@in.ibm.com>
Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'src/hwpf/src/plat_ring_traverse.C')
-rw-r--r-- | src/hwpf/src/plat_ring_traverse.C | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/src/hwpf/src/plat_ring_traverse.C b/src/hwpf/src/plat_ring_traverse.C new file mode 100644 index 00000000..b7bdb73c --- /dev/null +++ b/src/hwpf/src/plat_ring_traverse.C @@ -0,0 +1,467 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/src/plat_ring_traverse.C $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* 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 */ + +#include <plat_ring_traverse.H> + +#include <p9_putRingUtils.H> // for RS4 decompression utilities +#include <sbeXipUtils.H> +#include <fapi2AttributeService.H> // for FAPI_ATTR_GET +#include <plat_target_utils.H> // for plat_getChipTarget + +// SEEPROM start address +const uint32_t g_seepromAddr = SBE_SEEPROM_BASE_ORIGIN; +using namespace RING_TYPES; +const uint32_t CACHE_CONTAINED_MODE = 4; +const uint32_t RISK_LEVEL_MODE = 1; +#define CACHE_CONTAINED_MODE_OFFSET_IN_TOR 1 +#define RISK_LEVEL_MODE_OFFSET_IN_TOR 2 +#define OVERRIDE_VARIANT_SIZE 1 + + +/// +/// @brief This is a plat pecific (SBE Plat) function that locates the +/// Ring Container in the image and calls the functin to decompress the +/// RS4 string and apply it to the hardware. +/// @param i_target The target of Ring apply. +/// @param i_ringID The Ring ID that identifies the ring to be applied. +/// @return FAPI2_RC_SUCCESS on success, else error code. +/// +fapi2::ReturnCode findRS4InImageAndApply( + const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target, + const RingID i_ringID, + const fapi2::RingMode i_ringMode) +{ + SBE_TRACE(">> findRS4InImageAndApply"); + + fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; + bool l_applyOverride = false; + + do + { + //Apply scanring from .ring section + + // Get the address of the Section-TOR + P9XipHeader *l_hdr = getXipHdr(); + P9XipSection *l_section = + &(l_hdr->iv_section[P9_XIP_SECTION_SBE_RINGS]); + + if (!(l_section->iv_offset)) + { + SBE_TRACE("No ring data in .RING section"); + break; + } + + SectionTOR *l_sectionTOR = (SectionTOR *)(g_seepromAddr + + l_section->iv_offset); + + l_rc = getRS4ImageFromTor(i_target,i_ringID,l_sectionTOR, + l_applyOverride, + l_section->iv_offset, + i_ringMode); + + if(l_rc != fapi2::FAPI2_RC_SUCCESS) + { + break; + } + + //Apply scanring from .ring section + l_applyOverride = true; + l_section = NULL; + l_section = + &(l_hdr->iv_section[P9_XIP_SECTION_SBE_OVERRIDES]); + + if (!(l_section->iv_offset)) + { + SBE_TRACE("No ring data in .OVERRIDE section"); + break; + } + + l_sectionTOR = NULL; + l_sectionTOR = (SectionTOR *)(g_seepromAddr + + l_section->iv_offset); + + + l_rc = getRS4ImageFromTor(i_target,i_ringID,l_sectionTOR, + l_applyOverride, + l_section->iv_offset, + i_ringMode); + }while(0); + + return l_rc; +} + +fapi2::ReturnCode getRS4ImageFromTor( + const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target, + const RingID i_ringID, + SectionTOR *i_sectionTOR, + bool i_applyOverride, + const uint32_t i_sectionOffset, + const fapi2::RingMode i_ringMode) +{ + + // Determine the Offset ID and Ring Type for the given Ring ID. + uint32_t l_torOffset = 0; + RINGTYPE l_ringType = COMMON_RING; + CHIPLET_TYPE l_chipLetType; + fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; + do + { + + getRingProperties(i_ringID, l_torOffset, l_ringType,l_chipLetType); + if(INVALID_RING == l_torOffset) + { + SBE_TRACE("Invalid Ring ID - %d", i_ringID); + l_rc = fapi2::FAPI2_RC_INVALID_PARAMETER; + break; + } + + CHIPLET_DATA l_chipletData; + l_chipletData.iv_base_chiplet_number = 0; + l_chipletData.iv_num_common_rings = 0; + l_chipletData.iv_num_instance_rings = 0; + + uint8_t l_chipletID = i_target.getChipletNumber(); + uint16_t l_cpltRingVariantSz = 0; + uint32_t l_sectionOffset = 0; + switch(l_chipLetType) + { + case PERV_TYPE: // PERV + l_chipletData = PERV::g_pervData; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(PERV::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_PERV_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_PERV_INSTANCE_RING; + } + + break; + + case N0_TYPE: // Nest - N0 + l_chipletData = N0::g_n0Data; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(N0::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_N0_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_N0_INSTANCE_RING; + } + + break; + + case N1_TYPE: // Nest - N1 + l_chipletData = N1::g_n1Data; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(N1::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_N1_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_N1_INSTANCE_RING; + } + + break; + + case N2_TYPE: // Nest - N2 + l_chipletData = N2::g_n2Data; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(N2::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_N2_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_N2_INSTANCE_RING; + } + + break; + + case N3_TYPE: // Nest - N3 + l_chipletData = N3::g_n3Data; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(N3::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_N3_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_N3_INSTANCE_RING; + } + + break; + + case XB_TYPE: // XB - XBus2 + l_chipletData = XB::g_xbData; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(XB::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_XB_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_XB_INSTANCE_RING; + } + + break; + + case MC_TYPE: // MC - MC23 + l_chipletData = MC::g_mcData; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(MC::RingVariants)/ + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_MC_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_MC_INSTANCE_RING; + } + + break; + + case OB0_TYPE: // OB0 + l_chipletData = OB0::g_ob0Data; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(OB0::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_OB0_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_OB0_INSTANCE_RING; + } + + break; + case OB1_TYPE: // OB1 + l_chipletData = OB1::g_ob1Data; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(OB1::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_OB1_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_OB1_INSTANCE_RING; + } + + break; + case OB2_TYPE: // OB2 + l_chipletData = OB2::g_ob2Data; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(OB2::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_OB2_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_OB2_INSTANCE_RING; + } + + break; + case OB3_TYPE: // OB3 + l_chipletData = OB3::g_ob3Data; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(OB3::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_OB3_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_OB3_INSTANCE_RING; + } + + break; + + + case PCI0_TYPE: // PCI - PCI0 + l_chipletData = PCI0::g_pci0Data; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(PCI0::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_PCI0_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_PCI0_INSTANCE_RING; + } + + break; + + case PCI1_TYPE: // PCI - PCI1 + l_chipletData = PCI1::g_pci1Data; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(PCI1::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_PCI1_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_PCI1_INSTANCE_RING; + } + + break; + + case PCI2_TYPE: // PCI - PCI2 + l_chipletData = PCI2::g_pci2Data; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(PCI2::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_PCI2_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_PCI2_INSTANCE_RING; + } + + break; + + case EQ_TYPE: // EQ - Quad 0 - Quad 5 + l_chipletData = EQ::g_eqData; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + ( sizeof(EQ::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_EQ_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_EQ_INSTANCE_RING; + } + + break; + + case EC_TYPE: // EC - Core 0 - 23 + l_chipletData = EC::g_ecData; + l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE : + (sizeof(EC::RingVariants) / + sizeof(l_cpltRingVariantSz)); + + l_sectionOffset = i_sectionTOR->TOC_EC_COMMON_RING; + if(INSTANCE_RING == l_ringType) + { + l_sectionOffset = i_sectionTOR->TOC_EC_INSTANCE_RING; + } + + break; + + default: + SBE_TRACE("Invalid Target/ChipletID - %d", l_chipletID); + l_rc = fapi2::FAPI2_RC_INVALID_PARAMETER; + break; + + } // end of switch(l_chipletID) + + if (l_rc) + { + break; + } + + FAPI_INF("l_sectionOffset %08x",l_sectionOffset); + // Determine the section TOR address for the ring + uint32_t *l_sectionAddr = reinterpret_cast<uint32_t *>(g_seepromAddr + + i_sectionOffset + l_sectionOffset); + + SBE_TRACE ("l_sectionAddr %08X",l_sectionAddr); + + + if(INSTANCE_RING == l_ringType) + { + if ( l_chipletID > l_chipletData.iv_base_chiplet_number) + { + uint8_t l_chipletOffset = + (l_chipletID - l_chipletData.iv_base_chiplet_number); + l_sectionAddr += (l_chipletOffset * + (l_chipletData.iv_num_instance_rings )); + } + } + + // The ring variants in section TOR are expected to be in the sequence - + // 1. Base + // 2. Cache-Contained + // 3. Risk Level + + SBE_TRACE ("l_sectionAddr %08X",l_sectionAddr); + + // TOR records of Ring TOR are 2 bytes in size. + uint16_t *l_ringTorAddr = reinterpret_cast<uint16_t *>(l_sectionAddr) + + (l_torOffset * l_cpltRingVariantSz); + SBE_TRACE ("ring tor address %04X\n",l_ringTorAddr); + + // If there are non-base variants of the ring, we'll have to check + // attributes to determine the sequence of ring apply. + if( l_cpltRingVariantSz > 1) + { + // Check if this is cache-contained IPL + uint8_t l_iplPhase; + FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_IPL_PHASE, + fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> (), + l_iplPhase); + + // 4 : Cache Contained mode + if(CACHE_CONTAINED_MODE == l_iplPhase) + { + l_ringTorAddr += CACHE_CONTAINED_MODE_OFFSET_IN_TOR; + } + else + { + // Check if this is risk-level IPL + uint8_t l_riskLevel; + FAPI_ATTR_GET(fapi2::ATTR_RISK_LEVEL, + fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> (), + l_riskLevel); + if(RISK_LEVEL_MODE == l_riskLevel) + { + l_ringTorAddr += RISK_LEVEL_MODE_OFFSET_IN_TOR; + } + } + } + + SBE_TRACE("l_ringTorAddr %u",*l_ringTorAddr); + if(*l_ringTorAddr != 0) + { + uint8_t *l_addr = reinterpret_cast<uint8_t *>(l_sectionAddr); + uint8_t *l_rs4Address = reinterpret_cast<uint8_t *> + (l_addr + *l_ringTorAddr); + SBE_TRACE("l_rs4Address %08x",l_rs4Address); + l_rc = rs4DecompressionSvc(i_target,l_rs4Address, + i_applyOverride,i_ringMode); + if(l_rc != fapi2::FAPI2_RC_SUCCESS) + { + SBE_TRACE("Error from applyRS4_SS"); + break; + } + } + else + { + SBE_TRACE("Ring image is not found for this is ringId %u",i_ringID); + } + }while(0); + + SBE_TRACE("<< findRS4InImageAndApply Exit for ringId %d",i_ringID); + return l_rc; +} + |