Skip to content

Commit

Permalink
Leverage INTRP fully for SBE PSU Interrupt Handling
Browse files Browse the repository at this point in the history
  - 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>
  • Loading branch information
wghoffa authored and dcrowell77 committed Jun 29, 2018
1 parent 8a1a0c7 commit 7bd4032
Show file tree
Hide file tree
Showing 8 changed files with 356 additions and 168 deletions.
53 changes: 51 additions & 2 deletions src/include/usr/sbeio/sbe_psudd.H
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <util/singleton.H>
#include "sbe_sp_intf.H"
#include <map>
#include <arch/pirformat.H>

namespace SBEIO
{
Expand All @@ -46,6 +47,11 @@ namespace SBEIO
// within this component.
//-----------------------------------------------------------------------------

enum msgq_msg_t
{
MSG_INTR,
};

/** @class SbePsu
* @brief Class for SBE/PSU communication
*/
Expand Down Expand Up @@ -650,6 +656,14 @@ class SbePsu

~SbePsu();

/**
* Start message handler
*
* @note This function is used to spawn a new task.
* The args and return value are not used.
*/
static void* msg_handler(void * unused);

private:
//---------------------------------------------------------------------
// Local definitions for the device driver
Expand All @@ -666,6 +680,31 @@ class SbePsu
*/
const uint8_t ffdcPackageSize = 2;

/**
* @brief Response buffer from SBE
*/
psuResponse * iv_psuResponse;

/**
* @brief Indicator that PSU response is fully populated
*/
bool iv_responseReady;

/**
* @brief SBE PSU Message Queue
*/
msg_q_t iv_msgQ;

/**
* @brief Indicator if HB is shutting down
*/
bool iv_shutdownInProgress;

/**
* The sbe psu message handler.
*/
void msgHandler();

/**
* @brief allocate an ffdc buffer for the proc target
* @param[in] i_target proc to have ffdc buffer allocated
Expand All @@ -691,7 +730,7 @@ class SbePsu
psuCommand * i_pPsuRequest,
uint8_t i_reqMsgs);
/**
* @brief Read response from PSU
* @brief Check response from PSU
*
* @param[in] i_target Master proc to use for scoms
* @param[in] i_pPsuRequest Pointer to PSU request commands
Expand All @@ -701,7 +740,7 @@ class SbePsu
*
* @return errlHndl_t Error log handle on failure.
*/
errlHndl_t readResponse(TARGETING::Target * i_target,
errlHndl_t checkResponse(TARGETING::Target * i_target,
psuCommand * i_pPsuRequest,
psuResponse * o_pPsuResponse,
const uint64_t i_timeout,
Expand Down Expand Up @@ -748,6 +787,16 @@ class SbePsu
uint64_t i_addr,
uint64_t * i_pData);

/**
* @brief Handle PSU Interrupt
*
* @param[in] i_pir The PIR value of the proc that
* has the interrupt condition
*
* @return errlHndl_t Error log handle on failure
*/
errlHndl_t handleInterrupt(PIR_t i_pir);

/**
* @brief SBE PSU register addresses
*/
Expand Down
4 changes: 4 additions & 0 deletions src/include/usr/sbeio/sbeioreasoncodes.H
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ enum sbeioReasonCode
SBEIO_PSU_RESPONSE_ERROR = SBEIO_COMP_ID | 0x02,
SBEIO_PSU_NOT_READY = SBEIO_COMP_ID | 0x03,
SBEIO_PSU_FFDC_MISSING = SBEIO_COMP_ID | 0x04,
SBEIO_PSU_SEND = SBEIO_COMP_ID | 0x05,

// SBE FIFO error codes
SBEIO_FIFO_UPSTREAM_TIMEOUT = SBEIO_COMP_ID | 0x10,
Expand Down Expand Up @@ -132,6 +133,9 @@ enum sbeioReasonCode
// SBE Vital Attention error codes
SBEIO_SBE_RC_VALUE_INFO = SBEIO_COMP_ID | 0x60,

// Init error codes
SBEIO_RC_KERNEL_REG_FAILED = SBEIO_COMP_ID | 0x61,

// Remove once we collect the FFDC ourselves - @todo-RTC:144313
//termination_rc
SBEIO_HWSV_COLLECT_SBE_RC = SBEIO_COMP_ID | 0xFF,
Expand Down
68 changes: 0 additions & 68 deletions src/usr/intr/intrrp.C
Original file line number Diff line number Diff line change
Expand Up @@ -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:"
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)

{
Expand Down
6 changes: 3 additions & 3 deletions src/usr/intr/intrrp.H
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 3 additions & 4 deletions src/usr/isteps/istep16/call_host_activate_master.C
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
{
Expand All @@ -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();

Expand Down
4 changes: 2 additions & 2 deletions src/usr/mbox/mailboxsp.C
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/usr/pnor/spnorrp.C
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 7bd4032

Please sign in to comment.