/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/import/chips/p9/procedures/hwp/nest/p9_sbe_scominit.C $ */ /* */ /* OpenPOWER sbe Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2015,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ /* You may obtain a copy of the License at */ /* */ /* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ /* Unless required by applicable law or agreed to in writing, software */ /* distributed under the License is distributed on an "AS IS" BASIS, */ /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ /* implied. See the License for the specific language governing */ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ //------------------------------------------------------------------------------ /// /// @file p9_sbe_scominit.C /// @brief Peform SCOM initialization required for fabric & HBI operation (FAPI2) /// /// @author Joe McGill /// @author Christy Graves /// // // *HWP HWP Owner: Joe McGill // *HWP FW Owner: Thi Tran // *HWP Team: Nest // *HWP Level: 2 // *HWP Consumed by: SBE // //------------------------------------------------------------------------------ // Includes //------------------------------------------------------------------------------ #include #include #include #include #include #include #include //------------------------------------------------------------------------------ // Constant definitions //------------------------------------------------------------------------------ // XSCOM/LPC BAR constants const uint64_t XSCOM_BAR_MASK = 0xFF000003FFFFFFFFULL; const uint64_t LPC_BAR_MASK = 0xFF000000FFFFFFFFULL; // FBC FIR constants const uint64_t FBC_CENT_FIR_ACTION0 = 0x0000000000000000ULL; const uint64_t FBC_CENT_FIR_ACTION1 = 0x0440000000000000ULL; const uint64_t FBC_CENT_FIR_MASK = 0x111FC00000000000ULL; const uint64_t FBC_WEST_FIR_ACTION0 = 0x0000000000000000ULL; const uint64_t FBC_WEST_FIR_ACTION1 = 0x0000000000000000ULL; const uint64_t FBC_WEST_FIR_MASK = 0x0000FFFFC0000000ULL; const uint64_t FBC_EAST_FIR_ACTION0 = 0x0000000000000000ULL; const uint64_t FBC_EAST_FIR_ACTION1 = 0x0000000000000000ULL; const uint64_t FBC_EAST_FIR_MASK = 0x00FF1FFFC0000000ULL; // LPC FIR constants const uint64_t LPC_FIR_ACTION0 = 0x0000000000000000ULL; const uint64_t LPC_FIR_ACTION1 = 0xFF00000000000000ULL; const uint64_t LPC_FIR_MASK = 0x00F0000000000000ULL; // PBA FIR constants const uint64_t PBA_FIR_ACTION0 = 0x0000000000000000ULL; const uint64_t PBA_FIR_ACTION1 = 0x0C0100600C000000ULL; const uint64_t PBA_FIR_MASK = 0x3082448062FC0000ULL; //------------------------------------------------------------------------------ // Function definitions //------------------------------------------------------------------------------ fapi2::ReturnCode p9_sbe_scominit(const fapi2::Target& i_target) { FAPI_DBG("Entering ..."); fapi2::Target FAPI_SYSTEM; uint64_t l_base_addr_nm0; uint64_t l_base_addr_nm1; uint64_t l_base_addr_m; uint64_t l_base_addr_mmio; // set fabric topology information in each pervasive chiplet (outside of EC/EP) { // read fabric topology attributes uint32_t l_fbc_system_id; uint8_t l_fbc_group_id; uint8_t l_fbc_chip_id; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_SYSTEM_ID, i_target, l_fbc_system_id), "Error from FAPI_ATTR_GET (ATTR_PROC_FABRIC_SYSTEM_ID)"); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_GROUP_ID, i_target, l_fbc_group_id), "Error from FAPI_ATTR_GET (ATTR_PROC_FABRIC_GROUP_ID)"); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_CHIP_ID, i_target, l_fbc_chip_id), "Error from FAPI_ATTR_GET (ATTR_PROC_FABRIC_CHIP_ID)"); for (auto& l_chplt_target : i_target.getChildren (static_cast(fapi2::TARGET_FILTER_TP | fapi2::TARGET_FILTER_ALL_NEST | fapi2::TARGET_FILTER_XBUS | fapi2::TARGET_FILTER_ALL_OBUS | fapi2::TARGET_FILTER_ALL_MC | fapi2::TARGET_FILTER_ALL_PCI), fapi2::TARGET_STATE_FUNCTIONAL)) { fapi2::buffer l_cplt_conf0; FAPI_TRY(fapi2::getScom(l_chplt_target, PERV_CPLT_CONF0, l_cplt_conf0), "Error from getScom (PERV_CPLT_CONF0)"); l_cplt_conf0.insertFromRight (l_fbc_system_id) .insertFromRight(l_fbc_group_id) .insertFromRight(l_fbc_chip_id); FAPI_TRY(fapi2::putScom(l_chplt_target, PERV_CPLT_CONF0, l_cplt_conf0), "Error from putScom (PERV_CPLT_CONF0)"); } } // determine base address of chip nm/m/mmmio regions in real address space FAPI_TRY(p9_fbc_utils_get_chip_base_address(i_target, l_base_addr_nm0, l_base_addr_nm1, l_base_addr_m, l_base_addr_mmio), "Error from p9_fbc_utils_get_chip_base_address"); // set XSCOM BAR { fapi2::buffer l_xscom_bar; uint64_t l_xscom_bar_offset; FAPI_DBG("Configuring XSCOM BAR"); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_XSCOM_BAR_BASE_ADDR_OFFSET, FAPI_SYSTEM, l_xscom_bar_offset), "Error from FAPI_ATTR_GET (ATTR_PROC_XSCOM_BAR_BASE_ADDR_OFFSET)"); l_xscom_bar = l_base_addr_mmio; l_xscom_bar += l_xscom_bar_offset; FAPI_ASSERT((l_xscom_bar & XSCOM_BAR_MASK) == 0, fapi2::P9_SBE_SCOMINIT_XSCOM_BAR_ATTR_ERR(). set_TARGET(i_target). set_XSCOM_BAR(l_xscom_bar). set_XSCOM_BAR_OFFSET(l_xscom_bar_offset). set_BASE_ADDR_MMIO(l_base_addr_mmio), "Invalid XSCOM BAR configuration!"); FAPI_TRY(fapi2::putScom(i_target, PU_XSCOM_BASE_REG, l_xscom_bar), "Error from putScom (PU_XSCOM_BASE_REG)"); } // set LPC BAR { fapi2::buffer l_lpc_bar; uint64_t l_lpc_bar_offset; FAPI_DBG("Configuring LPC BAR"); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_LPC_BAR_BASE_ADDR_OFFSET, FAPI_SYSTEM, l_lpc_bar_offset), "Error from FAPI_ATTR_GET (ATRR_PROC_LPC_BAR_BASE_ADDR_OFFSET"); l_lpc_bar = l_base_addr_mmio; l_lpc_bar += l_lpc_bar_offset; FAPI_ASSERT((l_lpc_bar & LPC_BAR_MASK) == 0, fapi2::P9_SBE_SCOMINIT_LPC_BAR_ATTR_ERR(). set_TARGET(i_target). set_LPC_BAR(l_lpc_bar). set_LPC_BAR_OFFSET(l_lpc_bar_offset). set_BASE_ADDR_MMIO(l_base_addr_mmio), "Invalid LPC BAR configuration!"); FAPI_TRY(fapi2::putScom(i_target, PU_LPC_BASE_REG, l_lpc_bar), "Error from putScom (PU_LPC_BASE_REG)"); } // configure FBC FIRs { fapi2::buffer l_scom_data; // CENT FAPI_DBG("Configuring FBC CENT FIR"); // clear FIR l_scom_data = 0; FAPI_TRY(fapi2::putScom(i_target, PU_PB_CENT_SM0_PB_CENT_FIR_REG, l_scom_data), "Error from putScom (PU_PB_CENT_SM0_PB_CENT_FIR_REG)"); // configure action/mask l_scom_data = FBC_CENT_FIR_ACTION0; FAPI_TRY(fapi2::putScom(i_target, PU_PB_CENT_SM0_PB_CENT_FIR_ACTION0_REG, l_scom_data), "Error from putScom (PU_PB_CENT_SM0_PB_CENT_FIR_ACTION0_REG)"); l_scom_data = FBC_CENT_FIR_ACTION1; FAPI_TRY(fapi2::putScom(i_target, PU_PB_CENT_SM0_PB_CENT_FIR_ACTION1_REG, l_scom_data), "Error from putScom (PU_PB_CENT_SM0_PB_CENT_FIR_ACTION1_REG)"); l_scom_data = FBC_CENT_FIR_MASK; FAPI_TRY(fapi2::putScom(i_target, PU_PB_CENT_SM0_PB_CENT_FIR_MASK_REG, l_scom_data), "Error from putScom (PU_PB_CENT_SM0_PB_CENT_FIR_MASK_REG)"); // WEST FAPI_DBG("Configuring FBC WEST FIR"); // clear FIR l_scom_data = 0; FAPI_TRY(fapi2::putScom(i_target, PU_PB_WEST_SM0_PB_WEST_FIR_REG, l_scom_data), "Error from putScom (PU_PB_WEST_SM0_PB_WEST_FIR_REG)"); // configure action/mask l_scom_data = FBC_WEST_FIR_ACTION0; FAPI_TRY(fapi2::putScom(i_target, PU_PB_WEST_SM0_PB_WEST_FIR_ACTION0_REG, l_scom_data), "Error from putScom (PU_PB_WEST_SM0_PB_WEST_FIR_ACTION0_REG)"); l_scom_data = FBC_WEST_FIR_ACTION1; FAPI_TRY(fapi2::putScom(i_target, PU_PB_WEST_SM0_PB_WEST_FIR_ACTION1_REG, l_scom_data), "Error from putScom (PU_PB_WEST_SM0_PB_WEST_FIR_ACTION1_REG)"); l_scom_data = FBC_WEST_FIR_MASK; FAPI_TRY(fapi2::putScom(i_target, PU_PB_WEST_SM0_PB_WEST_FIR_MASK_REG, l_scom_data), "Error from putScom (PU_PB_WEST_SM0_PB_WEST_FIR_MASK_REG)"); // EAST FAPI_DBG("Configuring FBC EAST FIR"); // clear FIR l_scom_data = 0; FAPI_TRY(fapi2::putScom(i_target, PU_PB_EAST_FIR_REG, l_scom_data), "Error from putScom (PU_PB_EAST_FIR_REG)"); // configure action/mask l_scom_data = FBC_EAST_FIR_ACTION0; FAPI_TRY(fapi2::putScom(i_target, PU_PB_EAST_FIR_ACTION0_REG, l_scom_data), "Error from putScom (PU_PB_EAST_FIR_ACTION0_REG)"); l_scom_data = FBC_EAST_FIR_ACTION1; FAPI_TRY(fapi2::putScom(i_target, PU_PB_EAST_FIR_ACTION1_REG, l_scom_data), "Error from putScom (PU_PB_EAST_FIR_ACTION1_REG)"); l_scom_data = FBC_EAST_FIR_MASK; FAPI_TRY(fapi2::putScom(i_target, PU_PB_EAST_FIR_MASK_REG, l_scom_data), "Error from putScom (PU_PB_EAST_FIR_MASK_REG)"); } // configure PBA FIRs { fapi2::buffer l_scom_data; // clear FIR FAPI_DBG("Configuring PBA FIR"); l_scom_data = 0; FAPI_TRY(fapi2::putScom(i_target, PU_PBAFIR, l_scom_data), "Error from putScom (PU_PBAFIR)"); // configure action/mask l_scom_data = PBA_FIR_ACTION0; FAPI_TRY(fapi2::putScom(i_target, PU_PBAFIRACT0, l_scom_data), "Error from putScom (PU_PBAFIRACT0)"); l_scom_data = PBA_FIR_ACTION1; FAPI_TRY(fapi2::putScom(i_target, PU_PBAFIRACT1, l_scom_data), "Error from putScom (PU_PBAFIRACT1)"); l_scom_data = PBA_FIR_MASK; FAPI_TRY(fapi2::putScom(i_target, PU_PBAFIRMASK, l_scom_data), "Error from putScom (PU_PBAFIRMASK)"); } // configure LPC FIRs { fapi2::buffer l_scom_data; // clear FIR FAPI_DBG("Configuring LPC FIR"); l_scom_data = 0; FAPI_TRY(fapi2::putScom(i_target, PU_SYNC_FIR_REG, l_scom_data), "Error from putScom (PU_SYNC_FIR_REG)"); // configure action/mask l_scom_data = LPC_FIR_ACTION0; FAPI_TRY(fapi2::putScom(i_target, PU_SYNC_FIR_ACTION0_REG, l_scom_data), "Error from putScom (PU_SYNC_FIR_ACTION0_REG)"); l_scom_data = LPC_FIR_ACTION1; FAPI_TRY(fapi2::putScom(i_target, PU_SYNC_FIR_ACTION1_REG, l_scom_data), "Error from putScom (PU_SYNC_FIR_ACTION1_REG)"); l_scom_data = LPC_FIR_MASK; FAPI_TRY(fapi2::putScom(i_target, PU_SYNC_FIR_MASK_REG, l_scom_data), "Error from putScom (PU_SYNC_FIR_MASK_REG)"); } // configure chiplet pervasive FIRs / XFIRs { uint8_t l_mc_sync_mode = 0; fapi2::TargetFilter l_target_filter = static_cast(fapi2::TARGET_FILTER_TP | fapi2::TARGET_FILTER_ALL_NEST | fapi2::TARGET_FILTER_XBUS | fapi2::TARGET_FILTER_ALL_OBUS | fapi2::TARGET_FILTER_ALL_PCI); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MC_SYNC_MODE, i_target, l_mc_sync_mode), "Error from FAPI_ATTR_GET (ATTR_MC_SYNC_MODE)"); if (l_mc_sync_mode) { l_target_filter = static_cast(l_target_filter | fapi2::TARGET_FILTER_ALL_MC); } for (auto& l_chplt_target : i_target.getChildren(l_target_filter, fapi2::TARGET_STATE_FUNCTIONAL)) { FAPI_INF("Call p9_sbe_common_configure_chiplet_FIR"); FAPI_TRY(p9_sbe_common_configure_chiplet_FIR(l_chplt_target)); } } // configure PCI tracing logic { for (auto& l_chplt_target : i_target.getChildren (static_cast(fapi2::TARGET_FILTER_ALL_PCI), fapi2::TARGET_STATE_FUNCTIONAL)) { fapi2::buffer l_dbg_mode_reg; fapi2::buffer l_dbg_trace_mode_reg_2; FAPI_TRY(fapi2::getScom(l_chplt_target, PERV_DBG_MODE_REG, l_dbg_mode_reg), "Error from getScom (PERV_DBG_MODE_REG)"); l_dbg_mode_reg.setBit(); l_dbg_mode_reg.clearBit(); l_dbg_mode_reg.clearBit(); FAPI_TRY(fapi2::putScom(l_chplt_target, PERV_DBG_MODE_REG, l_dbg_mode_reg), "Error from putScom (PERV_DBG_MODE_REG)"); FAPI_TRY(fapi2::getScom(l_chplt_target, PERV_DBG_TRACE_MODE_REG_2, l_dbg_trace_mode_reg_2), "Error from getScom (PERV_DBG_TRACE_MODE_REG_2)"); l_dbg_trace_mode_reg_2.setBit(); FAPI_TRY(fapi2::putScom(l_chplt_target, PERV_DBG_TRACE_MODE_REG_2, l_dbg_trace_mode_reg_2), "Error from putScom (PERV_DBG_TRACE_MODE_REG_2)"); } } // execute NMMU initfile { FAPI_DBG("Executing NMMU initfile"); fapi2::ReturnCode l_rc; FAPI_EXEC_HWP(l_rc, p9_mmu_scom, i_target, FAPI_SYSTEM); if (l_rc) { FAPI_ERR("Error from p9_mmu_scom (p9.mmu.scom.initfile)"); fapi2::current_err = l_rc; goto fapi_try_exit; } } fapi_try_exit: FAPI_DBG("Exiting ..."); return fapi2::current_err; }