Skip to content

Conversation

ziuziakowska
Copy link

@ziuziakowska ziuziakowska commented Sep 18, 2025

This is an I2C device that allows external software such as opentitantool to communicate with and issue commands to devices on a QEMU I2C bus. The communication is done through a socket chardev.

See docs/i2c_transport.md for usage and wire protocol information.

The device can be instantiated with these command line parameters:

-chardev socket,id=i2c0tp,path=i2c0tp,server=on,wait=off -device ot-i2c-transport,bus=ot-i2c0,chardev=i2c0tp, to instantiate on Earlgrey bus ot-i2c0.

The intention is to use opentitantool to write to the socket and issue transactions, but for testing netcat can be used for manually providing commands using the protocol.

@ziuziakowska ziuziakowska force-pushed the ot_i2c_transport branch 2 times, most recently from 4aa1651 to c990a45 Compare September 18, 2025 15:33
{
(void)data;

DeviceClass *dc = DEVICE_CLASS(klass);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably need reset handler(s) to reinitialize your state machine, FIFO, ...

@ziuziakowska ziuziakowska force-pushed the ot_i2c_transport branch 4 times, most recently from e89e6b2 to d0289a0 Compare September 23, 2025 11:43
@ziuziakowska ziuziakowska changed the title [DRAFT, WIP] I2C transport device for Opentitantool I2C transport device for Opentitantool Sep 23, 2025

`-chardev socket,id=i2ctp,file=<name>,server=on,wait=off -device ot-i2c-transport,bus=<bus>,chardev=i2ctp`

Where `bus` is any of the OpenTitan Earlgrey I2C buses: `ot-i2c0`, `ot-i2c1`, or `ot-i2c2`.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be rather add a reference to EG and DJ machines, as several OT machines use I2C buses, which may have different naming / count, so it is probably better to move machine specific details to machine documentation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a note that these names are for EG. I do not know what the DJ I2C bus name is.

I think this will need a fix as in EG the devices have a OT_COMMON_DEV_ID property that is used to construct the name of the bus in ot_i2c. This property is not present in the DJ instantiation.

}

switch (event) {
case I2C_START_SEND:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate why SEND_ASYNC could not work with OT_I2C_TRANSPORT?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it should, but I do not know what the difference is between SEND and SEND_ASYNC in QEMU. I chose to use SEND for write transactions because it appears that SEND_ASYNC is a newer interface which might not be supported by all bus devices.


* All bytes values are encoded as a pair of case-insensitive ASCII hex digits. For example, decimal 161 is encoded as either `A1` or `a1`.

* End of a command is indicated with an `S`, this ends the transaction.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not know the capability of the OT I2C target mode capabilities, but how the restart are handled?

e.g. in I2C: W A R A S
with:

  • W: write
  • R: read
  • A: address
  • S: stop

BTW not sure to understand how ACK/NACK signalling is handled

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at it again, I think there is actually a way to perform something of a "repeated-start condition" and change the transfer direction without ever releasing the bus. I will rework the command parser to allow for this.

In QEMU's I2C implementation, send to write a byte of data to a device can NACK by returning a non-zero value. event can also NACK a start event. All other event and transfer types such as recv and send_async must succeed. In those cases the special !! value is returned instead of any data.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should'nt the protocol over the socket closely stick to the I2C protocol? I'm not sure I have a clear mental picture of the I2C data exchange over the socket vs. a real I2C bus. Maybe it is the case. I think it would be nice to have a short doc (ASCII doc in MD file?) to depict the I2C transport protocol over the socket vs. the physical I2C protocol.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the protocol slightly. Transactions now start with an address byte and then a R or W for the direction - this is a start condition. After that bytes can be written or read once started, and the transaction can change direction any number of times after that using additional Rs and Ws for a repeated-start condition. The transaction is stopped with an S.

This is a pretty thin wrapper around the raw I2C functions, but I do not think there is much we can do to make it more robust (e.g, QEMU's I2C implementation does not support multiple controllers at once, and there is nothing stopping anyone with access to the bus from ending any transfer with i2c_end_transfer including ones they are not part of, so these behaviours are undefined by us.)

The intention of this device is to be an I2C host device that is driven
externally by OpenTitanTool. It will be used to issue read and write
operations to other I2C devices on its bus - of primary interest is
issuing commands to the OpenTitan I2C host/target block.

This "bus device" is present on the bus, but it cannot be interacted
with by other bus devices and cannot have transactions targetting it.

Signed-off-by: Alice Ziuziakowska <[email protected]>
Needed for `ot_i2c_transport` to be able to communicate with `ot_i2c`
in target mode.

Signed-off-by: Alice Ziuziakowska <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants