src/ssx/occhw/occhw_scom.c
/// A raw getscom() through the PMC OCI/PIB bridge
///
/// \param address A standard 32-bit SCOM address, including multicast
/// addresses.
///
/// \param data Points to a container for the returned data.
///
/// \param timeout The software timeout as an SSX interval (timebase ticks),
/// or the special value SSX_WAIT_FOREVER to indicate no software timeout.
///
/// This routine executes in an SSX_CRITICAL critical section.
///
/// Unlike most other APIs, this API returns both positive and negative error
/// codes, as well as the 0 code for success. In the event of PCB errors, the
/// returned \a data is obtained from the PMC O2P data registers.  In the
/// event of non-PCB errors, the caller \a data is not modified.
///
/// If the transaction experiences a software timeout (controlled by the \a
/// timeout parameter) or a protocol error, the PMC PIB master will be left in
/// a state in which it is illegal to perform further SCOM access through the
/// PMC until the ongoing transaction is finished.
///
/// \retval 0 Success
///
///\ retval 1-7 A PCB error code.  See \c pcb_common.h
///
/// \retval -SCOM_TIMEOUT_ERROR The software timeout specified by the \a
/// timeout parameter expired before the transaction completed.
///
/// retval -SCOM_PROTOCOL_ERROR_GETSCOM_BUSY The PMC SCOM engine was busy when
/// the call was made.
A raw getscom() through the PMC OCI/PIB bridge
\param address A standard 32-bit SCOM address, including multicast
addresses.

\param data Points to a container for the returned data.

\param timeout The software timeout as an SSX interval (timebase ticks),
or the special value SSX_WAIT_FOREVER to indicate no software timeout.

This routine executes in an SSX_CRITICAL critical section.

Unlike most other APIs, this API returns both positive and negative error
codes, as well as the 0 code for success. In the event of PCB errors, the
returned \a data is obtained from the PMC O2P data registers.  In the
event of non-PCB errors, the caller \a data is not modified.

If the transaction experiences a software timeout (controlled by the \a
timeout parameter) or a protocol error, the PMC PIB master will be left in
a state in which it is illegal to perform further SCOM access through the
PMC until the ongoing transaction is finished.

\retval 0 Success

\ retval 1-7 A PCB error code.

\retval -SCOM_TIMEOUT_ERROR The software timeout specified by the \a
timeout parameter expired before the transaction completed.

SCOM_PROTOCOL_ERROR_GETSCOM_BUSY The PMC SCOM engine was busy when
the call was made.
A raw getscom () through the PMC OCI / PIB bridge \ param address A standard 32 - bit SCOM address including multicast addresses . \ param data Points to a container for the returned data . \ param timeout The software timeout as an SSX interval ( timebase ticks ) or the special value SSX_WAIT_FOREVER to indicate no software timeout . This routine executes in an SSX_CRITICAL critical section . Unlike most other APIs this API returns both positive and negative error codes as well as the 0 code for success . In the event of PCB errors the returned \ a data is obtained from the PMC O2P data registers . In the event of non - PCB errors the caller \ a data is not modified . If the transaction experiences a software timeout ( controlled by the \ a timeout parameter ) or a protocol error the PMC PIB master will be left in a state in which it is illegal to perform further SCOM access through the PMC until the ongoing transaction is finished . \ retval 0 Success \ retval 1 - 7 A PCB error code . \ retval - SCOM_TIMEOUT_ERROR The software timeout specified by the \ a timeout parameter expired before the transaction completed . SCOM_PROTOCOL_ERROR_GETSCOM_BUSY The PMC SCOM engine was busy when the call was made .
int
_getscom(uint32_t address, uint64_t* data, SsxInterval timeout)
{
    SsxMachineContext   ctx;
    int                 rc;
    occhw_scom_cmd_t*    scom_cmd = &OSD_PTR->scom_cmd;
    occhw_scom_status_t scom_status;
    do
    {
        if(address & OCCHW_SCOM_READ_MASK)
        {
            rc = -SCOM_INVALID_ADDRESS;
            break;
        }
        ssx_critical_section_enter(SSX_CRITICAL, &ctx);
        rc = ssx_irq_status_get(OCCHW_IRQ_IPI_SCOM);
        if (rc)
        {
            ssx_critical_section_exit(&ctx);
            rc = -SCOM_PROTOCOL_ERROR_GETSCOM_BUSY;
            break;
        }
        scom_cmd->scom_status.status32 = OCCHW_SCOM_PENDING;
        scom_cmd->scom_addr = address | OCCHW_SCOM_READ_MASK;
        ssx_irq_status_set(OCCHW_IRQ_IPI_SCOM, 1);
        rc = poll_scom(timeout);
        *data = scom_cmd->scom_data;
        scom_status.status32 = scom_cmd->scom_status.status32;
        ssx_critical_section_exit(&ctx);
        if(!rc)
        {
            if(scom_status.status32 == OCCHW_SCOM_PENDING)
            {
                rc = -SCOM_PROTOCOL_ERROR_GETSCOM_RST;
            }
            else
            {
                rc = scom_status.sibrc;
            }
        }
    }
    while(0);
    return rc;
}
int _getscom ( uint32_t address , uint64_t * data , SsxInterval timeout ) { SsxMachineContext ctx ; int rc ; occhw_scom_cmd_t * scom_cmd = & OSD_PTR -> scom_cmd ; occhw_scom_status_t scom_status ; do { if ( address & OCCHW_SCOM_READ_MASK ) { rc = - SCOM_INVALID_ADDRESS ; break ; } ssx_critical_section_enter ( SSX_CRITICAL , & ctx ) ; rc = ssx_irq_status_get ( OCCHW_IRQ_IPI_SCOM ) ; if ( rc ) { ssx_critical_section_exit ( & ctx ) ; rc = - SCOM_PROTOCOL_ERROR_GETSCOM_BUSY ; break ; } scom_cmd -> scom_status . status32 = OCCHW_SCOM_PENDING ; scom_cmd -> scom_addr = address | OCCHW_SCOM_READ_MASK ; ssx_irq_status_set ( OCCHW_IRQ_IPI_SCOM , 1 ) ; rc = poll_scom ( timeout ) ; * data = scom_cmd -> scom_data ; scom_status . status32 = scom_cmd -> scom_status . status32 ; ssx_critical_section_exit ( & ctx ) ; if ( ! rc ) { if ( scom_status . status32 == OCCHW_SCOM_PENDING ) { rc = - SCOM_PROTOCOL_ERROR_GETSCOM_RST ; } else { rc = scom_status . sibrc ; } } } while ( 0 ) ; return rc ; }
A raw getscom() through the PMC OCI/PIB bridge
\param address A standard 32-bit SCOM address, including multicast
addresses.
A raw getscom () through the PMC OCI / PIB bridge \ param address A standard 32 - bit SCOM address including multicast addresses .
// Check for a transaction already ongoing // Setup the write.  The 'read' bit is set in the address. // Notify the GPE (by raising an interrupt) that a request is pending // Poll until completed or timed out // Extract the data and status out of the scom command block //check that the GPE updated the scom status.  Normally, //the gpe won't clear the interrupt until it has updated //the status field.  The exception is if the GPE gets //reset. //The SIBRC field of the MSR is where we get the status for //the last scom operation.