예제 #1
0
/**
 * @brief This function updates the NVDIMM firmware code
 */
void call_nvdimm_update()
{
    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ENTER_MRK"call_nvdimm_update()");

    TARGETING::TargetHandleList l_nvdimmTargetList;
    TARGETING::TargetHandleList l_procList;
    TARGETING::getAllChips(l_procList, TARGETING::TYPE_PROC, false);

    // grab the NVDIMMs under each processor and add to overall list
    for (auto l_proc : l_procList)
    {
        TARGETING::TargetHandleList tmpList =
            TARGETING::getProcNVDIMMs(l_proc);
        l_nvdimmTargetList.insert(l_nvdimmTargetList.end(),
                                  tmpList.begin(), tmpList.end());
    }

    // Run the nvdimm update function if the list is not empty
    if ( !l_nvdimmTargetList.empty() )
    {
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
            "call_nvdimm_update(): found %d nvdimms to check for update",
            l_nvdimmTargetList.size());
        bool updateWorked = NVDIMM::nvdimm_update(l_nvdimmTargetList);
        if (!updateWorked)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "call_nvdimm_update(): nvdimm update failed");
        }
    }

    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,EXIT_MRK"call_nvdimm_update()");
}
예제 #2
0
///////////////////////////////////////////////////////////////////////////////
// ErrlManager::ackErrLogInPnor()
///////////////////////////////////////////////////////////////////////////////
bool ErrlManager::ackErrLogInPnor( uint32_t i_errEid )
{
    TRACFCOMP( g_trac_errl, ENTER_MRK"ackErrLogInPnor(%.8x)", i_errEid);
    bool rc = true;

    // look for an un-ACKed log that matches this eid
    uint32_t i;
    for (i = 0; i < iv_maxErrlInPnor; i++)
    {
        if (!isSlotEmpty(i) && !isSlotACKed(i))
        {
            uint32_t l_eid = readEidFromFlattened(i);
            if (l_eid == i_errEid)
            {
                TRACDCOMP( g_trac_errl, INFO_MRK"ackErrLogInPnor: match in slot %d", i);
                setACKInFlattened(i);
                break;
            }
        }
    } // for

    // if we made it through the loop w/out breaking early
    if (i == iv_maxErrlInPnor)
    {
        //could not find the errorlog to mark for acknowledgment
        TRACDCOMP( g_trac_errl, ERR_MRK"ackErrLogInPnor failed to find the error log" );
        rc = false;
    }

    TRACFCOMP( g_trac_errl, EXIT_MRK"ackErrLogInPnor returning %s",
            rc ? "true" : "false");
    return rc;
} // ackErrLogInPnor
예제 #3
0
ErrlManager::ErrlManager()
    :
        iv_currLogId(0),
        iv_pStorage(NULL),
        iv_hwasProcessCalloutFn(NULL),
        iv_msgQ(NULL)
{
    TRACFCOMP( g_trac_errl, ENTER_MRK "ErrlManager::ErrlManager constructor" );


    iv_hwasProcessCalloutFn = rt_processCallout;

    TARGETING::Target * sys = NULL;
    TARGETING::targetService().getTopLevelTarget( sys );

    if(sys)
    {
        iv_currLogId = sys->getAttr<TARGETING::ATTR_HOSTSVC_PLID>();
    }
    else
    {
        iv_currLogId = 0x9fbad000;
        TRACFCOMP( g_trac_errl, ERR_MRK"HOSTSVC_PLID not available" );
    }

    TRACFCOMP( g_trac_errl, EXIT_MRK "ErrlManager::ErrlManager constructor." );
}
예제 #4
0
///////////////////////////////////////////////////////////////////////////////
//  Handling commit error log.
///////////////////////////////////////////////////////////////////////////////
void ErrlManager::commitErrLog(errlHndl_t& io_err, compId_t i_committerComp )
{

    TRACDCOMP( g_trac_errl, ENTER_MRK"ErrlManager::commitErrLog" );
    do
    {
        if (io_err == NULL)
        {
            // put out warning trace
            TRACFCOMP(g_trac_errl, ERR_MRK "commitErrLog() - NULL pointer");
            break;
        }

        TRACFCOMP(g_trac_errl, "commitErrLog() called by %.4X for plid=0x%X,"
                               "Reasoncode=%.4X", i_committerComp,
                               io_err->plid(), io_err->reasonCode() );

        // Deferred callouts not allowed at runtime - this call will check,
        // flag and change any that are found.
        io_err->deferredDeconfigure();

        TRACFCOMP( g_trac_errl, INFO_MRK
                   "Send an error log to hypervisor to commit. plid=0x%X",
                   io_err->plid() );

        io_err->commit(i_committerComp);
        sendMboxMsg(io_err);
        io_err = NULL;

    } while( 0 );

   TRACDCOMP( g_trac_errl, EXIT_MRK"ErrlManager::commitErrLog" );

   return;
}
예제 #5
0
// Helper function to run Memory Diagnostics on a list of targets.
errlHndl_t __runMemDiags( TargetHandleList i_trgtList )
{
    errlHndl_t errl = nullptr;

    do
    {
        errl = ATTN::startService();
        if ( nullptr != errl )
        {
            TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                       "ATTN::startService() failed" );
            break;
        }

        errl = MDIA::runStep( i_trgtList );
        if ( nullptr != errl )
        {
            TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                       "MDIA::runStep() failed" );
            break;
        }

        errl = ATTN::stopService();
        if ( nullptr != errl )
        {
            TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                       "ATTN::stopService() failed" );
            break;
        }

    } while (0);

    return errl;
}
예제 #6
0
파일: xscom.C 프로젝트: AmesianX/hostboot
/**
 * @brief Reset the Scom engine regs
 *
 * @param[in]  i_target        Target of the CPU that the xscom is for
 * @param[in]  i_virtAddr      virtual address of the CPU that the xscom is
 *                             targeted for
 *
 * @return none
 */
void resetScomEngine(TARGETING::Target* i_target,
                           uint64_t* i_virtAddr)
{
    errlHndl_t l_err = NULL;
    HMER l_hmer;
    uint64_t io_buffer = 0;
    size_t io_buflen = XSCOM_BUFFER_SIZE;
    uint64_t* l_virtAddr = 0;

    // xscom registers that need to be set.
    XscomAddrType_t XscomAddr[] = { {0x0202000F, CurThreadCpu},
                                    {0x02020007, TargetCpu},
                                    {0x02020009, TargetCpu},};

    TRACFCOMP(g_trac_xscom,"resetScomEngine: XSCOM RESET INTIATED");

    // Loop through the registers you want to write to 0
    for (int i = 0; i<3; i++)
    {
        // First address we need to read is for the Cpu that this thread is
        // running on.  Need to find the virtAddr for that CPU.
        if (XscomAddr[i].target_type == CurThreadCpu)
        {
            l_virtAddr =  getCpuIdVirtualAddress();
        }
        // The rest are xscoms are to the target cpu.
        else
        {
            l_virtAddr = i_virtAddr;
        }

        //*********************************************************
        // Write SCOM ADDR To reset the XSCOM ENGINE
        //*********************************************************
        l_err = xScomDoOp(DeviceFW::WRITE,
                          l_virtAddr,
                          XscomAddr[i].addr,
                          &io_buffer,
                          io_buflen,
                          l_hmer);


        // If not successful
        if (l_err)
        {
            // Delete thie errorlog as this is in the errorpath already.
            delete l_err;

            TRACFCOMP(g_trac_xscom,ERR_MRK "XSCOM RESET FAILED: XscomAddr = %.16llx, VAddr=%llx",XscomAddr[i], l_virtAddr );
        }

        // unmap the device now that we are done with the scom to that area.
        if (XscomAddr[i].target_type == CurThreadCpu)
        {
            mmio_dev_unmap(reinterpret_cast<void*>(l_virtAddr));
        }
    }

    return;
}
예제 #7
0
///////////////////////////////////////////////////////////////////////////////
//  Handling commit error log.
///////////////////////////////////////////////////////////////////////////////
void ErrlManager::commitErrLog(errlHndl_t& io_err, compId_t i_committerComp )
{

    TRACDCOMP( g_trac_errl, ENTER_MRK"ErrlManager::commitErrLog" );
    do
    {
        if (io_err == NULL)
        {
            // put out warning trace
            TRACFCOMP(g_trac_errl, ERR_MRK "commitErrLog() - NULL pointer");
            break;
        }

        TRACFCOMP(g_trac_errl, "commitErrLog() called by %.4X for eid=%.8x, Reasoncode=%.4X",
                    i_committerComp, io_err->eid(), io_err->reasonCode() );

        if (io_err->sev() != ERRORLOG::ERRL_SEV_INFORMATIONAL)
        {
            iv_nonInfoCommitted = true;
            lwsync();
        }

        //Ask ErrlEntry to check for any special deferred deconfigure callouts
        io_err->deferredDeconfigure();

        //Offload the error log to the errlog message queue
        sendErrlogToMessageQueue ( io_err, i_committerComp );
        io_err = NULL;

   } while( 0 );

   TRACDCOMP( g_trac_errl, EXIT_MRK"ErrlManager::commitErrLog" );

   return;
}
예제 #8
0
void* call_dmi_io_dccal (void *io_pArgs)
{
    IStepError l_StepError;

    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_dmi_io_dccal entry" );

    do
    {
        auto l_procModel = TARGETING::targetService().getProcessorModel();

        switch (l_procModel)
        {
            case TARGETING::MODEL_CUMULUS:
                cumulus_dccal_setup(l_StepError);
                break;
            case TARGETING::MODEL_AXONE:
                axone_dccal_setup(l_StepError);
                break;
            case TARGETING::MODEL_NIMBUS:
            default:
                TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                    "skipping p9_io_dmi_dccal because not required for current processor model 0x%x", l_procModel);
                break;
        }

    }while(0);


    TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_dmi_io_dccal exit" );

    // end task, returning any errorlogs to IStepDisp
    return l_StepError.getErrorHandle();
}
//
// Wrapper function to call proc_fbc_eff_config_aggregate
//
void*   call_host_fbc_eff_config_aggregate( void    *io_pArgs )
{
    errlHndl_t l_errl = NULL;
    ISTEP_ERROR::IStepError l_stepError;

    TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
               "call_host_fbc_eff_config_aggregate entry" );

    TARGETING::TargetHandleList l_procChips;
    getAllChips( l_procChips, TARGETING::TYPE_PROC);
    for (const auto & l_procChip: l_procChips)
    {
        fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>l_fapi2CpuTarget(l_procChip);
        FAPI_INVOKE_HWP(l_errl,p9_fbc_eff_config_aggregate,l_fapi2CpuTarget);
        if(l_errl)
        {
            l_stepError.addErrorDetails(l_errl);
            TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                       "ERROR : call_proc_fbc_eff_config_aggregate, PLID=0x%x",
                       l_errl->plid() );
            errlCommit(l_errl, HWPF_COMP_ID);
        }
    }

    TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
               "call_host_fbc_eff_config_aggregate exit" );

    return l_stepError.getErrorHandle();
}
예제 #10
0
파일: rt_occ.C 프로젝트: jk-ozlabs/hostboot
    int enable_occ_actuation (int i_occ_activation)
    {
        int rc = 0;
#ifdef CONFIG_HTMGT
        errlHndl_t err = HTMGT::enableOccActuation(0 != i_occ_activation);
        if (err)
        {
            rc = err->reasonCode();
            if (0 == rc)
            {
                // If there was a failure, be sure to return non-zero status
                rc = -1;
            }
            TRACFCOMP (g_fapiTd,ERR_MRK"enable_occ_actuation: OCC state change"
                       " failed with rc=0x%04X (actuate=%d)",
                       err->reasonCode(), i_occ_activation);
            errlCommit (err, HWPF_COMP_ID);
        }
#else
        rc = -1;
        TRACFCOMP(g_fapiTd,ERR_MRK"Unexpected call to enable_occ_actuation(%d)"
                  " when HTMGT is not enabled", i_occ_activation);
#endif
        return rc;
    }
예제 #11
0
ErrlManager::ErrlManager()
    :
        iv_currLogId(0),
        iv_pStorage(NULL),
        iv_hwasProcessCalloutFn(NULL),
        iv_msgQ(NULL)
{
    TRACFCOMP( g_trac_errl, ENTER_MRK "ErrlManager::ErrlManager constructor" );


    iv_hwasProcessCalloutFn = rt_processCallout;

    TARGETING::Target * sys = NULL;
    TARGETING::targetService().getTopLevelTarget( sys );

    if(sys)
    {
        iv_currLogId = sys->getAttr<TARGETING::ATTR_HOSTSVC_PLID>();

        // set whether we want to skip certain error logs or not.
        iv_hiddenErrLogsEnable =
            sys->getAttr<TARGETING::ATTR_HIDDEN_ERRLOGS_ENABLE>();

        TRACFCOMP( g_trac_errl,"iv_hiddenErrorLogsEnable = 0x%x",
                iv_hiddenErrLogsEnable );

    }
    else
    {
        iv_currLogId = 0x9fbad000;
        TRACFCOMP( g_trac_errl, ERR_MRK"HOSTSVC_PLID not available" );
    }

    TRACFCOMP( g_trac_errl, EXIT_MRK "ErrlManager::ErrlManager constructor." );
}
예제 #12
0
파일: pnorrp.C 프로젝트: HankChang/hostboot
/**
 * @brief  Write 1 page of data to the PNOR device
 */
errlHndl_t PnorRP::writeToDevice( uint64_t i_offset,
                                  uint64_t i_chip,
                                  bool i_ecc,
                                  void* i_src )
{
    TRACUCOMP(g_trac_pnor, "PnorRP::writeToDevice> i_offset=%X, i_chip=%d", i_offset, i_chip );
    errlHndl_t l_errhdl = NULL;
    uint8_t* ecc_buffer = NULL;

    do
    {
#ifdef CONFIG_SFC_IS_AST2400
        //@todo RTC:106881 -- Add full write/erase support
        TRACFCOMP(g_trac_pnor, "PnorRP::writeToDevice> Skipping all writes in BMC for now" );
        break;
#endif


        TARGETING::Target* pnor_target = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL;

        // assume a single page to write
        void* data_to_write = i_src;
        size_t write_size = PAGESIZE;

        // apply ECC to data if needed
        if( i_ecc )
        {
            ecc_buffer = new uint8_t[PAGESIZE_PLUS_ECC];
            PNOR::ECC::injectECC( reinterpret_cast<uint8_t*>(i_src),
                                  PAGESIZE,
                                  reinterpret_cast<uint8_t*>(ecc_buffer) );
            data_to_write = reinterpret_cast<void*>(ecc_buffer);
            write_size = PAGESIZE_PLUS_ECC;
        }

        //no need for mutex since only ever a singleton object
        iv_stats[i_offset/PAGESIZE].numWrites++;

        // write the data out to the PNOR DD
        errlHndl_t l_errhdl = DeviceFW::deviceWrite( pnor_target,
                                       data_to_write,
                                       write_size,
                                       DEVICE_PNOR_ADDRESS(i_chip,i_offset) );
        if( l_errhdl )
        {
            TRACFCOMP(g_trac_pnor, "PnorRP::writeToDevice> Error from device : RC=%X", l_errhdl->reasonCode() );
            break;
        }
    } while(0);

    if( ecc_buffer )
    {
        delete[] ecc_buffer;
    }

    TRACUCOMP(g_trac_pnor, "< PnorRP::writeToDevice" );
    return l_errhdl;
}
예제 #13
0
파일: dvpd.C 프로젝트: open-power/hostboot
/**
 * @brief Callback function to check for a record override
 */
errlHndl_t DvpdFacade::checkForRecordOverride( const char* i_record,
                                               TARGETING::Target* i_target,
                                               uint8_t*& o_ptr )
{
    TRACFCOMP(g_trac_vpd,ENTER_MRK"DvpdFacade::checkForRecordOverride( %s, 0x%.8X )",
              i_record, get_huid(i_target));
    errlHndl_t l_errl = nullptr;
    o_ptr = nullptr;

    assert( i_record != nullptr, "DvpdFacade::checkForRecordOverride() i_record is null" );
    assert( i_target != nullptr, "DvpdFacade::checkForRecordOverride() i_target is null" );

    VPD::RecordTargetPair_t l_recTarg =
      VPD::makeRecordTargetPair(i_record,i_target);

    do
    {
        // We only support overriding MEMD
        if( strcmp( i_record, "MEMD" ) )
        {
            TRACFCOMP(g_trac_vpd,"Record %s has no override", i_record);
            mutex_lock(&iv_mutex); //iv_overridePtr is not threadsafe
            iv_overridePtr[l_recTarg] = nullptr;
            mutex_unlock(&iv_mutex);
            break;
        }

        // Compare the last nibble
        constexpr uint32_t l_vmMask = 0x0000000F;
        input_args_t l_args = { DVPD::MEMD, DVPD::VM, VPD::AUTOSELECT };
        l_errl = getMEMDFromPNOR( l_args,
                                  i_target,
                                  l_vmMask );
        if( l_errl )
        {
            TRACFCOMP(g_trac_vpd,ERR_MRK"ERROR from getMEMDFromPNOR.");
            break;
        }

    } while(0);

    // For any error, we should reset the override map so that we'll
    //  attempt everything again the next time we want VPD
    mutex_lock(&iv_mutex); //iv_overridePtr is not threadsafe
    if( l_errl )
    {
        iv_overridePtr.erase(l_recTarg);
    }
    else
    {
        o_ptr = iv_overridePtr[l_recTarg];
    }
    mutex_unlock(&iv_mutex);

    return l_errl;
}
예제 #14
0
///////////////////////////////////////////////////////////////////////////////
// ErrlManager::startup()
///////////////////////////////////////////////////////////////////////////////
void * ErrlManager::startup ( void* i_self )
{
    TRACFCOMP( g_trac_errl, ENTER_MRK "ErrlManager::startup..." );

    //Start a thread and let error log message handler running.
    reinterpret_cast<ErrlManager *>(i_self)->errlogMsgHndlr();

    TRACFCOMP( g_trac_errl, EXIT_MRK "ErrlManager::startup" );
    return NULL;
}
예제 #15
0
void* call_cen_arrayinit (void *io_pArgs)
{
    IStepError l_StepError;
    errlHndl_t l_err = NULL;

    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_arrayinit entry" );

    TARGETING::TargetHandleList l_membufTargetList;
    getAllChips(l_membufTargetList, TYPE_MEMBUF);

    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_arrayinit: %d membufs found",
            l_membufTargetList.size());

    for (const auto & l_membuf_target : l_membufTargetList)
    {
        TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
            "cen_arrayinit HWP target HUID %.8x",
            TARGETING::get_huid(l_membuf_target));

        //  call the HWP with each target
        fapi2::Target <fapi2::TARGET_TYPE_MEMBUF_CHIP> l_fapi_membuf_target
                (l_membuf_target);

        FAPI_INVOKE_HWP(l_err, cen_arrayinit, l_fapi_membuf_target);

        //  process return code.
        if ( l_err )
        {
            TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                "ERROR 0x%.8X:  cen_arrayinit HWP on target HUID %.8x",
                l_err->reasonCode(), TARGETING::get_huid(l_membuf_target) );

            // capture the target data in the elog
            ErrlUserDetailsTarget(l_membuf_target).addToLog( l_err );

            // Create IStep error log and cross reference to error that occurred
            l_StepError.addErrorDetails( l_err );

            // Commit Error
            errlCommit( l_err, ISTEP_COMP_ID );
        }
        else
        {
            TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                     "SUCCESS :  cen_arrayinit HWP");
        }

    }


    TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_arrayinit exit" );

    return l_StepError.getErrorHandle();
}
예제 #16
0
파일: pnorrp.C 프로젝트: bjwyman/hostboot
/**
 * @brief  Constructor
 */
PnorRP::PnorRP()
: iv_TOC_used(0)
,iv_msgQ(NULL)
,iv_startupRC(0)
{
    TRACFCOMP(g_trac_pnor, "PnorRP::PnorRP> " );
    // setup everything in a separate function
    initDaemon();

    TRACFCOMP(g_trac_pnor, "< PnorRP::PnorRP : Startup Errors=%X ", iv_startupRC );
}
예제 #17
0
//  Runtime processCallout
bool rt_processCallout(errlHndl_t &io_errl,
                       uint8_t * i_pData,
                       uint64_t i_Size,
                       bool i_DeferredOnly)
{
    HWAS::callout_ud_t *pCalloutUD = (HWAS::callout_ud_t *)i_pData;
    if(i_DeferredOnly)
    {
        if ((pCalloutUD->type == HWAS::HW_CALLOUT) &&
            ((pCalloutUD->deconfigState == HWAS::DELAYED_DECONFIG) ||
             (pCalloutUD->deconfigState == HWAS::DECONFIG)))
        {
            pCalloutUD->deconfigState = HWAS::NO_DECONFIG;

            TRACFCOMP( g_trac_errl, ERR_MRK
                       "Runtime errorlog callout with DELAYED_DECONFIG or "
                       "DECONFIG not allowed! Changed to NO_DECONFIG. "
                       " plid: 0x%X. Deconfig State: 0x%x", io_errl->plid(),
                       pCalloutUD->deconfigState);
        }

    }

    // Gard callouts are handled by the HWSV if there is an FSP
    // if we attempt to create a gard record it requires us to read
    // PNOR which we cannot do on FSP based machines
    if(!INITSERVICE::spBaseServicesEnabled())
    {
        if ((pCalloutUD->type == HWAS::HW_CALLOUT) &&
            (pCalloutUD->gardErrorType != HWAS::GARD_NULL))
        {
                TARGETING::Target *pTarget = NULL;
                uint8_t * l_uData = (uint8_t *)(pCalloutUD + 1);
                bool l_err = HWAS::retrieveTarget(l_uData, pTarget, io_errl);

                if (!l_err)
                {
                    errlHndl_t errl = HWAS::theDeconfigGard().platCreateGardRecord
                        (pTarget,
                            io_errl->eid(),
                            pCalloutUD->gardErrorType);
                    if (errl)
                    {
                        TRACFCOMP( g_trac_errl, ERR_MRK
                            "rt_processCallout: error from platCreateGardRecord");
                        errlCommit(errl, HWAS_COMP_ID);
                    }
                }

        }
    }
    return true;
}
예제 #18
0
///////////////////////////////////////////////////////////////////////////////
// ErrlManager::sendMboxMsg()
///////////////////////////////////////////////////////////////////////////////
void ErrlManager::sendMboxMsg ( errlHndl_t& io_err )
{
    TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::sendToHypervisor" );
    do
    {
#ifdef CONFIG_BMC_IPMI
        TRACFCOMP(g_trac_errl,INFO_MRK"Send msg to BMC for errlogId [0x%08x]",
                  io_err->plid() );
        // convert to SEL/eSEL and send to BMC over IPMI
        sendErrLogToBmc(io_err);
#else
        TRACDCOMP(g_trac_errl,
                  INFO_MRK"Send msg to FSP for errlogId [0x%08x]",
                  io_err->plid() );

        uint32_t l_msgSize = io_err->flattenedSize();
        uint8_t * temp_buff = new uint8_t [l_msgSize ];
        io_err->flatten ( temp_buff, l_msgSize );

        if(g_hostInterfaces && g_hostInterfaces->sendErrorLog)
        {
            int rc = g_hostInterfaces->sendErrorLog(io_err->plid(),
                                                    l_msgSize,
                                                    temp_buff);

            if(rc)
            {
                TRACFCOMP(g_trac_errl, ERR_MRK
                          "Failed sending error log to FSP. rc: %d. "
                          "plid: 0x%08x",
                          rc,
                          io_err->plid() );
            }
        }
        else
        {
            TRACFCOMP(g_trac_errl, ERR_MRK
                      "Host interfaces not initialized, error log not sent. "
                      "plid: 0x%08x",
                      io_err->plid()
                      );
        }
        delete [] temp_buff;
#endif
        delete io_err;
        io_err = NULL;

    } while (0);

    TRACFCOMP( g_trac_errl, EXIT_MRK"sendToHypervisor()" );
    return;
}
예제 #19
0
errlHndl_t RtPnor::readTOC ()
{
    TRACFCOMP(g_trac_pnor, ENTER_MRK"RtPnor::readTOC" );
    errlHndl_t l_err = NULL;
    uint8_t* l_toc0Buffer = new uint8_t[PNOR::TOC_SIZE];
    do {
        if (g_hostInterfaces && g_hostInterfaces->pnor_read)
        {
            //find proc id
            uint64_t l_procId;
            TARGETING::Target* l_masterProc = NULL;
            TARGETING::targetService().masterProcChipTargetHandle(l_masterProc);
            l_err = RT_TARG::getRtTarget (l_masterProc, l_procId);
            if (l_err)
            {
                TRACFCOMP(g_trac_pnor, "RtPnor::readTOC: getRtTarget failed");
                break;
            }
            // offset = 0 means read the entire PNOR::TOC partition
            // This offset is offset into the partition, not offset from the
            // beginning of the flash
            l_err = readFromDevice (l_procId, PNOR::TOC, 0,
                    PNOR::TOC_SIZE, false, l_toc0Buffer);
            if (l_err)
            {
                TRACFCOMP(g_trac_pnor,"RtPnor::readTOC:readFromDevice failed"
                          " for TOC0");
                break;
            }

            // When we ask for TOC partition, Opal returns a valid TOC.
            // So, we don't need to verify the second TOC in parseTOC
            // Therefore, sending invalid value for second toc
            PNOR::TOCS l_tocUsed;
            l_err = PNOR::parseTOC(l_toc0Buffer, 0, l_tocUsed, iv_TOC, 0);
            if (l_err)
            {
                TRACFCOMP(g_trac_pnor, "RtPnor::readTOC: parseTOC failed");
                break;
            }
        }
    } while (0);

    if(l_toc0Buffer != NULL)
    {
        delete[] l_toc0Buffer;
    }

    TRACFCOMP(g_trac_pnor, EXIT_MRK"RtPnor::readTOC" );
    return l_err;
}
예제 #20
0
    // send the sync complete message
    errlHndl_t AttributeSync::sendSyncCompleteMessage( )
    {
        TRACFCOMP(g_trac_targeting, "sending sync complete message");

        errlHndl_t l_err = NULL;

        msg_t * msg = msg_allocate();

        // initialize msg buffer
        memset( msg, 0, sizeof(msg_t) );

        msg->type = ATTR_SYNC_COMPLETE_TO_FSP;

        ATTR_SYNC_ADD_PAGE_COUNT( iv_total_pages, msg->data[0] );

        l_err = sendMboxMessage( SYNCHRONOUS, msg );

        if( l_err == NULL )
        {
            // see if there was an error on the other end
            ATTR_SYNC_RC return_code = ATTR_SYNC_GET_RC( msg->data[0] );

            if ( return_code )
            {
                TRACFCOMP(g_trac_targeting, "return code: 0x%x", return_code );

                /*@
                 *   @errortype
                 *   @moduleid      TARG_MOD_ATTR_SYNC
                 *   @reasoncode    TARG_RC_ATTR_SYNC_TO_FSP_FAIL
                 *   @userdata1     return code from FSP attribute sync
                 *   @userdata2     section ID of for section being sync'd
                 *
                 *   @devdesc       The Attribute synchronization code on the
                 *                  FSP side was unable to complete the sync
                 *                  operation successfully.
                 */
                 l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
                                        TARG_MOD_ATTR_SYNC,
                                        TARG_RC_ATTR_SYNC_TO_FSP_FAIL,
                                        return_code,
                                        (uint64_t)iv_section_to_sync);
            }
        }

        // for a syncronous message we need to free the message
        msg_free( msg );

        return l_err;
    }
예제 #21
0
파일: pnorrp.C 프로젝트: bjwyman/hostboot
/**
 * @brief  Destructor
 */
PnorRP::~PnorRP()
{
    TRACFCOMP(g_trac_pnor, "PnorRP::~PnorRP> " );

    // delete the message queue we created
    if( iv_msgQ )
    {
        msg_q_destroy( iv_msgQ );
    }

    // should kill the task we spawned, but that isn't needed right now

    TRACFCOMP(g_trac_pnor, "< PnorRP::~PnorRP" );
}
예제 #22
0
///////////////////////////////////////////////////////////////////////////////
// ErrlManager::errlogShutdown()
///////////////////////////////////////////////////////////////////////////////
void ErrlManager::errlogShutdown()
{
    // if there are errorlogs that didn't get fully processed, trace them
    // and clean up
    while (!iv_errlList.empty())
    {
        // Get errl and its flags
        ErrlFlagPair_t l_pair = iv_errlList.front();
        // If still true that means it was not processed

        TRACFCOMP(g_trac_errl, INFO_MRK "Failed to fully process Errl(eid %.8x) - Errl Flags Bitfield = 0x%X",
                    l_pair.first->eid(), l_pair.second);

        delete l_pair.first;
        l_pair.first = NULL;
        // delete from the list
        iv_errlList.pop_front();
    } // while items on iv_errlList list

    // Ensure that all the error logs are pushed out to PNOR
    // prior to the PNOR resource provider shutting down.
    int l_rc = mm_remove_pages(FLUSH, (void *) iv_pnorAddr,
                    iv_maxErrlInPnor * PNOR_ERROR_LENGTH);
    if( l_rc )
    {
        //If mm_remove_pages returns none zero for error then
        //log an error trace in this case.
        TRACFCOMP(g_trac_errl, ERR_MRK "Fail to flush the page %p size %d",
                iv_pnorAddr, iv_maxErrlInPnor * PNOR_ERROR_LENGTH);
    }

    // Un-register error log message queue from the shutdown
    INITSERVICE::unregisterShutdownEvent( iv_msgQ);

    if (iv_isMboxEnabled)
    {
        // Un-register error log message queue from the mailbox service
        MBOX::msgq_unregister( MBOX::HB_ERROR_MSGQ );
    }

    // Do not destroy the queue... there are paths where the daemon thread
    // still has references to the queue or the unregisterShutdownEvent did
    // not take effect because we were already in the middle of a system
    // shutdown.
    // Leaving this message queue around really isn't a leak because we are
    // shutting down.
    // msg_q_destroy(iv_msgQ);

    return;
}
예제 #23
0
// ----------------------------------------------------------------------------
// configureBootMode()
// ----------------------------------------------------------------------------
void AST2400BootConfig::configureBootMode(uint8_t i_bootMode )
{
    // assume boot mode is exclusive..
    switch( i_bootMode )
    {
        case NORMAL:
            {
                TRACFCOMP(g_bc_trace,
                        "configureBootMode() - Boot Mode = NORMAL");
                break;
            }
        // RTC:123376 - Need to investigate if any additional flags need to be
        // set or if terminate on error is sufficient
        case TERMINATE_ON_ERROR:
            {

                TARGETING::Target* l_pTopLevel = NULL;
                TARGETING::targetService().getTopLevelTarget(l_pTopLevel);

                TRACFCOMP(g_bc_trace,
                        "configureBootMode() - Boot Mode = TERMINATE_ON_ERROR");

                l_pTopLevel->setAttr<TARGETING::ATTR_MNFG_FLAGS>
                                        (TARGETING::MNFG_FLAG_SRC_TERM );
                break;
            }

        case ISTEP_MODE:
            {
                TRACFCOMP(g_bc_trace,
                        "configureBootMode() - Boot Mode = ISTEP MODE");

                TARGETING::Target* l_pTopLevel = NULL;
                TARGETING::targetService().getTopLevelTarget(l_pTopLevel);

                l_pTopLevel->setAttr<TARGETING::ATTR_ISTEP_MODE>(1);

                break;
            }

         default:
                  TRACFCOMP(g_bc_trace,
                            "WRN>>configureBootMode() - Boot mode = "
                             "INVALID[0x%x] default to normal", i_bootMode );
                break;

          break;
    }
}
예제 #24
0
///////////////////////////////////////////////////////////////////////////////
// ErrlManager::sendErrLogToFSP()
///////////////////////////////////////////////////////////////////////////////
void ErrlManager::sendErrLogToFSP ( errlHndl_t& io_err )
{
    msg_t *msg = NULL;

    TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::sendErrLogToFSP" );
    do
    {
        //Create a mailbox message to send to FSP
        msg = msg_allocate();
        msg->type = ERRLOG_SEND_TO_FSP_TYPE;

        uint32_t l_msgSize = io_err->flattenedSize();

        //Data[0] will be hostboot error log ID so Hostboot can
        //keep track of the error log when FSP responses back.

        msg->data[0] = io_err->eid();
        msg->data[1] = l_msgSize;

        void * temp_buff = MBOX::allocate( l_msgSize );

        io_err->flatten ( temp_buff, l_msgSize );
        msg->extra_data = temp_buff;

        TRACDCOMP( g_trac_errl, INFO_MRK"Send msg to FSP for errlogId %.8x",
                                                               io_err->eid() );
        errlHndl_t l_err = MBOX::send( MBOX::FSP_ERROR_MSGQ, msg );
        if( !l_err )
        {
            // clear this - we're done with the message;
            // the receiver will free the storage when it's done
            msg = NULL;
        }
        else
        {
           TRACFCOMP(g_trac_errl, ERR_MRK"Failed sending error log to FSP");

           //Free the extra data due to the error
           MBOX::deallocate( msg->extra_data );
           msg_free( msg );
           msg = NULL;

           delete l_err;
           l_err = NULL;
        }
    } while (0);

    TRACFCOMP( g_trac_errl, EXIT_MRK"ErrlManager::sendErrLogToFSP" );
} // sendErrLogToFSP
예제 #25
0
uint64_t ErrlSctnHdr::flatten( void * o_pBuffer, const uint64_t i_cbBuffer )
{
    uint64_t   l_rc = 0;

    // Compile-time assertions
    CPPASSERT( 8 == sizeof( pelSectionHeader_t ));
    CPPASSERT( 2 == sizeof( iv_sid ));
    CPPASSERT( 2 == sizeof( iv_slen ));
    CPPASSERT( 1 == sizeof( iv_ver ));
    CPPASSERT( 1 == sizeof( iv_sst ));
    CPPASSERT( 2 == sizeof( iv_compId ));

    if( i_cbBuffer >= sizeof( pelSectionHeader_t ))
    {
        // See errltypes.H for pelSectionHeader_t
        pelSectionHeader_t * p  = static_cast<pelSectionHeader_t *>(o_pBuffer);
        p->sid      = iv_sid;
        p->len      = iv_slen;
        p->ver      = iv_ver;
        p->sst      = iv_sst;
        p->compId   = iv_compId;

        l_rc = sizeof( pelSectionHeader_t );
    }
    else
    {
        TRACFCOMP( g_trac_errl, "ErrlSctnHdr::flatten: buffer too small");
    }

    return l_rc;
};
예제 #26
0
파일: rt_vpd.C 프로젝트: HankChang/hostboot
// ------------------------------------------------------------------
// Fake writePNOR - image is in memory
// ------------------------------------------------------------------
errlHndl_t writePNOR ( uint64_t i_byteAddr,
                       size_t i_numBytes,
                       void * i_data,
                       TARGETING::Target * i_target,
                       pnorInformation & i_pnorInfo,
                       uint64_t &io_cachedAddr,
                       mutex_t * i_mutex )
{
    errlHndl_t err = NULL;
    // Does VPD write ever need to be supported at runtime?
    TRACFCOMP(g_trac_vpd, ERR_MRK
              "RT writePNOR: VPD write not supported at runtime.");

    /*@
     * @errortype
     * @reasoncode       VPD::VPD_RT_WRITE_NOT_SUPPORTED
     * @severity         ERRORLOG::ERRL_SEV_UNRECOVERABLE
     * @moduleid         VPD::VPD_RT_WRITE_PNOR
     * @userdata1        target huid
     * @userdata2        VPD type
     * @devdesc          VPD write not supported at runtime
     */
    err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                   VPD::VPD_RT_WRITE_PNOR,
                                   VPD::VPD_RT_WRITE_NOT_SUPPORTED,
                                   get_huid(i_target),
                                   i_pnorInfo.pnorSection);

    err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
                             HWAS::SRCI_PRIORITY_HIGH);

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

    return err;
}
예제 #27
0
    //**************************************************************************
    // FREQVOLTSVC::runP8BuildPstateDataBlock
    //**************************************************************************
    errlHndl_t runP8BuildPstateDataBlock(
                                           const TARGETING::Target * i_procChip,
                                           PstateSuperStructure * o_data)
    {
        errlHndl_t l_err = NULL;

        // Assert on NULL input target
        assert(i_procChip != NULL);

        // convert to fapi target
        fapi::Target l_fapiProcChip(fapi::TARGET_TYPE_PROC_CHIP,
                              reinterpret_cast<void *>
                              (const_cast<TARGETING::Target*>(i_procChip)) );

        FAPI_INVOKE_HWP(l_err, p8_build_pstate_datablock,l_fapiProcChip,o_data);

        if( l_err != NULL)
        {
            TRACFCOMP( g_fapiTd,ERR_MRK"Error from HWP: "
                     "p8_build_pstate_datablock for target HUID: 0x%08X",
                     i_procChip->getAttr<TARGETING::ATTR_HUID>());
        }

        return l_err;
    }
예제 #28
0
파일: pnorrp.C 프로젝트: bjwyman/hostboot
/**
 * @brief  Convert a virtual address into the PNOR device address
 */
errlHndl_t PnorRP::computeDeviceAddr( void* i_vaddr,
                                      uint64_t& o_offset,
                                      uint64_t& o_chip,
                                      bool& o_ecc )
{
    errlHndl_t l_errhdl = NULL;
    o_offset = 0;
    o_chip = 99;
    uint64_t l_vaddr = (uint64_t)i_vaddr;

    // make sure this is one of our addresses
    if( !((l_vaddr >= BASE_VADDR)
          && (l_vaddr < LAST_VADDR)) )
    {
        TRACFCOMP( g_trac_pnor, "PnorRP::computeDeviceAddr> Virtual Address outside known PNOR range : i_vaddr=%p", i_vaddr );
        /*@
         * @errortype
         * @moduleid     PNOR::MOD_PNORRP_WAITFORMESSAGE
         * @reasoncode   PNOR::RC_INVALID_ADDRESS
         * @userdata1    Virtual Address
         * @userdata2    Base PNOR Address
         * @devdesc      PnorRP::computeDeviceAddr> Virtual Address outside
         *               known PNOR range
         * @custdesc    A problem occurred while accessing the boot flash.
         */
        l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                        PNOR::MOD_PNORRP_COMPUTEDEVICEADDR,
                                        PNOR::RC_INVALID_ADDRESS,
                                        l_vaddr,
                                        BASE_VADDR,
                                        true /*Add HB SW Callout*/);
        l_errhdl->collectTrace(PNOR_COMP_NAME);
        return l_errhdl;
    }

    // find the matching section
    PNOR::SectionId id = PNOR::INVALID_SECTION;
    l_errhdl = computeSection( l_vaddr, id );
    if( l_errhdl )
    {
        return l_errhdl;
    }

    // pull out the information we need to return from our global copy
    o_chip = iv_TOC[id].chip;
    o_ecc = (bool)(iv_TOC[id].integrity & FFS_INTEG_ECC_PROTECT);
    o_offset = l_vaddr - iv_TOC[id].virtAddr; //offset into section

    // for ECC we need to figure out where the ECC-enhanced offset is
    //  before tacking on the offset to the section
    if( o_ecc )
    {
        o_offset = (o_offset * 9) / 8;
    }
    // add on the offset of the section itself
    o_offset += iv_TOC[id].flashAddr;

    TRACUCOMP( g_trac_pnor, "< PnorRP::computeDeviceAddr: i_vaddr=%X, o_offset=0x%X, o_chip=%d", l_vaddr, o_offset, o_chip );
    return l_errhdl;
}
예제 #29
0
    const uint8_t* TPMS_CAPABILITY_DATA_unmarshal(TPMS_CAPABILITY_DATA* val,
                                                  const uint8_t* i_tpmBuf,
                                                  size_t * io_tpmBufSize)
    {
        i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
                                  &(val->capability),
                                  sizeof(val->capability));

        switch (val->capability)
        {
          case TPM_CAP_HANDLES:
              {
                  return TPML_HANDLE_unmarshal(
                                      &(val->data.tpmHandles), i_tpmBuf,
                                      io_tpmBufSize);
              }
              break;
          case TPM_CAP_TPM_PROPERTIES:
              {
                  return TPML_TAGGED_TPM_PROPERTY_unmarshal(
                                      &(val->data.tpmProperties), i_tpmBuf,
                                      io_tpmBufSize);
              }
              break;
          default:
              {
                  TRACFCOMP( g_trac_trustedboot,
                       "TPMS_CAPABILITY_DATA::unmarshal Unknown capability");
                  return NULL;
              }
              break;
        }
        return NULL;
    }
예제 #30
0
/**
 * @brief Send a user-defined SPI command
 */
errlHndl_t SfcFake::sendSpiCmd( uint8_t i_opCode,
                                uint32_t i_address,
                                size_t i_writeCnt,
                                const uint8_t* i_writeData,
                                size_t i_readCnt,
                                uint8_t* o_readData )
{
    TRACFCOMP( g_trac_pnor, "SfcFake::sendSpiCmd> Nothing to do here : opcode=%.2X", i_opCode );
    /*@
     * @errortype
     * @moduleid     PNOR::MOD_SFCFAKE_SENDSPICMD
     * @reasoncode   PNOR::RC_UNSUPPORTED_OPERATION
     * @userdata1[0:31]  Op Code
     * @userdata1[32:63] Address
     * @userdata2    <unused>
     * @devdesc      SfcFake::sendSpiCmd> Function is not supported
     * @custdesc     Firmware error accessing flash during IPL
     */
    return new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                   PNOR::MOD_SFCFAKE_SENDSPICMD,
                                   PNOR::RC_UNSUPPORTED_OPERATION,
                                   TWO_UINT32_TO_UINT64(i_opCode,
                                                        i_address),
                                   0,
                                   true /*Software error*/);
}