I3C target overview¶
This chapter provides a high level overview of the I3C target functionalities implemented in the core.
Configuration script¶
The I3C Core is configured with the i3c_core_config Python script, which reads configurations from the i3c_core_configs.yaml YAML file.
The supported configurations can be found in the i3c_core_configs.yaml file.
More details on the usage of the tool can be found in the relevant README.
System Bus¶
The I3C core can connect to system buses via dedicated adapters:
AXI4
AHB - The AHB-Lite implementation is based on the AMBA 3 AHB-Lite Protocol Specification (IHI0033A)
Virtual target¶
The I3C core implements the Secure Firmware Recovery protocol according to the Open Compute “Secure Firmware Recovery” specification rev. 1.1-rc5.
For this purpose, the I3C core exposes a “virtual” target with its own static and dynamic bus addresses.
The virtual target implementation shares most of its logic with the “main” one while retaining a distinct data path.
Certain CCC commands like SETAASA and SETDASA are implemented separately for the “main” and “virtual” targets.
Register descriptions¶
Register descriptions are specified in the RDL format for I3C core CSRs:
I3C Capability and Operational Registers (I3CBase)
Programmable I/O (PIOControl)
Extended Capabilities (I3C_EC)
Device Address Table (DAT)
Device Characteristic Table (DCT)
The RDL files generate the relevant SystemVerilog which can be found in the src/csr/ directory. The auto-generated descriptions are included in the Register descriptions chapter.
Target Interface Queues¶
There are also target interface queues via Target Transaction Interface (TTI):
RX - read descriptor & data queues
TX - write descriptor & data queues
IBI - IBI combined descriptor + data queue
Target recovery interface¶
Several functionalities related to the recovery interface have been implemented for Caliptra:
Recovery mode enable control via a CSR field
Hardware recovery packet handling (private read/write)
Hardware PEC checksum calculation and checking
Access to Recovery CSRs from the I3C side
Status signaling via output pins:
recovery_payload_available_orecovery_image_activated_o
Address Behavior¶
Dynamic and Static Address Priority¶
Per the I3C specification, once a Target has been assigned a Dynamic Address (via ENTDAA, SETDASA, SETAASA, or SETNEWDA), it shall stop responding to its Static Address. The core implements this as follows:
If
DYNAMIC_ADDR_VALID = 1, the Target matches only onDYNAMIC_ADDRIf
DYNAMIC_ADDR_VALID = 0andSTATIC_ADDR_VALID = 1, the Target matches onSTATIC_ADDR
This rule applies independently to both the main target and the virtual target.
IBI Address¶
When sending In-Band Interrupts, the Target uses a separate IBI address derived from the main (non-virtual) target’s address with dynamic-over-static priority:
If the Dynamic Address is valid, the IBI address is the Dynamic Address.
Otherwise, the IBI address falls back to the Static Address.
This is implemented in configuration.sv:
assign target_ibi_addr_o = target_dyn_addr_valid_o ? target_dyn_addr_o : target_sta_addr_o;
assign target_ibi_addr_valid_o = target_sta_addr_valid_o || target_dyn_addr_valid_o;
IBI transmission is gated on target_ibi_addr_valid. If neither address is valid,
target_ibi_addr_valid is deasserted and any pending IBI requests are effectively masked
(the ibi_pending signal in i3c_target_fsm.sv requires target_ibi_addr_valid_i).
Virtual Target Addressing¶
The virtual target (used for recovery) has its own independent address pair
(VIRT_STATIC_ADDR, VIRT_DYNAMIC_ADDR) with the same dynamic-over-static priority rule.
Both the main and virtual target addresses are checked in parallel on every incoming
transaction. When the virtual target address matches, the virtual_device_sel signal
routes the data path to the recovery handler, and TTI queue interrupts are gated.
Private reads and writes¶
The core handles I3C private reads and writes
This functionality passes Avery test suite tests
Private writes push data to the TTI RX Queue, accessible from the AXI bus, allowing the CPU to read the data
The number of received bytes is written into the TTI RX descriptor Queue
The software is supposed to first read the descriptor data, and then the number of bytes defined by the descriptor for the TTI RX Queue
Private reads send data on I3C lines from TTI TX Queue
The software has to write the TTI TX Queue prior to a I3C private read transaction
The TTI TX descriptor is used similarly to set the max number of bytes to be sent in the next private read transaction
In-Band Interrupts (IBI)¶
The core is capable of raising In-Band Interrupts. IBIs are controlled using descriptors written to a dedicated IBI queue by software. Optional IBI data immediately follows the descriptor in the same queue.
The core watches the IBI queue for a descriptor write. Once a descriptor is written, the core peeks it and waits until the defined count of data words is written to the queue. Finally, the core outputs the Mandatory Data Byte (MDB) and the data as 8-bit words.
I3C Common Command Codes (CCC)¶
The I3C core supports all CCCs required by the I3C Basic spec. See I3C Common Command Codes (CCC) for the full list of supported CCCs, CCCs that update registers without firmware notification, and CCC error handling.
Other features¶
Target Reset Pattern is detected and causes assertion of output pins, based on the action selected with RSTACT:
peripheral_reset_oescalated_reset_o
The core correctly detects HDR-Exit Pattern
Optional 60 us HDR error recovery timer for TE0/TE1 error recovery (see Error Detection and Recovery)
Target error detection (TE0-TE5) with interrupt reporting and saturating counters (see Error Detection and Recovery)