Skip to content

Commit

Permalink
deploy: 2b0b1ad
Browse files Browse the repository at this point in the history
  • Loading branch information
mczyz-antmicro committed Sep 10, 2024
1 parent 6be7a67 commit 38029bf
Show file tree
Hide file tree
Showing 27 changed files with 1,305 additions and 185 deletions.
Binary file added _images/i3c_csr_rd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/i3c_csr_wr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/recovery_handler.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/recovery_handler_bd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 16 additions & 16 deletions _sources/ci_queues.md.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,32 @@ Controller Interface queues consist of:
Controller Interface queues are depth-configurable with the [I3C Configuration](config.md#configuring-the-i3c-core).

Queues generate several status indicators that will be used to trigger appropriate interrupts:
* `*_fifo_empty_` - no elements are enqueued in corresponding FIFO.
* `*_fifo_empty_` - no elements are enqueued in the corresponding FIFO.
* `*_fifo_full_` - `*_FIFO_DEPTH` are enqueued in the corresponding FIFO.
* `*_fifo_apch_thld_` - the user-defined threshold has been reached. <!-- TODO: name will be changed -->

## Queue threshold
Command and response queue thresholds are controlled via [QUEUE_THLD_CTRL](https://github.com/chipsalliance/i3c-core-rdl/blob/4028ed29254aefdbe9c805e8bfaa275e200994ba/src/rdl/pio_registers.rdl#L44) register.
Command and response queue thresholds are controlled via the [QUEUE_THLD_CTRL](https://github.com/chipsalliance/i3c-core-rdl/blob/4028ed29254aefdbe9c805e8bfaa275e200994ba/src/rdl/pio_registers.rdl#L44) register.
RX and TX data queue thresholds are controlled via [DATA_BUFFER_THLD_CTRL](https://github.com/chipsalliance/i3c-core-rdl/blob/4028ed29254aefdbe9c805e8bfaa275e200994ba/src/rdl/pio_registers.rdl#L75).

### Command queue threshold
* The threshold for command queue is set by a write to the `QUEUE_THLD_CTRL` to the 8-bit `CMD_EMPTY_BUF_THLD` field.
* The threshold `N` of range `<1, 255>` (inclusive) will cause an `CMD_QUEUE_READY_STAT` interrupt when there's `N` or more remaining empty entries left in the command queue.
* If the `N` value is greater than the size of the command queue (`CMD_FIFO_DEPTH`) the full depth will be considered (the threshold will be set to `CMD_FIFO_DEPTH`).
* The threshold for command queue is set by a write to the 8-bit `CMD_EMPTY_BUF_THLD` field of the `QUEUE_THLD_CTRL` register.
* The `N` threshold of `<1, 255>` range (inclusive) will cause an `CMD_QUEUE_READY_STAT` interrupt when there's `N` or more remaining empty entries in the command queue.
* If the `N` value is greater than the size of the command queue (`CMD_FIFO_DEPTH`), the full depth will be considered (the threshold will be set to `CMD_FIFO_DEPTH`).

### Response queue threshold
* The threshold for response queue is set by a write to `QUEUE_THLD_CTRL` to the 8-bit `RESP_BUF_THLD` field.
* The threshold `N` of range `<1, 255>` (inclusive) will cause an `RESP_READY_STAT` interrupt when there's `N` or more responses enqueued in the response queue.
* If the `N` value is greater or equal than the size of the response queue (`RESP_FIFO_DEPTH`) the full depth will be considered (the threshold will be set to `RESP_FIFO_DEPTH - 1`)
### Response queue threshold
* The threshold for response queue is set by a write to the 8-bit `RESP_BUF_THLD` field of the `QUEUE_THLD_CTRL` register.
* The `N` threshold of `<1, 255>` range (inclusive) will cause an `RESP_READY_STAT` interrupt when there's `N` or more responses enqueued in the response queue.
* If the `N` value is greater or equal than the size of the response queue (`RESP_FIFO_DEPTH`), the full depth will be considered (the threshold will be set to `RESP_FIFO_DEPTH - 1`)

### TX queue threshold
* The threshold for the TX queue is set by a write to `DATA_BUFFER_THLD_CTRL` to the 3-bit `TX_BUF_THLD` field.
* The threshold `N` of range `<0, 7>` (inclusive) will trigger an `TX_THLD_STAT` interrupt when `2^(N+1)` (`2` to the power of `N+1`) `DWORD` empty entries are available in the TX queue.
* The software must provide an `N` value that corresponds to the threshold less or equal than `TX_FIFO_DEPTH`, otherwise the `clog2(TX_FIFO_DEPTH) - 1` will be applied.
* The threshold for the TX queue is set by a write to the 3-bit `TX_BUF_THLD` field of the `DATA_BUFFER_THLD_CTRL` register.
* The `N` threshold of `<0, 7>` range (inclusive) will trigger an `TX_THLD_STAT` interrupt when `2^(N+1)` (`2` to the power of `N+1`) empty `DWORD` entries are available in the TX queue.
* The software must provide an `N` value that corresponds to the threshold less or equal than `TX_FIFO_DEPTH`, otherwise `clog2(TX_FIFO_DEPTH) - 1` will be applied.

### RX queue threshold
* The threshold for the RX queue is set by a write to `DATA_BUFFER_THLD_CTRL` to the 3-bit `RX_BUF_THLD` field.
* The threshold `N` of range `<0, 7>` (inclusive) will trigger an `RX_THLD_STAT` interrupt when `2^(N+1)` (`2` to the power of `N+1`) `DWORD` entries are enqueued in the RX queue.
* The software must provide an `N` value that corresponds to the threshold less than `RX_FIFO_DEPTH`, otherwise the `clog2(RX_FIFO_DEPTH) - 2` will be applied.
* The threshold for the RX queue is set by a write to the 3-bit `RX_BUF_THLD` field of the `DATA_BUFFER_THLD_CTRL` register.
* The `N` threshold of `<0, 7>` range (inclusive) will trigger an `RX_THLD_STAT` interrupt when `2^(N+1)` (`2` to the power of `N+1`) `DWORD` entries are enqueued in the RX queue.
* The software must provide an `N` value that corresponds to the threshold less than `RX_FIFO_DEPTH`, otherwise `clog2(RX_FIFO_DEPTH) - 2` will be applied.

All queues utilize [caliptra_prim_fifo_sync.sv](https://github.com/chipsalliance/caliptra-rtl/blob/9c815c335a92901b27458271a885b2128e51e687/src/caliptra_prim/rtl/caliptra_prim_fifo_sync.sv#L9) fifo implementation.
All queues utilize the [caliptra_prim_fifo_sync.sv](https://github.com/chipsalliance/caliptra-rtl/blob/9c815c335a92901b27458271a885b2128e51e687/src/caliptra_prim/rtl/caliptra_prim_fifo_sync.sv#L9) FIFO implementation.
6 changes: 3 additions & 3 deletions _sources/dv.md.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Design verification

This chapter presents available models and tools, which are used for I3C verification.
The core is verified with [the Cocotb/Verilator + unit tests](../../verification/block) and [the UVM test suite](../../verification/uvm_i3c/).
This chapter presents the available models and tools which are used for I3C verification.
The core is verified with [the Cocotb/Verilator + unit tests](../../verification/cocotb/block) and [the UVM test suite](../../verification/uvm_i3c).

## Verification plan

The verification plan is [here](../../verification/uvm_i3c/testplan.hjson).
The verification plans can be found [here](../../verification/uvm_i3c).
2 changes: 1 addition & 1 deletion _sources/ext_cap.md.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ This specification provides definitions and descriptions of the following Capabi

The Controller Config Capability follows section 7.7.3 of the [I3C HCI Specification](introduction.md#spec-i3c-hci).

### Secure Firmware Recovery Interface (ID=0xC0)
### <a name="secure_firmware_recovery_interface"/>Secure Firmware Recovery Interface (ID=0xC0)

This section is based on the Open Compute Project Secure Firmware Recovery, Version 1.0 and I3C Target Recovery Specification

Expand Down
1 change: 1 addition & 0 deletions _sources/index.md.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ normal_operation
:maxdepth: 2

ext_cap
recovery_flow
```

```{toctree}
Expand Down
8 changes: 4 additions & 4 deletions _sources/introduction.md.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Introduction

This document describes the open-source I3C Basic controller.
This document describes the open source I3C Basic controller.
The scope of the project includes:
* Secondary Controller Mode
* Active Controller Mode
Expand All @@ -10,15 +10,15 @@ The scope of the project includes:
Secondary Controller Mode with generic TX/RX transfers can serve the same role as an I3C Target Device with support for Legacy I2C communication.
```

The I3C Core provides a Controller Interface, which is developed in compliance with:
The I3C Core provides a Controller Interface which is developed in compliance with:
* <a name="spec-i3c-basic"></a>MIPI Alliance Specification for I3C Basic, Version 1.1.1
* <a name="spec-i3c-hci"></a>MIPI Alliance Specification for I3C HCI, Version 1.2
* <a name="spec-i3c-tcri"></a>MIPI Alliance Specification for I3C TCRI, Version 1.0

Specification documents can be obtained directly from [MIPI website](https://www.mipi.org/specifications/i3c-hci), however, a login with MIPI Alliance account is required.
The specification documents can be obtained directly from the [MIPI website](https://www.mipi.org/specifications/i3c-hci), however, a login with a MIPI Alliance account is required.

Some terminology of the MIPI Alliance Specifications carry over to this documentation and requires additional context:
* `Active Controller Mode` is the mode, in which the I3C Core initiates transfers on the I3C bus and is primarily responsible for bus initialization and management
* `Active Controller Mode` is the mode in which the I3C Core initiates transfers on the I3C bus and is primarily responsible for bus initialization and management
* `Secondary Controller Mode` is the mode, in which the I3C Core joins the I3C Bus as a Target Device and is conditionally responsible for specific bus management tasks
* `Secondary Controller Mode` and `Standby Controller Mode` are used interchangeably
* `Controller Interface` and `Host Controller Interface` are used interchangeably
Expand Down
102 changes: 102 additions & 0 deletions _sources/recovery_flow.md.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Recovery flow

The recovery flow is implemented according to OCP Secure Firmware Recovery standard v1.1-rc3.
In recovery mode, the I3C Core acts as an I3C Target Device.
In the Recovery Mode the Recovery Initiator Device (e.g. BMC) is primarily responsible for streaming the Firmware Recovery Image to the I3C Core.
In order to facilitate this process, the I3C Core implements CSRs as specified in the [Secure Firmware Recovery Interface](ext_cap.md#secure_firmware_recovery_interface).
The firmware is responsible for implementing the recovery flow and transfering firmware data to the program memory.

The recovery flow adheres to the following steps:

1. Upon reset the hardware sets FIFO size and region type in the `INDIRECT_FIFO_STATUS` CSR
2. The device's firmware configures the I3C core and sets appropriate bits in `PROT_CAP` CSR to indicate its recovery capabilities
These must include the mandatory ones:
- bit 0 (`DEVICE_ID`)
- bit 4 (`DEVICE_STATUS`)
- bit 6 (`Local C-image support`) or bit 7 (`Push C-image support`)
- bit 5 (`INDIRECT_CTRL`) only if bit 7 is set
2. Upon request for recovery mode entry, the firmware writes 0x3 (Recovery mode) to `DEVICE_STATUS`
:::{note}
What actually triggers the recovery mode?
:::
3. The Recovery Handler writes 0x1 (Awaiting recovery image) to `RECOVERY_STATUS` and sets recovery image index to 0
4. The Recovery Initiator writes to `INDIRECT_FIFO_CTRL` to inform the Recovery handler about the image size
- Component Memory Space (`CMS`) field is set to 0
5. The Recovery Initiator writes a data chunk to the receive fifo via `INDIRECT_FIFO_DATA` CSR.
The I3C core responds with a NACK in case when the FIFO is full.
6. The Recovery Handler updates FIFO pointers (Read Index and Write Index) presented in `INDIRECT_FIFO_STATUS` CSR
7. The device's firmware reacts to a signal (interrupt, CSR poll?) that a data chunk has been written to the FIFO
8. The device's firmware reads the data chunk from the FIFO and stores it in appropriate location in memory
9. Steps 5 to 8 are repeated until the Recovery handler detects that the whole firmware image has been transmitted
10. The device's firmware polls `RECOVERY_CONTROL` register until it receives the "Activate image" command from the Recovery Initiator
11. The device's firmware updates the `RECOVERY_STATUS` CSR to indicate that the uploaded firmware is being booted

## Recovery handler

Since the OCP Secure Firmware Recovery standard describes a set of CSRs that are the interface between the device being updated and the Recovery Initiator, I3C transactions that implement accessing them must be handled in logic instead of firmware which is the purpose of the Recovery Handler block.

When the recovery mode is active the handler takes over the TTI interface of the controller effectively detaching it from TTI CSRs.
![](img/recovery_handler.png)

The architecture of the Recovery Handler module is shown in the block diagram below:
![](img/recovery_handler_bd.png)

The module's backend is connected directly to the controller's TTI interface.
There are several muxes on RX and TX data paths which allow bypassing the module in normal operation mode and remove/inject data in recovery mode.
There are two `PEC` (Packet Error Code) blocks responsible for calculating CRC for RX and TX data paths.
The CRC algorithm operates on individual bytes and implements C(x) = x^8+x^2+x^1+1 polynomial (see MCTP I3C binding, section 5.3.1).
The frontend is connected to I3C core CSRs accessible by software.

### Normal operation

When recovery mode is inactive switches `R4SW`, `T4SW` are closed and all muxes are set to form a direct path between controller's TTI interface, TTI queues and TTI CSRs.

### Recovery operation

In recovery mode switches `R4SW` and `T4SW` are open and muxes `R4MUX` and `T4MUX` connect TTI queues frontend to recovery CSRs (`INDIRECT_FIFO`). Apart from the muxes, there's additional logic that controls when data can be accessed through `INDIRECT_FIFO` interface.

## CSR access via I3C

Recovery mode CSRs are accessible through I3C bus. The following protocol is used to implement read/write operations:

### CSR Write
![](img/i3c_csr_wr.png)

The Recovery Initiator sends command byte followed by 16-bit payload length LSB and MSB bytes using I3C private transfers.
Payload data bytes follow ended by a Packet Error Code (PEC) checksum.

### CSR Read
![](img/i3c_csr_rd.png)

For CSR read the Recovery Initiator sends only the command byte and PEC checksum.
Next, it issues a repeated start and begins a private read transaction.
The device responds by sending data length LSB and MSB bytes followed by the data and PEC.

## Recovery handler operation

The main job of the Recovery Handler is providing hardware means for an active controller to access CSRs relevant to recovery operation.

### CSR write

When the Recovery Initiator tries to write to a CSR through I3C it first sends the command byte followed by two length bytes which are received by the handler logic.
If the length is non-zero the handler resets the `PEC` block and sets `R2MUX` to pass the remaining data to TTI RX data queue.
The `R2MUX` disconnects the queue just before the last byte which is the PEC checksum.
Finally, The last byte is compared with the checksum computed by the `PEC` block.

If the checksum matches the command handling part of the handler logic reads data from the TTI RX data queue and updates relevant CSR fields.

If the checksum does not match then the handler discards all the data in the queue.

In case of an `INDIRECT_FIFO_DATA` write command the handler does not process the data at all. Instead it opens `R3MUX` to make it available to the software.
When the software reads data from `INDIRECT_FIFO_DATA` CSR the handler updates the queue pointer in `INDIRECT_FIFO_STATUS` CSR.

### CSR read

A CSR read begins similarly as write by receiving the command byte.
Following that, the command handling part reads data from the CSR being read and passes it to the transmit part which formats the response I3C packet.

The transmit logic injects CSR length, resets TX `PEC` module, sends the CSR content to the I3C core and finally injects the calculated PEC checksum.

:::{note}
TODO: Handle `INDIRECT_FIFO_DATA` read. This is not a priority as firmware write is more important than readback.
:::
20 changes: 10 additions & 10 deletions _sources/timings.md.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

In this chapter we present:
* the SoC Management Interface
* implemented oversampling of the I3C signals
* implemented driver
* the implemented oversampling of the I3C signals
* the implemented drivers

The I3C Core exposes control over the electrical and timing configurations via [the SoC Management Interface](../../src/rdl/soc_management_interface.rdl).

```{note}
Current numbers are not final and subject to change. Reserved for future.
Current numbers are not final and are subject to change. Reserved for future.
```

## Clock speed and oversampling
Expand All @@ -31,20 +31,20 @@ In Active Controller Mode:

## Open-drain vs Push-pull configuration

The I3C controller uses both Open-Drain and Push-Pull drivers and different timings are used for them.
The I3C controller uses both Open-Drain and Push-Pull drivers, and different timings are used for them.
The Open-Drain and Push-Pull drivers are both used within one I3C Frame.

## Rise and fall times

Driver strength can be adjusted by setting correct values in the I3C Pad Attribute Configuration Register.
The minimum allowed rise/fall times are: `150e6*bus_period`, which is 12 ns for the 12.5 MHz bus.
When calculating timings it is worth to include all falling edges in the LOW state.
The minimum allowed rise/fall times are `150e6*bus_period`, which is 12 ns for the 12.5 MHz bus.
When calculating timings, it is worth including all falling edges in the LOW state.
Similarly, all the rising edges are part of the HIGH state.
This is because we will flip the bit in the internal implementation at the start of t{sub}`CR,CF` and then the actual rise/fall time will occur naturally.

## Timing control registers

The SoC Management Interface defines the following registers, which can be used for timing control:
The SoC Management Interface defines the following registers which can be used for timing control:
* `T_R_REG`
* `T_F_REG`
* `T_SU_DAT_REG`
Expand All @@ -58,9 +58,9 @@ The SoC Management Interface defines the following registers, which can be used
* `T_AVAL_REG`
* `T_IDLE_REG`

Value of each of these registers expresses time delay, expressed in the I3C clock period.
Default values are provided for the 500MHz clock.
A python script [timing.py](../../tools/timing/timing.py) is provided to recalculate values for higher clock frequencies.
The value of each of these registers expresses time delay, expressed in the I3C clock period.
The default values are provided for the 500MHz clock.
The [timing.py](../../tools/timing/timing.py) Python script is provided to recalculate values for higher clock frequencies.

### Rise/fall Time Register
### Setup Time Register
Expand Down
Loading

0 comments on commit 38029bf

Please sign in to comment.