src/lib/occlib/ipc_core.c
///////////////////////////////////////////////////////////////////////////////
/// Helper function used by ipc_send_cmd and ipc_send_rsp to send a message
///
Helper function used by ipc_send_cmd and ipc_send_rsp to send a message
Helper function used by ipc_send_cmd and ipc_send_rsp to send a message
int ipc_send_msg(ipc_msg_t* msg, uint32_t target_id)
{
    ipc_target_t*           target_cbufs;
    uint8_t*                read_count;
    uint8_t*                write_count;
    ipc_msg_t**             msgs;
    KERN_MACHINE_CONTEXT    ctx;
    int                     rc = IPC_RC_SUCCESS;
    uint8_t                 num_entries;
    do
    {
        if(target_id > OCCHW_INST_ID_MAX)
        {
            rc = IPC_RC_INVALID_TARGET_ID;
            break;
        }
        target_cbufs = &OSD_PTR->ipc_data.targets[target_id];
        msgs = &target_cbufs->cbufs[OCCHW_INST_ID_SELF][0];
        read_count = &target_cbufs->counts.reads.counts8[OCCHW_INST_ID_SELF];
        write_count = &target_cbufs->counts.writes.counts8[OCCHW_INST_ID_SELF];
        KERN_CRITICAL_SECTION_ENTER(KERN_CRITICAL, &ctx);
        num_entries = *write_count - *read_count;
        if(num_entries < IPC_CBUF_SIZE)
        {
            msg->func_id.active_flag = 1;
            msgs[*write_count % IPC_CBUF_SIZE] = msg;
            (*write_count)++;
#ifdef GPE_IPC_TIMERS
            msg->begin_time = in32(OCB_OTBR);
#endif
            KERN_IRQ_STATUS_SET(IPC_GET_IRQ(target_id), 1);
        }
        else
        {
            if(num_entries == IPC_CBUF_SIZE)
            {
                rc = IPC_RC_BUFFER_FULL;
            }
            else
            {
                rc = IPC_RC_TARGET_BLOCKED;
            }
        }
        KERN_CRITICAL_SECTION_EXIT(&ctx);
    }
    while(0);
    return rc;
}
int ipc_send_msg ( ipc_msg_t * msg , uint32_t target_id ) { ipc_target_t * target_cbufs ; uint8_t * read_count ; uint8_t * write_count ; ipc_msg_t * * msgs ; KERN_MACHINE_CONTEXT ctx ; int rc = IPC_RC_SUCCESS ; uint8_t num_entries ; do { if ( target_id > OCCHW_INST_ID_MAX ) { rc = IPC_RC_INVALID_TARGET_ID ; break ; } target_cbufs = & OSD_PTR -> ipc_data . targets [ target_id ] ; msgs = & target_cbufs -> cbufs [ OCCHW_INST_ID_SELF ] [ 0 ] ; read_count = & target_cbufs -> counts . reads . counts8 [ OCCHW_INST_ID_SELF ] ; write_count = & target_cbufs -> counts . writes . counts8 [ OCCHW_INST_ID_SELF ] ; KERN_CRITICAL_SECTION_ENTER ( KERN_CRITICAL , & ctx ) ; num_entries = * write_count - * read_count ; if ( num_entries < IPC_CBUF_SIZE ) { msg -> func_id . active_flag = 1 ; msgs [ * write_count % IPC_CBUF_SIZE ] = msg ; ( * write_count ) ++ ; #ifdef GPE_IPC_TIMERS msg -> begin_time = in32 ( OCB_OTBR ) ; #endif KERN_IRQ_STATUS_SET ( IPC_GET_IRQ ( target_id ) , 1 ) ; } else { if ( num_entries == IPC_CBUF_SIZE ) { rc = IPC_RC_BUFFER_FULL ; } else { rc = IPC_RC_TARGET_BLOCKED ; } } KERN_CRITICAL_SECTION_EXIT ( & ctx ) ; } while ( 0 ) ; return rc ; }
Helper function used by ipc_send_cmd and ipc_send_rsp to send a message
Helper function used by ipc_send_cmd and ipc_send_rsp to send a message
// Check for invalid target ID //Prevent other threads on this processor from updating the cbuf //Determine the number of entries in the buffer //If the cbuf isn't full, then add the message and raise an interrupt // Mark the message as being active //raise the IPC interrupt on the target //Check if cbuf is just full or is blocked