Exemplo n.º 1
0
/*----------------------------------------------------------------------------*/
int main(void)
{
  struct DeviceDriver device;

  struct Interface * const i2c = init(I2c, &i2cConfig);
  assert(i2c);

  deviceInit(&device, i2c, LED_PIN, DEVICE_ADDRESS);

  struct Timer * const timer = init(GpTimer, &timerConfig);
  assert(timer);
  timerSetOverflow(timer, 1000);

  bool event = false;
  timerSetCallback(timer, onTimerOverflow, &event);
  timerEnable(timer);

  while (1)
  {
    while (!event)
      barrier();
    event = false;

    deviceWrite(&device);

    while (!event)
      barrier();
    event = false;

    deviceRead(&device);
  }

  return 0;
}
Exemplo n.º 2
0
    void Settings::_init()
    {
        errlHndl_t l_errl = NULL;
        size_t size = sizeof(iv_regValue);

        // Read / cache security switch setting from processor.
        l_errl = deviceRead(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL,
                            &iv_regValue, size,
                            DEVICE_SCOM_ADDRESS(SECURITY_SWITCH_REGISTER));

        // If this errors, we're in bad shape and shouldn't trust anything.
        assert(NULL == l_errl);
    }
Exemplo n.º 3
0
/// @brief Platform-level implementation called by getRing()
ReturnCode platGetRing(const Target<TARGET_TYPE_ALL>& i_target,
                       const scanRingId_t i_address,
                       variable_buffer& o_data,
                       const RingMode i_ringMode)
{
    FAPI_DBG(ENTER_MRK "platGetRing");

    // Note: Trace is placed here in plat code because PPE doesn't support
    //       trace in common fapi2_hw_access.H
    bool l_traceit = platIsScanTraceEnabled();

    ReturnCode l_rc;
    errlHndl_t l_err = NULL;

    // Extract the component pointer
    TARGETING::Target* l_target =
            reinterpret_cast<TARGETING::Target*>(i_target.get());

    // Grab the name of the target
    TARGETING::ATTR_FAPI_NAME_type l_targName = {0};
    fapi2::toString(i_target, l_targName, sizeof(l_targName));

    // Output buffer must be set to ring's len by user
    uint64_t l_ringLen = o_data.getBitLength();
    uint64_t l_flag = platGetDDScanMode(i_ringMode);
    size_t l_size = o_data.getLength<uint8_t>();
    l_err = deviceRead(l_target,
                       o_data.pointer(),
                       l_size,
                       DEVICE_SCAN_ADDRESS(i_address, l_ringLen, l_flag));
    if (l_err)
    {
        FAPI_ERR("platGetRing: deviceRead returns error!");
        FAPI_ERR("fapiGetRing failed - Target %s, Addr %.16llX",
                  l_targName, i_address);
        l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
    }

    if (l_traceit)
    {
        uint64_t l_data = o_data.get<uint64_t>();
        FAPI_SCAN("TRACE : GETRING     :  %s : %.16llX %.16llX",
                  l_targName,
                  i_address,
                  l_data);
    }

    FAPI_DBG(EXIT_MRK "platGetRing");
    return l_rc;
}
Exemplo n.º 4
0
//******************************************************************************
//todGetScom()
//******************************************************************************
errlHndl_t todGetScom(const TARGETING::Target * i_target,
                      const uint64_t i_address,
                      fapi2::variable_buffer & o_data)
{
    errlHndl_t l_err = NULL;

    // Perform SCOM read
    uint64_t l_data = 0;
    size_t l_size = sizeof(uint64_t);

    l_err = deviceRead((TARGETING::Target *)i_target,
                       &l_data,
                       l_size,
                       DEVICE_SCOM_ADDRESS(i_address));

    return l_err;
}
Exemplo n.º 5
0
    uint64_t Daemon::readScratchReg()
    {
        size_t l_size = sizeof(uint64_t);
        uint64_t value = 0;

        errlHndl_t l_errl =
            deviceRead(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL,
                       &value, l_size,
                       DEVICE_SCOM_ADDRESS(MB_SCRATCH_REGISTER_1));

        if (l_errl)
        {
            errlCommit(l_errl, TRACE_COMP_ID);
        }

        return value;
    }
Exemplo n.º 6
0
/**
 * @brief Performs a presence detect operation on a Processor Chip.
 *
 * This function does FSI presence detect and compares it to the Module
 * VPD that is present, following the pre-defined prototype for a
 * device-driver framework function.
 *
 * @param[in]   i_opType        Operation type, see DeviceFW::OperationType
 *                              in driverif.H
 * @param[in]   i_target        Presence detect target
 * @param[in/out] io_buffer     Read: Pointer to output data storage
 *                              Write: Pointer to input data storage
 * @param[in/out] io_buflen     Input: size of io_buffer (in bytes, always 1)
 *                              Output: Success = 1, Failure = 0
 * @param[in]   i_accessType    DeviceFW::AccessType enum (userif.H)
 * @param[in]   i_args          This is an argument list for DD framework.
 *                              In this function, there are no arguments.
 * @return  errlHndl_t
 */
errlHndl_t procPresenceDetect(DeviceFW::OperationType i_opType,
                              TARGETING::Target* i_target,
                              void* io_buffer,
                              size_t& io_buflen,
                              int64_t i_accessType,
                              va_list i_args)
{
    errlHndl_t l_errl = NULL;
    uint32_t l_saved_plid = 0;

    if (unlikely(io_buflen < sizeof(bool)))
    {
        TRACFCOMP(g_trac_fsi,
                  ERR_MRK "FSI::procPresenceDetect> Invalid data length: %d",
                  io_buflen);
        /*@
         * @errortype
         * @moduleid     FSI::MOD_FSIPRES_PROCPRESENCEDETECT
         * @reasoncode   FSI::RC_INVALID_LENGTH
         * @userdata1    Data Length
         * @devdesc      presenceDetect> Invalid data length (!= 1 bytes)
         */
        l_errl =
                new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                        FSI::MOD_FSIPRES_PROCPRESENCEDETECT,
                                        FSI::RC_INVALID_LENGTH,
                                        TO_UINT64(io_buflen),
                                        true /*SW error*/);
        io_buflen = 0;
        return l_errl;
    }

    // First look for FSI presence bits
    bool fsi_present = false;

    TARGETING::Target* l_masterChip = NULL;
    TARGETING::targetService().masterProcChipTargetHandle(l_masterChip);

    if ((i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) ||
        (i_target == l_masterChip))
    {
        fsi_present = true;
    }
    else
    {
        fsi_present = isSlavePresent(i_target);
    }

    // Next look for valid Module VPD
    bool check_for_mvpd = true;
#ifdef CONFIG_MVPD_READ_FROM_HW
    check_for_mvpd = fsi_present;
#endif // CONFIG_MVPD_READ_FROM_HW

    bool mvpd_present = false;
    size_t theSize = 0;

    if ( check_for_mvpd )
    {
        l_errl = deviceRead( i_target,
                            NULL,
                            theSize,
                            DEVICE_MVPD_ADDRESS( MVPD::CP00,
                                                 MVPD::VD ) );
        if( l_errl )
        {
            if( fsi_present )
            {
                // Save this plid to use later
                l_saved_plid = l_errl->plid();

                // commit this log because we expected to have VPD
                errlCommit( l_errl,
                            FSI_COMP_ID );
            }
            else
            {
                // just delete this
                delete l_errl;
            }
        }

        if( theSize > 0 )
        {
            uint8_t theData[theSize];
            l_errl = deviceRead( i_target,
                                 theData,
                                 theSize,
                                 DEVICE_MVPD_ADDRESS( MVPD::CP00,
                                                      MVPD::VD ) );
            if( l_errl )
            {
                if( fsi_present )
                {

                    // Save this plid to use later
                    l_saved_plid = l_errl->plid();

                    // commit this log because we expected to have VPD
                    errlCommit( l_errl,
                                FSI_COMP_ID );
                }
                else
                {
                    // just delete this
                    delete l_errl;
                }
            }
            else
            {
                mvpd_present = true;
            }
        }
    }


    // Finally compare the 2 methods
    if( fsi_present != mvpd_present )
    {
        TRACFCOMP(g_trac_fsi,
                  ERR_MRK "FSI::procPresenceDetect> FSI (=%d) and MVPD (=%d) do not agree for %.8X",
                  fsi_present, mvpd_present, TARGETING::get_huid(i_target));
        /*@
         * @errortype
         * @moduleid     FSI::MOD_FSIPRES_PROCPRESENCEDETECT
         * @reasoncode   FSI::RC_FSI_MVPD_MISMATCH
         * @userdata1    HUID of processor
         * @userdata2[0:31]    FSI Presence
         * @userdata2[32:63]   MVPD Presence
         * @devdesc      presenceDetect> FSI and MVPD do not agree
         */
        l_errl =
                new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                        FSI::MOD_FSIPRES_PROCPRESENCEDETECT,
                                        FSI::RC_FSI_MVPD_MISMATCH,
                                        TARGETING::get_huid(i_target),
                                        TWO_UINT32_TO_UINT64(
                                            fsi_present,
                                            mvpd_present));

        // Callout the processor
        l_errl->addHwCallout( i_target,
                              HWAS::SRCI_PRIORITY_LOW,
                              HWAS::NO_DECONFIG,
                              HWAS::GARD_NULL );

        // if there is a saved PLID, apply it to this error log
        if (l_saved_plid)
        {
            l_errl->plid(l_saved_plid);
        }

        // Add FFDC for the target to an error log
        getFsiFFDC( FFDC_PRESENCE_FAIL, l_errl, i_target);


        // Add FSI and VPD trace
        l_errl->collectTrace("FSI");
        l_errl->collectTrace("VPD");

        // commit this log and move on
        errlCommit( l_errl,
                    FSI_COMP_ID );
    }


    bool present = fsi_present && mvpd_present;
    memcpy(io_buffer, &present, sizeof(present));
    io_buflen = sizeof(present);

    return NULL;
}
Exemplo n.º 7
0
/// @brief Platform-level implementation called by modifyRing()
ReturnCode platModifyRing(const Target<TARGET_TYPE_ALL>& i_target,
                          const scanRingId_t i_address,
                          const variable_buffer& i_data,
                          const ChipOpModifyMode i_modifyMode,
                          const RingMode i_ringMode)
{
    FAPI_DBG(ENTER_MRK "platModifyRing");

    // TODO RTC:152489 - story to finish this modifyRing
    FAPI_ERR("platModifyRing: not supported yet");
    assert(0,"platModifyRing not supported yet.");

    ReturnCode l_rc;
    errlHndl_t l_err = NULL;
    variable_buffer l_current_data(i_data);

    // Note: Trace is placed here in plat code because PPE doesn't support
    //       trace in common fapi2_hw_access.H
    bool l_traceit = platIsScanTraceEnabled();

    // Grab the name of the target
    TARGETING::ATTR_FAPI_NAME_type l_targName = {0};
    fapi2::toString(i_target, l_targName, sizeof(l_targName));

    do
    {
        // Extract the component pointer
        TARGETING::Target* l_target =
                reinterpret_cast<TARGETING::Target*>(i_target.get());

        // --------------------
        // Read current value
        // --------------------
        uint64_t l_ringLen = l_current_data.getBitLength();
        uint64_t l_flag = platGetDDScanMode(i_ringMode);
        size_t l_size = l_current_data.getLength<uint8_t>();
        l_err = deviceRead(l_target,
                           l_current_data.pointer(),
                           l_size,
                           DEVICE_SCAN_ADDRESS(i_address, l_ringLen, l_flag));
        if (l_err)
        {
            FAPI_ERR("platModifyRing: deviceRead returns error!");
            FAPI_ERR("platModifyRing failed - Target %s, Addr %.16llX",
                  l_targName, i_address);

            // Add the error log pointer as data to the ReturnCode
            l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));

            // break out if read fails
            break;
        }

        // ----------------------
        // Applying modification
        // ----------------------
        /* TODO-RTC:151261 - re-enable when variable_buffer operations supported
        if (fapi2::CHIP_OP_MODIFY_MODE_OR == i_modifyMode)
        {
            l_current_data |= i_data;
        }
        else if (fapi2::CHIP_OP_MODIFY_MODE_AND == i_modifyMode)
        {
            l_current_data &= i_data;
        }
        else
        {
            l_current_data ^= i_data;
        } */


        // -------------------------
        // Write back updated data
        // -------------------------
        l_err = deviceWrite(l_target,
                        l_current_data.pointer(),
                        l_size,
                        DEVICE_SCAN_ADDRESS(i_address, l_ringLen, l_flag));
        if (l_err)
        {
            FAPI_ERR("platModifyRing: deviceWrite returns error!");
            FAPI_ERR("platModifyRing failed - Target %s, Addr %.16llX",
                  l_targName, i_address);
            // Add the error log pointer as data to the ReturnCode
            l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
            break;
        }

    } while (0);

    if (l_traceit)
    {
        uint64_t l_data = l_current_data.get<uint64_t>();
        FAPI_SCAN("TRACE : MODIFYRING  :  %s : %.16llX %.16llX",
                  l_targName,
                  i_address,
                  l_data);
    }
    FAPI_DBG(EXIT_MRK "platModifyRing");
    return l_rc;
}
Exemplo n.º 8
0
/// @brief Platform-level implementation called by getScom()
ReturnCode platGetScom(const Target<TARGET_TYPE_ALL>& i_target,
                       const uint64_t i_address,
                       buffer<uint64_t>& o_data)
{
    ReturnCode l_rc;
    errlHndl_t l_err = NULL;

    FAPI_DBG(ENTER_MRK "platGetScom");
    // Note: Trace is placed here in plat code because PPE doesn't support
    //       trace in common fapi2_hw_access.H
    bool l_traceit = platIsScanTraceEnabled();

    // Extract the component pointer
    TARGETING::Target* l_target =
              reinterpret_cast<TARGETING::Target*>(i_target.get());

    // Grab the name of the target
    TARGETING::ATTR_FAPI_NAME_type l_targName = {0};
    fapi2::toString(i_target, l_targName, sizeof(l_targName));

    // Perform SCOM read
    size_t l_size = sizeof(uint64_t);
    l_err = deviceRead(l_target,
                       &o_data(),
                       l_size,
                       DEVICE_SCOM_ADDRESS(i_address, opMode));

    //If an error occured durring the device read and a pib_err_mask is set,
    // then we will check if the err matches the mask, if it does we
    // ignore the error
    if(l_err && (pib_err_mask != 0x00))
    {
        checkPibMask(l_err);
    }

    if (l_err)
    {
        if(opMode & fapi2::IGNORE_HW_ERROR)
        {
            delete l_err;
            l_err = nullptr;
        }
        else
        {
            FAPI_ERR("platGetScom: deviceRead returns error!");
            FAPI_ERR("fapiGetScom failed - Target %s, Addr %.16llX",
                     l_targName, i_address);
            l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
        }
    }

    if (l_traceit)
    {
        uint64_t l_data = (uint64_t)o_data;
        FAPI_SCAN("TRACE : GETSCOM     :  %s : %.16llX %.16llX",
                  l_targName,
                  i_address,
                  l_data);
    }

    FAPI_DBG(EXIT_MRK "platGetScom");
    return l_rc;
}
Exemplo n.º 9
0
/// @brief Platform-level implementation of modifyCfamRegister()
ReturnCode platModifyCfamRegister(const Target<TARGET_TYPE_ALL>& i_target,
                                  const uint32_t i_address,
                                  const buffer<uint32_t> i_data,
                                  const ChipOpModifyMode i_modifyMode)
{
    FAPI_DBG(ENTER_MRK "platModifyCfamRegister");
    ReturnCode l_rc;
    errlHndl_t l_err = NULL;
    bool l_traceit = platIsScanTraceEnabled();
    const char* l_modeString = platModeString(i_modifyMode);

    // Grab the name of the target
    TARGETING::ATTR_FAPI_NAME_type l_targName = {0};
    fapi2::toString(i_target, l_targName, sizeof(l_targName));

    do
    {
        // Can't access cfam engine on master processor
        l_err = verifyCfamAccessTarget(i_target,i_address);
        if (l_err)
        {
            FAPI_ERR("platModifyCfamRegister: verifyCfamAccessTarget returns error!");
            l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
            break;
        }

        // Extract the component pointer
        TARGETING::Target* l_target =
                reinterpret_cast<TARGETING::Target*>(i_target.get());

        // Get the chip target if l_target is not a chip
        TARGETING::Target* l_myChipTarget = NULL;
        l_err = getCfamChipTarget(l_target, l_myChipTarget);
        if (l_err)
        {
            FAPI_ERR("platModifyCfamRegister: getCfamChipTarget returns error!");
            l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
            break;
        }

        // Read current value
        // Address needs to be multiply by 4 because register addresses are word
        // offsets but the FSI addresses are byte offsets.
        // However, we need to preserve the engine's offset of 0x0C00 and 0x1000
        uint64_t l_addr = ((i_address & CFAM_ADDRESS_MASK) << 2) |
            (i_address & CFAM_ENGINE_OFFSET);
        buffer<uint32_t> l_data = 0;
        size_t l_size = sizeof(uint32_t);
        l_err = deviceRead(l_myChipTarget,
                           &l_data(),
                           l_size,
                           DEVICE_FSI_ADDRESS(l_addr));
        if (l_err)
        {
            FAPI_ERR("platModifyCfamRegister: deviceRead returns error!");
            l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
            break;
        }

        // Applying modification
        platProcess32BitModifyMode(i_modifyMode, i_data, l_data);

        // Write back
        l_err = deviceWrite(l_target,
                            &l_data(),
                            l_size,
                            DEVICE_FSI_ADDRESS(l_addr));
        if (l_err)
        {
            FAPI_ERR("platModifyCfamRegister: deviceWrite returns error!");
            l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
            break;
        }

    } while (0);

    if (l_rc != fapi2::FAPI2_RC_SUCCESS)
    {
        FAPI_ERR("platModifyCfamRegister failed - Target %s, Addr %.8X",
                  l_targName, i_address);
    }

    if( l_traceit )
    {
        uint32_t l_data = (uint32_t)i_data;
        FAPI_SCAN( "TRACE : MODCFAMREG  : %s : %.8X %.8X %s",
                   l_targName,
                   i_address,
                   l_data,
                   l_modeString );
    }

    FAPI_DBG(EXIT_MRK "platModifyCfamRegister");
    return l_rc;
}
Exemplo n.º 10
0
/// @brief Platform-level implementation called by getCfamRegister()
ReturnCode platGetCfamRegister(const Target<TARGET_TYPE_ALL>& i_target,
                               const uint32_t i_address,
                               buffer<uint32_t>& o_data)
{
    FAPI_DBG(ENTER_MRK "platGetCfamRegister");
    ReturnCode l_rc;
    errlHndl_t l_err = NULL;
    bool l_traceit = platIsScanTraceEnabled();

    // Grab the name of the target
    TARGETING::ATTR_FAPI_NAME_type l_targName = {0};
    fapi2::toString(i_target, l_targName, sizeof(l_targName));

    do
    {
        // Extract the target pointer
        TARGETING::Target* l_target =
                reinterpret_cast<TARGETING::Target*>(i_target.get());

        // Get the chip target if l_target is not a chip
        TARGETING::Target* l_myChipTarget = NULL;
        l_err = getCfamChipTarget(l_target, l_myChipTarget);
        if (l_err)
        {
            FAPI_ERR("platGetCfamRegister: getCfamChipTarget returns error!");
            FAPI_ERR("fapiGetCfamRegister failed - Target %s, Addr %.8X",
                      l_targName, i_address);
            l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
            break;
        }

        // Can't access cfam engine on master processor
        l_err = verifyCfamAccessTarget(i_target,i_address);
        if (l_err)
        {
            FAPI_ERR("platGetCfamRegister: verifyCfamAccessTarget returns error!");
            l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
            break;
        }

        // Perform CFAM read via FSI
        // Address needs to be multiply by 4 because register addresses are
        //  word offsets but the FSI addresses are byte offsets.
        // However, we need to preserve the engine's offset in the top byte
        uint64_t l_addr = ((i_address & CFAM_ADDRESS_MASK) << 2) |
            (i_address & CFAM_ENGINE_OFFSET);
        size_t l_size = sizeof(uint32_t);
        l_err = deviceRead(l_myChipTarget,
                           &o_data(),
                           l_size,
                           DEVICE_FSI_ADDRESS(l_addr));
        if (l_err)
        {
            FAPI_ERR("platGetCfamRegister: deviceRead returns error!");
            l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
            break;
        }

    } while(0);

    if (l_rc != fapi2::FAPI2_RC_SUCCESS)
    {
       FAPI_ERR("fapiGetCfamRegister failed - Target %s, Addr %.8X",
                 l_targName, i_address);
    }

    if( l_traceit )
    {
        uint32_t l_data = (uint32_t)o_data;
        FAPI_SCAN( "TRACE : GETCFAMREG  : %s : %.8X %.8X",
                   l_targName,
                   i_address,
                   l_data);
    }

    FAPI_DBG(EXIT_MRK "platGetCfamRegister");
    return l_rc;
}
Exemplo n.º 11
0
/// @brief Platform-level implementation called by putScomUnderMask()
ReturnCode platPutScomUnderMask(const Target<TARGET_TYPE_ALL>& i_target,
                                const uint64_t i_address,
                                const buffer<uint64_t> i_data,
                                const buffer<uint64_t> i_mask)
{
    ReturnCode l_rc;
    errlHndl_t l_err = NULL;

    FAPI_DBG(ENTER_MRK "platPutScomUnderMask");
    // Note: Trace is placed here in plat code because PPE doesn't support
    //       trace in common fapi2_hw_access.H
    bool l_traceit = platIsScanTraceEnabled();

    // Grab the name of the target
    TARGETING::ATTR_FAPI_NAME_type l_targName = {0};
    fapi2::toString(i_target, l_targName, sizeof(l_targName));

    do
    {
        // Extract the component pointer
        TARGETING::Target* l_target =
                  reinterpret_cast<TARGETING::Target*>(i_target.get());

        // Get current value from HW
        uint64_t l_data = 0;
        size_t l_size = sizeof(uint64_t);
        l_err = deviceRead(l_target,
                           &l_data,
                           l_size,
                           DEVICE_SCOM_ADDRESS(i_address,opMode));
        if (l_err && !(opMode & fapi2::IGNORE_HW_ERROR))
        {
            FAPI_ERR("platPutScomUnderMask: deviceRead returns error!");
            l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
            break;
        }
        else if(l_err)
        {
            delete l_err;
            l_err = nullptr;
            break;
        }

        // Calculate new value to write to reg
        uint64_t l_inMaskInverted = ~i_mask;    // Write mask inverted
        uint64_t l_newMask = (i_data & i_mask);  // Retain set data bits

        // l_data = current data set bits
        l_data &= l_inMaskInverted;

        // l_data = current data set bit + set mask bits
        l_data |= l_newMask;

        // Write new value
        l_err = deviceWrite(l_target,
                            &l_data,
                            l_size,
                            DEVICE_SCOM_ADDRESS(i_address,opMode));
        if (l_err && !(opMode & fapi2::IGNORE_HW_ERROR))
        {
            FAPI_ERR("platPutScomUnderMask: deviceWrite returns error!");
            l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
            break;
        }
        else if (l_err)
        {
            delete l_err;
            l_err = nullptr;
            break;

        }

    } while (0);

    if(l_err && (pib_err_mask != 0x00))
    {
        checkPibMask(l_err);
    }

    if (l_rc != fapi2::FAPI2_RC_SUCCESS)
    {
       FAPI_ERR("platPutScomUnderMask failed - Target %s, Addr %.16llX",
                l_targName, i_address);
    }

    if( l_traceit )
    {
        uint64_t l_data = i_data;
        uint64_t l_mask = i_mask;
        FAPI_SCAN( "TRACE : PUTSCOMMASK : %s : %.16llX %.16llX %.16llX",
                   l_targName,
                   i_address,
                   l_data,
                   l_mask);
    }

    FAPI_DBG(EXIT_MRK "platPutScomUnderMask");
    return l_rc;
}
Exemplo n.º 12
0
// ------------------------------------------------------------------
// dimmPresenceDetect
// ------------------------------------------------------------------
errlHndl_t dimmPresenceDetect( DeviceFW::OperationType i_opType,
                               TARGETING::Target * i_target,
                               void * io_buffer,
                               size_t & io_buflen,
                               int64_t i_accessType,
                               va_list i_args )
{
    errlHndl_t err = NULL;
    bool present = false;
    size_t presentSz = sizeof(present);

    TRACSSCOMP( g_trac_spd,
                ENTER_MRK"dimmPresenceDetect()" );

    do
    {
        // Check to be sure that the buffer is big enough.
        if( !(io_buflen >= sizeof(bool)) )
        {
            TRACFCOMP( g_trac_spd,
                       ERR_MRK"dimmPresenceDetect() - Invalid Data Length: %d",
                       io_buflen );

            /*@
             * @errortype
             * @reasoncode       VPD::VPD_INSUFFICIENT_BUFFER_SIZE
             * @severity         ERRORLOG::ERRL_SEV_UNRECOVERABLE
             * @moduleid         VPD::VPD_SPD_PRESENCE_DETECT
             * @userdata1        Buffer Length
             * @userdata2        <UNUSED>
             * @devdesc          Buffer for checking Presence Detect
             *                   was not the correct size.
             */
            err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                           VPD::VPD_SPD_PRESENCE_DETECT,
                                           VPD::VPD_INSUFFICIENT_BUFFER_SIZE,
                                           TO_UINT64(io_buflen),
                                           0x0,
                                           true /*Add HB Software Callout*/);

            err->collectTrace( "SPD", 256);

            break;
        }

        // Is the target present
#ifdef CONFIG_DJVPD_READ_FROM_HW
        // Check if the parent MBA/MEMBUF is present.  If it is not then
        // no reason to check the DIMM which would otherwise generate
        // tons of FSI errors.  We can't just check if parent MBA
        // is functional because DIMM presence detect is called before
        // the parent MBA/MEMBUF is set as present/functional.
        TARGETING::TargetHandleList membufList;
        TARGETING::PredicateCTM membufPred( TARGETING::CLASS_CHIP,
                                            TARGETING::TYPE_MEMBUF );
        TARGETING::targetService().getAssociated(
            membufList,
            i_target,
            TARGETING::TargetService::PARENT_BY_AFFINITY,
            TARGETING::TargetService::ALL,
            &membufPred);

        bool parentPresent = false;
        const TARGETING::TargetHandle_t membufTarget = *(membufList.begin());

        err = deviceRead(membufTarget, &parentPresent, presentSz,
                                DEVICE_PRESENT_ADDRESS());
        if (err)
        {
            TRACFCOMP(
                g_trac_spd,
                "Error reading parent MEMBUF present: huid 0x%X DIMM huid 0x%X",
                TARGETING::get_huid(membufTarget),
                TARGETING::get_huid(i_target) );
            break;
        }
        if (!parentPresent)
        {
            present = false;
            // Invalidate the SPD in PNOR
            err = VPD::invalidatePnorCache(i_target);
            if (err)
            {
                TRACFCOMP( g_trac_spd, "Error invalidating SPD in PNOR" );
            }
            break;
        }
#endif

        present = spdPresent( i_target );

        if( present == false )
        {
            TRACUCOMP( g_trac_spd,
                       INFO_MRK"Dimm was found to be NOT present." );
        }
        else
        {
            TRACUCOMP( g_trac_spd,
                       INFO_MRK"Dimm was found to be present." );
        }

#if defined(CONFIG_DJVPD_READ_FROM_HW) && defined(CONFIG_DJVPD_READ_FROM_PNOR)
        if( present )
        {
            // Check if the VPD data in the PNOR matches the SEEPROM
            err = VPD::ensureCacheIsInSync( i_target );
            if( err )
            {
                present = false;

                TRACFCOMP(g_trac_spd,ERR_MRK "dimmPresenceDetectt> Error during ensureCacheIsInSync (SPD)" );
                break;
            }
        }
        else
        {
            // SPD is not present, invalidate the SPD in PNOR
            err = VPD::invalidatePnorCache(i_target);
            if (err)
            {
                TRACFCOMP( g_trac_spd, "Error invalidating SPD in PNOR" );
            }
        }
#endif

        if( present && !err )
        {
            //Fsp sets PN/SN so if there is none, do it here
            if(!INITSERVICE::spBaseServicesEnabled())
            {
                //populate serial and part number attributes
                SPD::setPartAndSerialNumberAttributes( i_target );
            }

            // Read ATTR_CLEAR_DIMM_SPD_ENABLE attribute
            TARGETING::Target* l_sys = NULL;
            TARGETING::targetService().getTopLevelTarget(l_sys);

            TARGETING::ATTR_CLEAR_DIMM_SPD_ENABLE_type l_clearSPD =
                l_sys->getAttr<TARGETING::ATTR_CLEAR_DIMM_SPD_ENABLE>();

            // If SPD clear is enabled then write 0's into magic word for 
            // DIMM_BAD_DQ_DATA keyword
            // Note: If there's an error from performing the clearing,
            // just log the error and continue.
            if (l_clearSPD)
            {
                size_t l_size = 0;

                // Do a read to get the DIMM_BAD_DQ_DATA keyword size
                err = deviceRead(i_target, NULL, l_size,
                                 DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ));
                if (err)
                {
                    TRACFCOMP(g_trac_spd, "dimmPresenceDetect - "
                        "Error reading DIMM_BAD_DQ_DATA keyword size");
                    errlCommit( err, VPD_COMP_ID );
                }
                else
                {
                    // Clear the data
                    TRACFCOMP( g_trac_spd, "Clearing out BAD_DQ_DATA SPD on "
                               "DIMM HUID 0x%X",
                               TARGETING::get_huid(i_target));

                    uint8_t * l_data = static_cast<uint8_t*>(malloc( l_size ));
                    memset(l_data, 0, l_size);

                    err = deviceWrite(i_target, l_data, l_size,
                                     DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ));
                    if (err)
                    {
                        TRACFCOMP( g_trac_spd, "Error trying to clear SPD on "
                                   "DIMM HUID 0x%X",
                                   TARGETING::get_huid(i_target));
                        errlCommit( err, VPD_COMP_ID );
                    }

                    // Free the memory
                    if (NULL != l_data)
                    {
                        free(l_data);
                    }
                }
            }
        }

        // copy present value into output buffer so caller can read it
        memcpy( io_buffer, &present, presentSz );
        io_buflen = presentSz;

    } while( 0 );

    TRACSSCOMP( g_trac_spd,
                EXIT_MRK"dimmPresenceDetect()" );

    return err;
} // end dimmPresenceDetect
Exemplo n.º 13
0
// ------------------------------------------------------------------
// dimmPresenceDetect
// ------------------------------------------------------------------
errlHndl_t dimmPresenceDetect( DeviceFW::OperationType i_opType,
                               TARGETING::Target * i_target,
                               void * io_buffer,
                               size_t & io_buflen,
                               int64_t i_accessType,
                               va_list i_args )
{
    errlHndl_t err = NULL;
    bool present = false;
    size_t presentSz = sizeof(present);

    TRACSSCOMP( g_trac_spd, ENTER_MRK"dimmPresenceDetect() "
                "DIMM HUID 0x%X", TARGETING::get_huid(i_target));
    do
    {
        // Check to be sure that the buffer is big enough.
        if( !(io_buflen >= sizeof(bool)) )
        {
            TRACFCOMP( g_trac_spd, ERR_MRK"dimmPresenceDetect() "
                       "Invalid Data Length: %d",
                       io_buflen );

            /*@
             * @errortype
             * @reasoncode       VPD::VPD_INSUFFICIENT_BUFFER_SIZE
             * @severity         ERRORLOG::ERRL_SEV_UNRECOVERABLE
             * @moduleid         VPD::VPD_SPD_PRESENCE_DETECT
             * @userdata1        Buffer Length
             * @userdata2        <UNUSED>
             * @devdesc          Buffer for checking Presence Detect
             *                   was not the correct size.
             */
            err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                           VPD::VPD_SPD_PRESENCE_DETECT,
                                           VPD::VPD_INSUFFICIENT_BUFFER_SIZE,
                                           TO_UINT64(io_buflen),
                                           0x0,
                                           true /*Add HB Software Callout*/);

            err->collectTrace( "SPD", 256);

            break;
        }

        // Is the target present?
#ifdef CONFIG_DJVPD_READ_FROM_HW
        // Check if the i2c master is present.
        // If it is not then no reason to check the DIMM which would
        // otherwise generate tons of FSI errors.
        // We can't just check if parent MCA or MBA
        // is functional because DIMM presence detect is called before
        // the parent MCS/MCA or MBA/MEMBUF is set as present/functional.
        bool l_i2cMasterPresent = false;

        do
        {
            // get eeprom vpd primary info
            TARGETING::EepromVpdPrimaryInfo eepromData;
            if( !(i_target->
                     tryGetAttr<TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO>
                         ( eepromData ) ) )
            {
                TRACFCOMP( g_trac_spd, ERR_MRK"dimmPresenceDetect() "
                           "Error: no eeprom vpd primary info" );
                break;
            }

            // find i2c master target
            TARGETING::TargetService& tS = TARGETING::targetService();
            bool exists = false;
            tS.exists( eepromData.i2cMasterPath, exists );
            if( !exists )
            {
                TRACFCOMP( g_trac_spd, ERR_MRK"dimmPresenceDetect() "
                           "i2cMasterPath attribute path doesn't exist");
                break;
            }

            // Since it exists, convert to a target
            TARGETING::Target * l_i2cMasterTarget =
                                   tS.toTarget( eepromData.i2cMasterPath );

            if( NULL == l_i2cMasterTarget )
            {
                TRACFCOMP( g_trac_spd, ERR_MRK"dimmPresenceDetect() "
                           "i2cMasterPath target is NULL");
                break;
            }
            TRACSSCOMP( g_trac_spd, "dimmPresenceDetect() "
                "i2c master HUID 0x%X", TARGETING::get_huid(l_i2cMasterTarget));

            // Check if present
            TARGETING::Target* masterProcTarget = NULL;
            TARGETING::targetService().masterProcChipTargetHandle(
                                                        masterProcTarget );
            // Master proc is taken as always present. Validate other targets.
            if (l_i2cMasterTarget != masterProcTarget)
            {
                l_i2cMasterPresent = FSI::isSlavePresent(l_i2cMasterTarget);
                if( !l_i2cMasterPresent )
                {
                    TRACFCOMP( g_trac_spd, ERR_MRK"dimmPresenceDetect() "
                               "isSlavePresent failed");
                    break;
                }
            }
            l_i2cMasterPresent = true;
        }
        while (0);

        if (!l_i2cMasterPresent)
        {
            present = false;
            // Invalidate the SPD in PNOR
            err = VPD::invalidatePnorCache(i_target);
            if (err)
            {
                TRACFCOMP( g_trac_spd, ERR_MRK"dimmPresenceDetect() "
                           "Error invalidating SPD in PNOR" );
            }
            break;
        }
#endif

        present = spdPresent( i_target );

        if( present == false )
        {
            TRACUCOMP( g_trac_spd, INFO_MRK"dimmPresenceDetect() "
                       "Dimm was found to be NOT present." );
        }
        else
        {
            TRACUCOMP( g_trac_spd, INFO_MRK"dimmPresenceDetect() "
                       "Dimm was found to be present." );
        }

#if defined(CONFIG_DJVPD_READ_FROM_HW) && defined(CONFIG_DJVPD_READ_FROM_PNOR)
        if( present )
        {
            // Check if the VPD data in the PNOR matches the SEEPROM
            err = VPD::ensureCacheIsInSync( i_target );
            if( err )
            {
                present = false;
                TRACFCOMP( g_trac_spd, ERR_MRK"dimmPresenceDetect() "
                           "Error during ensureCacheIsInSync (SPD)" );
                break;
            }
        }
        else
        {
            // SPD is not present, invalidate the SPD in PNOR
            err = VPD::invalidatePnorCache(i_target);
            if (err)
            {
                TRACFCOMP( g_trac_spd, ERR_MRK"dimmPresenceDetect() "
                           "Error invalidating SPD in PNOR" );
            }
        }
#endif

        if( present && !err )
        {
            //Fsp sets PN/SN so if there is none, do it here
            if(!INITSERVICE::spBaseServicesEnabled())
            {
                //populate serial and part number attributes
                SPD::setPartAndSerialNumberAttributes( i_target );
            }

            // Read ATTR_CLEAR_DIMM_SPD_ENABLE attribute
            TARGETING::Target* l_sys = NULL;
            TARGETING::targetService().getTopLevelTarget(l_sys);

            TARGETING::ATTR_CLEAR_DIMM_SPD_ENABLE_type l_clearSPD =
                l_sys->getAttr<TARGETING::ATTR_CLEAR_DIMM_SPD_ENABLE>();

            // If SPD clear is enabled then write 0's into magic word for
            // DIMM_BAD_DQ_DATA keyword
            // Note: If there's an error from performing the clearing,
            // just log the error and continue.
            if (l_clearSPD)
            {
                size_t l_size = 0;

                // Do a read to get the DIMM_BAD_DQ_DATA keyword size
                err = deviceRead(i_target, NULL, l_size,
                                 DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ));
                if (err)
                {
                    TRACFCOMP( g_trac_spd, ERR_MRK"dimmPresenceDetect() "
                        "Error reading DIMM_BAD_DQ_DATA keyword size");
                    errlCommit( err, VPD_COMP_ID );
                }
                else
                {
                    // Clear the data
                    TRACFCOMP( g_trac_spd, "Clearing out BAD_DQ_DATA SPD on "
                               "DIMM HUID 0x%X",
                               TARGETING::get_huid(i_target));

                    uint8_t * l_data = static_cast<uint8_t*>(malloc( l_size ));
                    memset(l_data, 0, l_size);

                    err = deviceWrite(i_target, l_data, l_size,
                                     DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ));
                    if (err)
                    {
                        TRACFCOMP(g_trac_spd, ERR_MRK"dimmPresenceDetect() "
                                  "Error trying to clear SPD on DIMM HUID 0x%X",
                                  TARGETING::get_huid(i_target));
                        errlCommit( err, VPD_COMP_ID );
                    }

                    // Free the memory
                    if (NULL != l_data)
                    {
                        free(l_data);
                    }
                }
            }
        }

        // copy present value into output buffer so caller can read it
        memcpy( io_buffer, &present, presentSz );
        io_buflen = presentSz;

    } while( 0 );

    TRACSSCOMP( g_trac_spd, EXIT_MRK"dimmPresenceDetect()" );

    return err;
} // end dimmPresenceDetect