IRQ

IRQ configuration and claims

These functions require advertised IRQ support. Global output masking preserves enabled queued events. Event-enable changes affect future admissions. Peer-DMA and RMEM claims identify a peer; other claim sources have a deterministic zero peer index. Sequence numbers identify IRQ events, not DMA requests or their result.

openenoc_endpoint_status_t openenoc_endpoint_irq_set_config(volatile csr__endpoint_interface_t *endpoint, const openenoc_endpoint_irq_config_t *config)

Apply event enables and the global output gate.

Parameters:
  • endpoint – In; required mapped, word-aligned endpoint-interface pointer.

  • config – In; required desired IRQ configuration.

Returns:

OK; INVALID_ARGUMENT for invalid arguments; UNSUPPORTED when IRQ or an enabled event’s feature is absent; NOT_READY while an IRQ error-clear command is pending.

Side effects:

Suppresses output while updating event enables, then applies the requested global enable; preserves queued claims and reservations.

openenoc_endpoint_status_t openenoc_endpoint_irq_get_config(volatile const csr__endpoint_interface_t *endpoint, openenoc_endpoint_irq_config_t *config)

Read current IRQ enables.

Parameters:
  • endpoint – In; required mapped, word-aligned endpoint-interface pointer.

  • config – Out; required IRQ-configuration destination.

Returns:

OK; INVALID_ARGUMENT for invalid arguments, or UNSUPPORTED when IRQ is absent.

Side effects:

Reads IRQ control and event-enable registers.

openenoc_endpoint_status_t openenoc_endpoint_irq_set_global_enable(volatile csr__endpoint_interface_t *endpoint, bool enable)

Set the endpoint IRQ-output gate.

Parameters:
  • endpoint – In; required mapped, word-aligned endpoint-interface pointer.

  • enable – In; requested output enable.

Returns:

OK; INVALID_ARGUMENT for invalid arguments; UNSUPPORTED when IRQ is absent; NOT_READY while an IRQ error-clear command is pending.

Side effects:

Changes the physical output gate; enabled event capture continues while it is disabled.

openenoc_endpoint_status_t openenoc_endpoint_irq_set_event_enable(volatile csr__endpoint_interface_t *endpoint, openenoc_endpoint_irq_source_t source, bool enable)

Set one IRQ event admission enable.

Parameters:
  • endpoint – In; required mapped, word-aligned endpoint-interface pointer.

  • source – In; one defined openenoc_endpoint_irq_source_t value.

  • enable – In; requested event enable.

Returns:

OK; INVALID_ARGUMENT for invalid endpoint pointer/source; UNSUPPORTED when IRQ is absent or the enabled source feature is absent.

Side effects:

Updates the selected event enable while preserving existing claims/reservations.

openenoc_endpoint_status_t openenoc_endpoint_irq_get_status(volatile const csr__endpoint_interface_t *endpoint, openenoc_endpoint_irq_status_t *status)

Read IRQ FIFO, reservation, output and sticky-error state.

Parameters:
  • endpoint – In; required mapped, word-aligned endpoint-interface pointer.

  • status – Out; required IRQ-status destination.

Returns:

OK; INVALID_ARGUMENT for invalid arguments, or UNSUPPORTED when IRQ is absent.

Side effects:

Reads status without consuming claims or clearing errors.

openenoc_endpoint_status_t openenoc_endpoint_irq_get_pending_commands(volatile const csr__endpoint_interface_t *endpoint, bool *clear_errors_pending, bool *complete_pending)

Read maintenance-command acknowledgement state.

Parameters:
  • endpoint – In; required mapped, word-aligned endpoint-interface pointer.

  • clear_errors_pending – Out; optional error-clear pending flag; may be null.

  • complete_pending – Out; optional completion pending flag; may be null.

Returns:

OK; INVALID_ARGUMENT for invalid endpoint pointer or both outputs null; UNSUPPORTED when IRQ is absent.

Preconditions:

At least one output pointer is required.

Side effects:

Reads command registers and writes requested outputs; does not issue commands.

openenoc_endpoint_status_t openenoc_endpoint_irq_get_claim(volatile const csr__endpoint_interface_t *endpoint, openenoc_endpoint_irq_claim_t *claim)

Read the stable FIFO-head claim.

Parameters:
  • endpoint – In; required mapped, word-aligned endpoint-interface pointer.

  • claim – Out; required source, peer-index and sequence destination.

Returns:

OK; INVALID_ARGUMENT for invalid endpoint pointer/output; UNSUPPORTED when IRQ is absent; NOT_READY when no valid claim exists.

Side effects:

Reads without consuming the claim. The output remains unchanged when no claim is available.

openenoc_endpoint_status_t openenoc_endpoint_irq_request_complete(volatile csr__endpoint_interface_t *endpoint, const openenoc_endpoint_irq_claim_t *claim)

Submit completion of the supplied current claim.

Parameters:
  • endpoint – In; required mapped, word-aligned endpoint-interface pointer.

  • claim – In; required claim identity returned by get_claim or the source callback.

Returns:

OK; INVALID_ARGUMENT for invalid endpoint pointer/claim or stale/mismatching identity; UNSUPPORTED when IRQ is absent; NOT_READY while a previous completion command is pending.

Preconditions:

Serialize claim ownership. source, peer_index and seq must identify the current valid FIFO-head claim.

Side effects:

Compares the three identity fields against the current claim, writes generated completion fields, and sets valid last. Returns without waiting for hardware acknowledgement. Error records are cleared independently.

openenoc_endpoint_status_t openenoc_endpoint_irq_request_clear_errors(volatile csr__endpoint_interface_t *endpoint)

Submit clearing of IRQ-controller sticky errors.

Parameters:
  • endpoint – In; required mapped, word-aligned endpoint-interface pointer.

Returns:

OK; INVALID_ARGUMENT for invalid arguments, or UNSUPPORTED when IRQ is absent. NOT_READY while the previous IRQ error-clear command is pending.

Side effects:

Submits error clear without waiting. Hardware clears overflow/invalid-completion records without consuming claims.

IRQ dispatch, binding and maintenance

openenoc_endpoint_irq_callbacks_t contains one named callback for each of the six event sources, an optional error callback, and application context. A source callback has the openenoc_endpoint_irq_callback_t signature: endpoint-interface pointer, const current claim, and context. Its claim pointer is valid only during the callback. HAL submits completion after the callback returns; callbacks must not complete the claim themselves. Direct RX handling may continue through TLAST as remaining frame beats arrive.

The CPU entry invokes the bound error callback for a nonzero accumulated result; explicit service calls return their result to the caller. Missing selected callbacks and unknown sources produce UNHANDLED_SOURCE while still submitting claim completion. Controller OVERFLOW and INVALID_COMPLETE records are reported until explicitly cleared. CPU EOI does not remove an endpoint claim.

RMEM failures use source 5 and the associated peer’s shared error record. Peer-DMA completion uses source 0 and also covers failed incoming bulk requests. Clearing the error record and completing the event remain separate operations.

openenoc_endpoint_irq_result_t openenoc_endpoint_irq_service(volatile csr__endpoint_interface_t *endpoint, const openenoc_endpoint_irq_callbacks_t *callbacks, uint32_t event_budget, uint32_t *handled_events)

Service a bounded number of claims without waiting for completion acknowledgements.

Parameters:
  • endpoint – In; required mapped, word-aligned endpoint-interface pointer.

  • callbacks – In; optional descriptor; a null descriptor/selected source callback makes available claims unhandled.

  • event_budget – In; maximum claims processed in this call. Zero performs no dispatch and only reports error state.

  • handled_events – Out; optional number of claims whose completion was submitted by this call; may be null. Set to zero even when access validation fails.

Returns:

openenoc_endpoint_irq_result_t bitmask: OK, UNHANDLED_SOURCE, OVERFLOW, INVALID_COMPLETE, UNSUPPORTED, or INVALID_ARGUMENT, with the OPENENOC_ENDPOINT_IRQ_RESULT_ prefix.

Preconditions:

Callbacks must preserve claim ownership and must not issue their own completion command.

Side effects:

Invokes the matching named source callback for each handled claim, submits their completion, and returns when completion is pending or the budget is exhausted. Explicit callers receive error results directly.

openenoc_endpoint_status_t openenoc_endpoint_irq_bind(volatile csr__endpoint_interface_t *endpoint, const openenoc_endpoint_irq_callbacks_t *callbacks)

Bind the endpoint and source callbacks to the HAL CPU IRQ entry.

Parameters:
  • endpoint – In; validated mapped interface pointer, or null together with callbacks to unbind.

  • callbacks – In; optional persistent callback descriptor; may be null. Both arguments null remove the existing binding.

Returns:

OK; INVALID_ARGUMENT for invalid arguments, or UNSUPPORTED when IRQ is absent.

Preconditions:

CPU IRQs must be masked; retain the mapping, descriptor and context. The CPU entry serves one bound endpoint.

Side effects:

Updates the single bound endpoint/callback context used by the CPU IRQ entry.

void openenoc_endpoint_irq_mask(void)

Disable all CPU IRQ sources through platform hooks.

Returns:

No value.

Side effects:

Changes CPU interrupt masking, including the state restored after an active IRQ returns.

void openenoc_endpoint_irq_unmask(void)

Enable the endpoint CPU IRQ source through platform hooks.

Returns:

No value.

Side effects:

Enables only the endpoint source and any required global CPU interrupt gate.

openenoc_endpoint_irq_result_t openenoc_endpoint_irq_handler(uintptr_t cpu_irq_state)

Handle the platform-native CPU IRQ state.

Parameters:
  • cpu_irq_state – In; opaque native state passed by the platform assembly wrapper.

Returns:

openenoc_endpoint_irq_result_t bitmask; includes NOT_BOUND or UNHANDLED_CPU_IRQ for missing binding or unsupported CPU sources, and service result flags.

Side effects:

Classifies CPU sources, services the bound endpoint, reports errors through the bound error callback, and masks CPU IRQs for unbound/unhandled CPU-source conditions.

openenoc_endpoint_status_t openenoc_endpoint_irq_complete(volatile csr__endpoint_interface_t *endpoint)

Complete the current claim and wait for hardware acknowledgement.

Parameters:
  • endpoint – In; required mapped, word-aligned endpoint-interface pointer.

Returns:

OK after hardware accepts completion; INVALID_ARGUMENT for an invalid endpoint pointer or claim identity; UNSUPPORTED when IRQ is absent; NOT_READY when no current claim exists or a previous completion command is pending.

Preconditions:

The caller owns claim completion and serializes consumers. Hardware must make progress; this function has no software wait timeout.

Side effects:

Reads the current claim, validates and submits its completion, then polls until hardware clears completion valid. Sticky errors are unchanged.

openenoc_endpoint_status_t openenoc_endpoint_irq_clear_errors(volatile csr__endpoint_interface_t *endpoint)

Clear IRQ-controller sticky errors and wait for hardware acknowledgement.

Parameters:
  • endpoint – In; required mapped, word-aligned endpoint-interface pointer.

Returns:

OK after hardware accepts clearing; INVALID_ARGUMENT for an invalid endpoint pointer; UNSUPPORTED when IRQ is absent; NOT_READY while a previous IRQ error-clear command is pending.

Preconditions:

Hardware must make progress; this function has no software wait timeout.

Side effects:

Submits clearing of overflow and invalid-completion errors, then polls until hardware clears the command. It preserves queued claims and DMA/RMEM error records.

CPU platform contract

The CPU IRQ entry lives in HAL. The selected sw/platform/<platform> supplies the internal mask and source-classification hooks declared in openenoc_endpoint_irq.h, plus its startup and assembly context wrapper. HAL includes no CPU-specific header; the platform implementation does not access endpoint CSR registers or call the endpoint HAL.

Each platform defines the opaque encoding of cpu_irq_state. Its assembly wrapper passes this state to the HAL entry and performs processor interrupt controller acknowledgement where required. Source-classification hooks inspect that state without consuming endpoint claims. Porting to another CPU preserves the application callback and runtime function contracts.

On PicoRV32, irq_entry saves the integer context and q0 return PC, passes the q1 source bitmask to the HAL handler, restores the context, and executes retirq. CPU input 3 is the endpoint source; a set bit in the CPU IRQ mask disables its source.

void _openenoc_endpoint_irq_disable_all(void)

Internal platform hook used by the public CPU mask function.

Returns:

No value.

Side effects:

Disables all CPU IRQ sources, including the interrupt state restored after an active handler returns.

void _openenoc_endpoint_irq_enable_endpoint(void)

Internal platform hook used by the public CPU unmask function.

Returns:

No value.

Side effects:

Enables only the endpoint CPU IRQ source and any required processor-wide interrupt gate.

bool _openenoc_endpoint_irq_is_endpoint(uintptr_t cpu_irq_state)

Classify whether the native CPU IRQ state includes the endpoint source.

Parameters:
  • cpu_irq_state – In; opaque platform-native IRQ state supplied by the assembly wrapper.

Returns:

true when the endpoint source is represented; otherwise false.

Side effects:

Inspects the supplied state without modifying CPU IRQ or endpoint claim state.

bool _openenoc_endpoint_irq_has_unhandled_sources(uintptr_t cpu_irq_state)

Classify whether the native state includes a source outside the endpoint IRQ.

Parameters:
  • cpu_irq_state – In; opaque platform-native IRQ state supplied by the assembly wrapper.

Returns:

true when an unsupported CPU IRQ source is represented; otherwise false.

Side effects:

Inspects the supplied state without modifying CPU IRQ or endpoint claim state.

Public declarations

The maintained header below provides the exact public type and enum definitions.

IRQ public types, claims and callbacks
 1typedef enum {
 2    OPENENOC_ENDPOINT_IRQ_SOURCE_PEER_DMA_COMPLETE = 0,
 3    OPENENOC_ENDPOINT_IRQ_SOURCE_NON_OETP_DMA_TX_COMPLETE = 1,
 4    OPENENOC_ENDPOINT_IRQ_SOURCE_NON_OETP_DMA_RX_COMPLETE = 2,
 5    OPENENOC_ENDPOINT_IRQ_SOURCE_NON_OETP_DIRECT_TX_COMPLETE = 3,
 6    OPENENOC_ENDPOINT_IRQ_SOURCE_NON_OETP_DIRECT_RX_AVAILABLE = 4,
 7    OPENENOC_ENDPOINT_IRQ_SOURCE_RMEM_ERROR = 5,
 8} openenoc_endpoint_irq_source_t;
 9
10typedef struct {
11    bool global_enable;
12    bool peer_dma_complete;
13    bool non_oetp_dma_tx_complete;
14    bool non_oetp_dma_rx_complete;
15    bool non_oetp_direct_tx_complete;
16    bool non_oetp_direct_rx_available;
17    bool rmem_error;
18} openenoc_endpoint_irq_config_t;
19
20typedef struct {
21    bool claim_pending;
22    bool credit_full;
23    bool overflow;
24    bool invalid_complete;
25    bool irq_asserted;
26    uint8_t fifo_level;
27    uint8_t reserved_count;
28} openenoc_endpoint_irq_status_t;
29
30// Combinable result flags.
31typedef enum {
32    OPENENOC_ENDPOINT_IRQ_RESULT_OK = 0,
33    OPENENOC_ENDPOINT_IRQ_RESULT_UNHANDLED_SOURCE = 1,
34    OPENENOC_ENDPOINT_IRQ_RESULT_OVERFLOW = 2,
35    OPENENOC_ENDPOINT_IRQ_RESULT_INVALID_COMPLETE = 4,
36    OPENENOC_ENDPOINT_IRQ_RESULT_UNHANDLED_CPU_IRQ = 8,
37    OPENENOC_ENDPOINT_IRQ_RESULT_NOT_BOUND = 16,
38    OPENENOC_ENDPOINT_IRQ_RESULT_UNSUPPORTED = 32,
39    OPENENOC_ENDPOINT_IRQ_RESULT_INVALID_ARGUMENT = 64,
40} openenoc_endpoint_irq_result_t;
41
42typedef void (*openenoc_endpoint_irq_error_callback_t)(
43    openenoc_endpoint_irq_result_t result,
44    void *context);
45
46typedef struct {
47    openenoc_endpoint_irq_source_t source;
48    uint16_t peer_index;
49    uint16_t seq;
50} openenoc_endpoint_irq_claim_t;
51
52typedef void (*openenoc_endpoint_irq_callback_t)(
53    volatile csr__endpoint_interface_t *endpoint,
54    const openenoc_endpoint_irq_claim_t *claim,
55    void *context);
56
57typedef struct {
58    openenoc_endpoint_irq_callback_t peer_dma_complete;
59    openenoc_endpoint_irq_callback_t non_oetp_dma_tx_complete;
60    openenoc_endpoint_irq_callback_t non_oetp_dma_rx_complete;
61    openenoc_endpoint_irq_callback_t non_oetp_direct_tx_complete;
62    openenoc_endpoint_irq_callback_t non_oetp_direct_rx_available;
63    openenoc_endpoint_irq_callback_t rmem_error;
64    openenoc_endpoint_irq_error_callback_t error;
65    void *context;
66} openenoc_endpoint_irq_callbacks_t;
67