コード例 #1
0
ファイル: p9a_mmio_util.C プロジェクト: open-power/hostboot
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;
}
コード例 #2
0
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;
}
コード例 #3
0
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;
}
コード例 #4
0
//-----------------------------------------------------------------------------------
// 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;
}