-
Notifications
You must be signed in to change notification settings - Fork 13
ot_spi_device,ot_spi_host: Bugfix + Refactoring + Passthrough mode implementation
#255
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ot_spi_device,ot_spi_host: Bugfix + Refactoring + Passthrough mode implementation
#255
Conversation
b7c3b04 to
2e2300b
Compare
2264c77 to
f1a68a2
Compare
f1a68a2 to
6e8f034
Compare
e8ef6d7 to
ad5c39c
Compare
ot_spi_device: Refactoring + Passthrough mode implementationot_spi_device,ot_spi_host: Refactoring + Passthrough mode implementation
ca61a08 to
28ffc3c
Compare
|
I have discovered that OT SPI Device is not the only device controlling this SPI bus, the bus is actually shared by OT SPI Host 0 in Earlgrey, and OT SPI Host is bypassed entirely when Passthrough mode is enabled. This seems to only be documented here. As such this PR has been reworked a bit. |
rivos-eblot
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
quick review.
28ffc3c to
a49e9bf
Compare
a49e9bf to
3a643ee
Compare
ot_spi_device,ot_spi_host: Refactoring + Passthrough mode implementationot_spi_device,ot_spi_host: Bugfix + Refactoring + Passthrough mode implementation
3a643ee to
05aa2a7
Compare
05aa2a7 to
6fc1a21
Compare
|
Just missing some checks in OT SPI Host to inhibit its activity when Passthrough on SPI Device is enabled, which should be a very pathological situation. Otherwise ready for review and nits up to now. |
AlexJones0
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (with 1 additional comment), thanks for all the hard work on this!
| "%s: W/O register 0x%02" HWADDR_PRIx " (%s)\n", __func__, | ||
| addr, SPI_REG_NAME(reg)); | ||
| qemu_log_mask(LOG_GUEST_ERROR, "%s: %s: W/O register 0x%02x (%s)\n", | ||
| __func__, s->ot_id, (uint32_t)addr, SPI_REG_NAME(reg)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can just be fixed in a separate PR (not an issue introduced by this PR, don't want to add even more work), but this should probably be TPM_REG_NAME (@engdoreis)
rivos-eblot
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, however the 80-column rule is broken in a couple of locations:
- Comments can be rewrapped (which implies shortening or splitting a partial URL)
- Macro definitions seem to be mis-managed that with
clang-format-20, alignment takes precedence over line with (despite the settings), so till it is fixed, the best option is to add another/* clang-format off/on */block. I spent a dozen of minutes experiencing different settings but they all fail.
Note:
This PR breaks several of our SPI device unit tests, but I would not bet on them and I have no time at the moment to track down the issue(s) and I do not want to delay this PR any longer.
I'll try to run them on Verilator when possible. This means adding support for the Verilator SPI device protocol. I'm not sure how difficult this could be.
1d723e3 to
d111644
Compare
I'm slightly confused by this - the code looks okay to me and is
Yes, I've seen this before - were there some specific macros that you think @ziuziakowska needs to add
Hmm, that's mildly concerning. For the open source OpenTitan testing, our tests using SPI bootstrapping (e.g. ownership transfer) and the TPM test are all still passing, so it looks good, but it's possible that there's an edge case exercised by your tests that has been missed somewhere (or, like you suggest, the tests might themselves have problems). |
I think the new changes are ok, but some of the existing lines were not: FIELD(FLASH_STATUS, TB, 5u, 1u) /* beware actual bits depend on emulated dev. */
SHARED_FIELD(CMD_INFO_DUMMY_SIZE, 12u, 3u) /* limited to bits, ignore in QEMU */
SHARED_FIELD(CMD_INFO_DUMMY_EN, 15u, 1u) /* only use this bit for dummy cfg */
SHARED_FIELD(CMD_INFO_PAYLOAD_DIR, 20u, 1u) /* not used in Flash mode (guess) */
SHARED_FIELD(CMD_INFO_PAYLOAD_SWAP_EN, 21u, 1u) /* not used in Flash mode */
#define SPI_SRAM_CMD_OFFSET (SPI_SRAM_PAYLOAD_OFFSET + SPI_SRAM_PAYLOAD_SIZE)
* opentitan.org/book/hw/ip/spi_device/doc/programmers_guide.html#dual-port-sram-layout
#define SPI_SRAM_ADDR_END (SPI_SRAM_TPM_WRITE_OFFSET + SPI_SRAM_TPM_WRITE_SIZE)
The block that contains the two
I think that we at least overlooked the default |
|
Beware that at least one commit in the PR does not build ( |
Signed-off-by: Alice Ziuziakowska <[email protected]>
Signed-off-by: Alice Ziuziakowska <[email protected]>
The bit-fields previously used here are just advisory/convention, the whole 22-bit field is RW and software maintained. This is also expected behaviour for spi_passthru_test. Signed-off-by: Alice Ziuziakowska <[email protected]>
The bytes are received over the wire and stored in the buffer most-significant byte first (big-endian), so the dummy byte is the last byte not the first. Signed-off-by: Alice Ziuziakowska <[email protected]>
Expected by spi_passthru_test, see: https://github.com/lowRISC/opentitan/blob/master/sw/host/tests/chip/spi_device/src/spi_passthru.rs#L70-L80 Signed-off-by: Alice Ziuziakowska <[email protected]>
…ALUE Name is more verbose but matches the usage better, as in `ot_spi_host` Signed-off-by: Alice Ziuziakowska <[email protected]>
d111644 to
74767fc
Compare
This commit simplifies command slot definitions and the associated state and control flow. The HW CFG and the HW STA commands have been combined into just HW commands, as in flash mode they are handled in hardware by some way and should therefore share the same data path. For passthrough mode, a subset of these HW commands can be intercepted (all except for WREN and WRDI). As the matched command slot number determines whether the command is a SW or HW command, the `OtSpiFlashCommand` enum has been removed in favour of using `is_sw_command` to return the boolean. Command slot matching has been brought out into its own function, `match_command_slot`, which returns whether an opcode was matched in the command info registers. The decoded slot number is only valid if this returns true. Also a bug is fixed in `ot_spi_device_exec_command` where hardcoded opcodes for read commands were used instead of the opcodes in the associated command slot. Signed-off-by: Alice Ziuziakowska <[email protected]>
Signed-off-by: Alice Ziuziakowska <[email protected]>
... and removes `OtSpiDeviceAddrMode`. `ot_spi_device_get_command_address_size` now returns the size of the address field in the current command, using the value in `cmd_info` and the current 4B enable state. Signed-off-by: Alice Ziuziakowska <[email protected]>
Log the `ot_id`, and remove usages of `HWADDR_PRIx` Signed-off-by: Alice Ziuziakowska <[email protected]>
Signed-off-by: Alice Ziuziakowska <[email protected]>
This implements a passthrough enable and chip select IRQ and a method to interact with the downstream SPI bus, for use by upstream SPI Device. Signed-off-by: Alice Ziuziakowska <[email protected]>
This adds the corresponding out IRQs to OT SPI Device, as well as a property that contains the downstream OT SPI Host. Signed-off-by: Alice Ziuziakowska <[email protected]>
…IRQs Signed-off-by: Alice Ziuziakowska <[email protected]>
This commit implements the Passthrough mode on SPI Device. Passthrough mode allows the device to act as a proxy for a downstream flash device, optionally intercepting commands to send back its own values, filtering commands sent downstream, or transparently translating address and payload bytes. This also "implements" the Disabled mode, which discards all bytes sent to the device. Signed-off-by: Alice Ziuziakowska <[email protected]>
Signed-off-by: Alice Ziuziakowska <[email protected]>
74767fc to
5059dc5
Compare
|
Fixed any failing-to-build commits. |
Thanks for the changes and the work on the SPI device. |
|
Failing regression tests on this PR ( |
This PR implements the Passthrough mode for OT SPI Device and any required changes in OT SPI Host. Passthrough mode allows for external SPI transfers to be passed through to a downstream device, and optionally intercepted or modified by OT SPI Device.
In HW, OT SPI Device and OT SPI Host are linked by their SPI bus and a wire that represents whether the Device is in Passthrough mode. If Passthrough mode is enabled, the SPI Host is entirely bypassed and SPI Device has full control over the bus, which it uses to talk to the same downstream flash as SPI Host. See Documentation reference, RTL.
This passthrough mechanism is only implemented by OT SPI Host if it has one CS line: RTL
The structure of the PR is as follows:
ot_spi_devicefor the Passthrough implementation.ot_spi_host- two GPIOs are used to communicate Passthrough enabled and the Chip Select as driven by OT SPI Device, OT SPI Device and OT SPI Host are then linked together.ot_spi_device.I have tried to handle most corner-cases I can think of, but some conflicting configuration options might not behave as expected.
Unimplemented features:
Testing:
This implementation has been tested against
spi_passthru_test. See lowRISC/opentitan#28649 for the changes required in OpenTitan. To test manually the steps are:dd if=/dev/zero of=<flash> bs=1M count=32spi_passthru_test, with these additional flags:-global ot-earlgrey-board.spiflash0=w25q256 -drive if=mtd,file=<flash>,format=raw,bus=0