diff options
author | Bill Hoffa <wghoffa@us.ibm.com> | 2018-06-06 13:29:17 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-06-28 22:43:13 -0400 |
commit | 7bd4032abfb75ca6a9a4eb9c44ab9443c81a6198 (patch) | |
tree | 87766c021712bbca5466c117ea0ac86c8cf238dc /src/usr | |
parent | 8a1a0c7e98a9091c62e715b1b9c44a7f3de90b39 (diff) | |
download | talos-hostboot-7bd4032abfb75ca6a9a4eb9c44ab9443c81a6198.tar.gz talos-hostboot-7bd4032abfb75ca6a9a4eb9c44ab9443c81a6198.zip |
Leverage INTRP fully for SBE PSU Interrupt Handling
- Remove PSU Handling from INTRP code and instead treat PSU
interrupts like any other interrupt type
- Add msg_handler to SBE PSU Code to handle interrupts
- Add better interrupt handling to timeout path so the interrupt
condition will be cleared instead of represented continuously
- Handle shutdown message from INTRP
Change-Id: I5eafea806e147c22be235ae1c54a5ce4706aa012
RTC: 149698
CQ: SW418168
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60049
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/intr/intrrp.C | 68 | ||||
-rw-r--r-- | src/usr/intr/intrrp.H | 6 | ||||
-rw-r--r-- | src/usr/isteps/istep16/call_host_activate_master.C | 7 | ||||
-rw-r--r-- | src/usr/mbox/mailboxsp.C | 4 | ||||
-rw-r--r-- | src/usr/pnor/spnorrp.C | 2 | ||||
-rw-r--r-- | src/usr/sbeio/sbe_psudd.C | 380 |
6 files changed, 301 insertions, 166 deletions
diff --git a/src/usr/intr/intrrp.C b/src/usr/intr/intrrp.C index 20b41fdd9..9e3f5930b 100644 --- a/src/usr/intr/intrrp.C +++ b/src/usr/intr/intrrp.C @@ -483,10 +483,6 @@ errlHndl_t IntrRp::_init() MSG_INTR_SHUTDOWN, INITSERVICE::INTR_PRIORITY); - //The INTRP itself will monitor/handle PSU Interrupts - // so unmask those interrupts - l_err = unmaskInterruptSource(LSI_PSU, l_procIntrHdlr); - //Set value for enabled threads uint64_t l_en_threads = get_enabled_threads(); TRACFCOMP(g_trac_intr, "IntrRp::_init() Threads enabled:" @@ -1520,10 +1516,6 @@ void IntrRp::routeInterrupt(intr_hdlr_t* i_proc, (uint32_t) i_type, rc); } } - else if (i_type == LSI_PSU) - { - handlePsuInterrupt(i_type, i_proc, i_pir); - } else // no queue registered for this interrupt type { // Throw it away for now. @@ -1845,66 +1837,6 @@ errlHndl_t IntrRp::setCommonInterruptBARs(intr_hdlr_t * i_proc, return l_err; } -errlHndl_t IntrRp::handlePsuInterrupt(ext_intr_t i_type, - intr_hdlr_t* i_proc, - PIR_t& i_pir) -{ - //TODO FIXME RTC 149698 - // Long term will leverage mask register to avoid - // polling loop below - errlHndl_t l_err = NULL; - TARGETING::Target* procTarget = i_proc->proc; - - do { - size_t scom_len = 8; - uint64_t l_reg = 0x0; - l_err = deviceRead(procTarget, - &l_reg, - scom_len, - DEVICE_SCOM_ADDRESS(PSI_BRIDGE_PSU_DOORBELL_REG)); - if (l_err) - { - break; - } - TRACDCOMP( g_trac_intr, "%.8X = %.16llX", - PSI_BRIDGE_PSU_DOORBELL_REG, l_reg ); - - //If the interrupt is driven by the doorbell, yield - // to give the driver a chance to take care of it - if( l_reg & PSI_BRIDGE_PSU_HOST_DOORBELL ) - { - nanosleep(0,10000); - task_yield(); - } - - //Clear the PSU Scom Reg Interrupt Status register - // but ignore the bit that the PSU driver uses - // to avoid a race condition - uint64_t l_andVal = PSI_BRIDGE_PSU_HOST_DOORBELL; - uint64_t size = sizeof(l_andVal); - l_err = deviceWrite(procTarget, - &l_andVal, - size, - DEVICE_SCOM_ADDRESS(PSI_BRIDGE_PSU_DOORBELL_ANDREG)); - - if (l_err) - { - TRACFCOMP(g_trac_intr, "Error clearing scom - %x", - PSI_BRIDGE_PSU_DOORBELL_ANDREG); - break; - } - - //Interrupt Processing is complete - re-enable - // this interrupt source - uint64_t intSource = i_type; - TRACFCOMP(g_trac_intr, "handlePsuInterrupt - Calling completeInterruptProcessing"); - completeInterruptProcessing(intSource, i_pir); - - } while(0); - - return l_err; -} - void IntrRp::completeInterruptProcessing(uint64_t& i_intSource, PIR_t& i_pir) { diff --git a/src/usr/intr/intrrp.H b/src/usr/intr/intrrp.H index 46f6f2616..b0245a868 100644 --- a/src/usr/intr/intrrp.H +++ b/src/usr/intr/intrrp.H @@ -182,9 +182,9 @@ namespace INTR //PSI Host Bridge ESB Constants PSI_BRIDGE_ESB_BAR_VALID = 0x0000000000000001ULL, PSI_BRIDGE_ESB_NOTIFY_VALID = 0x0000000000000001ULL, - PSI_BRIDGE_PSU_DOORBELL_REG = 0x000D0063, - PSI_BRIDGE_PSU_DOORBELL_ANDREG = 0x000D0064, - PSI_BRIDGE_PSU_HOST_DOORBELL = 0x8000000000000000, + PSI_BRIDGE_ESB_QUERY_OFFSET = 0x800, + PSI_BRIDGE_ESB_OFF_OFFSET = 0xD00, + PSI_BRIDGE_ESB_RESET_OFFSET = 0XC00, //XIVE Interrupt Controller Constants XIVE_IC_BAR_SCOM_ADDR = 0x05013010, diff --git a/src/usr/isteps/istep16/call_host_activate_master.C b/src/usr/isteps/istep16/call_host_activate_master.C index bb70255d0..ecbf78325 100644 --- a/src/usr/isteps/istep16/call_host_activate_master.C +++ b/src/usr/isteps/istep16/call_host_activate_master.C @@ -203,9 +203,9 @@ void* call_host_activate_master (void *io_pArgs) "Target HUID %.8X", TARGETING::get_huid(l_proc_target)); - //In the future possibly move default "waitTime" value to SBEIO code - uint64_t waitTime = 1000000; // bump the wait time to 1 sec - l_errl = SBEIO::startDeadmanLoop(waitTime); + //In the future possibly move default "waitTime" value to SBEIO code + uint64_t waitTime = 1000000; // bump the wait time to 1 sec + l_errl = SBEIO::startDeadmanLoop(waitTime); if ( l_errl ) { @@ -228,7 +228,6 @@ void* call_host_activate_master (void *io_pArgs) // applied during wakeup MAGIC_INSTRUCTION(MAGIC_SIMICS_CORESTATESAVE); - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "draining interrupt Q"); INTR::drainQueue(); diff --git a/src/usr/mbox/mailboxsp.C b/src/usr/mbox/mailboxsp.C index 777699e34..7bd1ccde5 100644 --- a/src/usr/mbox/mailboxsp.C +++ b/src/usr/mbox/mailboxsp.C @@ -1731,7 +1731,7 @@ bool MailboxSp::quiesced() if( result == true ) { - TRACFCOMP(g_trac_mbox,INFO_MRK"quiesed == true, iv_shutdown_msg[%p]", + TRACFCOMP(g_trac_mbox,INFO_MRK"quiesced == true, iv_shutdown_msg[%p]", iv_shutdown_msg); if(iv_shutdown_msg == NULL || (iv_shutdown_msg->data[1] == SHUTDOWN_STATUS_GOOD)) @@ -1794,7 +1794,7 @@ void MailboxSp::handleIPC(queue_id_t i_msg_q_id, msg_t * i_msg) msg_q_t msgq = r->second; // Only async message supported right now - // Interface already inforces this. + // Interface already enforces this. int rc = msg_send(msgq,i_msg); if(rc) diff --git a/src/usr/pnor/spnorrp.C b/src/usr/pnor/spnorrp.C index dc32e06d6..f3e67d202 100644 --- a/src/usr/pnor/spnorrp.C +++ b/src/usr/pnor/spnorrp.C @@ -44,7 +44,7 @@ extern trace_desc_t* g_trac_pnor; -// used to uniquley identify the secure PNOR RP message queue +// used to uniquely identify the secure PNOR RP message queue const char* SPNORRP_MSG_Q = "spnorrpq"; // Easy macro replace for unit testing diff --git a/src/usr/sbeio/sbe_psudd.C b/src/usr/sbeio/sbe_psudd.C index 9df26744a..98f5520b4 100644 --- a/src/usr/sbeio/sbe_psudd.C +++ b/src/usr/sbeio/sbe_psudd.C @@ -49,10 +49,17 @@ #include <errl/errludlogregister.H> #include <sbeio/sbe_retry_handler.H> #include <initservice/initserviceif.H> +#include <intr/interrupt.H> +#include <errno.h> +#include <sys/time.h> +#include <errl/errludprintk.H> trace_desc_t* g_trac_sbeio; TRAC_INIT(&g_trac_sbeio, SBEIO_COMP_NAME, 6*KILOBYTE, TRACE::BUFFER_SLOW); +// used to uniquley identify the SBE PSU message queue +const char* SBE_PSU_MSG_Q = "sbepsuq"; + #define SBE_TRACF(printf_string,args...) \ TRACFCOMP(g_trac_sbeio,"psudd: " printf_string,##args) #define SBE_TRACD(printf_string,args...) \ @@ -71,11 +78,79 @@ SbePsu & SbePsu::getTheInstance() return Singleton<SbePsu>::instance(); } +void * SbePsu::msg_handler(void *unused) +{ + Singleton<SbePsu>::instance().msgHandler(); + return nullptr; +} + /** * @brief Constructor **/ SbePsu::SbePsu() + : + iv_psuResponse(nullptr), + iv_responseReady(false), + iv_shutdownInProgress(false) { + errlHndl_t l_err = nullptr; + size_t rc = 0; + + //Create message queue + iv_msgQ = msg_q_create(); + + //Register message queue with unique identifier + rc = msg_q_register(iv_msgQ, SBE_PSU_MSG_Q); + + if(rc) // could not register msgQ with kernel + { + SBE_TRACF(ERR_MRK "SbePsu() Could not register" + "message queue with kernel"); + + /*@ errorlog tag + * @errortype ERRL_SEV_CRITICAL_SYS_TERM + * @moduleid SBEIO_PSU + * @reasoncode SBEIO_RC_KERNEL_REG_FAILED + * @userdata1 rc from msq_q_register + * @devdesc Could not register mailbox message queue + */ + l_err = new ErrlEntry + ( + ERRL_SEV_CRITICAL_SYS_TERM, + SBEIO_PSU, + SBEIO_RC_KERNEL_REG_FAILED, // reason Code + rc, // rc from msg_send + 0, + true //Add HB Software Callout + ); + } + + if (!l_err) + { + + // create task before registering the msgQ so any waiting interrupts get + // handled as soon as the msgQ is registered with the interrupt service + // provider + task_create(SbePsu::msg_handler, NULL); + + //Register message queue with INTRP for Interrupts + // of type LSI_PSU. The INTRP will route messages + // to this queue when interrupts of that type are + // detected + l_err = INTR::registerMsgQ(iv_msgQ, + MSG_INTR, + INTR::LSI_PSU); + } + + if (l_err) + { + SBE_TRACF(ERR_MRK"Error in SbePsu Constructor"); + l_err->collectTrace(INTR_COMP_NAME, 256); + // save off reason code before committing + auto l_reason = l_err->reasonCode(); + errlCommit(l_err, SBEIO_COMP_ID); + INITSERVICE::doShutdown(l_reason); + } } /** @@ -94,6 +169,60 @@ SbePsu::~SbePsu() } } +void SbePsu::msgHandler() +{ + // Mark as an independent daemon so if it crashes we terminate. + task_detach(); + + errlHndl_t l_err = nullptr; + + while(1) + { + msg_t* msg = msg_wait(iv_msgQ); + + //Message should never be nullptr + assert(msg != nullptr,"SbePsu::msgHandle: msg is nullptr"); + + switch(msg->type) + { + case MSG_INTR: + { + if (msg->data[0] == INTR::SHUT_DOWN) + { + iv_shutdownInProgress = true; + SBE_TRACF("SbePsu::msgHandler Handle Shutdown"); + //respond so INTRP can continue + // with shutdown procedure + msg_respond(iv_msgQ,msg); + } + else + { + //Handle the interrupt message -- pass the PIR of the + // proc causing the interrupt + SBE_TRACD("SbePsu::msgHandler got MSG_INTR message"); + l_err = handleInterrupt(msg->data[1]); + + if (l_err) + { + SBE_TRACF("SbePsu::msgHandler handleInterrupt returned an error"); + l_err->collectTrace(SBEIO_COMP_NAME); + l_err->collectTrace(INTR_COMP_NAME, 256); + errlCommit(l_err, SBEIO_COMP_ID); + } + + // Respond to the interrupt handler regardless of error + INTR::sendEOI(iv_msgQ,msg); + } + } + break; + default: + msg->data[1] = -EINVAL; + msg_respond(iv_msgQ, msg); + } + } + +} + /** * @brief perform SBE PSU chip-op * @@ -117,53 +246,73 @@ errlHndl_t SbePsu::performPsuChipOp(TARGETING::Target * i_target, SBE_TRACD(ENTER_MRK "performPsuChipOp"); - // If not a SBE_PSU_SET_FFDC_ADDRESS command, we allocate an FFDC buffer - // and set FFDC adress - if(i_pPsuRequest->command != SBE_PSU_SET_FFDC_ADDRESS) - { - errl = allocateFFDCBuffer(i_target); - } - if (errl) + //Only perform new chip-ops if we aren't shutting down + if (!iv_shutdownInProgress) { - SBE_TRACF(ERR_MRK"performPsuChipOp::" - " setFFDC address returned an error"); - return errl; - } - - //Serialize access to PSU - mutex_lock(&l_psuOpMux); + // If not an SBE_PSU_SET_FFDC_ADDRESS command, + // we allocate an FFDC buffer and set FFDC adress + if(i_pPsuRequest->command != SBE_PSU_SET_FFDC_ADDRESS) + { + errl = allocateFFDCBuffer(i_target); + } + if (errl) + { + SBE_TRACF(ERR_MRK"performPsuChipOp::" + " setFFDC address returned an error"); + return errl; + } - // Check that target is not NULL - assert(i_target != nullptr,"performPsuChipOp: proc target is NULL"); + //Serialize access to PSU + mutex_lock(&l_psuOpMux); - do - { - // write PSU Request - errl = writeRequest(i_target, - i_pPsuRequest, - i_reqMsgs); - if (errl)//error has been generated + if (iv_psuResponse != nullptr) { - SBE_TRACF(ERR_MRK"performPsuChipOp::" - " writeRequest returned an error"); - break; + //There should already be a timeout errorlog for this condition, + // simply log a message and continue as the previous timeout was + // not deemed fatal. + SBE_TRACF(ERR_MRK "performPsuChipOp Previous PSU response never completed."); } + iv_psuResponse = o_pPsuResponse; + iv_responseReady = false; - // read PSU response and check results - errl = readResponse(i_target, - i_pPsuRequest, - o_pPsuResponse, - i_timeout, - i_rspMsgs); - if (errl){ - SBE_TRACF(ERR_MRK"performPsuChipOp::" - " readResponse returned an error"); - break; // return with error + // Check that target is not NULL + assert(i_target != nullptr,"performPsuChipOp: proc target is NULL"); + + do + { + // write PSU Request + errl = writeRequest(i_target, + i_pPsuRequest, + i_reqMsgs); + if (errl)//error has been generated + { + SBE_TRACF(ERR_MRK"performPsuChipOp::" + " writeRequest returned an error"); + break; + } + + // read PSU response and check results + errl = checkResponse(i_target, + i_pPsuRequest, + iv_psuResponse, + i_timeout, + i_rspMsgs); + if (errl){ + SBE_TRACF(ERR_MRK"performPsuChipOp::" + " checkResponse returned an error"); + break; // return with error + } } - } - while (0); + while (0); - mutex_unlock(&l_psuOpMux); + iv_psuResponse = nullptr; + mutex_unlock(&l_psuOpMux); + } + else + { + SBE_TRACF(ERR_MRK"performPsuChipOp::" + "Skipping operation because of Shutdown operation"); + } SBE_TRACD(EXIT_MRK "performPsuChipOp"); @@ -286,48 +435,120 @@ errlHndl_t SbePsu::writeRequest(TARGETING::Target * i_target, return errl; } + +errlHndl_t SbePsu::handleInterrupt(PIR_t i_pir) +{ + errlHndl_t errl = nullptr; + SBE_TRACD(ENTER_MRK "SbePsu::handleInterrupt"); + bool l_responseAvailable = false; + + do + { + uint64_t l_intrGroupID = PIR_t::groupFromPir(i_pir.word); + uint64_t l_intrChipID = PIR_t::chipFromPir(i_pir.word); + // Find the chip that presented the interrupt + TARGETING::Target* l_intrChip = nullptr; + TARGETING::TargetHandleList l_procTargetList; + getAllChips(l_procTargetList, TARGETING::TYPE_PROC, false); + for (auto & l_chip: l_procTargetList) + { + auto l_chipId = + (l_chip)->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>(); + auto l_groupId = + (l_chip)->getAttr<TARGETING::ATTR_FABRIC_GROUP_ID>(); + if( l_chipId == l_intrChipID && l_groupId == l_intrGroupID ) + { + l_intrChip = (l_chip); + break; + } + } + assert(l_intrChip != nullptr, + "SbePsu::handleInterrupt: l_intrChip is nullptr"); + + //Occasionally, there is a PSU interrupt that is not associated + // with a PSU response. The HOST_DOORBELL reg will indicate if + // there is a response available. If there is, it will be read. + // If not the interrupt condition simply needs to be cleared. + uint64_t l_doorbellVal = 0x0; + errl = readScom(l_intrChip,PSU_HOST_DOORBELL_REG_RW,&l_doorbellVal); + if (errl) + { break; } + + if (l_doorbellVal & HOST_RESPONSE_WAITING) + { + //In this case the doorbell reg indicated a response is + //available + l_responseAvailable = true; + //read the response registers + uint64_t * l_pMessage = + reinterpret_cast<uint64_t *>(iv_psuResponse); + uint64_t l_addr = PSU_HOST_SBE_MBOX4_REG; + + for (uint8_t i=0; i<(sizeof(psuResponse)/sizeof(uint64_t)); i++) + { + errl = readScom(l_intrChip,l_addr,l_pMessage); + if (errl) + { break; } + l_addr++; + l_pMessage++; + } + if (errl) + { break; } + + //Notify PSU response has been read + uint64_t l_data = HOST_CLEAR_RESPONSE_WAITING; + errl = writeScom(l_intrChip,PSU_HOST_DOORBELL_REG_AND,&l_data); + if (errl) + { break; } + } + + //Clear the rest of the PSU Scom Reg Interrupt Status register + // This clears the PSU interrupt condition so the PSU interrupt + // won't be re-presented + uint64_t l_data = HOST_RESPONSE_WAITING; + errl = writeScom(l_intrChip,PSU_HOST_DOORBELL_REG_AND,&l_data); + if (errl) break; + + } while (0); + + // Only indicate a response is ready if we found legitimate + // PSU message data. + if (l_responseAvailable) + { + iv_responseReady = true; + } + + SBE_TRACD(EXIT_MRK "SbePsu::handleInterrupt"); + + return errl; +} + /** * @brief Read PSU response messages */ -errlHndl_t SbePsu::readResponse(TARGETING::Target * i_target, - psuCommand * i_pPsuRequest, - psuResponse * o_pPsuResponse, - const uint64_t i_timeout, - uint8_t i_rspMsgs) +errlHndl_t SbePsu::checkResponse(TARGETING::Target * i_target, + psuCommand * i_pPsuRequest, + psuResponse * o_pPsuResponse, + const uint64_t i_timeout, + uint8_t i_rspMsgs) { errlHndl_t errl = NULL; - SBE_TRACD(ENTER_MRK "readResponse"); + SBE_TRACD(ENTER_MRK "checkResponse"); do { //wait for request to be completed errl = pollForPsuComplete(i_target,i_timeout,i_pPsuRequest); - if (errl) break; // return with error - - //read the response registers - uint64_t * l_pMessage = (uint64_t *)o_pPsuResponse; - uint64_t l_addr = PSU_HOST_SBE_MBOX4_REG; - for (uint8_t i=0;i<4;i++) - { - errl = readScom(i_target,l_addr,l_pMessage); - if (errl) break; - l_addr++; - l_pMessage++; - } - if (errl) break; - - //notify PSU response has been read - uint64_t l_data = HOST_CLEAR_RESPONSE_WAITING; - errl = writeScom(i_target,PSU_HOST_DOORBELL_REG_AND,&l_data); - if (errl) break; - + if (errl) + { break; } // return with error + //At this point we will have valid data in iv_psuResponse //If the command is not supported, then print a statement and break out if(o_pPsuResponse->primaryStatus == SBE_PRI_INVALID_COMMAND && o_pPsuResponse->secondaryStatus == SBE_SEC_COMMAND_NOT_SUPPORTED) { - SBE_TRACF("sbe_psudd.C :: readResponse: COMMAND NOT SUPPORTED " + SBE_TRACF("sbe_psudd.C :: checkResponse: COMMAND NOT SUPPORTED " " cmd=0x%02x%02x prim=0x%08x secondary=0x%08x" " expected seqID=%d actual seqID=%d", i_pPsuRequest->commandClass, @@ -349,7 +570,7 @@ errlHndl_t SbePsu::readResponse(TARGETING::Target * i_target, (i_pPsuRequest->seqID != o_pPsuResponse->seqID)) { - SBE_TRACF(ERR_MRK "sbe_psudd.C :: readResponse: " + SBE_TRACF(ERR_MRK "sbe_psudd.C :: checkResponse: " "failing response status " " cmd=0x%02x%02x prim=0x%08x secondary=0x%08x" " expected seqID=%d actual seqID=%d", @@ -361,7 +582,6 @@ errlHndl_t SbePsu::readResponse(TARGETING::Target * i_target, o_pPsuResponse->seqID); SBE_TRACFBIN("Full response:", o_pPsuResponse, sizeof(psuResponse)); - /*@ * @errortype * @moduleid SBEIO_PSU @@ -394,7 +614,7 @@ errlHndl_t SbePsu::readResponse(TARGETING::Target * i_target, //Deallocate FFDC buffer if(i_pPsuRequest->command == SBE_PSU_SET_FFDC_ADDRESS) { - SBE_TRACF(ERR_MRK, "sbe_psudd.C: readResponse: " + SBE_TRACF(ERR_MRK, "sbe_psudd.C: checkResponse: " "Set FFDC Address failed."); PageManager::freePage(l_ffdcPkg); iv_ffdcPackageBuffer.erase(i_target); @@ -450,7 +670,7 @@ errlHndl_t SbePsu::readResponse(TARGETING::Target * i_target, } while (0); - SBE_TRACD(EXIT_MRK "readResponse"); + SBE_TRACD(EXIT_MRK "checkResponse"); return errl; } @@ -463,21 +683,14 @@ errlHndl_t SbePsu::pollForPsuComplete(TARGETING::Target * i_target, psuCommand* i_pPsuRequest) { errlHndl_t l_errl = NULL; - SBE_TRACD(ENTER_MRK "pollForPsuComplete"); - uint64_t l_elapsed_time_ns = 0; - uint64_t l_data = 0; - bool l_trace = true; //initialize so first call is traced do { - // read response doorbell to see if ready - l_errl = readScom(i_target,PSU_HOST_DOORBELL_REG_RW,&l_data,l_trace); - if (l_errl) break; // return with error - - // check if response is now ready to be read - if (l_data & HOST_RESPONSE_WAITING) + //The handling of the interrupt will set the + // iv_psuResponse variable with the incoming message data + if (iv_responseReady) { break; // return with success } @@ -635,18 +848,9 @@ errlHndl_t SbePsu::pollForPsuComplete(TARGETING::Target * i_target, // try later nanosleep( 0, 10000 ); //sleep for 10us l_elapsed_time_ns += 10000; - - // There will be many polls to check for the complete. If there - // is a problem, then there will be hundreds before timing out - // and giving up. Having one trace entry showing the poll request - // parameters is useful. Hundreds of identical entries is not. Hundreds - // with a non-continuous trace overruns the initial interaction. - l_trace = false; //only trace once to avoid flooding the trace } while (1); - task_yield(); //let INTR in - SBE_TRACD(EXIT_MRK "pollForPsuComplete"); return l_errl; |