summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorBill Hoffa <wghoffa@us.ibm.com>2018-06-06 13:29:17 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-06-28 22:43:13 -0400
commit7bd4032abfb75ca6a9a4eb9c44ab9443c81a6198 (patch)
tree87766c021712bbca5466c117ea0ac86c8cf238dc /src/usr
parent8a1a0c7e98a9091c62e715b1b9c44a7f3de90b39 (diff)
downloadtalos-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.C68
-rw-r--r--src/usr/intr/intrrp.H6
-rw-r--r--src/usr/isteps/istep16/call_host_activate_master.C7
-rw-r--r--src/usr/mbox/mailboxsp.C4
-rw-r--r--src/usr/pnor/spnorrp.C2
-rw-r--r--src/usr/sbeio/sbe_psudd.C380
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;
OpenPOWER on IntegriCloud