Caliptra I3C Peripheral Driver - #417
Draft
rusty1968 wants to merge 10 commits into
Draft
Conversation
The stock caliptra-mcu-sw emulator main only drains the I3C socket's command channel into the emulated target when built with one of its test-* cargo features; in a featureless build, frames written to --i3c-port accumulate in an mpsc channel nobody reads, so the firmware's TTI RX queue never fills and the smoke test could not pass. Replace the emulator's entry point with a local main (linking the unmodified upstream emulator_lib) that unconditionally calls the public start_i3c_controller() before the run loop, following the same local-main pattern as the signer target. Also harden the test itself: - target.rs: drop enable_rx_interrupt() and pure-poll instead; the system image has an empty interrupt table, and a delivered frame would vector the CPU to address zero (observed as a terminal mcause=1 exception at epc=0). - host harness: treat only the firmware's "waiting for private write" log line as readiness (the emulator's socket banner prints minutes before firmware boots), and keep sending frames until the runner exits instead of 15 attempts fired during boot. i3c_smoke_test now passes in ~16s (previously failed after 161s).
The i3c-core TTI expects the descriptor before the data: the TX descriptor write opens the buffer that subsequent tx_data_port writes fill, and the first word written to the IBI port is parsed as the IBI descriptor. The driver had both orders inverted (data first), which panicked the emulator's I3C model on the first tx_write and would have corrupted any IBI with a payload. Matches the upstream caliptra-mcu-sw runtime driver (runtime/kernel/drivers/i3c/src/core.rs). Found by the new i3c_echo test; the smoke test never transmits, so it could not catch this.
Firmware raises an IBI (MDB 0xA5 with a 4-byte payload) on each received private write; the host asserts the MDB arrives over the I3C socket. Gives the descriptor-first ibi_raise() ordering fix behavioral coverage. Only the MDB is asserted: the emulator's IBI model does not yet forward the payload to the controller side (upstream TODO in check_ibi_buffer).
Unlike the polling smoke test, the firmware discovers the frame solely via the TTI RX-descriptor interrupt: IRQ 2 on the VeeR PIC, wired through the pw_kernel interrupt table to a handler that masks the level-triggered enable and flags the main thread. Getting this to work surfaced a real platform gap: the emulated VeeR core delivers external interrupts by jumping through the MEIVT redirect table (which must live in DCCM), but pw_kernel never programs MEIVT. The first external interrupt therefore escalated to a "table not in DCCM" NMI with an unprogrammed vector, sending the CPU to address 0 -- the terminal mcause=1/epc=0 exception originally seen when the smoke test enabled the RX interrupt. The firmware works around it by filling a redirect table in DCCM with the mtvec trap vector before enabling the interrupt; the proper fix belongs in pigweed's veer_pic early_init.
Move the external-interrupt redirect table setup from the i3c_irq test firmware into the kernel where it belongs: veer_pic early_init now fills a target-provided MEIVT table (every entry pointing at the mtvec trap vector, so redirected interrupts take the standard trap path and the claim id is read from MEIHAP) and writes the MEIVT CSR. The table location comes from a new optional MEIVT_BASE_ADDRESS on VeerPicConfigInterface, defaulting to None so other pigweed users are unaffected; target/veer places it at DCCM base 0x50000000 as the VeeR core requires. All veer system images now get working external interrupts, not just the one test that carried the workaround. Candidate for upstreaming to pigweed. Note: syscall_latency still fails with a similar epc=0 signature, but after its measurement completes, in the userspace process exit path -- a separate pw_kernel bug, unrelated to MEIVT.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.