|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Arm Ethos-U55 NPU command/queue driver foundation (RA8P1-only). More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_npu_job_t |
| One Ethos-U55 inference job: a command stream plus its tensor arenas. More... | |
| struct | ra8_npu_status_t |
| Decoded snapshot of the NPU_STATUS register. More... | |
Functions | |
| ra8_err_t | ra8_npu_init (void) |
| Bring the NPU out of module-stop and soft-reset it. | |
| ra8_err_t | ra8_npu_deinit (void) |
| Gate the NPU back into module-stop. | |
| ra8_err_t | ra8_npu_reset (void) |
| Soft-reset an already-initialized NPU. | |
| ra8_err_t | ra8_npu_read_id (uint32_t *out_id) |
| Read the Ethos-U55 NPU_ID (architecture / product revision) register. | |
| ra8_err_t | ra8_npu_submit (const ra8_npu_job_t *job) |
| Program the command queue and tensor region base pointers for a job. | |
| ra8_err_t | ra8_npu_run (void) |
| Kick the currently-submitted job (transition the NPU to running). | |
| ra8_err_t | ra8_npu_poll (bool *out_done) |
| Non-blocking completion / fault poll of a running job. | |
| ra8_err_t | ra8_npu_wait (void) |
| Bounded busy-wait until the running job completes or faults. | |
| ra8_err_t | ra8_npu_read_status (ra8_npu_status_t *out) |
| Read and decode the NPU_STATUS register. | |
| ra8_err_t | ra8_npu_clear_irq (void) |
| Acknowledge (clear) a raised NPU interrupt. | |
| ra8_err_t | ra8_npu_irq_arm (void) |
| Arm the interrupt-driven completion latch for the submitted job. | |
| void | ra8_npu_irq_handler (void *ctx) |
| NPU interrupt service routine: latch completion / fault, ack the IRQ. | |
| ra8_err_t | ra8_npu_wait_irq (void) |
| Block on the NPU interrupt until the armed job completes or faults. | |
Arm Ethos-U55 NPU command/queue driver foundation (RA8P1-only).
Public API of the Ethos-U55 micro-NPU driver on the Renesas RA8P1 (R7KA8P1KFLCAC). This is the DRIVER FOUNDATION: it brings the NPU out of module-stop, soft-resets the block, and models the Ethos-U55 command-stream submission protocol – program the command-queue base/size (QBASE/QSIZE), program the per-tensor AXI region bases (BASEPn), kick the job (CMD.transition_to_running_state), then poll or take the IRQ for completion and read STATUS for faults.
It is deliberately NOT a Vela compiler and NOT a TFLite-micro runtime: it consumes a pre-compiled command stream (produced offline by Vela) plus the input/output/scratch tensors already resident in shared system SRAM, and runs one inference job. Building the command stream and the tensor-arena layout is the caller's (or a future runtime's) responsibility – see the follow-ups filed against the RA8P1 epic.
The register interface is the Arm Ethos-U55 architectural APB map (see ra8_npu_regs.h for the primary-source transcription). There is no RA8P1 board yet, so the command/queue construction is host-tested for the exact register write sequence only; a real on-silicon inference is a follow-up.
Not thread-safe. The NPU is a single-job engine; the caller owns serialisation. Call from a single-threaded context or with the NPU IRQ masked.
Definition in file ra8_npu.h.
|
nodiscard |
Acknowledge (clear) a raised NPU interrupt.
Writes CMD.clear_irq. Call from the NPU ISR (or after an IRQ-driven completion) so the line de-asserts and the next job can raise it.
| k_ra8_ok | Clear-IRQ request issued. |
| k_ra8_err_not_initialized | ra8_npu_init() had not run. |
|
nodiscard |
Gate the NPU back into module-stop.
Clears the driver's initialized flag and releases the NPU MSTP reference. Any in-flight job should be stopped first; the foundation does not force-stop a running stream.
| k_ra8_ok | NPU gated (or still referenced by another user). |
| k_ra8_err_not_initialized | ra8_npu_init() had not run. |
| k_ra8_err_hw_timeout | MSTP bit did not read back as set within budget. |
|
nodiscard |
Bring the NPU out of module-stop and soft-reset it.
Ungates the NPU via the ref-counted ra8_mstp substrate (MSTPCRA bit 16 on the RA8P1), then issues a soft reset and polls STATUS.reset until the block reports ready or a bounded budget expires. NPUCLK is supplied by the CGC clock tree configured at system-clock init; this driver assumes it is running.
| k_ra8_ok | NPU clocked, reset complete, ready for a job. |
| k_ra8_err_hw_timeout | Reset did not complete within the spin budget. |
| k_ra8_err_hw_error | An MSTP read-back or NPU fault bit was observed. |
Referenced by internal_npu_infer_execute(), and main().
|
nodiscard |
Arm the interrupt-driven completion latch for the submitted job.
Resets the internal completion state to "waiting" so ra8_npu_wait_irq can block until ra8_npu_irq_handler observes the job finish. Call it AFTER ra8_npu_submit and BEFORE ra8_npu_run when the caller intends to take the NPU interrupt instead of busy-polling. The interrupt itself must already be routed to ra8_npu_irq_handler via ra8_isr_register(k_ra8_npu_event_irq, ...).
| k_ra8_ok | Completion latch armed; the IRQ path may now be used. |
| k_ra8_err_not_initialized | ra8_npu_init() had not run. |
| k_ra8_err_invalid_state | No job has been submitted since init/reset. |
Referenced by internal_npu_infer_run_job_irq().
| void ra8_npu_irq_handler | ( | void * | ctx | ) |
NPU interrupt service routine: latch completion / fault, ack the IRQ.
Register this with ra8_isr_register(k_ra8_npu_event_irq, ra8_npu_irq_handler, nullptr, priority, ...). On entry it reads STATUS, latches the internal completion state to "done" (command stream fully consumed) or "faulted" (any bus / parse / weight-decoder / ECC fault), then writes CMD.clear_irq so the line de-asserts. It performs no logging on the hot path and touches the NPU only through the already-cited ra8_npu_read_status / ra8_npu_clear_irq accessors, so it adds no new register citation. A waiter unblocks via ra8_npu_wait_irq.
| [in] | ctx | Unused registration cookie (kept for ra8_isr_handler_t ABI). |
Referenced by internal_npu_infer_execute().
|
nodiscard |
Non-blocking completion / fault poll of a running job.
Reads STATUS once. Reports completion when the command stream end has been reached, and reports a hardware fault when any bus / parse / weight-decoder / ECC fault bit is latched.
| [out] | out_done | On k_ra8_ok, true when the job has finished, else false. |
| k_ra8_ok | Poll succeeded; *out_done set accordingly. |
| k_ra8_err_null_ptr | out_done was nullptr. |
| k_ra8_err_not_initialized | ra8_npu_init() had not run. |
| k_ra8_err_hw_error | A STATUS fault bit is set. |
|
nodiscard |
Read the Ethos-U55 NPU_ID (architecture / product revision) register.
Presence/revision probe. The value encodes the Arm architecture and product revision fields; a driver typically reads it once after ra8_npu_init() to confirm the block responds.
| [out] | out_id | On success, the raw 32-bit NPU_ID value. |
| k_ra8_ok | *out_id holds the NPU_ID value. |
| k_ra8_err_null_ptr | out_id was nullptr. |
| k_ra8_err_not_initialized | ra8_npu_init() had not run. |
Referenced by internal_npu_infer_execute(), and main().
|
nodiscard |
Read and decode the NPU_STATUS register.
| [out] | out | On success, the decoded status snapshot. |
| k_ra8_ok | *out holds the decoded status. |
| k_ra8_err_null_ptr | out was nullptr. |
| k_ra8_err_not_initialized | ra8_npu_init() had not run. |
Referenced by main().
|
nodiscard |
Soft-reset an already-initialized NPU.
Issues an NPU_RESET and polls STATUS.reset until the block is ready, returning the engine to the idle/stopped state. Use between jobs to clear a latched fault.
| k_ra8_ok | Reset complete; NPU idle. |
| k_ra8_err_not_initialized | ra8_npu_init() had not run. |
| k_ra8_err_hw_timeout | Reset did not complete within the spin budget. |
|
nodiscard |
Kick the currently-submitted job (transition the NPU to running).
Sets CMD.transition_to_running_state, after which the NPU parses the command queue programmed by ra8_npu_submit(). Completion is observed via ra8_npu_poll() / ra8_npu_wait() or the NPU IRQ.
| k_ra8_ok | Run request issued. |
| k_ra8_err_not_initialized | ra8_npu_init() had not run. |
| k_ra8_err_invalid_state | No job has been submitted since init/reset. |
Referenced by internal_npu_infer_run_job_irq(), internal_npu_smoke_run_job(), and internal_npu_vela_run_job().
|
nodiscard |
Program the command queue and tensor region base pointers for a job.
Writes QBASE (64-bit, split lo/hi) to the job's command-stream address and QSIZE to its byte length, then writes each in-use BASEPn pair to the corresponding tensor-arena AXI base. Does NOT start the job – call ra8_npu_run() afterwards. Programming is idempotent: re-submitting overwrites the previous descriptor.
| [in] | job | Job descriptor (command stream + region bases). Not retained. |
| k_ra8_ok | Queue and region pointers programmed. |
| k_ra8_err_null_ptr | job or job->cmd_stream was nullptr. |
| k_ra8_err_invalid_size | job->cmd_stream_bytes was 0. |
| k_ra8_err_invalid_arg | job->region_count exceeds k_ra8_npu_region_count. |
| k_ra8_err_not_initialized | ra8_npu_init() had not run. |
Referenced by internal_npu_infer_run_job_irq(), internal_npu_smoke_run_job(), and internal_npu_vela_run_job().
|
nodiscard |
Bounded busy-wait until the running job completes or faults.
Spins ra8_npu_poll() up to a fixed iteration budget (NASA Rule 2). Returns as soon as the job completes, a fault is latched, or the budget is exhausted.
| k_ra8_ok | Job completed (command stream fully consumed). |
| k_ra8_err_not_initialized | ra8_npu_init() had not run. |
| k_ra8_err_hw_error | A STATUS fault bit was observed. |
| k_ra8_err_hw_timeout | Job did not complete within the spin budget. |
Referenced by internal_npu_smoke_run_job(), and internal_npu_vela_run_job().
|
nodiscard |
Block on the NPU interrupt until the armed job completes or faults.
The interrupt-driven alternative to the busy-wait ra8_npu_wait. Spins a bounded budget (NASA Rule 2), issuing a WFI on the target between checks so the core sleeps until ra8_npu_irq_handler latches a result. On the unit-test host WFI compiles away and the test drives ra8_npu_irq_handler directly. Requires ra8_npu_irq_arm to have armed the latch first.
| k_ra8_ok | The ISR observed completion (command stream consumed). |
| k_ra8_err_not_initialized | ra8_npu_init() had not run. |
| k_ra8_err_invalid_state | The completion latch was not armed. |
| k_ra8_err_hw_error | The ISR latched a STATUS fault. |
| k_ra8_err_hw_timeout | No completion latched within the spin budget. |
Referenced by internal_npu_infer_run_job_irq().