Ejemplo n.º 1
0
    void Daemon::collectTracePages()
    {
        // Clear indication from clients.
        iv_service->iv_daemon->clearSignal();

        // Collect buffer pages from front-end.
        BufferPage* srcPages[BUFFER_COUNT];
        for (size_t i = 0; i < BUFFER_COUNT; i++)
        {
            iv_curPages[i] = srcPages[i] =
                iv_service->iv_buffers[i]->claimPages();

            iv_curOffset[i] = 0;
        }

        char* contBuffer = NULL;
        size_t contBufferSize = 0;

        // Process buffer pages.
        do
        {
            size_t whichBuffer = BUFFER_COUNT;
            Entry* whichEntry = NULL;
            uint64_t minTimeStamp = UINT64_MAX;

            // Find the entry with the earliest timestamp.
            for (size_t i = 0; i < BUFFER_COUNT; i++)
            {
                if (NULL == iv_curPages[i]) continue;

                Entry* entry =
                    reinterpret_cast<Entry*>(
                        &((&(iv_curPages[i]->data[0]))[iv_curOffset[i]])
                    );

                trace_bin_entry_t* binEntry =
                    reinterpret_cast<trace_bin_entry_t*>(
                        &(entry->data[0])
                    );

                // Wait for entry to be committed.
                while(unlikely(entry->committed == 0))
                {
                    task_yield();
                }
                isync();

                uint64_t curTimeStamp =
                    TWO_UINT32_TO_UINT64(binEntry->stamp.tbh,
                                         binEntry->stamp.tbl);

                if (curTimeStamp < minTimeStamp)
                {
                    whichBuffer = i;
                    whichEntry = entry;
                    minTimeStamp = curTimeStamp;
                }
            }

            // Did not find another entry, our work is done.
            if (whichBuffer == BUFFER_COUNT)
            {
                break;
            }

            // Increment pointers to next buffer entry.
            iv_curOffset[whichBuffer] += whichEntry->size + sizeof(Entry);
            if (iv_curOffset[whichBuffer] >= iv_curPages[whichBuffer]->usedSize)
            {
                iv_curPages[whichBuffer] = iv_curPages[whichBuffer]->next;
                iv_curOffset[whichBuffer] = 0;
            }

            trace_bin_entry_t* contEntry =
                reinterpret_cast<trace_bin_entry_t*>(&whichEntry->data[0]);

            // Calculate the sizes of the entry.
            size_t contEntryDataLength = contEntry->head.length +
                                         sizeof(trace_bin_entry_t);

            size_t contEntrySize = whichEntry->comp->iv_compNameLen +
                                   contEntryDataLength;

            // Allocate a new continuous trace page if needed.
            if ((NULL == contBuffer) ||
                ((contBufferSize + contEntrySize) >= PAGESIZE))
            {
                if (NULL != contBuffer)
                {
                    sendContBuffer(contBuffer, contBufferSize);
                    // contBuffer pointer is transfered to mailbox now.
                }

                contBuffer = reinterpret_cast<char*>(malloc(PAGESIZE));
                memset(contBuffer, '\0', PAGESIZE);
                contBuffer[0] = TRACE_BUF_CONT;
                contBufferSize = 1;
            }

            // Add entry to continous trace.
            memcpy(&contBuffer[contBufferSize],
                   whichEntry->comp->iv_compName,
                   whichEntry->comp->iv_compNameLen);
            contBufferSize += whichEntry->comp->iv_compNameLen;

            memcpy(&contBuffer[contBufferSize],
                   &whichEntry->data[0],
                   contEntryDataLength);
            contBufferSize += contEntryDataLength;

            // Allocate a new back-end entry.
            Entry* mainBuffEntry = NULL;
            while (NULL ==
                (mainBuffEntry =
                    iv_last->claimEntry(whichEntry->size + sizeof(Entry))))
            {
                BufferPage* n = BufferPage::allocate(true);

                n->next = iv_last;
                iv_last->prev = n;
                iv_last = n;
            }

            // Move entry from front-end buffer to back-end.
            replaceEntry(whichEntry, mainBuffEntry);

        } while(1);

        // Send remainder of continous trace buffer.
        if (NULL != contBuffer)
        {
            if (contBufferSize > 1)
            {
                sendContBuffer(contBuffer, contBufferSize);
                // contBuffer pointer is transfered to mailbox now.
            }
            else
            {
                free(contBuffer);
            }
        }

        // Release pages.
        for (size_t i = 0; i < BUFFER_COUNT; i++)
        {
            // Toggle lock to ensure no trace extract currently going on.
            iv_service->iv_buffers[i]->consumerOp();

            while(srcPages[i])
            {
                BufferPage* tmp = srcPages[i]->next;
                BufferPage::deallocate(srcPages[i]);
                srcPages[i] = tmp;
            }
        }

    }
Ejemplo n.º 2
0
/**
 * @brief Performs a presence detect operation on a Membuf Chip.
 *
 * This function does FSI presence detect, 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 membPresenceDetect(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::membPresenceDetect> Invalid data length: %d",
                  io_buflen);
        /*@
         * @errortype
         * @moduleid     FSI::MOD_FSIPRES_MEMBPRESENCEDETECT
         * @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_MEMBPRESENCEDETECT,
                                        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 = isSlavePresent(i_target);

    // Next look for memb FRU VPD
    bool cvpd_present = false;
    bool check_for_cvpd = true;

#ifdef CONFIG_CVPD_READ_FROM_HW
    check_for_cvpd = fsi_present;
#endif

    if ( check_for_cvpd )
    {
       cvpd_present = VPD::cvpdPresent( i_target );
    }


#if defined(CONFIG_CVPD_READ_FROM_HW) && defined(CONFIG_CVPD_READ_FROM_PNOR)
    if( cvpd_present )
    {
        // Check if the VPD data in the PNOR matches the SEEPROM
        l_errl = VPD::ensureCacheIsInSync( i_target );
        if( l_errl )
        {
            // Save this plid to use later
            l_saved_plid = l_errl->plid();
            cvpd_present = false;

            TRACFCOMP(g_trac_fsi,ERR_MRK "FSI::membPresenceDetect> Error during ensureCacheIsInSync (CVPD)" );
            errlCommit( l_errl, FSI_COMP_ID );
        }
    }
    else
    {
        // FSI is not present, invalidate MVPD in the PNOR
        l_errl = VPD::invalidatePnorCache(i_target);
        if (l_errl)
        {
            TRACFCOMP( g_trac_fsi, "Error invalidating MVPD in PNOR" );
            errlCommit( l_errl, FSI_COMP_ID );
        }
    }
#endif

    // Finally compare the 2 methods
    if( fsi_present != cvpd_present )
    {

        TRACFCOMP(g_trac_fsi, ERR_MRK "FSI::membPresenceDetect> "
                  "FSI (=%d) and VPD (=%d) do not agree for %.8X",
                  fsi_present, cvpd_present, TARGETING::get_huid(i_target));
        /*@
         * @errortype
         * @moduleid     FSI::MOD_FSIPRES_MEMBPRESENCEDETECT
         * @reasoncode   FSI::RC_FSI_CVPD_MISMATCH
         * @userdata1    HUID of membuffer
         * @userdata2[0:31]    FSI Presence
         * @userdata2[32:63]   VPD Presence
         * @devdesc      presenceDetect> FSI and CVPD do not agree
         */
        l_errl =
                new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                        FSI::MOD_FSIPRES_MEMBPRESENCEDETECT,
                                        FSI::RC_FSI_CVPD_MISMATCH,
                                        TARGETING::get_huid(i_target),
                                        TWO_UINT32_TO_UINT64(
                                            fsi_present,
                                            cvpd_present));

        // Callout the membuf
        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 && cvpd_present;
    if( present )
    {
        //Fsp sets PN/SN so if there is none, do it here
        if(!INITSERVICE::spBaseServicesEnabled())
        {
            // set part and serial number attributes for current target
            VPD::setPartAndSerialNumberAttributes( i_target );
        }

    }
    memcpy(io_buffer, &present, sizeof(present));
    io_buflen = sizeof(present);

    return NULL;
}
Ejemplo n.º 3
0
    //**************************************************************************
    // FREQVOLTSVC::setWofFrequencyUpliftSelected
    //**************************************************************************
    void setWofFrequencyUpliftSelected()
    {

        // get mrw data
        TARGETING::Target* l_pTopLevel = NULL;
        (void)TARGETING::targetService().getTopLevelTarget(l_pTopLevel);
        ATTR_WOF_FREQUENCY_UPLIFT_type l_upliftTable = {{{0}}};
        ATTR_WOF_PROC_SORT_type l_procSortTable = {{0}};
        ATTR_NOMINAL_FREQ_MHZ_type l_sysNomFreqMhz =
            l_pTopLevel->getAttr<ATTR_NOMINAL_FREQ_MHZ>();
        ATTR_WOF_ENABLED_type l_wofEnabled = l_pTopLevel->getAttr
                                           < TARGETING::ATTR_WOF_ENABLED > ();

        // tryGetAttr used due to complex data type. Expected to always work.
        if (!l_pTopLevel->tryGetAttr<ATTR_WOF_FREQUENCY_UPLIFT>(l_upliftTable))
        {
            // The zero initialized values will be used for the select array
            TRACFCOMP(g_fapiTd, "Failed to get ATTR_WOF_FREQUENCY_UPLIFT");
        }
        // tryGetAttr used due to complex data type. Expected to always work.
        if ( !l_pTopLevel->tryGetAttr<ATTR_WOF_PROC_SORT>(l_procSortTable))
        {
            // Not finding the sort table will result in not finding the index
            // which will result in a log later
            TRACFCOMP(g_fapiTd, "Failed to get ATTR_WOF_PROC_SORT");
        }

        // get the list of procs
        TargetHandleList l_procTargetList;
        getAllChips(l_procTargetList, TYPE_PROC, true);

        // for each proc, fill in Wof Frequency Uplift Selected attribute
        for (TargetHandleList::const_iterator
                l_proc_iter = l_procTargetList.begin();
                l_proc_iter != l_procTargetList.end();
                ++l_proc_iter)
        {
            TARGETING::Target * l_pProcTarget = *l_proc_iter;

            // find number of active cores
            TARGETING::TargetHandleList l_presCoreList;
            getChildAffinityTargetsByState( l_presCoreList,
                      const_cast<TARGETING::Target*>(l_pProcTarget),
                      TARGETING::CLASS_UNIT,
                      TARGETING::TYPE_CORE,
                      TARGETING::UTIL_FILTER_PRESENT);
            uint8_t l_activeCores = l_presCoreList.size();
            TRACDCOMP(g_fapiTd, "setWofFrequencyUpliftSelected:"
                            " number of active cores  is %d ",
                            l_activeCores);

            // find WOF index. For example:
            // ATTR_WOF_PROC_SORT =
            // Cores/Nom Freq/Index
            //   8    3325     1
            //   10   2926     2
            //   12   2561     3
            //   12   3093     4
            // Use WOF index=3 for active cores=12 && nom freq=2561
            uint8_t l_wofIndex = 0;
            for (uint8_t i=0;i<4;i++)
            {
                if ( (l_activeCores   == l_procSortTable[i][0]) &&
                     (l_sysNomFreqMhz == l_procSortTable[i][1]) )
                {
                   l_wofIndex = l_procSortTable[i][2];
                   break;
                }
            }
            TRACDCOMP(g_fapiTd, "setWofFrequencyUpliftSelected:"
                            " WOF index is %d ",
                            l_wofIndex);
            // validate WOF index
            ATTR_WOF_FREQUENCY_UPLIFT_SELECTED_type l_selectedTable = {{0}};
            if ( (!l_wofIndex) || (l_wofIndex > 4))
            {
                if (l_wofEnabled) // log error if WOF enabled
                {
                    TRACFCOMP(g_fapiTd, "setWofFrequencyUpliftSelected:"
                        " No WOF table index match found HUID:0x%08X"
                        " active cores=%d, nom freq=%d, index=%d",
                        l_pProcTarget->getAttr<TARGETING::ATTR_HUID>(),
                        l_activeCores,
                        l_sysNomFreqMhz,
                        l_wofIndex);

                    errlHndl_t l_err = NULL;
                    /*@
                     * @errortype
                     * @moduleid         fapi::MOD_GET_WOF_FREQ_UPLIFT_SELECTED
                     * @reasoncode       fapi::RC_INVALID_WOF_INDEX
                     * @userdata1[0:31]  Proc HUID
                     * @userdata1[32:63] WOF Freq Uplift Index
                     * @userdata2[0:31]  Number of active cores
                     * @userdata2[32:63] Nomimal Frequency
                     * @devdesc          When WOF is enabled, the WOF Freq
                     *                   Uplift index should be 1,2,3, or 4
                     */
                    l_err =
                        new  ERRORLOG::ErrlEntry(
                             ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                             fapi::MOD_GET_WOF_FREQ_UPLIFT_SELECTED,
                             fapi::RC_INVALID_WOF_INDEX,
                             TWO_UINT32_TO_UINT64(
                                 l_pProcTarget->getAttr<TARGETING::ATTR_HUID>(),
                                 l_wofIndex),
                             TWO_UINT32_TO_UINT64(
                                 l_activeCores,
                                 l_sysNomFreqMhz));

                    // Callout HW as WOF mrw data is incorrect
                    l_err->addHwCallout(l_pProcTarget, HWAS::SRCI_PRIORITY_MED,
                                         HWAS::NO_DECONFIG, HWAS::GARD_NULL);

                    // Include WOF processor sort table
                    TRACFBIN (g_fapiTd,
                              "WOF processor sort table",
                              l_procSortTable,
                              sizeof(l_procSortTable));
                    l_err->collectTrace(FAPI_TRACE_NAME);

                    // log error and keep going
                    errlCommit(l_err,HWPF_COMP_ID);
                }
                // make sure zeros are set in the selected table attribute
                memset(l_selectedTable,
                       0,
                       sizeof(l_selectedTable));
            }
            else
            {
                // use index to set Wof Frequency Uplift selected attribute
                // note: mrw index is 1 based
                memcpy(l_selectedTable,
                       &l_upliftTable[l_wofIndex-1][0][0],
                       sizeof(l_selectedTable));
            }
            if (!l_pProcTarget->trySetAttr<ATTR_WOF_FREQUENCY_UPLIFT_SELECTED>
                                             (l_selectedTable))
            {
                //unlikely, crash
                TRACFCOMP(g_fapiTd,
                            "Failed to set ATTR_WOF_FREQUENCY_UPLIFT_SELECTED");
                assert(0);
            }
        }
        return;
    }
Ejemplo n.º 4
0
static errlHndl_t load_pnor_section(PNOR::SectionId i_section,
        uint64_t i_physAddr)
{
    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ENTER_MRK"load_pnor_section()");
    errlHndl_t err = nullptr;

#ifdef CONFIG_SECUREBOOT
    // Securely load section
    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,"load_pnor_section: secure section load of secId=0x%X (%s)",
              i_section, PNOR::SectionIdToString(i_section));
    err = PNOR::loadSecureSection(i_section);
    if (err)
    {
        return err;
    }
    // Do not need to unload since we have plenty of memory at this point.
#endif

    // Get the section info from PNOR.
    PNOR::SectionInfo_t pnorSectionInfo;
    err = PNOR::getSectionInfo( i_section, pnorSectionInfo );
    if( err != nullptr )
    {
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                 "load_pnor_section: Could not get section info from %x",
                  i_section);
        return err;
    }

    // XZ repository: http:git.tukaani.org/xz.git
    // Header specifics can be found in xz/doc/xz-file-format.txt
    const uint8_t HEADER_MAGIC[]= { 0xFD, '7', 'z', 'X', 'Z', 0x00 };
    uint8_t* l_pnor_header = reinterpret_cast<uint8_t *>(pnorSectionInfo.vaddr);

    bool l_pnor_is_XZ_compressed = (0 == memcmp(l_pnor_header,
                               HEADER_MAGIC, sizeof(HEADER_MAGIC)));

    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
             "load_pnor_section: is XZ_compressed: %d",
              l_pnor_is_XZ_compressed);

    // This assumes that the maximum decompression ratio will always be less
    // than 1:16 (compressed:uncompressed).  This works because XZ compression
    // is usually 14.1%, the decompressor does not need the exact size, and
    // we have all of mainstore memory at this point.
    uint32_t uncompressedPayloadSize = l_pnor_is_XZ_compressed ?
            (pnorSectionInfo.size * 16) : pnorSectionInfo.size;


    const uint32_t originalPayloadSize = pnorSectionInfo.size;

    printk( "Loading PNOR section %d (%s) %d bytes @0x%lx\n",
            i_section,
            pnorSectionInfo.name,
            originalPayloadSize,
            i_physAddr );

    void * loadAddr = NULL;
    // Map in the physical memory we are loading into.
    // If we are not xz compressed, the uncompressedSize
    // is equal to the original size.
    loadAddr = mm_block_map( reinterpret_cast<void*>( i_physAddr ),
                             uncompressedPayloadSize );

    // Print out inital progress bar.
#ifdef CONFIG_CONSOLE
    const int progressSteps = 80;
    int progress = 0;
    for ( int i = 0; i < progressSteps; ++i )
    {
        printk( "." );
    }
    printk( "\r" );
#endif

    if(!l_pnor_is_XZ_compressed)
    {
        // Load the data block by block and update the progress bar.
        const uint32_t BLOCK_SIZE = 4096;
        for ( uint32_t i = 0; i < originalPayloadSize; i += BLOCK_SIZE )
        {
            memcpy( reinterpret_cast<void*>(
                      reinterpret_cast<uint64_t>(loadAddr) + i ),
                    reinterpret_cast<void*>( pnorSectionInfo.vaddr + i ),
                    std::min( originalPayloadSize - i, BLOCK_SIZE ) );
#ifdef CONFIG_CONSOLE
            for ( int new_progress = (i * progressSteps) /
                  originalPayloadSize;
                  progress <= new_progress; progress++ )
            {
                printk( "=" );
            }
#endif
        }
#ifdef CONFIG_CONSOLE
        printk( "\n" );
#endif
    }

    if(l_pnor_is_XZ_compressed)
    {
        struct xz_buf b;
        struct xz_dec *s;
        enum xz_ret ret;

        xz_crc32_init();
        s = xz_dec_init(XZ_SINGLE, 0);
        if(s == NULL)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ERR_MRK
                     "load_pnor_section: XZ Embedded Initialization failed");
            return err;
        }

        static const uint64_t compressed_SIZE = originalPayloadSize;
        static const uint64_t decompressed_SIZE = uncompressedPayloadSize;

        b.in = reinterpret_cast<uint8_t *>( pnorSectionInfo.vaddr);
        b.in_pos = 0;
        b.in_size = compressed_SIZE;
        b.out = reinterpret_cast<uint8_t *>(loadAddr);
        b.out_pos = 0;
        b.out_size = decompressed_SIZE;

        ret = xz_dec_run(s, &b);

        if(ret == XZ_STREAM_END)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                     "load_pnor_section: The %s section was decompressed.",
                      pnorSectionInfo.name);
        }else
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ERR_MRK
                     "load_pnor_section: xz-embedded returned an error, ",
                     "the ret is %d",ret);

            /*@
             * @errortype
             * @reasoncode       fapi::RC_INVALID_RETURN_XZ_CODE
             * @severity         ERRORLOG::ERRL_SEV_UNRECOVERABLE
             * @moduleid         fapi::MOD_START_XZ_PAYLOAD
             * @devdesc          xz-embedded has returned an error.
             *                   the return code can be found in xz.h
             * @custdesc         Error uncompressing payload image from
             *                   boot flash
             * @userdata1        Return code from xz-embedded
             * @userdata2[0:31]  Original Payload Size
             * @userdata2[32:63] Uncompressed Payload Size
             */
            err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                            fapi::MOD_START_XZ_PAYLOAD,
                            fapi::RC_INVALID_RETURN_XZ_CODE,
                            ret,TWO_UINT32_TO_UINT64(
                                    originalPayloadSize,
                                    uncompressedPayloadSize));
            err->addProcedureCallout(HWAS::EPUB_PRC_PHYP_CODE,
                            HWAS::SRCI_PRIORITY_HIGH);

        }
        //Clean up memory
        xz_dec_end(s);

    }

    int rc = 0;
    rc = mm_block_unmap(reinterpret_cast<void *>(loadAddr));
    if(rc)
    {
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ERR_MRK
                 "load_pnor_section: mm_block_unmap returned 1");

        /*@
         * @errortype
         * @reasoncode      fapi::RC_MM_UNMAP_ERR
         * @severity        ERRORLOG::ERRL_SEV_UNRECOVERABLE
         * @moduleid        fapi::MOD_START_XZ_PAYLOAD
         * @devdesc         mm_block_unmap returned incorrectly with 0
         * @custdesc        Error unmapping memory section
         */
        err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                      fapi::MOD_START_XZ_PAYLOAD,
                                      fapi::RC_MM_UNMAP_ERR,
                                      0,0,0);
    }
    return err;
}
Ejemplo n.º 5
0
errlHndl_t RtPnor::writeToDevice( uint64_t i_procId,
                                  PNOR::SectionId i_section,
                                  uint64_t i_offset,
                                  size_t i_size,
                                  bool i_ecc,
                                  void* i_src )
{
    TRACFCOMP(g_trac_pnor, ENTER_MRK"RtPnor::writeToDevice: i_offset=0x%X, "
           "i_procId=%d sec=%d size=0x%X ecc=%d", i_offset, i_procId, i_section,
             i_size, i_ecc);
    errlHndl_t l_err        = nullptr;
    uint8_t*   l_eccBuffer  = nullptr;

    do
    {
        void*  l_dataToWrite      = i_src;
        size_t l_writeSize        = i_size;
        size_t l_writeSizePlusECC = (i_size * 9)/8;
        uint64_t l_offset         = i_offset;

        // apply ECC to data if needed
        if( i_ecc )
        {
            l_eccBuffer = new uint8_t[l_writeSizePlusECC];
            PNOR::ECC::injectECC( reinterpret_cast<uint8_t*>(i_src),
                              l_writeSize,
                              reinterpret_cast<uint8_t*>(l_eccBuffer) );
            l_dataToWrite = reinterpret_cast<void*>(l_eccBuffer);
            l_writeSize = l_writeSizePlusECC;
            l_offset    = (i_offset * 9)/8;
        }

        const char* l_partitionName = SectionIdToString(i_section);
        if (g_hostInterfaces && g_hostInterfaces->pnor_write)
        {
            //make call into opal to write the data
            int l_rc = g_hostInterfaces->pnor_write(i_procId,
                        l_partitionName,l_offset,l_dataToWrite,l_writeSize);
            if (l_rc != static_cast<int>(l_writeSize))
            {
                TRACFCOMP(g_trac_pnor, "RtPnor::writeToDevice: pnor_write failed "
                    "proc:%d, part:%s, offset:0x%X, size:0x%X, dataPt:0x%X,"
                    " rc:%d", i_procId, l_partitionName, l_offset, l_writeSize,
                    l_dataToWrite, l_rc);
                /*@
                 * @errortype
                 * @moduleid            PNOR::MOD_RTPNOR_WRITETODEVICE
                 * @reasoncode          PNOR::RC_PNOR_WRITE_FAILED
                 * @userdata1[00:31]    rc returned from pnor_write
                 * @userdata1[32:63]    section ID
                 * @userdata2[00:31]    offset within the section
                 * @userdata2[32:63]    size of data written in bytes
                 * @devdesc             g_hostInterfaces->pnor_write failed
                 * @custdesc            Error accessing system firmware flash
                 */
                l_err = new ERRORLOG::ErrlEntry(
                             ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                             PNOR::MOD_RTPNOR_WRITETODEVICE,
                             PNOR::RC_PNOR_WRITE_FAILED,
                             TWO_UINT32_TO_UINT64(l_rc, i_section),
                             TWO_UINT32_TO_UINT64(l_offset, l_writeSize),
                             true);
                 break;
            }
            else if( l_rc != static_cast<int>(l_writeSize) )
            {
                TRACFCOMP( g_trac_pnor, "RtPnor::writeToDevice: only read 0x%X bytes, expecting 0x%X", l_rc, l_writeSize );
            }
        }
        else
        {
            TRACFCOMP(g_trac_pnor,"RtPnor::writeToDevice: This version of"
                    " OPAL does not support pnor_write");
            /*@
             * @errortype
             * @moduleid           PNOR::MOD_RTPNOR_WRITETODEVICE
             * @reasoncode         PNOR::RC_PNOR_WRITE_NOT_SUPPORTED
             * @devdesc            g_hostInterfaces->pnor_write not supported
             * @custdesc           Error accessing system firmware flash
             */
            //@todo Add PNOR callout RTC:116145
            l_err = new ERRORLOG::ErrlEntry(
                             ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                             PNOR::MOD_RTPNOR_WRITETODEVICE,
                             PNOR::RC_PNOR_WRITE_NOT_SUPPORTED,
                             0,0,true);
            break;

        }
    } while(0);

    if( l_eccBuffer )
    {
        delete[] l_eccBuffer;
    }

    TRACFCOMP(g_trac_pnor, EXIT_MRK"RtPnor::writeToDevice" );
    return l_err;
}
Ejemplo n.º 6
0
    //**************************************************************************
    // FREQVOLTSVC::getSysFreq
    //**************************************************************************
    errlHndl_t getSysFreq(
          uint32_t & o_sysVPDPowerSaveMinFreqMhz,
          TARGETING::ATTR_NOMINAL_FREQ_MHZ_type & o_sysNomFreqMhz,
          TARGETING::ATTR_FREQ_CORE_MAX_type & o_sysVPDTurboMaxFreqMhz,
          TARGETING::ATTR_ULTRA_TURBO_FREQ_MHZ_type &
                                                   o_sysVPDUltraTurboMinFreqMhz)
    {
        uint32_t   l_minsysVPDTurboMaxFreqMhz = 0;
        uint32_t   l_maxsysVPDPowerSaveMinFreqMhz = 0;
        uint32_t   l_minsysVPDUltraTurboFreqMhz = 0;
        fapi::ReturnCode l_rc;
        errlHndl_t l_err = NULL;

        do
        {
            o_sysNomFreqMhz = 0;
            o_sysVPDTurboMaxFreqMhz = 0;
            o_sysVPDPowerSaveMinFreqMhz = 0;
            o_sysVPDUltraTurboMinFreqMhz = 0;

            //Get the top level (system) target  handle
            TARGETING::Target* l_pTopLevel = NULL;
            (void)TARGETING::targetService().getTopLevelTarget(l_pTopLevel);

            // Assert on failure getting system target
            assert( l_pTopLevel != NULL );

            // Retrun Fvmin as ultra turbo freq if WOF enabled.
            ATTR_WOF_ENABLED_type l_wofEnabled = l_pTopLevel->getAttr
                                           < TARGETING::ATTR_WOF_ENABLED > ();
            TRACFCOMP(g_fapiTd,"getSysFreq: WOF_ENABLED is %d ",l_wofEnabled);

            //Filter functional unit
            TARGETING::PredicateIsFunctional l_isFunctional;

            // Filter core unit
            TARGETING::PredicateCTM l_coreUnitFilter(TARGETING::CLASS_UNIT,
                                                     TARGETING::TYPE_CORE);

            //Filter functional cores
            TARGETING::PredicatePostfixExpr l_funcCoreUnitFilter;

            // core units AND functional
            l_funcCoreUnitFilter.push(&l_coreUnitFilter).push
                                                        (&l_isFunctional).And();

            // Loop through all the targets, looking for functional core units.
            TARGETING::TargetRangeFilter l_pFilter(
                                             TARGETING::targetService().begin(),
                                             TARGETING::targetService().end(),
                                             &l_funcCoreUnitFilter);
            // Assert if no functional cores are found
            assert(l_pFilter);

            bool l_copyOnce = true;

            // Loop through functional cores to get frequency
            for(; l_pFilter; ++l_pFilter )
            {
                TARGETING::Target * l_pTarget = *l_pFilter;

                fapi::voltageBucketData_t l_poundVdata = {0};

                // Get Parent Chip target
                const TARGETING::Target * l_pChipTarget =
                                                    getParentChip(l_pTarget);
                fapi::Target l_pFapiChipTarget(fapi::TARGET_TYPE_PROC_CHIP,
                            (const_cast<TARGETING::Target*>(l_pChipTarget) ));

                // Get core number for record number
                TARGETING::ATTR_CHIP_UNIT_type l_coreNum =
                        l_pTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>();

                uint32_t l_record = (uint32_t) MVPD::LRP0 + l_coreNum;

                // Get #V bucket data
                l_rc = fapiGetPoundVBucketData(l_pFapiChipTarget,
                                               l_record,
                                               l_poundVdata);
                if(l_rc)
                {
                    TRACFCOMP( g_fapiTd,ERR_MRK"Error getting #V data for HUID:"
                             "0x%08X",
                             l_pTarget->getAttr<TARGETING::ATTR_HUID>());

                    // Convert fapi returnCode to Error handle
                    l_err = fapiRcToErrl(l_rc);

                    break;
                }

                uint32_t l_sysVPDPowerSaveMinFreqMhz = l_poundVdata.PSFreq;
                TARGETING::ATTR_NOMINAL_FREQ_MHZ_type l_sysNomFreqMhz =
                                l_poundVdata.nomFreq;
                TARGETING::ATTR_FREQ_CORE_MAX_type l_sysVPDTurboMaxFreqMhz =
                                l_poundVdata.turboFreq;
                // WOF defines the reserved Fvmin value as ultra turbo
                TARGETING::ATTR_ULTRA_TURBO_FREQ_MHZ_type
                             l_sysVPDUltraTurboFreqMhz = l_poundVdata.fvminFreq;
                TRACFCOMP(g_fapiTd,INFO_MRK"Nominal freq is: [0x%08X]. Turbo "
                          "freq is: [0x%08x]. PowerSave freq is: [0x%08X]."
                          " Ultra Turbo is: [0x%08x]",
                          l_sysNomFreqMhz, l_sysVPDTurboMaxFreqMhz,
                          l_sysVPDPowerSaveMinFreqMhz,
                          l_sysVPDUltraTurboFreqMhz);

                if( true == l_copyOnce)
                {
                    o_sysNomFreqMhz = l_sysNomFreqMhz;
                    l_minsysVPDTurboMaxFreqMhz = l_sysVPDTurboMaxFreqMhz;
                    l_maxsysVPDPowerSaveMinFreqMhz =
                                             l_sysVPDPowerSaveMinFreqMhz;
                    l_minsysVPDUltraTurboFreqMhz = l_sysVPDUltraTurboFreqMhz;
                    l_copyOnce = false;
                }

                // frequency is never zero so create error if it is zero.
                if( (l_sysNomFreqMhz == 0)         ||
                    (l_sysVPDTurboMaxFreqMhz == 0) ||
                    (l_sysVPDPowerSaveMinFreqMhz == 0) )
                {
                    TRACFCOMP(g_fapiTd,ERR_MRK"Frequency is zero, "
                             "nominal freq: 0x%04X,turbo freq: 0x%08X",
                             "PowerSave freq is: [0x%08X]",
                             l_sysNomFreqMhz,
                             l_sysVPDTurboMaxFreqMhz,
                             l_sysVPDPowerSaveMinFreqMhz);

                    /*@
                     * @errortype
                     * @moduleid         fapi::MOD_GET_SYS_FREQ
                     * @reasoncode       fapi::RC_INVALID_DATA
                     * @userdata1[0:31]  Proc HUID
                     * @userdata1[32:63] Nominal frequency
                     * @userdata2[0:31]  Max Turbo frequency from VPD
                     * @userdata2[32:63] Min Power Save frequency from VPD
                     * @devdesc          Either nominal, max turbo or min power
                     *                   save frequency for the processor HUID
                     *                   (userdata1) is zero
                     */
                    l_err =
                        new ERRORLOG::ErrlEntry(
                                         ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                         fapi::MOD_GET_SYS_FREQ,
                                         fapi::RC_INVALID_DATA,
                    TWO_UINT32_TO_UINT64(
                                     l_pTarget->getAttr<TARGETING::ATTR_HUID>(),
                                     l_sysNomFreqMhz),
                    TWO_UINT32_TO_UINT64(l_sysVPDTurboMaxFreqMhz,
                                         l_sysVPDPowerSaveMinFreqMhz));

                    // Callout HW as VPD data is incorrect
                    l_err->addHwCallout(l_pTarget, HWAS::SRCI_PRIORITY_HIGH,
                                         HWAS::DECONFIG, HWAS::GARD_NULL);

                    break;
                }

                // If WOF is enabled, Ultra Turbo frequency should not be zero.
                // Return 0 for ultra turbo freq
                if( (fapi::ENUM_ATTR_WOF_ENABLED_ENABLED == l_wofEnabled)  &&
                    (l_sysVPDUltraTurboFreqMhz == 0) )
                {
                    TRACFCOMP(g_fapiTd,
                              ERR_MRK"GetSysFreq: Ultra Turbo frequency is 0");

                    /*@
                     * @errortype
                     * @moduleid         fapi::MOD_GET_SYS_FREQ
                     * @reasoncode       fapi::RC_INVALID_ULTRA_TURBO_FREQ
                     * @userdata1        Proc HUID
                     * @userdata2        Invalid ultra turbo frequency
                     * @devdesc          When WOF is enabled, ultra turbo freq
                     *                   should not be 0
                     */
                    l_err =
                        new ERRORLOG::ErrlEntry(
                                     ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                     fapi::MOD_GET_SYS_FREQ,
                                     fapi::RC_INVALID_ULTRA_TURBO_FREQ,
                                     l_pTarget->getAttr<TARGETING::ATTR_HUID>(),
                                     l_sysVPDUltraTurboFreqMhz);

                    // Callout HW as VPD data is incorrect
                    l_err->addHwCallout(l_pTarget, HWAS::SRCI_PRIORITY_MED,
                                         HWAS::NO_DECONFIG, HWAS::GARD_NULL);

                    // log error and keep going
                    errlCommit(l_err,HWPF_COMP_ID);
                }

                // Validate nominal frequency. If differs,
                // create error and stop processing further.
                if( o_sysNomFreqMhz != l_sysNomFreqMhz )
                {
                    TRACFCOMP(g_fapiTd,ERR_MRK
                             "Nominal Frequency:[0x%04X] does not "
                             "match with other core nominal frequency:[0x%04X]",
                             l_sysNomFreqMhz, o_sysNomFreqMhz);

                    /*@
                     * @errortype
                     * @moduleid    fapi::MOD_GET_SYS_FREQ
                     * @reasoncode  fapi::RC_INVALID_FREQ
                     * @userdata1   Invalid frequency
                     * @userdata2   Expected frequency
                     * @devdesc     Nominal frequency(userdata1) does not match
                     *              nominal frequency(userdata2) on other cores.
                     *              Should be the same for all chips.
                     */
                    l_err =
                        new ERRORLOG::ErrlEntry(
                                         ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                         fapi::MOD_GET_SYS_FREQ,
                                         fapi::RC_INVALID_FREQ,
                                         l_sysNomFreqMhz,
                                         o_sysNomFreqMhz);

                    // Callout HW as VPD data is incorrect
                    l_err->addHwCallout(l_pTarget, HWAS::SRCI_PRIORITY_HIGH,
                                         HWAS::DECONFIG, HWAS::GARD_NULL);

                    break;
                }

                // Save the min turbo freq
                if (l_sysVPDTurboMaxFreqMhz < l_minsysVPDTurboMaxFreqMhz)
                {
                    l_minsysVPDTurboMaxFreqMhz = l_sysVPDTurboMaxFreqMhz;
                }
                // Save the max powersave freq
                if (l_sysVPDPowerSaveMinFreqMhz >
                                    l_maxsysVPDPowerSaveMinFreqMhz)
                {
                    l_maxsysVPDPowerSaveMinFreqMhz =
                                    l_sysVPDPowerSaveMinFreqMhz;
                }
                // Save the min ultra turbo freq
                // If WOF is enabled, do not expect to see a zero value. But if
                // there is a zero value, then return zero.
                if (l_sysVPDUltraTurboFreqMhz < l_minsysVPDUltraTurboFreqMhz)
                {
                    l_minsysVPDUltraTurboFreqMhz = l_sysVPDUltraTurboFreqMhz;
                }

            } // end for loop
            if (l_err != NULL)
            {
                break;
            }

            // Get min turbo freq
            o_sysVPDTurboMaxFreqMhz = l_minsysVPDTurboMaxFreqMhz;

            // Get max powersave freq
            o_sysVPDPowerSaveMinFreqMhz = l_maxsysVPDPowerSaveMinFreqMhz;

            // Get ultra turbo freq
            o_sysVPDUltraTurboMinFreqMhz = l_minsysVPDUltraTurboFreqMhz;

        } while (0);

        TRACFCOMP(g_fapiTd,EXIT_MRK"o_sysNomFreqMhz: 0x%08X, "
                  "o_sysVPDTurboMaxFreqMhz: 0x%08X, "
                  "o_sysVPDPowerSaveMinFreqMhz: 0x%08X, "
                  "o_sysVPDUltraTurboFreqMhz: 0x%08x",
                   o_sysNomFreqMhz, o_sysVPDTurboMaxFreqMhz,
                   o_sysVPDPowerSaveMinFreqMhz,
                   o_sysVPDUltraTurboMinFreqMhz );

        return l_err;
    }
Ejemplo n.º 7
0
/*******************Private Methods*********************/
errlHndl_t RtPnor::readFromDevice (uint64_t i_procId,
                                   PNOR::SectionId i_section,
                                   uint64_t i_offset,
                                   size_t i_size,
                                   bool i_ecc,
                                   void* o_data) const
{
    TRACFCOMP(g_trac_pnor, ENTER_MRK"RtPnor::readFromDevice: i_offset=0x%X, "
           "i_procId=%d sec=%d size=0x%X ecc=%d", i_offset, i_procId, i_section,
             i_size, i_ecc);
    errlHndl_t l_err        = nullptr;
    uint8_t*   l_eccBuffer  = nullptr;
    do
    {

        const char* l_partitionName  = SectionIdToString(i_section);
        void*  l_dataToRead          = o_data;
        size_t l_readSize            = i_size;
        size_t l_readSizePlusECC     = (i_size * 9)/8;
        uint64_t l_offset            = i_offset;

        // if we need to handle ECC, we need to read more
        if( i_ecc )
        {
            l_eccBuffer  = new uint8_t[l_readSizePlusECC]();
            l_dataToRead = l_eccBuffer;
            l_readSize   = l_readSizePlusECC;
            l_offset     = (i_offset * 9)/8;
        }

        int l_rc = 0;
        if (g_hostInterfaces && g_hostInterfaces->pnor_read)
        {
            // get the data from OPAL
            l_rc = g_hostInterfaces->pnor_read(i_procId, l_partitionName,
                    l_offset, l_dataToRead, l_readSize);
            if (l_rc < 0)
            {
                TRACFCOMP(g_trac_pnor, "RtPnor::readFromDevice: pnor_read"
                        " failed proc:%d, part:%s, offset:0x%X, size:0x%X,"
                        " dataPt:0x%X, rc:%d", i_procId, l_partitionName,
                        l_offset, l_readSize, l_dataToRead, l_rc);

                // prevent hang between ErrlManager and rt_pnor
                assert(iv_initialized,
                      "RtPnor::readFromDevice: pnor_read returned an error"
                      " during initialization");

                /*@
                 * @errortype
                 * @moduleid            PNOR::MOD_RTPNOR_READFROMDEVICE
                 * @reasoncode          PNOR::RC_PNOR_READ_FAILED
                 * @userdata1[00:31]    rc returned from pnor_read
                 * @userdata1[32:63]    section ID
                 * @userdata2[00:31]    offset within the section
                 * @userdata2[32:63]    size of data read in bytes
                 * @devdesc             g_hostInterfaces->pnor_read failed
                 * @custdesc            Error accessing system firmware flash
                 */
                //@todo Add PNOR callout RTC:116145
                l_err = new ERRORLOG::ErrlEntry(
                                 ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                 PNOR::MOD_RTPNOR_READFROMDEVICE,
                                 PNOR::RC_PNOR_READ_FAILED,
                                 TWO_UINT32_TO_UINT64(l_rc, i_section),
                                 TWO_UINT32_TO_UINT64(l_offset, l_readSize),
                                 true);
                break;
            }
            else if( l_rc != static_cast<int>(l_readSize) )
            {
                TRACFCOMP( g_trac_pnor, "RtPnor::readFromDevice: only read 0x%X bytes, expecting 0x%X", l_rc, l_readSize );

                if( PNOR::TOC == i_section )
                {
                    // we can't know how big the TOC partition is without
                    // reading it so we have to make a request for more
                    // data and then handle a smaller amount getting returned
                    TRACFCOMP( g_trac_pnor, "Ignoring mismatch for TOC" );
                }
                else // everything else should have a known size
                {
                  // prevent hang between ErrlManager and rt_pnor
                  assert(iv_initialized,
                      "RtPnor::readFromDevice: pnor_read failed to read "
                      "expected amount before rt_pnor initialization");

                    /*@
                     * @errortype
                     * @moduleid            PNOR::MOD_RTPNOR_READFROMDEVICE
                     * @reasoncode          PNOR::RC_WRONG_SIZE_FROM_READ
                     * @userdata1[00:31]    section ID
                     * @userdata1[32:63]    requested size of read
                     * @userdata2[00:31]    requested start offset into flash
                     * @userdata2[32:63]    actual amount read
                     * @devdesc             Amount of data read from pnor does
                     *                      not match expected size
                     * @custdesc          Error accessing system firmware flash
                     */
                    l_err = new ERRORLOG::ErrlEntry(
                                ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                PNOR::MOD_RTPNOR_READFROMDEVICE,
                                PNOR::RC_WRONG_SIZE_FROM_READ,
                                TWO_UINT32_TO_UINT64(i_section,l_readSize),
                                TWO_UINT32_TO_UINT64(l_offset,l_rc),
                                true);
                    break;
                }
            }
        }
        else
        {
            TRACFCOMP(g_trac_pnor,"RtPnor::readFromDevice: This version of"
                    " OPAL does not support pnor_read");

            // prevent hang between ErrlManager and rt_pnor
            assert(iv_initialized,
                      "RtPnor::readFromDevice: OPAL version does NOT support"
                      "pnor_read during initialization");
            /*@
             * @errortype
             * @moduleid           PNOR::MOD_RTPNOR_READFROMDEVICE
             * @reasoncode         PNOR::RC_PNOR_READ_NOT_SUPPORTED
             * @devdesc            g_hostInterfaces->pnor_read not supported
             * @custdesc           Error accessing system firmware flash
             */
            //@todo Add PNOR callout RTC:116145
            l_err = new ERRORLOG::ErrlEntry(
                             ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                             PNOR::MOD_RTPNOR_READFROMDEVICE,
                             PNOR::RC_PNOR_READ_NOT_SUPPORTED,
                             0,0,true);
            break;
        }
        // remove the ECC data
        if( i_ecc )
        {
            TRACFCOMP(g_trac_pnor, "RtPnor::readFromDevice: removing ECC...");
            // remove the ECC and fix the original data if it is broken
            size_t l_eccSize = (l_rc/9)*8;
            l_eccSize = std::min( l_eccSize, i_size );
            PNOR::ECC::eccStatus ecc_stat =
                 PNOR::ECC::removeECC(reinterpret_cast<uint8_t*>(l_dataToRead),
                                      reinterpret_cast<uint8_t*>(o_data),
                                      l_eccSize); //logical size of read data

            // create an error if we couldn't correct things
            if( ecc_stat == PNOR::ECC::UNCORRECTABLE )
            {
                TRACFCOMP(g_trac_pnor,"RtPnor::readFromDevice>"
                    " Uncorrectable ECC error : chip=%d,offset=0x%.X",
                    i_procId, i_offset );

                // prevent hang between ErrlManager and rt_pnor
                assert(iv_initialized,
                      "RtPnor::readFromDevice: UNCORRECTABLE_ECC encountered"
                      " during initialization");
                /*@
                 * @errortype
                 * @moduleid    PNOR::MOD_RTPNOR_READFROMDEVICE
                 * @reasoncode  PNOR::RC_UNCORRECTABLE_ECC
                 * @devdesc     UNCORRECTABLE ECC
                 */
                //@todo Add PNOR callout RTC:116145
                l_err = new ERRORLOG::ErrlEntry(
                                    ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                    PNOR::MOD_RTPNOR_READFROMDEVICE,
                                    PNOR::RC_UNCORRECTABLE_ECC,
                                    0, 0, true);
                break;
            }

            // found an error so we need to fix something
            else if( ecc_stat != PNOR::ECC::CLEAN )
            {
                TRACFCOMP(g_trac_pnor,"RtPnor::readFromDevice>"
                      "Correctable ECC error : chip=%d, offset=0x%.X",
                      i_procId, i_offset );
                if (g_hostInterfaces && g_hostInterfaces->pnor_write)
                {

                    //need to write good data back to PNOR
                    int l_rc = g_hostInterfaces->pnor_write(i_procId,
                            l_partitionName,l_offset, l_dataToRead,l_readSize);
                    if (l_rc != static_cast<int>(l_readSize))
                    {
                        TRACFCOMP(g_trac_pnor, "RtPnor::readFromDevice> Error"
                        " writing corrected data back to device");

                        // prevent hang between ErrlManager and rt_pnor
                        assert(iv_initialized,
                            "RtPnor::readFromDevice: pnor_write returned an"
                            " error during initialization");

                        /*@
                         * @errortype
                         * @moduleid   PNOR::MOD_RTPNOR_READFROMDEVICE
                         * @reasoncode PNOR::RC_PNOR_WRITE_FAILED
                         * @userdata1  rc returned from pnor_write
                         * @userdata2  Expected size of write
                         * @devdesc    error writing corrected data back to PNOR
                         * @custdesc   Error accessing system firmware flash
                         */
                        l_err = new ERRORLOG::ErrlEntry(
                                          ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                          PNOR::MOD_RTPNOR_READFROMDEVICE,
                                          PNOR::RC_PNOR_WRITE_FAILED,
                                          l_rc, l_readSize, true);
                        errlCommit(l_err, PNOR_COMP_ID);
                    }
                }
            }
        }
    } while(0);

    if( l_eccBuffer )
    {
        delete[] l_eccBuffer;
    }

    TRACFCOMP(g_trac_pnor, EXIT_MRK"RtPnor::readFromDevice" );
    return l_err;
}
Ejemplo n.º 8
0
/*******************Private Methods*********************/
errlHndl_t RtPnor::readFromDevice (uint64_t i_procId,
                                   PNOR::SectionId i_section,
                                   uint64_t i_offset,
                                   size_t i_size,
                                   bool i_ecc,
                                   void* o_data)
{
    TRACFCOMP(g_trac_pnor, ENTER_MRK"RtPnor::readFromDevice: i_offset=0x%X, "
           "i_procId=%d sec=%d size=0x%X ecc=%d", i_offset, i_procId, i_section,
             i_size, i_ecc);
    errlHndl_t l_err        = NULL;
    uint8_t*   l_eccBuffer  = NULL;
    do
    {

        const char* l_partitionName  = cv_EYECATCHER[i_section];
        void*  l_dataToRead          = o_data;
        size_t l_readSize            = i_size;
        size_t l_readSizePlusECC     = (i_size * 9)/8;
        uint64_t l_offset            = i_offset;

        // if we need to handle ECC, we need to read more
        if( i_ecc )
        {
            l_eccBuffer  = new uint8_t[l_readSizePlusECC]();
            l_dataToRead = l_eccBuffer;
            l_readSize   = l_readSizePlusECC;
            l_offset     = (i_offset * 9)/8;
        }

        int l_rc = 0;
        if (g_hostInterfaces && g_hostInterfaces->pnor_read)
        {
            // get the data from OPAL
            l_rc = g_hostInterfaces->pnor_read(i_procId, l_partitionName,
                    l_offset, l_dataToRead, l_readSize);
            if (l_rc < 0)
            {
                TRACFCOMP(g_trac_pnor, "RtPnor::readFromDevice: pnor_read"
                        " failed proc:%d, part:%s, offset:0x%X, size:0x%X,"
                        " dataPt:0x%X, rc:%d", i_procId, l_partitionName,
                        l_offset, l_readSize, l_dataToRead, l_rc);
                /*@
                 * @errortype
                 * @moduleid            PNOR::MOD_RTPNOR_READFROMDEVICE
                 * @reasoncode          PNOR::RC_PNOR_READ_FAILED
                 * @userdata1[00:31]    rc returned from pnor_read
                 * @userdata1[32:63]    section ID
                 * @userdata2[00:31]    offset within the section
                 * @userdata2[32:63]    size of data read in bytes
                 * @devdesc             g_hostInterfaces->pnor_read failed
                 * @custdesc            Error accessing system firmware flash
                 */
                //@todo Add PNOR callout RTC:116145
                l_err = new ERRORLOG::ErrlEntry(
                                 ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                 PNOR::MOD_RTPNOR_READFROMDEVICE,
                                 PNOR::RC_PNOR_READ_FAILED,
                                 TWO_UINT32_TO_UINT64(l_rc, i_section),
                                 TWO_UINT32_TO_UINT64(l_offset, l_readSize),
                                 true);
                break;
            }
            else if( l_rc != static_cast<int>(l_readSize) )
            {
                TRACFCOMP( g_trac_pnor, "RtPnor::readFromDevice: only read 0x%X bytes, expecting 0x%X", l_rc, l_readSize );
            }
        }
        else
        {
            TRACFCOMP(g_trac_pnor,"RtPnor::readFromDevice: This version of"
                    " OPAL does not support pnor_read");
                /*@
                 * @errortype
                 * @moduleid           PNOR::MOD_RTPNOR_READFROMDEVICE
                 * @reasoncode         PNOR::RC_PNOR_READ_NOT_SUPPORTED
                 * @devdesc            g_hostInterfaces->pnor_read not supported
                 * @custdesc           Error accessing system firmware flash
                 */
                //@todo Add PNOR callout RTC:116145
                l_err = new ERRORLOG::ErrlEntry(
                                 ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                 PNOR::MOD_RTPNOR_READFROMDEVICE,
                                 PNOR::RC_PNOR_READ_NOT_SUPPORTED,
                                 0,0,true);
                break;
        }
        // remove the ECC data
        if( i_ecc )
        {
            TRACFCOMP(g_trac_pnor, "RtPnor::readFromDevice: removing ECC...");
            // remove the ECC and fix the original data if it is broken
            PNOR::ECC::eccStatus ecc_stat =
                 PNOR::ECC::removeECC(reinterpret_cast<uint8_t*>(l_dataToRead),
                                      reinterpret_cast<uint8_t*>(o_data),
                                      l_rc); //actual size of read data

            // create an error if we couldn't correct things
            if( ecc_stat == PNOR::ECC::UNCORRECTABLE )
            {
                TRACFCOMP(g_trac_pnor,"RtPnor::readFromDevice>"
                    " Uncorrectable ECC error : chip=%d,offset=0x%.X",
                    i_procId, i_offset );
                /*@
                 * @errortype
                 * @moduleid    PNOR::MOD_RTPNOR_READFROMDEVICE
                 * @reasoncode  PNOR::RC_UNCORRECTABLE_ECC
                 * @devdesc     UNCORRECTABLE ECC
                 */
                //@todo Add PNOR callout RTC:116145
                l_err = new ERRORLOG::ErrlEntry(
                                    ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                    PNOR::MOD_RTPNOR_READFROMDEVICE,
                                    PNOR::RC_UNCORRECTABLE_ECC,
                                    0, 0, true);
                break;
            }

            // found an error so we need to fix something
            else if( ecc_stat != PNOR::ECC::CLEAN )
            {
                TRACFCOMP(g_trac_pnor,"RtPnor::readFromDevice>"
                      "Correctable ECC error : chip=%d, offset=0x%.X",
                      i_procId, i_offset );
                if (g_hostInterfaces && g_hostInterfaces->pnor_write)
                {

                    //need to write good data back to PNOR
                    int l_rc = g_hostInterfaces->pnor_write(i_procId,
                            l_partitionName,l_offset, l_dataToRead,l_readSize);
                    if (l_rc != static_cast<int>(l_readSize))
                    {
                        TRACFCOMP(g_trac_pnor, "RtPnor::readFromDevice> Error"
                        " writing corrected data back to device");

                        /*@
                         * @errortype
                         * @moduleid   PNOR::MOD_RTPNOR_READFROMDEVICE
                         * @reasoncode PNOR::RC_PNOR_WRITE_FAILED
                         * @userdata1  rc returned from pnor_write
                         * @userdata2  Expected size of write
                         * @devdesc    error writing corrected data back to PNOR
                         * @custdesc   Error accessing system firmware flash
                         */
                        l_err = new ERRORLOG::ErrlEntry(
                                          ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                          PNOR::MOD_RTPNOR_READFROMDEVICE,
                                          PNOR::RC_PNOR_WRITE_FAILED,
                                          l_rc, l_readSize, true);
                        errlCommit(l_err, PNOR_COMP_ID);
                    }
                }
            }
        }
    } while(0);

    if( l_eccBuffer )
    {
        delete[] l_eccBuffer;
    }

    TRACFCOMP(g_trac_pnor, EXIT_MRK"RtPnor::readFromDevice" );
    return l_err;
}
Ejemplo n.º 9
0
errlHndl_t fsiScomPerformOp(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_err = NULL;

    uint64_t l_scomAddr = va_arg(i_args,uint64_t);
    ioData6432 scratchData;
    uint32_t l_command = 0;
    uint32_t l_status = 0;
    bool need_unlock = false;
    size_t op_size = sizeof(uint32_t);
    mutex_t* l_mutex = NULL;

    do{

        if( io_buflen != sizeof(uint64_t) )
        {
            TRACFCOMP( g_trac_fsiscom, ERR_MRK "fsiScomPerformOp> Invalid data length : io_buflen=%d", io_buflen );
            /*@
             * @errortype
             * @moduleid     FSISCOM::MOD_FSISCOM_PERFORMOP
             * @reasoncode   FSISCOM::RC_INVALID_LENGTH
             * @userdata1    SCOM Address
             * @userdata2    Data Length
             * @devdesc      fsiScomPerformOp> Invalid data length (!= 8 bytes)
             * @custdesc     A problem occurred during the IPL of the system:
             *               Invalid data length for a SCOM operation.
             */
            l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                            FSISCOM::MOD_FSISCOM_PERFORMOP,
                                            FSISCOM::RC_INVALID_LENGTH,
                                            l_scomAddr,
                                            TO_UINT64(io_buflen));
            l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
                                        HWAS::SRCI_PRIORITY_LOW );
            ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target").
              addToLog(l_err);
            break;
        }

        if( (l_scomAddr & 0xFFFFFFFF80000000) != 0)
        {
            TRACFCOMP( g_trac_fsiscom, ERR_MRK "fsiScomPerformOp> Address contains more than 31 bits : l_scomAddr=0x%.16X", l_scomAddr );
            /*@
             * @errortype
             * @moduleid     FSISCOM::MOD_FSISCOM_PERFORMOP
             * @reasoncode   FSISCOM::RC_INVALID_ADDRESS
             * @userdata1    SCOM Address
             * @userdata2    Target HUID
             * @devdesc      fsiScomPerformOp> Address contains
             *               more than 31 bits.
             * @custdesc     A problem occurred during the IPL of the system:
             *               Invalid address on a SCOM operation.
             */
            l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                            FSISCOM::MOD_FSISCOM_PERFORMOP,
                                            FSISCOM::RC_INVALID_ADDRESS,
                                            l_scomAddr,
                                            TARGETING::get_huid(i_target));
            l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
                                        HWAS::SRCI_PRIORITY_LOW );
            ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target").
              addToLog(l_err);
            break;
        }

        l_command = static_cast<uint32_t>(l_scomAddr & 0x000000007FFFFFFF);

        // use the chip-specific mutex attribute
        l_mutex = i_target->getHbMutexAttr<TARGETING::ATTR_FSI_SCOM_MUTEX>();

        if(i_opType == DeviceFW::WRITE)
        {
            memcpy(&(scratchData.data64), io_buffer, 8);

            TRACUCOMP( g_trac_fsiscom, "fsiScomPerformOp> Write(l_scomAddr=0x%X, l_data0=0x%X, l_data1=0x%X)", l_scomAddr, scratchData.data32_0, scratchData.data32_1);


            // atomic section >>
            mutex_lock(l_mutex);
            need_unlock = true;


            //write bits 0-31 to data0
            l_err = DeviceFW::deviceOp( DeviceFW::WRITE,
                                        i_target,
                                        &scratchData.data32_0,
                                        op_size,
                                        DEVICE_FSI_ADDRESS(DATA0_REG));
            if(l_err)
            {
                break;
            }

            //write bits 32-63 to data1
            l_err = DeviceFW::deviceOp( DeviceFW::WRITE,
                                        i_target,
                                        &scratchData.data32_1,
                                        op_size,
                                        DEVICE_FSI_ADDRESS(DATA1_REG));
            if(l_err)
            {
                break;
            }

            //write to FSI2PIB command reg starts write operation
             //bit 0 high => write command
            l_command = 0x80000000 | l_command;
            l_err = DeviceFW::deviceOp( DeviceFW::WRITE,
                                        i_target,
                                        &l_command,
                                        op_size,
                                        DEVICE_FSI_ADDRESS(COMMAND_REG));
            if(l_err)
            {
                break;
            }

            //check status reg to see result
            l_err = DeviceFW::deviceOp( DeviceFW::READ,
                                        i_target,
                                        &l_status,
                                        op_size,
                                        DEVICE_FSI_ADDRESS(STATUS_REG));
            if(l_err)
            {
                break;
            }

            // Check the status reg for errors
            if( (l_status & PIB_ERROR_BITS)      // PCB/PIB Errors
                || (l_status & PIB_ABORT_BIT)  ) // PIB Abort
            {
                TRACFCOMP( g_trac_fsiscom, ERR_MRK"fsiScomPerformOp:Write: PCB/PIB error received: l_status=0x%X)", l_status);
                /*@
                 * @errortype
                 * @moduleid     FSISCOM::MOD_FSISCOM_PERFORMOP
                 * @reasoncode   FSISCOM::RC_WRITE_ERROR
                 * @userdata1    SCOM Addr
                 * @userdata2[00:31]  Target HUID
                 * @userdata2[32:63]  SCOM Status Reg
                 * @devdesc      fsiScomPerformOp> Error returned
                 *               from SCOM Engine after write
                 * @custdesc     A problem occurred during the IPL of the system:
                 *               Error returned from SCOM engine after write.
                 */
                l_err = new ERRORLOG::ErrlEntry(
                                ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                FSISCOM::MOD_FSISCOM_PERFORMOP,
                                FSISCOM::RC_WRITE_ERROR,
                                l_scomAddr,
                                TWO_UINT32_TO_UINT64(
                                           TARGETING::get_huid(i_target),
                                           l_status));

                // call common error handler to do callouts and recovery
                pib_error_handler( i_target, l_err, l_status, l_scomAddr );

                //Grab the PIB2OPB Status reg for a XSCOM Block error
                if( (l_status & 0x00007000) == 0x00001000 ) //piberr=001
                {
                    //@todo: Switch to external FSI FFDC interfaces RTC:35064
                    TARGETING::Target* l_master = NULL;
                    TARGETING::targetService().
                      masterProcChipTargetHandle(l_master);

                    uint64_t scomdata = 0;
                    size_t scomsize = sizeof(uint64_t);
                    errlHndl_t l_err2 = DeviceFW::deviceOp( DeviceFW::READ,
                                           l_master,
                                           &scomdata,
                                           scomsize,
                                           DEVICE_XSCOM_ADDRESS(0x00020001));
                    if( l_err2 ) {
                        delete l_err2;
                    } else {
                        TRACFCOMP( g_trac_fsiscom, "PIB2OPB Status = %.16X", scomdata );
                    }
                }

                break;
            }

            // atomic section <<
            need_unlock = false;
            mutex_unlock(l_mutex);
        }
        else if(i_opType == DeviceFW::READ)
        {
            TRACUCOMP( g_trac_fsiscom, "fsiScomPerformOp: Read(l_scomAddr=0x%.8X)", l_scomAddr);

            // atomic section >>
            mutex_lock(l_mutex);
            need_unlock = true;


            //write to FSI2PIB command reg starts read operation
            // bit 0 low -> read command
            l_err = DeviceFW::deviceOp( DeviceFW::WRITE,
                                        i_target,
                                        &l_command,
                                        op_size,
                                        DEVICE_FSI_ADDRESS(COMMAND_REG));
            if(l_err)
            {
                break;
            }

            //check ststus reg to see result
            l_err = DeviceFW::deviceOp( DeviceFW::READ,
                                        i_target,
                                        &l_status,
                                        op_size,
                                        DEVICE_FSI_ADDRESS(STATUS_REG));
            if(l_err)
            {
                break;
            }

            // Check the status reg for errors
            if( (l_status & PIB_ERROR_BITS)      // PCB/PIB Errors
                || (l_status & PIB_ABORT_BIT)  ) // PIB Abort
            {
                TRACFCOMP( g_trac_fsiscom, ERR_MRK"fsiScomPerformOp:Read: PCB/PIB error received: l_status=0x%0.8X)", l_status);

                /*@
                 * @errortype
                 * @moduleid     FSISCOM::MOD_FSISCOM_PERFORMOP
                 * @reasoncode   FSISCOM::RC_READ_ERROR
                 * @userdata1    SCOM Addr
                 * @userdata2[00:31]  Target HUID
                 * @userdata2[32:63]  SCOM Status Reg
                 * @devdesc      fsiScomPerformOp> Error returned from SCOM Engine after read.
                 * @custdesc     A problem occurred during the IPL of the system:
                 *               Error returned from SCOM engine after read.
                 */
                l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                                FSISCOM::MOD_FSISCOM_PERFORMOP,
                                                FSISCOM::RC_READ_ERROR,
                                                l_scomAddr,
                                                TWO_UINT32_TO_UINT64(
                                                 TARGETING::get_huid(i_target),
                                                 l_status));

                // call common error handler to do callouts and recovery
                pib_error_handler( i_target, l_err, l_status, l_scomAddr );

                break;
            }

            //read bits 0-31 to data0
            l_err = DeviceFW::deviceOp( DeviceFW::READ,
                                        i_target,
                                        &scratchData.data32_0,
                                        op_size,
                                        DEVICE_FSI_ADDRESS(DATA0_REG));
            if(l_err)
            {
                break;
            }

            //read bits 32-63 to data1
            l_err = DeviceFW::deviceOp( DeviceFW::READ,
                                        i_target,
                                        &scratchData.data32_1,
                                        op_size,
                                        DEVICE_FSI_ADDRESS(DATA1_REG));
            if(l_err)
            {
                break;
            }

            // atomic section <<
            need_unlock = false;
            mutex_unlock(l_mutex);

            TRACUCOMP( g_trac_fsiscom, "fsiScomPerformOp: Read: l_scomAddr=0x%X, l_data0=0x%X, l_data1=0x%X", l_scomAddr, scratchData.data32_0, scratchData.data32_1);

             memcpy(io_buffer, &(scratchData.data64), 8);
        }
        else
        {
            TRACFCOMP( g_trac_fsiscom, ERR_MRK"fsiScomPerformOp:Unsupported Operation Type: i_opType=%d)", i_opType);

            /*@
             * @errortype
             * @moduleid     FSISCOM::MOD_FSISCOM_PERFORMOP
             * @reasoncode   FSISCOM::RC_INVALID_OPTYPE
             * @userdata1[0:31]    Operation Type (i_opType) : 0=READ, 1=WRITE
             * @userdata1[32:64]   Input scom address
             * @userdata2    Target HUID
             * @devdesc      fsiScomPerformOp> Unsupported Operation Type specified
             * @custdesc     A problem occurred during the IPL of the system:
             *               Unsupported SCOM operation type.
             */
            l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                            FSISCOM::MOD_FSISCOM_PERFORMOP,
                                            FSISCOM::RC_INVALID_OPTYPE,
                                            TWO_UINT32_TO_UINT64(i_opType,
                                                                 l_scomAddr),
                                            TARGETING::get_huid(i_target),
                                            true /*SW error*/);
            //Add this target to the FFDC
            ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target").
              addToLog(l_err);

            break;

        }

    }while(0);

    if( need_unlock && l_mutex )
    {
        mutex_unlock(l_mutex);
    }


    return l_err;

}
Ejemplo n.º 10
0
//******************************************************************************
//TodSvc::setActiveMdmtForResetBackup
//******************************************************************************
errlHndl_t TodSvc::setActiveMdmtForResetBackup(
        const p9_tod_setup_tod_sel i_activeConfig)
{
    TOD_ENTER("setActiveMdmtForResetBackup");
    errlHndl_t  l_errHdl = NULL;

    //While doing a resetBackup it was found that in memory copy of active
    //topology is not present, (system has done a RR )
    //In order to ensure redundancy of processor and oscillator source on the
    //backup topology we needed to have the copy of active topology in memory.

    //However we may not need to recreate the complete active topology from
    //the persistant topology information file.
    //It would be just sufficient if we have the todControls built and MDMT set

    do{

        l_errHdl = TOD::buildTodDrawers(i_activeConfig);
        if ( l_errHdl )
        {
            TOD_ERR("Failed to build TOD drawers for %s",
                    (TOD::TodSvcUtil::
                     topologyTypeToString(i_activeConfig)));
            break;
        }

        TARGETING::Target* l_primaryMdmt = NULL;
        TARGETING::Target* l_secondaryMdmt = NULL;

        //Read the HW to get the configured MDMT's
        l_errHdl = TOD::getConfiguredMdmt(l_primaryMdmt,
                    l_secondaryMdmt);
        if ( l_errHdl )
        {
            TOD_ERR("Failed to get the configured MDMTs ");
            break;
        }

        TARGETING::Target* l_mdmtOnActiveTopology = NULL;
        l_mdmtOnActiveTopology = ( i_activeConfig ==  TOD_PRIMARY )?
            l_primaryMdmt : l_secondaryMdmt;

        if ( !l_mdmtOnActiveTopology ) //Big problem--This should not happen

        {
            TOD_ERR("TOD HW logic is already running but we cannot locate"
                    "MDMT for the %s , that is active",
                    (TOD::TodSvcUtil::
                     topologyTypeToString(i_activeConfig)));
            /*@
             * @errortype
             * @moduleid     TOD_MDMT_TOPOLOGY
             * @reasoncode   TOD_NO_VALID_MDMT_FOUND
             * @userdata1    EMOD_TOD_SET_ACTIVE_MDMT
             * @userdata2    Topology type on which MDMT was searched
             * @devdesc      Error: Could not find MDMT on active topology
             *               even though TOD HW logic is running
             * @custdesc     Host failed to boot because there was a problem
             *               configuring Time Of Day on the Host processors
             */

            l_errHdl = new ERRORLOG::ErrlEntry(
                               ERRORLOG::ERRL_SEV_INFORMATIONAL,
                               TOD_MDMT_TOPOLOGY,
                               TOD_NO_VALID_MDMT_FOUND,
                               EMOD_TOD_SET_ACTIVE_MDMT,
                               i_activeConfig);
            break;

        }

        //We have the valid MDMT target now, find the TodProc object
        //corresponding to it and also figure out the TodDrawer object to
        //which this processor belongs

        //To do so get the TodProc object whose HUID matches with the HUID
        //of the active topology's MDMT, and also get the TOD drawer to which
        //this TodProc object belongs
        TodDrawer* l_masterDrawer = NULL;
        TodProc* l_masterProc = NULL;
        std::list<TodDrawer*> l_drawerList;
        TOD::getDrawers(i_activeConfig, l_drawerList);

        bool l_drawerFound = false;

        for(std::list<TodDrawer*>::iterator l_drawerItr =
                l_drawerList.begin();
                ((l_drawerItr != l_drawerList.end()) && !l_drawerFound);
                ++l_drawerItr)
        {
            const std::list<TodProc*>& l_procsList =
                (*l_drawerItr)->getProcs();
            for(std::list<TodProc*>::const_iterator l_procItr =
                    l_procsList.begin();
                    ((l_procItr != l_procsList.end()) && !l_drawerFound);
                    ++l_procItr)
            {
                if (
                        (*l_procItr)->getTarget()
                        ==
                        l_mdmtOnActiveTopology)
                {
                    l_masterProc = *l_procItr;
                    l_masterDrawer = *l_drawerItr;
                    l_drawerFound = true;
                }

            }

        }

        if ( !l_masterProc || !l_masterDrawer )
        {

            //This should never happen unless we have goofed up big time

            TOD_ERR("Could not find TOD objects for the configured "
                    "MDMT 0x%08X on %s",
                    GETHUID(l_mdmtOnActiveTopology),
                    (TOD::TodSvcUtil::
                     topologyTypeToString(i_activeConfig)));

            //FIX_ME_BEFORE_PRODUCTION_Q1
            bool l_masterProcNotFound = ( !l_masterProc )? true : false;
            bool l_masterDrawerNotFound = ( !l_masterDrawer )? true : false;

            /*@
             * @errortype
             * @moduleid     TOD_FIND_MASTER_PROC
             * @reasoncode   TOD_MASTER_TARGET_NOT_FOUND
             * @userdata1[32:64] 1 = Master proc was not found , zero otherwise
             * @userdata1[32:63] 1 = Master drawer was not found, zero otherwise
             * @userdata2[0:31]  EMOD_TOD_SET_ACTIVE_MDMT
             * @userdata2[32:64] Active topology
             * @devdesc      Either processor or drawer object was not found for
             *               the  MDMT found by reading the processor registers.
             * @custdesc     Service Processor Firmware encountered an internal
             *               error
             */

            l_errHdl = new ERRORLOG::ErrlEntry(
                               ERRORLOG::ERRL_SEV_INFORMATIONAL,
                               TOD_FIND_MASTER_PROC,
                               TOD_MASTER_TARGET_NOT_FOUND,
                               TWO_UINT32_TO_UINT64(
                                   l_masterProcNotFound,
                                   l_masterDrawerNotFound),
                               TWO_UINT32_TO_UINT64(
                                   EMOD_TOD_SET_ACTIVE_MDMT,
                                   i_activeConfig));
            break;

        }

        //Now we have the all the objects required to set the MDMT
        (void) TOD::setMdmtOfActiveConfig(
                i_activeConfig,
                l_masterProc,
                l_masterDrawer);

    }while(0);

    TOD_EXIT();
    return l_errHdl;
}
Ejemplo n.º 11
0
    //**************************************************************************
    // FREQVOLTSVC::getSysFreq
    //**************************************************************************
    errlHndl_t getSysFreq(
            uint32_t & o_sysVPDPowerSaveMinFreqMhz,
            TARGETING::ATTR_NOMINAL_FREQ_MHZ_type & o_sysNomFreqMhz,
            TARGETING::ATTR_FREQ_CORE_MAX_type & o_sysVPDTurboMaxFreqMhz)
    {
        uint32_t   l_minsysVPDTurboMaxFreqMhz = 0;
        uint32_t   l_maxsysVPDPowerSaveMinFreqMhz = 0;
        fapi::ReturnCode l_rc;
        errlHndl_t l_err = NULL;

        do
        {
            o_sysNomFreqMhz = 0;
            o_sysVPDTurboMaxFreqMhz = 0;
            o_sysVPDPowerSaveMinFreqMhz = 0;

            //Filter functional unit
            TARGETING::PredicateIsFunctional l_isFunctional;

            // Filter core unit
            TARGETING::PredicateCTM l_coreUnitFilter(TARGETING::CLASS_UNIT,
                                                     TARGETING::TYPE_CORE);

            //Filter functional cores
            TARGETING::PredicatePostfixExpr l_funcCoreUnitFilter;

            // core units AND functional
            l_funcCoreUnitFilter.push(&l_coreUnitFilter).push
                                                        (&l_isFunctional).And();

            // Loop through all the targets, looking for functional core units.
            TARGETING::TargetRangeFilter l_pFilter(
                                             TARGETING::targetService().begin(),
                                             TARGETING::targetService().end(),
                                             &l_funcCoreUnitFilter);
            // Assert if no functional cores are found
            assert(l_pFilter);

            bool l_copyOnce = true;

            // Loop through functional cores to get frequency
            for(; l_pFilter; ++l_pFilter )
            {
                TARGETING::Target * l_pTarget = *l_pFilter;

                fapi::voltageBucketData_t l_poundVdata = {0};

                // Get Parent Chip target
                const TARGETING::Target * l_pChipTarget =
                                                    getParentChip(l_pTarget);

                // Get core number for record number
                TARGETING::ATTR_CHIP_UNIT_type l_coreNum =
                        l_pTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>();

                uint32_t l_record = (uint32_t) MVPD::LRP0 + l_coreNum;

                // Get #V bucket data
                l_rc = fapiGetPoundVBucketData(l_pChipTarget,
                                               l_record,
                                               l_poundVdata);
                if(l_rc)
                {
                    TRACFCOMP( g_fapiTd,ERR_MRK"Error getting #V data for HUID:"
                             "0x%08X",
                             l_pTarget->getAttr<TARGETING::ATTR_HUID>());

                    // Convert fapi returnCode to Error handle
                    l_err = fapiRcToErrl(l_rc);

                    break;
                }

                uint32_t l_sysVPDPowerSaveMinFreqMhz = l_poundVdata.PSFreq;
                TARGETING::ATTR_NOMINAL_FREQ_MHZ_type l_sysNomFreqMhz =
                                l_poundVdata.nomFreq;
                TARGETING::ATTR_FREQ_CORE_MAX_type l_sysVPDTurboMaxFreqMhz =
                                l_poundVdata.turboFreq;
                TRACFCOMP(g_fapiTd,INFO_MRK"Nominal freq is: [0x%08X]. Turbo "
                          "freq is: [0x%08x]. PowerSave freq is: [0x%08X]",
                          l_sysNomFreqMhz, l_sysVPDTurboMaxFreqMhz,
                          l_sysVPDPowerSaveMinFreqMhz );

                if( true == l_copyOnce)
                {
                    o_sysNomFreqMhz = l_sysNomFreqMhz;
                    l_minsysVPDTurboMaxFreqMhz = l_sysVPDTurboMaxFreqMhz;
                    l_maxsysVPDPowerSaveMinFreqMhz =
                                             l_sysVPDPowerSaveMinFreqMhz;
                    l_copyOnce = false;
                }

                // frequency is never zero so create error if it is zero.
                if( (l_sysNomFreqMhz == 0)         ||
                    (l_sysVPDTurboMaxFreqMhz == 0) ||
                    (l_sysVPDPowerSaveMinFreqMhz == 0) )
                {
                    TRACFCOMP(g_fapiTd,ERR_MRK"Frequency is zero, "
                             "nominal freq: 0x%04X,turbo freq: 0x%08X",
                             "PowerSave freq is: [0x%08X]",
                             l_sysNomFreqMhz,
                             l_sysVPDTurboMaxFreqMhz,
                             l_sysVPDPowerSaveMinFreqMhz);

                    /*@
                     * @errortype
                     * @moduleid         fapi::MOD_GET_SYS_FREQ
                     * @reasoncode       fapi::RC_INVALID_DATA
                     * @userdata1[0:31]  Proc HUID
                     * @userdata1[32:63] Nominal frequency
                     * @userdata2[0:31]  Max Turbo frequency from VPD
                     * @userdata2[32:63] Min Power Save frequency from VPD
                     * @devdesc          Either nominal, max turbo or min power
                     *                   save frequency for the processor HUID
                     *                   (userdata1) is zero
                     */
                    l_err =
                        new ERRORLOG::ErrlEntry(
                                         ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                         fapi::MOD_GET_SYS_FREQ,
                                         fapi::RC_INVALID_DATA,
                    TWO_UINT32_TO_UINT64(
                                     l_pTarget->getAttr<TARGETING::ATTR_HUID>(),
                                     l_sysNomFreqMhz),
                    TWO_UINT32_TO_UINT64(l_sysVPDTurboMaxFreqMhz,
                                         l_sysVPDPowerSaveMinFreqMhz));

                    // Callout HW as VPD data is incorrect
                    l_err->addHwCallout(l_pTarget, HWAS::SRCI_PRIORITY_HIGH,
                                         HWAS::DECONFIG, HWAS::GARD_NULL);

                    break;
                }

                // Validate nominal frequency. If differs,
                // create error and stop processing further.
                if( o_sysNomFreqMhz != l_sysNomFreqMhz )
                {
                    TRACFCOMP(g_fapiTd,ERR_MRK
                             "Nominal Frequency:[0x%04X] does not "
                             "match with other core nominal frequency:[0x%04X]",
                             l_sysNomFreqMhz, o_sysNomFreqMhz);

                    /*@
                     * @errortype
                     * @moduleid    fapi::MOD_GET_SYS_FREQ
                     * @reasoncode  fapi::RC_INVALID_FREQ
                     * @userdata1   Invalid frequency
                     * @userdata2   Expected frequency
                     * @devdesc     Nominal frequency(userdata1) does not match
                     *              nominal frequency(userdata2) on other cores.
                     *              Should be the same for all chips.
                     */
                    l_err =
                        new ERRORLOG::ErrlEntry(
                                         ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                         fapi::MOD_GET_SYS_FREQ,
                                         fapi::RC_INVALID_FREQ,
                                         l_sysNomFreqMhz,
                                         o_sysNomFreqMhz);

                    // Callout HW as VPD data is incorrect
                    l_err->addHwCallout(l_pTarget, HWAS::SRCI_PRIORITY_HIGH,
                                         HWAS::DECONFIG, HWAS::GARD_NULL);

                    break;
                }

                // Save the min turbo freq
                if (l_sysVPDTurboMaxFreqMhz < l_minsysVPDTurboMaxFreqMhz)
                {
                    l_minsysVPDTurboMaxFreqMhz = l_sysVPDTurboMaxFreqMhz;
                }
                // Save the max powersave freq
                if (l_sysVPDPowerSaveMinFreqMhz >
                                    l_maxsysVPDPowerSaveMinFreqMhz)
                {
                    l_maxsysVPDPowerSaveMinFreqMhz =
                                    l_sysVPDPowerSaveMinFreqMhz;
                }

            } // end for loop
            if (l_err != NULL)
            {
                break;
            }

            // Get min turbo freq
            o_sysVPDTurboMaxFreqMhz = l_minsysVPDTurboMaxFreqMhz;

            // Get max powersave freq
            o_sysVPDPowerSaveMinFreqMhz = l_maxsysVPDPowerSaveMinFreqMhz;

        } while (0);

        TRACFCOMP(g_fapiTd,EXIT_MRK"o_sysNomFreqMhz: 0x%08X, "
                  "o_sysVPDTurboMaxFreqMhz: 0x%08X, "
                  "o_sysVPDPowerSaveMinFreqMhz: 0x%08X",
                   o_sysNomFreqMhz, o_sysVPDTurboMaxFreqMhz,
                   o_sysVPDPowerSaveMinFreqMhz );

        return l_err;
    }