Exemplo n.º 1
0
bool Service::intrTaskWait(msg_t * & o_msg)
{
    // wait for a shutdown message
    // or an interrupt

    bool shutdown = false;
    msg_q_t q = iv_intrTaskQ;

    o_msg = msg_wait(q);

    ATTN_FAST("...intr task woke up");

    shutdown = o_msg->type == SHUTDOWN;

    if(shutdown)
    {
        // this was a shutdown message.
        // ack the message and tell the
        // task loop to exit

        iv_intrTaskQ = 0;
        iv_shutdownPrdTask = true;

        msg_respond(q, o_msg);

        ATTN_FAST("interrupt task shutting down");
    }

    return shutdown;
}
Exemplo n.º 2
0
    void* consoleDaemon(void* unused)
    {
        // Detach and register daemon with shutdown path.
        task_detach();
        INITSERVICE::registerShutdownEvent(g_msgq, SYNC,
                                           INITSERVICE::CONSOLE_PRIORITY);

        // Create a default output UART device if there isn't already one.
        //    - Some devices are registered via the CONSOLE_UART_DEFINE_DEVICE
        //      macro and therefore don't need this.
        if (NULL == Uart::g_device)
        {
            Uart::g_device = new Uart();
            Uart::g_device->initialize();
        }

        while(1)
        {
            msg_t* msg = msg_wait(g_msgq);

            switch (msg->type)
            {
                case DISPLAY:
                {
                    if (NULL != msg->extra_data)
                    {
                        char timestamp[11];
                        sprintf(timestamp, "%3d.%05d|",
                                msg->data[0],
                                    // 5 Digits worth of ns.
                                (msg->data[1]*100000)/NS_PER_SEC);
                        _display(timestamp);

                        _display(
                            static_cast<const char*>(msg->extra_data));
                        free(msg->extra_data);
                    }
                    msg_free(msg);
                    break;
                }

                case SYNC:
                {
                    msg_respond(g_msgq, msg);
                    break;
                }
            }

        }

        return NULL;
    }
Exemplo n.º 3
0
bool
trace_syscall(pid_t pid, bool until_sync)
{
  PfnOnEntry on_entry = on_entry_print;
  PfnOnReturn on_return = on_return_print;
  if (until_sync)
  {
    on_entry = on_entry_sync;
    on_return = on_return_nothing;
  }
  for(;;)
  {
    int sysc_nr;
    int sysc_rc;
    bool is_errno;

    /* trace until we reach next syscall */
    if (-1 == msg_ptrace(pid, PTRACE_SYSCALL, 0, 0))
      return false;
    if (!msg_wait(VOODOO_SIGTRAP, pid))
      return false;
    if (!msg_get_syscall(pid, &sysc_nr))
      return false;
    if (!on_entry(sysc_nr))
      break;

    /* get return value of syscall */
    if (-1 == msg_ptrace(pid, PTRACE_SYSCALL, 0, 0))
      return false;
    if (!msg_wait(VOODOO_SIGTRAP, pid))
      return false;
    is_errno = msg_get_errno(pid, &sysc_rc);
    if (!on_return(sysc_rc, is_errno))
      break;
  }
  return true;
}
Exemplo n.º 4
0
//@todo: RTC 119832
void IpmiSEL::execute(void)
{
    //Mark as an independent daemon so if it crashes we terminate.
    task_detach();

    // Register shutdown events with init service.
    //      Done at the "end" of shutdown processesing.
    //      This will flush out any IPMI messages which were sent as
    //      part of the shutdown processing. We chose MBOX priority
    //      as we don't want to accidentally get this message after
    //      interrupt processing has stopped in case we need intr to
    //      finish flushing the pipe.
    INITSERVICE::registerShutdownEvent(iv_msgQ, IPMISEL::MSG_STATE_SHUTDOWN,
                                       INITSERVICE::MBOX_PRIORITY);

    barrier_wait(&iv_sync_start);

    while(true)
    {
        msg_t* msg = msg_wait(iv_msgQ);

        const IPMISEL::msg_type msg_type =
            static_cast<IPMISEL::msg_type>(msg->type);

        // Invert the "default" by checking here. This allows the compiler
        // to warn us if the enum has an unhadled case but still catch
        // runtime errors where msg_type is set out of bounds.
        assert(msg_type <= IPMISEL::MSG_LAST_TYPE,
               "msg_type %d not handled", msg_type);

        switch(msg_type)
        {
            case IPMISEL::MSG_SEND_ESEL:
                IPMISEL::process_esel(msg);
                //done with msg
                msg_free(msg);
                break;

            case IPMISEL::MSG_STATE_SHUTDOWN:
                IPMI_TRAC(INFO_MRK "ipmisel shutdown event");

                //Respond that we are done shutting down.
                msg_respond(iv_msgQ, msg);
                break;
        }
    } // while(1)
    IPMI_TRAC(EXIT_MRK "message loop");
    return;
} // execute
Exemplo n.º 5
0
///////////////////////////////////////////////////////////////////////////////
// ErrlManager::errlogMsgHndlr()
///////////////////////////////////////////////////////////////////////////////
void ErrlManager::errlogMsgHndlr ()
{
    TRACFCOMP( g_trac_errl, ENTER_MRK "Enter ErrlManager::errlogMsgHndlr" );

    while( 1 )
    {
        msg_t * theMsg = msg_wait( iv_msgQ );
        TRACFCOMP( g_trac_errl, INFO_MRK"Got an error log Msg - Type: 0x%08x",
                                                               theMsg->type );
        //Process message just received
        switch( theMsg->type )
        {
            case ERRLOG_ACCESS_PNOR_TYPE:
                {
                    // PNOR is up and running now.

                    setupPnorInfo();

                    //We are done with the msg
                    msg_free(theMsg);

                    // go back and wait for a next msg
                    break;
                }
            case ERRLOG_ACCESS_TARG_TYPE:
                {
                    // TARGETING is up and running now.

                    //  do we NOT need to send the error?
                    TARGETING::Target * sys = NULL;
                    TARGETING::targetService().getTopLevelTarget( sys );
                    TARGETING::SpFunctions spfn;

                    if (!(sys &&
                          sys->tryGetAttr<TARGETING::ATTR_SP_FUNCTIONS>(spfn) &&
                          spfn.baseServices))
                    {
                        iv_isSpBaseServices = false;

                        // if there are queued errors, clear the Mbox flag
                        // since they will never be sent, which will delete
                        // the errors that have been fully processed
                        ErrlListItr_t it = iv_errlList.begin();
                        while(it != iv_errlList.end())
                        {
                            // Mark MBOX processing complete
                            _clearFlag(*it, MBOX_FLAG);
                            _updateErrlListIter(it);
                        }
                    }

                    //We are done with the msg
                    msg_free(theMsg);

                    // go back and wait for a next msg
                    break;
                }
            case ERRLOG_ACCESS_MBOX_TYPE:
                {
                    // MBOX is up and running now.

                    // do we need to send the errorlog
                    TARGETING::Target * sys = NULL;
                    TARGETING::targetService().getTopLevelTarget( sys );
                    TARGETING::SpFunctions spfn;

                    if (sys &&
                        sys->tryGetAttr<TARGETING::ATTR_SP_FUNCTIONS>(spfn) &&
                        spfn.mailboxEnabled)
                    {
                        iv_isMboxEnabled = true;
                    }

                    // if we're supposed to and can now send msgs, do it.
                    if (iv_isSpBaseServices && iv_isMboxEnabled)
                    {
                        // Register messageQ with Mailbox to receive message.
                        errlHndl_t l_err =
                                MBOX::msgq_register( MBOX::HB_ERROR_MSGQ,
                                                    iv_msgQ );
                        if( l_err )
                        {
                            TRACFCOMP(g_trac_errl, ERR_MRK "Msg queue already registered");

                            delete( l_err );
                            l_err = NULL;

                            //If we got an error then it means the message queue
                            //is registered with mailbox.
                            //This should not happen. So assert here.
                            assert(0);
                        }

                        // if errors came in before MBOX was ready,
                        // the errors would be on this list. send them now.
                        ErrlListItr_t it = iv_errlList.begin();
                        while(it != iv_errlList.end())
                        {
                            // Check if MBOX processing is needed
                            if (_isFlagSet(*it, MBOX_FLAG))
                            {
                                // send errlog
                                sendErrLogToFSP(it->first);
                                // Mark MBOX processing complete
                                _clearFlag(*it, MBOX_FLAG);
                            }
                            _updateErrlListIter(it);
                        }
                    }
                    else
                    {
                        // Delete errors that have been completely processed
                        ErrlListItr_t it = iv_errlList.begin();
                        while(it != iv_errlList.end())
                        {
                            // Mark MBOX processing complete
                            _clearFlag(*it, MBOX_FLAG);
                            _updateErrlListIter(it);
                        }
                    }

                    //We are done with the msg
                    msg_free(theMsg);

                    // go back and wait for a next msg
                    break;
                }
            case ERRLOG_ACCESS_IPMI_TYPE:
                {
#ifdef CONFIG_BMC_IPMI
                    // IPMI is up and running now.
                    iv_isIpmiEnabled = true;

                    // if we can now send msgs, do it.
                    // if errors came in before IPMI was ready,
                    // the errors would be on this list. send them now.
                    ErrlListItr_t it = iv_errlList.begin();
                    while(it != iv_errlList.end())
                    {
                        // Check if IPMI processing is needed
                        if (_isFlagSet(*it, IPMI_FLAG))
                        {
                            // send errorlog
                            sendErrLogToBmc(it->first);
                            // Mark IPMI processing complete
                            _clearFlag(*it, IPMI_FLAG);
                        }
                        _updateErrlListIter(it);
                    }
#endif

                    //We are done with the msg
                    msg_free(theMsg);

                    // go back and wait for a next msg
                    break;
                }
            case ERRLOG_ACCESS_ERRLDISP_TYPE:
                {
#ifdef CONFIG_CONSOLE_OUTPUT_ERRORDISPLAY
                    // Errldisplay now ready
                    iv_isErrlDisplayEnabled = true;

                    CONSOLE::displayf("ERRL",
                        "Dumping errors reported prior to registration");

                    // Display errlogs to errldisplay
                    ErrlListItr_t it = iv_errlList.begin();
                    while(it != iv_errlList.end())
                    {
                        // Check if ERRLDISP processing is needed
                        if (_isFlagSet(*it, ERRLDISP_FLAG))
                        {
                            ERRORLOGDISPLAY::errLogDisplay().msgDisplay
                                        (it->first,
                                        ((it->first->reasonCode()) & 0xFF00));
                            // Mark ERRLDISP processing complete
                            _clearFlag(*it, ERRLDISP_FLAG);
                        }
                        _updateErrlListIter(it);
                    }
#endif
                    //We are done with the msg
                    msg_free(theMsg);

                    break;
                }
            case ERRLOG_NEEDS_TO_BE_COMMITTED_TYPE:
                {
                    // Extract error log handle from the message. We need the
                    // error log handle to pass along
                    errlHndl_t l_err = (errlHndl_t) theMsg->extra_data;

                    // Ask the ErrlEntry to assign commit component, commit time
                    l_err->commit( (compId_t) theMsg->data[0] );

                    // Pair with all flags set to add to the errlList
                    ErrlFlagPair_t l_pair(l_err, ALL_FLAGS);

#ifdef CONFIG_CONSOLE_OUTPUT_ERRORDISPLAY
                    // Display errl to errldisplay
                    if (iv_isErrlDisplayEnabled)
                    {
                        ERRORLOGDISPLAY::errLogDisplay().msgDisplay
                                            (l_err,
                                            ( (l_err->reasonCode()) & 0xFF00));
                        // Mark ERRLDISP processing complete on this error
                        _clearFlag(l_pair, ERRLDISP_FLAG);
                    }
#endif
                    //Save the error log to PNOR
                    bool l_savedToPnor = saveErrLogToPnor(l_err);

                    // Check if we actually saved the msg to PNOR
                    if (l_savedToPnor)
                    {
                        // Mark PNOR processing complete on this error
                        _clearFlag(l_pair, PNOR_FLAG);
                    }

#ifdef STORE_ERRL_IN_L3
                    //Write the error log to L3 memory
                    //useful ONLY for the hb-errl tool
                    saveErrLogEntry ( l_err );
#endif

                    //Try to send the error log if someone is there to receive
                    if (!iv_isSpBaseServices)
                    {
                        // Mark MBOX processing complete on this error
                        _clearFlag(l_pair, MBOX_FLAG);
                    }
                    else if (iv_isSpBaseServices && iv_isMboxEnabled)
                    {
                        sendErrLogToFSP(l_err);

                        // Mark MBOX processing complete on this error
                        _clearFlag(l_pair, MBOX_FLAG);
                    }

#ifdef CONFIG_BMC_IPMI
                    if (iv_isIpmiEnabled)
                    {
                        // convert to SEL/eSEL and send to BMC over IPMI
                        sendErrLogToBmc(l_err);

                        // Mark IPMI processing complete on this error
                        _clearFlag(l_pair, IPMI_FLAG);
                    }
#endif

                    //Ask the ErrlEntry to process any callouts
                    l_err->processCallout();

                    //Ask if it is a terminating log
                    if( l_err->isTerminateLog() )
                    {
                        TRACFCOMP( g_trac_errl, INFO_MRK
                                   "Terminating error was committed"
                                   " errlmanager is reqesting a shutdown.");

                        INITSERVICE::doShutdown(l_err->plid(), true);

                        TRACDCOMP( g_trac_errl,
                                INFO_MRK"shutdown in progress" );
                    }

                    // If l_errl has not been fully proccessed delete it
                    // otherwise add to list
                    if (l_pair.second == 0)
                    {
                        delete l_err;
                        l_err = NULL;
                    }
                    else
                    {
                        iv_errlList.push_back(l_pair);
                    }

                    //We are done with the msg
                    msg_free(theMsg);

                    // else go back and wait for a next msg
                    break;
                }
            case ERRLOG_COMMITTED_ACK_RESPONSE_TYPE:
                {
                    //Hostboot must keep track and clean up hostboot error
                    //logs in PNOR after it is committed by FSP.
                    uint32_t l_tmpPlid = theMsg->data[0]>>32;
                    TRACFCOMP( g_trac_errl, INFO_MRK"ack: %.8x", l_tmpPlid);

                    bool didAck = ackErrLogInPnor(l_tmpPlid);
                    if (!didAck)
                    {
                        // couldn't find that errlog in PNOR, look in our
                        // errlMsgList - maybe it's there waiting
                        ErrlListItr_t it = std::find_if(iv_errlList.begin(),
                                        iv_errlList.end(),
                                        std::bind1st(ptr_fun(&compareEidToPlid)
                                                             ,l_tmpPlid));
                        // Check if such errl was found
                        if (it != iv_errlList.end())
                        {
                            // We found the errlog
                            // Mark PNOR processing complete
                            _clearFlag(*it, PNOR_FLAG);
                            _updateErrlListIter(it);
                        }
                    }

                    msg_free(theMsg);

                    // We didn't have room before in PNOR to save an
                    // error log, so try now since we just ACKed one.
                    ErrlListItr_t it = std::find_if(iv_errlList.begin(),
                                        iv_errlList.end(),
                                        bind2nd(ptr_fun(_isFlagSet),
                                        PNOR_FLAG));

                    // Check if such errl was found
                    if (it != iv_errlList.end())
                    {
                        bool l_savedToPnor = saveErrLogToPnor(it->first);

                        // check if we actually saved the msg to PNOR
                        if (l_savedToPnor)
                        {
                            // Mark PNOR processing complete
                            _clearFlag(*it, PNOR_FLAG);
                            _updateErrlListIter(it);
                        }
                        // else, still couldn't save it (for some reason) so
                        // it's still on the list.
                    }
                    break;
                }
            case ERRLOG_SHUTDOWN_TYPE:
                TRACFCOMP( g_trac_errl, INFO_MRK "Shutdown event received" );

                //Start shutdown process for error log
                errlogShutdown();

                // Respond that we are done shutting down.
                msg_respond ( iv_msgQ, theMsg );

                TRACFCOMP( g_trac_errl, INFO_MRK "Shutdown event processed" );

                break;

            default:
                // Default Message
                TRACFCOMP( g_trac_errl, ERR_MRK "Unexpected message type 0x%08x",
                                                                  theMsg->type );

                msg_free(theMsg);
                break;
        } // switch
    }

    //The errlogMsgHndlr should run all the time. It only
    //exits when error log message thread is killed.
    TRACFCOMP( g_trac_errl, EXIT_MRK "Exit ErrlManager::errlogMsgHndlr" );
    return;
}
Exemplo n.º 6
0
    errlHndl_t AttributeSync::syncSectionFromFsp(
                                    TARGETING::SECTION_TYPE i_section_to_sync,
                                    msg_q_t i_pMsgQ )
    {
        TARG_INF( ENTER_MRK "AttributeSync::syncSectionFromFsp" );

        errlHndl_t l_errl    = NULL;
        bool l_sync_complete = false;
        ATTR_SYNC_RC l_rc    = ATTR_SYNC_FAILURE;
        TARGETING::sectionRefData l_page;

        iv_section_to_sync = i_section_to_sync;
        memset( &l_page, 0, sizeof(TARGETING::sectionRefData) );

        do{
            if (!SECUREBOOT::allowAttrOverrides())
            {
                TARG_INF("AttributeSync::syncSectionFromFsp(): skipping since "
                         "attribute overrides are not allowed and we don't "
                         "trust the FSP");
                break;
            }

            // send a request to FSP to sync to Hostboot
            l_errl = sendSyncToHBRequestMessage();
            if (l_errl)
            {
                break;
            }

            do{

                // wait for FSP to send the section's attribute data
                TARG_DBG( "Wait for message from FSP");
                msg_t * l_pMsg = msg_wait(i_pMsgQ);

                // process message just received
                if ( ATTR_SYNC_SECTION_TO_HB == l_pMsg->type )
                {
                    TARG_DBG( "HB Attribute Sync Section message type received "
                        "from the FSP");

                    // get the section id
                    l_page.sectionId = ATTR_SYNC_GET_SECTION_ID(l_pMsg->data[0]);

                    // get the page number
                    l_page.pageNumber = ATTR_SYNC_GET_PAGE_NUMBER(l_pMsg->data[0]);

                    // save a pointer to the page
                    l_page.dataPtr =
                        reinterpret_cast<uint8_t *> (l_pMsg->extra_data);

                    // Validate the data received.  Ignore page if
                    // section id or page size is incorrect or if
                    // there are no page received since we cannot send
                    // an error back to the FSP at this point.  We will
                    // check later whether the correct number of valid
                    // pages for the section was received when FSP send
                    // us the sync complete message.

                    // if no page received
                    if ( NULL == l_page.dataPtr)
                    {
                        TARG_ERR("WARNING: "
                            "no attribute page received from FSP");
                    }
                    // if it's not the requested section
                    else if ( iv_section_to_sync != l_page.sectionId )
                    {
                        TARG_ERR("WARNING: "
                            "section type received from FSP = %u, expecting %u",
                            l_page.sectionId, iv_section_to_sync);

                        //Free the memory
                        free(l_pMsg->extra_data);
                        l_pMsg->extra_data = NULL;
                    }
                    // page size should always be 4K
                    else if ( PAGESIZE != l_pMsg->data[1] )
                    {
                        TARG_ERR("WARNING: "
                            "page size received from FSP = %u, expecting 4K",
                            l_pMsg->data[1]);

                        free(l_pMsg->extra_data);
                        l_pMsg->extra_data = NULL;
                    }
                    else
                    {
                        iv_pages.push_back(l_page);
                    }

                    // Free memory allocated for message
                    msg_free( l_pMsg );
                    l_pMsg = NULL;
                }
                else if ( ATTR_SYNC_COMPLETE_TO_HB == l_pMsg->type )
                {
                    TARG_DBG( "HB Attribute Sync Complete message type "
                        "received from the FSP");

                    l_sync_complete = true;

                    iv_total_pages = ATTR_SYNC_GET_PAGE_COUNT( l_pMsg->data[0] );

                    // check that the total # of valid pages received is correct
                    if ( iv_pages.size() == iv_total_pages )
                    {
                        // write the section to the Attribute virtual address
                        // space
                        l_rc = updateSectionData();

                        if (l_rc)
                        {
                            TARG_ERR(
                                "HB failed in writing the attribute section" );
                        }
                    }
                    else
                    {
                        TARG_ERR( "total # of valid pages received = %u, "
                            "expecting %u", iv_pages.size(), iv_total_pages);

                        l_rc = ATTR_SYNC_FAILURE;
                    }

                    if (l_rc)
                    {
                        /*@
                         *   @errortype
                         *   @moduleid      TARG_MOD_ATTR_SYNC
                         *   @reasoncode    TARG_RC_ATTR_SYNC_TO_HB_FAIL
                         *   @userdata1     return code
                         *   @userdata2     section to sync
                         *   @devdesc       The attribute synchronization from
                         *                  the FSP failed.
                         */
                         l_errl = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
                                                TARG_MOD_ATTR_SYNC,
                                                TARG_RC_ATTR_SYNC_TO_HB_FAIL,
                                                l_rc,
                                                iv_section_to_sync);
                    }

                    // send a msg back to FSP indicating success/failure
                    l_pMsg->data[0] = 0;
                    ATTR_SYNC_ADD_RC( l_rc, l_pMsg->data[0] );
                    int l_respond_rc = msg_respond(i_pMsgQ, l_pMsg);
                    if (l_respond_rc)
                    {
                        // Just output a trace here since FSP should
                        // handle error case where it doesn't receive
                        // a response from HB.
                        TARG_ERR( "WARNING: Bad rc from msg_respond: %d",
                            l_respond_rc);
                        msg_free( l_pMsg );
                        l_pMsg = NULL;
                    }
                }
                else
                {
                    TARG_ERR( "WARNING: Invalid message type [0x%x] received "
                        "from the FSP, ignoring...", l_pMsg->type);
                    msg_free( l_pMsg );
                    l_pMsg = NULL;
                }

            }while (false == l_sync_complete);

            // free memory
            if ( iv_pages.size() )
            {
                for ( size_t i = 0; i < iv_pages.size(); i++ )
                {
                    free( iv_pages[i].dataPtr );
                }

                iv_pages.clear();
            }

        }while (0);

        TARG_INF( EXIT_MRK "AttributeSync::syncSectionFromFsp" );
        return l_errl;
    }
Exemplo n.º 7
0
/**
 * @brief  Message receiver
 */
void PnorRP::waitForMessage()
{
    TRACFCOMP(g_trac_pnor, "PnorRP::waitForMessage>" );

    errlHndl_t l_errhdl = NULL;
    msg_t* message = NULL;
    uint8_t* user_addr = NULL;
    uint8_t* eff_addr = NULL;
    uint64_t dev_offset = 0;
    uint64_t chip_select = 0xF;
    bool needs_ecc = false;
    int rc = 0;
    uint64_t status_rc = 0;
    uint64_t fatal_error = 0;

    while(1)
    {
        status_rc = 0;
        TRACUCOMP(g_trac_pnor, "PnorRP::waitForMessage> waiting for message" );
        message = msg_wait( iv_msgQ );
        if( message )
        {
            /*  data[0] = virtual address requested
             *  data[1] = address to place contents
             */
            eff_addr = (uint8_t*)message->data[0];
            user_addr = (uint8_t*)message->data[1];

            //figure out the real pnor offset
            l_errhdl = computeDeviceAddr( eff_addr, dev_offset, chip_select, needs_ecc );
            if( l_errhdl )
            {
                status_rc = -EFAULT; /* Bad address */
            }
            else
            {
                switch(message->type)
                {
                    case( MSG_MM_RP_READ ):
                        l_errhdl = readFromDevice( dev_offset,
                                                   chip_select,
                                                   needs_ecc,
                                                   user_addr,
                                                   fatal_error );
                        if( l_errhdl || ( 0 != fatal_error ) )
                        {
                            status_rc = -EIO; /* I/O error */
                        }
                        break;
                    case( MSG_MM_RP_WRITE ):
                        l_errhdl = writeToDevice( dev_offset, chip_select, needs_ecc, user_addr );
                        if( l_errhdl )
                        {
                            status_rc = -EIO; /* I/O error */
                        }
                        break;
                    default:
                        TRACFCOMP( g_trac_pnor, "PnorRP::waitForMessage> Unrecognized message type : user_addr=%p, eff_addr=%p, msgtype=%d", user_addr, eff_addr, message->type );
                        /*@
                         * @errortype
                         * @moduleid     PNOR::MOD_PNORRP_WAITFORMESSAGE
                         * @reasoncode   PNOR::RC_INVALID_MESSAGE_TYPE
                         * @userdata1    Message type
                         * @userdata2    Requested Virtual Address
                         * @devdesc      PnorRP::waitForMessage> Unrecognized
                         *               message type
                         * @custdesc     A problem occurred while accessing
                         *               the boot flash.
                         */
                        l_errhdl = new ERRORLOG::ErrlEntry(
                                           ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                           PNOR::MOD_PNORRP_WAITFORMESSAGE,
                                           PNOR::RC_INVALID_MESSAGE_TYPE,
                                           TO_UINT64(message->type),
                                           (uint64_t)eff_addr,
                                           true /*Add HB SW Callout*/);
                        l_errhdl->collectTrace(PNOR_COMP_NAME);
                        status_rc = -EINVAL; /* Invalid argument */
                }
            }

            if( !l_errhdl && msg_is_async(message) )
            {
                TRACFCOMP( g_trac_pnor, "PnorRP::waitForMessage> Unsupported Asynchronous Message  : user_addr=%p, eff_addr=%p, msgtype=%d", user_addr, eff_addr, message->type );
                /*@
                 * @errortype
                 * @moduleid     PNOR::MOD_PNORRP_WAITFORMESSAGE
                 * @reasoncode   PNOR::RC_INVALID_ASYNC_MESSAGE
                 * @userdata1    Message type
                 * @userdata2    Requested Virtual Address
                 * @devdesc      PnorRP::waitForMessage> Unrecognized message
                 *               type
                 * @custdesc     A problem occurred while accessing the boot
                 *               flash.
                 */
                l_errhdl = new ERRORLOG::ErrlEntry(
                                         ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                         PNOR::MOD_PNORRP_WAITFORMESSAGE,
                                         PNOR::RC_INVALID_ASYNC_MESSAGE,
                                         TO_UINT64(message->type),
                                         (uint64_t)eff_addr,
                                         true /*Add HB SW Callout*/);
                l_errhdl->collectTrace(PNOR_COMP_NAME);
                status_rc = -EINVAL; /* Invalid argument */
            }

            if( l_errhdl )
            {
                errlCommit(l_errhdl,PNOR_COMP_ID);
            }


            /*  Expected Response:
             *      data[0] = virtual address requested
             *      data[1] = rc (0 or negative errno value)
             *      extra_data = Specific reason code.
             */
            message->data[1] = status_rc;
            message->extra_data = reinterpret_cast<void*>(fatal_error);
            rc = msg_respond( iv_msgQ, message );
            if( rc )
            {
                TRACFCOMP(g_trac_pnor, "PnorRP::waitForMessage> Error from msg_respond, giving up : rc=%d", rc );
                break;
            }
        }
    }


    TRACFCOMP(g_trac_pnor, "< PnorRP::waitForMessage" );
}
Exemplo n.º 8
0
int main(int argc, char *argv[])
{
    struct xnet_type_ops ops = {
        .buf_alloc = __mds_buf_alloc,
        .buf_free = NULL,
        .recv_handler = mds_spool_dispatch,
        .dispatcher = mds_fe_dispatch,
    };
    int err = 0;
    int self, sport = -1, i, j;
    int memonly, memlimit, mode, plot_method;
    char *value;
    char *ring_ip = NULL;
    char profiling_fname[256];
    
    hvfs_info(xnet, "MDS Unit Testing...\n");
    hvfs_info(xnet, "Mode is 0/1 (no ring/with ring)\n");

    if (argc < 2) {
        hvfs_err(xnet, "Self ID is not provided.\n");
        err = EINVAL;
        return err;
    } else {
        self = atoi(argv[1]);
        hvfs_info(xnet, "Self type+ID is mds:%d.\n", self);
        if (argc == 4) {
            ring_ip = argv[2];
            sport = atoi(argv[3]);
        } else if (argc == 3)
            ring_ip = argv[2];
    }

    value = getenv("memonly");
    if (value) {
        memonly = atoi(value);
    } else
        memonly = 1;

    value = getenv("memlimit");
    if (value) {
        memlimit = atoi(value);
    } else
        memlimit = 0;

    value = getenv("mode");
    if (value) {
        mode = atoi(value);
    } else 
        mode = 0;

    value = getenv("fsid");
    if (value) {
        fsid = atoi(value);
    } else
        fsid = 0;

    value = getenv("plot");
    if (value) {
        plot_method = atoi(value);
    } else
        plot_method = MDS_PROF_PLOT;

    st_init();
    mds_pre_init();
    hmo.prof.xnet = &g_xnet_prof;
    hmo.conf.itbid_check = 1;
    hmo.conf.prof_plot = plot_method;
    hmo.conf.option |= HVFS_MDS_NOSCRUB;
    hmo.cb_branch_init = mds_cb_branch_init;
    hmo.cb_branch_destroy = mds_cb_branch_destroy;

    mds_init(11);

    /* set the uuid base! */
    hmi.uuid_base = (u64)self << 45;

    for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
            xnet_update_ipaddr(HVFS_TYPE(i, j), 1, &ipaddr[i],
                               (short *)(&port[i][j]));
        }
    }

    xnet_update_ipaddr(HVFS_CLIENT(12), 1, &ipaddr[4], (short *)(&port[4][0]));
    xnet_update_ipaddr(HVFS_MDS(4), 1, &ipaddr[0], (short *)(&port[4][1]));

    /* prepare the ring address */
    if (!ring_ip) {
        xnet_update_ipaddr(HVFS_RING(0), 1, &ipaddr[3],
                           (short *)(&port[3][0]));
        if (sport == -1)
            sport = port[TYPE_MDS][self];
    } else {
        xnet_update_ipaddr(HVFS_RING(0), 1, &ring_ip,
                           (short *)(&port[3][0]));
        if (sport == -1)
            sport = port[TYPE_MDS][0];
    }
    
    /* setup the profiling file */
    memset(profiling_fname, 0, sizeof(profiling_fname));
    sprintf(profiling_fname, "./CP-BACK-mds.%d", self);
    hmo.conf.pf_file = fopen(profiling_fname, "w+");
    if (!hmo.conf.pf_file) {
        hvfs_err(xnet, "fopen() profiling file %s faield %d\n",
                 profiling_fname, errno);
        return EINVAL;
    }

    self = HVFS_MDS(self);

    hmo.xc = xnet_register_type(0, sport, self, &ops);
    if (IS_ERR(hmo.xc)) {
        err = PTR_ERR(hmo.xc);
        return err;
    }
    hmo.site_id = self;

    if (mode == 0) {
        hmi.gdt_salt = 0;
        hvfs_info(xnet, "Select GDT salt to %lx\n", hmi.gdt_salt);
        hmi.root_uuid = 1;
        hmi.root_salt = 0xdfeadb0;
        hvfs_info(xnet, "Select root salt to %lx\n", hmi.root_salt);
        
#if 0
        ring_add(&hmo.chring[CH_RING_MDS], HVFS_MDS(0));
        ring_add(&hmo.chring[CH_RING_MDS], HVFS_MDS(1));
        ring_add(&hmo.chring[CH_RING_MDS], HVFS_MDS(2));
        ring_add(&hmo.chring[CH_RING_MDS], HVFS_MDS(3));
#else
        ring_add(&hmo.chring[CH_RING_MDS], HVFS_MDS(4));
#endif
        ring_add(&hmo.chring[CH_RING_MDSL], HVFS_MDSL(0));
        ring_add(&hmo.chring[CH_RING_MDSL], HVFS_MDSL(1));

        ring_resort_nolock(hmo.chring[CH_RING_MDS]);
        ring_resort_nolock(hmo.chring[CH_RING_MDSL]);

        ring_dump(hmo.chring[CH_RING_MDS]);
        ring_dump(hmo.chring[CH_RING_MDSL]);
        
        /* insert the GDT DH */
        dh_insert(hmi.gdt_uuid, hmi.gdt_uuid, hmi.gdt_salt);
        bitmap_insert(0, 0);
    } else {
        hmo.cb_exit = mds_cb_exit;
        hmo.cb_hb = mds_cb_hb;
        hmo.cb_ring_update = mds_cb_ring_update;

        /* use ring info to init the mds */
        err = r2cli_do_reg(self, HVFS_RING(0), fsid, 0);
        if (err) {
            hvfs_err(xnet, "reg self %x w/ r2 %x failed w/ %d\n",
                     self, HVFS_RING(0), err);
            goto out;
        }
        hvfs_info(xnet, "HMI gdt uuid %ld salt %lx txg %ld\n", 
                  hmi.gdt_uuid, hmi.gdt_salt,
                  atomic64_read(&hmi.mi_txg));
    }
    
    err = mds_verify();
    if (err) {
        hvfs_err(xnet, "Verify MDS configration failed!\n");
        goto out;
    }

//    SET_TRACING_FLAG(xnet, HVFS_DEBUG);
//    SET_TRACING_FLAG(mds, HVFS_DEBUG | HVFS_VERBOSE);

    hvfs_info(xnet, "MDS is UP for serving requests now.\n");

    msg_wait();

    xnet_unregister_type(hmo.xc);

    st_destroy();
    mds_destroy();

    return 0;
out:
    st_destroy();
    mds_destroy();

    return err;
}