fapi2::ReturnCode addOMIBase(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, uint64_t& io_mmioAddr) { std::vector<uint64_t> l_base_addr_nm0; std::vector<uint64_t> l_base_addr_nm1; std::vector<uint64_t> l_base_addr_m; uint64_t l_addr_offset; uint64_t l_base_addr_mmio; fapi2::Target<fapi2::TARGET_TYPE_OMI> l_omi_target; fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_chip_target; l_omi_target = i_target.getParent<fapi2::TARGET_TYPE_OMI>(); l_chip_target = l_omi_target.getParent<fapi2::TARGET_TYPE_PROC_CHIP>(); // determine base address of chip MMIO range FAPI_TRY(p9_fbc_utils_get_chip_base_address(l_chip_target, EFF_FBC_GRP_CHIP_IDS, 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"); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET, l_omi_target, l_addr_offset), "Error from FAPI_ATTR_GET (ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET)"); io_mmioAddr |= (l_base_addr_mmio | l_addr_offset); fapi_try_exit: FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); return fapi2::current_err; }
fapi2::ReturnCode p9_rng_init_phase2(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_INF("Start"); fapi2::buffer<uint64_t> l_rng_cfg_data; fapi2::buffer<uint64_t> l_rng_bar_data; fapi2::buffer<uint64_t> l_rng_failed_int_data; fapi2::buffer<uint64_t> l_security_switch_data; uint16_t l_rng_cfg_self_test_hard_fail_status = 0; uint8_t l_nx_rng_bar_enable = 0; uint64_t l_nx_rng_bar_addr = 0; uint64_t l_nx_rng_bar_base_addr_offset = 0; uint8_t l_nx_rng_failed_int_enable = 0; uint64_t l_nx_rng_failed_int_addr = 0; std::vector<uint64_t> l_base_addr_nm0, l_base_addr_nm1, l_base_addr_m; uint64_t l_base_addr_mmio; uint8_t l_HW403701; // 5. RNG is allowed to run for M cycles (M = enough time to complete init; // recommend 1 second of time). // NOTE: accomplished by delay in execution time between phase1/phase2 HWPs // get the self test hard fail status in RNG CFG register FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW403701, i_target, l_HW403701), "Error from FAPI_ATTR_GET (ATTR_CHIP_EC_FEATURE_HW403701)"); FAPI_TRY(fapi2::getScom(i_target, PU_NX_RNG_CFG, l_rng_cfg_data), "Error from getScom (NX RNG Status and Control Register)"); if (!l_HW403701) { // 6. Host boot checks RNG fail bits again and if a fail is detected // then RNG is declared broken FAPI_DBG("Checking RNG fail status..."); // exit if failure is reported in self test hard fail status field l_rng_cfg_data.extractToRight<PU_NX_RNG_CFG_FAIL_REG, PU_NX_RNG_CFG_FAIL_REG_LEN>(l_rng_cfg_self_test_hard_fail_status); FAPI_ASSERT(!l_rng_cfg_self_test_hard_fail_status, fapi2::P9_RNG_INIT_SELF_TEST_FAILED_ERR(). set_TARGET(i_target). set_SELF_TEST_HARD_FAIL_STATUS(l_rng_cfg_self_test_hard_fail_status), "Self test hard fail status indicates failure"); } else { FAPI_DBG("Skipping check of RNG fail status..."); } // 7. Host boot maps RNG BARs (see Section 5.31 RNG BAR on page 185). // • NX RNG BAR (not mapped/enabled if RNG is broken) // • NCU RNG BAR (always mapped to good RNG) // • NX RNG Fail Interrupt Addres // self test indicates no hard fail // if instructed to map the BAR: // - enable NX RNG MMIO BAR and get the bar address attributes // - optionally map NX RNG failed interrupt address FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NX_RNG_BAR_ENABLE, i_target, l_nx_rng_bar_enable), "Error from FAPI_ATTR_GET (ATTR_PROC_NX_BAR_ENABLE)"); FAPI_TRY(p9_fbc_utils_get_chip_base_address(i_target, EFF_FBC_GRP_CHIP_IDS, 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"); // get RNG BAR addr FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NX_RNG_BAR_BASE_ADDR_OFFSET, i_target.getParent<fapi2::TARGET_TYPE_SYSTEM>(), l_nx_rng_bar_base_addr_offset), "Error from FAPI_ATTR_GET (ATTR_PROC_NX_BAR_BASE_ADDR_OFFSET)"); // caculate the NX RNG BAR ADDR based on the bar adddr offset l_nx_rng_bar_addr = l_base_addr_mmio; l_nx_rng_bar_addr += l_nx_rng_bar_base_addr_offset; if (l_nx_rng_bar_enable == fapi2::ENUM_ATTR_PROC_NX_RNG_BAR_ENABLE_ENABLE) { // map NX RNG MMIO BAR l_rng_bar_data.setBit<PU_NX_MMIO_BAR_ENABLE>(); l_rng_bar_data.insert<PU_NX_MMIO_BAR_BAR, PU_NX_MMIO_BAR_BAR_LEN, PU_NX_MMIO_BAR_BAR>(l_nx_rng_bar_addr); FAPI_TRY(fapi2::putScom(i_target, PU_NX_MMIO_BAR, l_rng_bar_data), "Error from putScom (PU_NX_MMIO_BAR)"); // map NX RNG failed interrupt address FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NX_RNG_FAILED_INT_ENABLE, i_target, l_nx_rng_failed_int_enable), "Error from FAPI_ATTR_GET (ATTR_PROC_NX_RNG_FAILED_INT_ENABLE)"); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NX_RNG_FAILED_INT_ADDR, i_target, l_nx_rng_failed_int_addr), "Error from FAPI_ATTR_GET (ATTR_PROC_NX_RNG_FAILED_INT_ADDR)"); if (l_nx_rng_failed_int_enable == fapi2::ENUM_ATTR_PROC_NX_RNG_FAILED_INT_ENABLE_ENABLE) { l_rng_failed_int_data.setBit<PU_RNG_FAILED_INT_ENABLE>(); l_rng_failed_int_data.insert<PU_RNG_FAILED_INT_ADDRESS, PU_RNG_FAILED_INT_ADDRESS_LEN, PU_RNG_FAILED_INT_ADDRESS> (l_nx_rng_failed_int_addr); FAPI_TRY(fapi2::putScom(i_target, PU_RNG_FAILED_INT, l_rng_failed_int_data), "Error from putScom (NX RNG Failed Interrupt Address Register"); } else { FAPI_DBG("Skipping setup of NX RNG Failed Interrupt Address Register"); } } else { FAPI_DBG("Skipping NX RNG BAR programming!"); } // set NX RNG enable l_rng_cfg_data.setBit<PU_NX_RNG_CFG_ENABLE>(); FAPI_TRY(fapi2::putScom(i_target, PU_NX_RNG_CFG, l_rng_cfg_data), "Error from putScom (NX RNG Status and Control Register)"); // 8. Host boot sets the NX “sticky bit” that asserts // tc_nx_block_rng_scom_wr. If tc_nx_block_rng_scom_wr = 1 writes to RNG // SCOM register addresses 32 - 38 and 40 are blocked. An attempted // write sets Power-Bus Interface FIR Data Register[Write to RNG SCOM // reg detected when writes disabled]. // set NX sticky bit to block future RNG SCOM writes // (tc_nx_block_rng_scom_wr) FAPI_TRY(fapi2::getScom(i_target, PU_SECURITY_SWITCH_REGISTER_SCOM, l_security_switch_data), "Error from getScom (Security Switch Register"); l_security_switch_data.setBit<PU_SECURITY_SWITCH_REGISTER_NX_RAND_NUM_GEN_LOCK>(); FAPI_TRY(fapi2::putScom(i_target, PU_SECURITY_SWITCH_REGISTER_SCOM, l_security_switch_data), "Error from putScom (Security Switch Register"); fapi_try_exit: FAPI_INF("End"); return fapi2::current_err; }
fapi2::ReturnCode p9a_omi_setup_bars( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_DBG("Start"); std::vector<uint64_t> l_base_addr_nm0; std::vector<uint64_t> l_base_addr_nm1; std::vector<uint64_t> l_base_addr_m; fapi2::buffer<uint64_t> l_mmio_bar; fapi2::buffer<uint64_t> l_cfg_bar; uint64_t l_base_addr_mmio; uint8_t l_pos; uint8_t l_mcc_pos; uint64_t l_ext_mask; // determine base address of chip MMIO range FAPI_TRY(p9_fbc_utils_get_chip_base_address(i_target, EFF_FBC_GRP_CHIP_IDS, 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"); FAPI_TRY(p9a_get_ext_mask(l_ext_mask)); FAPI_DBG("l_ext_mask: %x", l_ext_mask); FAPI_DBG("l_base_addr_mmio: 0x%llx", l_base_addr_mmio); for (auto l_mcc : i_target.getChildren<fapi2::TARGET_TYPE_MCC>()) { fapi2::ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET_Type l_bar_offset; uint64_t l_omi_inband_addr = 0; fapi2::buffer<uint64_t> l_scom_data; auto l_omi_targets = l_mcc.getChildren<fapi2::TARGET_TYPE_OMI>(); if (l_omi_targets.size() > 0) { // Set the sizes for the MMIO/Config bars FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mcc, l_pos), "Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X", (uint64_t)fapi2::current_err); l_scom_data.flush<0>(); // 2GB cfg and MMIO l_scom_data.insertFromRight<P9A_MI_MCFGP0_MCFGPR0_CONFIGURATION_GROUP_SIZE, P9A_MI_MCFGP0_MCFGPR0_CONFIGURATION_GROUP_SIZE_LEN>(mss::exp::ib::EXPLR_IB_BAR_SIZE); l_scom_data.insertFromRight<P9A_MI_MCFGP0_MCFGPR0_MMIO_GROUP_SIZE, P9A_MI_MCFGP0_MCFGPR0_MMIO_GROUP_SIZE_LEN>(mss::exp::ib::EXPLR_IB_BAR_SIZE); // Write to reg if (l_pos % 2 == 0) { FAPI_INF("Write MCFGP0 reg 0x%.16llX, Value 0x%.16llX", P9A_MI_MCFGP0, l_scom_data); FAPI_TRY(fapi2::putScom(l_mcc.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGP0, l_scom_data), "Error writing to MCS_MCFGP reg"); } else { FAPI_INF("Write MCFGP1 reg 0x%.16llX, Value 0x%.16llX", P9A_MI_MCFGP1, l_scom_data); FAPI_TRY(fapi2::putScom(l_mcc.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGP1, l_scom_data), "Error writing to MCS_MCFGP reg"); } for (auto l_omi : l_omi_targets) { // retrieve OMI pos FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_omi, l_pos), "Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS)"); // retrieve inband BAR offset FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET, l_omi, l_bar_offset), "Error from FAPI_ATTR_GET (ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET)"); FAPI_DBG("l_bar_offset: 0x%llx", l_bar_offset); // If this is channel B, then the B bit must be set. If it is not, then the B bit must not be set. FAPI_ASSERT( ((l_pos % 2) == 1) == // Is this B channel? ((l_bar_offset & mss::exp::ib::EXPLR_IB_BAR_B_BIT) == mss::exp::ib::EXPLR_IB_BAR_B_BIT), fapi2::PROC_OMI_SETUP_BARS_INVALID_BAR() .set_TARGET(l_omi) .set_BAR_VALUE(l_bar_offset), "B Channel requires BAR size bit set"); FAPI_ASSERT(((l_bar_offset & mss::exp::ib::EXPLR_IB_BAR_MASK_ZERO) == 0), fapi2::PROC_OMI_SETUP_BARS_INVALID_BAR() .set_TARGET(l_omi) .set_BAR_VALUE(l_bar_offset), "Bar size not honored"); FAPI_ASSERT(((l_bar_offset & mss::exp::ib::EXPLR_IB_MMIO_OFFSET) == 0), fapi2::PROC_OMI_SETUP_BARS_INVALID_BAR() .set_TARGET(l_omi) .set_BAR_VALUE(l_bar_offset), "MMIO bit must not be set"); l_omi_inband_addr = l_bar_offset; } FAPI_DBG("l_omi_inband_addr: 0x%llx", l_omi_inband_addr); // Force A Bar value l_omi_inband_addr = l_omi_inband_addr & (~mss::exp::ib::EXPLR_IB_BAR_B_BIT); FAPI_DBG("l_omi_inband_addr: 0x%llx", l_omi_inband_addr); // Add MMIO address for the chip l_omi_inband_addr = l_omi_inband_addr | l_base_addr_mmio; FAPI_DBG("l_omi_inband_addr: 0x%llx", l_omi_inband_addr); // Get cfg bar value fapi2::buffer<uint64_t> l_omi_inband_buf = l_omi_inband_addr; FAPI_DBG("l_omi_inband_buf: 0x%llx", l_omi_inband_buf); FAPI_TRY(extendBarAddress(l_ext_mask, l_omi_inband_buf, l_cfg_bar)); FAPI_DBG("l_cfg_bar: 0x%llx", l_cfg_bar); // Get MMIO bar value l_omi_inband_addr = l_omi_inband_addr | mss::exp::ib::EXPLR_IB_MMIO_OFFSET; l_omi_inband_buf = l_omi_inband_addr; FAPI_DBG("l_omi_inband_buf: 0x%llx", l_omi_inband_buf); FAPI_TRY(extendBarAddress(l_ext_mask, l_omi_inband_buf, l_mmio_bar)); FAPI_DBG("l_mmio_bar: 0x%llx", l_mmio_bar); // Write the channel cfg reg l_scom_data.flush<0>(); l_scom_data.setBit<P9A_MI_MCFGPR0_CONFIGURATION_VALID>(); //Enable CFG l_scom_data.setBit<P9A_MI_MCFGPR0_MMIO_VALID>(); //Enable MMIO l_scom_data.insert<P9A_MI_MCFGPR0_CONFIGURATION_GROUP_BASE_ADDRESS, P9A_MI_MCFGPR0_CONFIGURATION_GROUP_BASE_ADDRESS_LEN>(l_cfg_bar); l_scom_data.insert<P9A_MI_MCFGPR0_MMIO_GROUP_BASE_ADDRESS, P9A_MI_MCFGPR0_MMIO_GROUP_BASE_ADDRESS_LEN>(l_mmio_bar); // get MI target to configure MCFGPR fapi2::Target<fapi2::TARGET_TYPE_MI> l_mi = l_mcc.getParent<fapi2::TARGET_TYPE_MI>(); // retrieve DMI pos FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mcc, l_mcc_pos), "Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS)"); // configure inband channel 0 MCFGPR0 if(l_mcc_pos % 2 == 0) { FAPI_TRY(putScom(l_mi, P9A_MI_MCFGPR0, l_scom_data)); } // configure inband channel 1 MCFGPR1 else { FAPI_TRY(putScom(l_mi, P9A_MI_MCFGPR1, l_scom_data)); } } } fapi_try_exit: FAPI_DBG("End"); return fapi2::current_err; }
//----------------------------------------------------------------------------------- // Function definitions //----------------------------------------------------------------------------------- /// /// @brief configure Cumulus inband address /// /// @param[in] i_target => Processor chip target /// /// @return FAPI_RC_SUCCESS if the setup completes successfully, else error // fapi2::ReturnCode p9c_set_inband_addr(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { uint64_t l_base_addr_nm0, l_base_addr_nm1, l_base_addr_m, l_base_addr_mmio; FAPI_DBG("Start"); // determine base address of chip MMIO range FAPI_TRY(p9_fbc_utils_get_chip_base_address(i_target, EFF_FBC_GRP_CHIP_IDS, 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"); for (auto l_dmi : i_target.getChildren<fapi2::TARGET_TYPE_DMI>()) { fapi2::ATTR_DMI_INBAND_BAR_ENABLE_Type l_bar_enable; // retrieve inband BAR enable FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_DMI_INBAND_BAR_ENABLE, l_dmi, l_bar_enable), "Error from FAPI_ATTR_GET (ATTR_DMI_INBAND_BAR_ENABLE)"); if (l_bar_enable == fapi2::ENUM_ATTR_DMI_INBAND_BAR_ENABLE_ENABLE) { fapi2::ATTR_DMI_INBAND_BAR_BASE_ADDR_OFFSET_Type l_bar_offset; uint64_t l_dmi_inband_addr; fapi2::buffer<uint64_t> l_scom_data; uint8_t l_dmi_pos; // retrieve inband BAR offset FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_DMI_INBAND_BAR_BASE_ADDR_OFFSET, l_dmi, l_bar_offset), "Error from FAPI_ATTR_GET (ATTR_DMI_INBAND_BAR_BASE_ADDR_OFFSET)"); // form SCOM register format l_scom_data.flush<0>(); // BAR address 8:38 into bits 4:34 l_dmi_inband_addr = l_base_addr_mmio + l_bar_offset; l_scom_data.insert<4, 31, 8>(l_dmi_inband_addr); // Set valid(bit0 = 1), P9 mode(bit3 = 0) l_scom_data.setBit<0>(); // get MI target to configure MCFGPR fapi2::Target<fapi2::TARGET_TYPE_MI> l_mi = l_dmi.getParent<fapi2::TARGET_TYPE_MI>(); // retrieve DMI pos FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_dmi, l_dmi_pos), "Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS)"); // configure inband channel 0 MCFGPR0 if(l_dmi_pos % 2 == 0) { FAPI_TRY(fapi2::putScom(l_mi, MCS_MCRSVDE, l_scom_data), "Error from putScom MCFGPR0 for DMI id: %d", l_dmi_pos); } // configure inband channel 1 MCFGPR1 else { FAPI_TRY(fapi2::putScom(l_mi, MCS_MCRSVDF, l_scom_data), "Error from putScom MCFGPR1 for DMI id: %d", l_dmi_pos); } } } // configure host attention routing for (auto l_mc : i_target.getChildren<fapi2::TARGET_TYPE_MC>()) { fapi2::buffer<uint64_t> l_mcbcfg_data = 0; fapi2::buffer<uint64_t> l_mcbcfg_mask = 0; // Set P9 MCB Configuration Register // MCBCFGQ[62]=0 (disable special attention output) // MCBCFGQ[63]=1 (enable host attention output) l_mcbcfg_mask.setBit<62>(); l_mcbcfg_mask.setBit<63>(); l_mcbcfg_data.setBit<63>(); FAPI_TRY(fapi2::putScomUnderMask(l_mc, DMI_MCBCFG_0x070123E0, l_mcbcfg_data, l_mcbcfg_mask), "Error from putScom DMI_MCBCFG"); } for (auto l_mi : i_target.getChildren<fapi2::TARGET_TYPE_MI>()) { fapi2::buffer<uint64_t> l_mcmode2_data = 0; fapi2::buffer<uint64_t> l_mcmode2_mask = 0; // Set P9 MC Mode2 Register // MCMODE2Q[44]=0 (disable special attention output) // MCMODE2Q[45]=1 (enable host attention output) l_mcmode2_mask.setBit<44>(); l_mcmode2_mask.setBit<45>(); l_mcmode2_data.setBit<45>(); FAPI_TRY(fapi2::putScomUnderMask(l_mi, MI_MCMODE2_0x05010813, l_mcmode2_data, l_mcmode2_mask), "Error from putScom MI_MCMODE2"); } fapi_try_exit: FAPI_DBG("End"); return fapi2::current_err; }