#include <assert.h>

#include <hei_main.hpp>
#include <util/pdbg.hpp>
#include <util/trace.hpp>

namespace util
{

namespace pdbg
{

//------------------------------------------------------------------------------

pdbg_target* getTrgt(const libhei::Chip& i_chip)
{
    return (pdbg_target*)i_chip.getChip();
}

//------------------------------------------------------------------------------

const char* getPath(pdbg_target* i_trgt)
{
    return pdbg_target_path(i_trgt);
}

const char* getPath(const libhei::Chip& i_chip)
{
    return getPath(getTrgt(i_chip));
}

//------------------------------------------------------------------------------

uint32_t getChipPos(pdbg_target* i_trgt)
{
    uint32_t attr = 0;
    pdbg_target_get_attribute(i_trgt, "ATTR_FAPI_POS", 4, 1, &attr);
    return attr;
}

uint32_t getChipPos(const libhei::Chip& i_chip)
{
    return getChipPos(getTrgt(i_chip));
}

//------------------------------------------------------------------------------

uint8_t getTrgtType(pdbg_target* i_trgt)
{
    uint8_t attr = 0;
    pdbg_target_get_attribute(i_trgt, "ATTR_TYPE", 1, 1, &attr);
    return attr;
}

uint8_t getTrgtType(const libhei::Chip& i_chip)
{
    return getTrgtType(getTrgt(i_chip));
}

//------------------------------------------------------------------------------

pdbg_target* getPibTrgt(pdbg_target* i_procTrgt)
{
    // The input target must be a processor.
    assert(TYPE_PROC == getTrgtType(i_procTrgt));

    // Get the pib path.
    char path[16];
    sprintf(path, "/proc%d/pib", pdbg_target_index(i_procTrgt));

    // Return the pib target.
    pdbg_target* pibTrgt = pdbg_target_from_path(nullptr, path);
    assert(nullptr != pibTrgt);

    return pibTrgt;
}

//------------------------------------------------------------------------------

pdbg_target* getFsiTrgt(pdbg_target* i_procTrgt)
{
    // The input target must be a processor.
    assert(TYPE_PROC == getTrgtType(i_procTrgt));

    // Get the fsi path.
    char path[16];
    sprintf(path, "/proc%d/fsi", pdbg_target_index(i_procTrgt));

    // Return the fsi target.
    pdbg_target* fsiTrgt = pdbg_target_from_path(nullptr, path);
    assert(nullptr != fsiTrgt);

    return fsiTrgt;
}

//------------------------------------------------------------------------------

int getCfam(pdbg_target* i_trgt, uint32_t i_addr, uint32_t& o_val)
{
    // Only processor targets are supported.
    assert(TYPE_PROC == getTrgtType(i_trgt));

    auto fsiTrgt = util::pdbg::getFsiTrgt(i_trgt);

    int rc = fsi_read(fsiTrgt, i_addr, &o_val);

    if (0 != rc)
    {
        trace::err("fsi_read failure: trgt=%s addr=0x%08x",
                   util::pdbg::getPath(fsiTrgt), i_addr);
    }

    return rc;
}

//------------------------------------------------------------------------------

// IMPORTANT:
// The ATTR_CHIP_ID attribute will be synced from Hostboot to the BMC at some
// point during the IPL. It is possible that this information is needed before
// the sync occurs, in which case the value will return 0.
uint32_t __getChipId(pdbg_target* i_trgt)
{
    uint32_t attr = 0;
    pdbg_target_get_attribute(i_trgt, "ATTR_CHIP_ID", 4, 1, &attr);
    return attr;
}

// IMPORTANT:
// The ATTR_EC attribute will be synced from Hostboot to the BMC at some point
// during the IPL. It is possible that this information is needed before the
// sync occurs, in which case the value will return 0.
uint8_t __getChipEc(pdbg_target* i_trgt)
{
    uint8_t attr = 0;
    pdbg_target_get_attribute(i_trgt, "ATTR_EC", 1, 1, &attr);
    return attr;
}

uint32_t __getChipIdEc(pdbg_target* i_trgt)
{
    auto chipId = __getChipId(i_trgt);
    auto chipEc = __getChipEc(i_trgt);

    if (((0 == chipId) || (0 == chipEc)) && (TYPE_PROC == getTrgtType(i_trgt)))
    {
        // There is a special case where the model/level attributes have not
        // been initialized in the devtree. This is possible on the epoch IPL
        // where an attention occurs before Hostboot is able to update the
        // devtree information on the BMC. It may is still possible to get this
        // information from chips with CFAM access (i.e. a processor) via the
        // CFAM chip ID register.

        uint32_t val = 0;
        if (0 == getCfam(i_trgt, 0x100a, val))
        {
            chipId = ((val & 0x0F0FF000) >> 12);
            chipEc = ((val & 0xF0000000) >> 24) | ((val & 0x00F00000) >> 20);
        }
    }

    return ((chipId & 0xffff) << 16) | (chipEc & 0xff);
}

void __addChip(std::vector<libhei::Chip>& o_chips, pdbg_target* i_trgt,
               libhei::ChipType_t i_type)
{
    // Trace each chip for debug. It is important to show the type just in case
    // the model/EC does not exist. See note below.
    trace::inf("Chip found: type=0x%08" PRIx32 " chip=%s", i_type,
               getPath(i_trgt));

    if (0 == i_type)
    {
        // This is a special case. See the details in __getChipIdEC(). There is
        // nothing more we can do with this chip since we don't know what it is.
        // So ignore the chip for now.
    }
    else
    {
        o_chips.emplace_back(i_trgt, i_type);
    }
}

void getActiveChips(std::vector<libhei::Chip>& o_chips)
{
    o_chips.clear();

    // Iterate each processor.
    pdbg_target* procTrgt;
    pdbg_for_each_class_target("proc", procTrgt)
    {
        // We cannot use the proc target to determine if the chip is active.
        // There is some design limitation in pdbg that requires the proc
        // targets to always be active. Instead, we must get the associated pib
        // target and check if it is active.

        // Active processors only.
        if (PDBG_TARGET_ENABLED != pdbg_target_probe(getPibTrgt(procTrgt)))
            continue;

        // Add the processor to the list.
        __addChip(o_chips, procTrgt, __getChipIdEc(procTrgt));

        // Iterate the connected OCMBs, if they exist.
        pdbg_target* ocmbTrgt;
        pdbg_for_each_target("ocmb", procTrgt, ocmbTrgt)
        {
            // Active OCMBs only.
            if (PDBG_TARGET_ENABLED != pdbg_target_probe(ocmbTrgt))
                continue;

            // Add the OCMB to the list.
            __addChip(o_chips, ocmbTrgt, __getChipIdEc(ocmbTrgt));
        }
    }
}

//------------------------------------------------------------------------------

bool queryHardwareAnalysisSupported()
{
    // Hardware analysis is only supported on P10 systems and up.
    return (PDBG_PROC_P9 < pdbg_get_proc());
}

//------------------------------------------------------------------------------

} // namespace pdbg

} // namespace util
