/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfPhbUtils.C $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2013,2015 */ /* [+] 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 prdfPhbUtils.C */ #include #include #include using namespace TARGETING; namespace PRDF { using namespace PlatServices; namespace Proc { int32_t getConfiguredPHB( TargetHandle_t i_procTrgt, uint32_t i_iopciIdx, uint32_t i_clkIdx, TargetHandle_t & o_phbTrgt ) { #define PRDF_FUNC "[Proc::getConfiguredPHB] " int32_t o_rc = SUCCESS; o_phbTrgt = NULL; // Reference PCI Express Controller Functional Spec // (pe_P8spec_master104.pdf). Tables in chapter 6: IO Operation Modes enum TableBounds { MAX_CONFIGS = 14, MAX_FIRS = 3, MAX_CLOCKS = 2, // Array index for the processor models. MURANO_IDX = 0, VENICE_IDX, NAPLES_IDX, MAX_MODELS, }; enum TableValues { // These PHB enums must match the PHB position number. PHB0 = 0, PHB1, PHB2, PHB3, // The dSMP connections are not used but we will still list them in the // table just in case the are needed later. NONE = MAX_PHB_PER_PROC, SMP0 = MAX_PHB_PER_PROC, SMP1 = MAX_PHB_PER_PROC, }; static const uint8_t table[MAX_MODELS][MAX_CONFIGS][MAX_FIRS][MAX_CLOCKS] = { { //-------------------Murano------------------| //--IOPCIFIR-0-||-IOPCIFIR-1--||-IOPCIFIR-2--| //---A--|--B---||---A--|--B---||---A--|--B---| { {PHB0, PHB0}, {PHB1,NONE}, {NONE, NONE} }, // 0x0 { {PHB0, PHB0}, {PHB1,NONE}, {NONE, NONE} }, // 0x1 { {PHB0, NONE}, {PHB1,NONE}, {NONE, NONE} }, // 0x2 { {PHB0, PHB2}, {PHB1,NONE}, {NONE, NONE} }, // 0x3 { {PHB0, SMP0}, {PHB1,NONE}, {NONE, NONE} }, // 0x4 { {PHB0, SMP0}, {PHB1,NONE}, {NONE, NONE} }, // 0x5 { {PHB1, PHB1}, {SMP1,NONE}, {NONE, NONE} }, // 0x6 { {PHB1, PHB2}, {SMP1,NONE}, {NONE, NONE} }, // 0x7 { {SMP1, SMP0}, {PHB1,NONE}, {NONE, NONE} }, // 0x8 { {SMP1, SMP0}, {PHB1,NONE}, {NONE, NONE} }, // 0x9 { {SMP1, PHB2}, {SMP0,NONE}, {NONE, NONE} }, // 0xA { {PHB1, SMP0}, {SMP1,NONE}, {NONE, NONE} }, // 0xB { {SMP1, PHB2}, {PHB1,NONE}, {NONE, NONE} }, // 0xC }, { //------------------Venice-------------------| //--IOPCIFIR-0-||-IOPCIFIR-1--||-IOPCIFIR-2--| //---A--|--B---||---A--|--B---||---A--|--B---| { {PHB0, PHB0}, {PHB1, PHB1}, {NONE, NONE} }, // 0x0 { {PHB0, PHB0}, {PHB1, PHB2}, {NONE, NONE} }, // 0x1 { {PHB0, NONE}, {PHB1, PHB1}, {NONE, NONE} }, // 0x2 { {PHB0, NONE}, {PHB1, PHB2}, {NONE, NONE} }, // 0x3 { {PHB0, SMP0}, {PHB1, PHB1}, {NONE, NONE} }, // 0x4 { {PHB0, SMP0}, {PHB1, PHB2}, {NONE, NONE} }, // 0x5 { {SMP1, PHB0}, {PHB1, PHB1}, {NONE, NONE} }, // 0x6 { {SMP1, PHB0}, {PHB1, PHB2}, {NONE, NONE} }, // 0x7 { {SMP1, SMP0}, {PHB1, PHB1}, {NONE, NONE} }, // 0x8 { {SMP1, SMP0}, {PHB1, PHB2}, {NONE, NONE} }, // 0x9 { {SMP1, SMP0}, {PHB1, PHB2}, {NONE, NONE} }, // 0xA { {SMP1, SMP0}, {PHB1, PHB2}, {NONE, NONE} }, // 0xB { {SMP1, PHB0}, {PHB1, PHB2}, {NONE, NONE} }, // 0xC }, { //------------------Naples-------------------| //--IOPCIFIR-0-||-IOPCIFIR-1--||-IOPCIFIR-2--| //---A--|--B---||---A--|--B---||---A--|--B---| { {PHB0, PHB0}, {PHB1, PHB1}, {PHB3, NONE} }, // 0x0 { {PHB0, PHB0}, {PHB1, PHB2}, {PHB3, NONE} }, // 0x1 { {PHB0, NONE}, {PHB1, PHB1}, {PHB3, NONE} }, // 0x2 { {PHB0, NONE}, {PHB1, PHB2}, {PHB3, NONE} }, // 0x3 { {PHB0, NONE}, {PHB1, PHB1}, {PHB3, NONE} }, // 0x4 { {PHB0, NONE}, {PHB1, PHB2}, {PHB3, NONE} }, // 0x5 { {NONE, PHB0}, {PHB1, PHB1}, {PHB3, NONE} }, // 0x6 { {NONE, PHB0}, {PHB1, PHB2}, {PHB3, NONE} }, // 0x7 { {NONE, NONE}, {PHB1, PHB1}, {PHB3, NONE} }, // 0x8 { {NONE, NONE}, {PHB1, PHB2}, {PHB3, NONE} }, // 0x9 { {NONE, NONE}, {PHB1, PHB2}, {PHB3, NONE} }, // 0xA { {NONE, NONE}, {PHB1, PHB2}, {PHB3, NONE} }, // 0xB { {NONE, PHB0}, {PHB1, PHB2}, {PHB3, NONE} }, // 0xC }, }; do { // Check parameters if ( MAX_FIRS <= i_iopciIdx ) { PRDF_ERR( PRDF_FUNC "i_iopciIdx is unsupported: %d", i_iopciIdx ); o_rc = FAIL; break; } if ( MAX_CLOCKS <= i_clkIdx ) { PRDF_ERR( PRDF_FUNC "i_clkIdx is unsupported: %d", i_clkIdx ); o_rc = FAIL; break; } // Get the processor model and config table. MODEL model = getProcModel( i_procTrgt ); uint32_t modelIdx = MAX_MODELS; switch ( model ) { case MODEL_MURANO: modelIdx = MURANO_IDX; break; case MODEL_VENICE: modelIdx = VENICE_IDX; break; case MODEL_NAPLES: modelIdx = NAPLES_IDX; break; default: PRDF_ERR( PRDF_FUNC "unsupported processor model: %d", model ); o_rc = FAIL; } if ( SUCCESS != o_rc ) break; // Get the PHB configuration. uint32_t phbConfig = getPhbConfig( i_procTrgt ); if ( MAX_CONFIGS <= phbConfig ) { PRDF_ERR( PRDF_FUNC "unsupportd PHB config: %d", phbConfig ); o_rc = FAIL; break; } // Get the PHB target, if it exists. uint8_t phbPos = table[modelIdx][phbConfig][i_iopciIdx][i_clkIdx]; if ( MAX_PHB_PER_PROC > phbPos ) { o_phbTrgt = getConnectedChild( i_procTrgt, TYPE_PCI, phbPos ); if ( NULL == o_phbTrgt ) // Target should exist. { PRDF_ERR( PRDF_FUNC "getConnectedChild(%d) failed", phbPos ); o_rc = FAIL; break; } } } while (0); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "Failed: i_procTrgt=0x%08x i_iopciIdx=%d " "i_clkIdx=%d", getHuid(i_procTrgt), i_iopciIdx, i_clkIdx ); } return o_rc; #undef PRDF_FUNC } } // end namespace Proc } // end namespace PRDF