TPM FIFO mode: DATA FIFO (0x24) and INTF_ID (0x30) never returns and rdfifo_aborted gets set
Nobody has claimed this yet.
- Dominant language
- SystemVerilog
- Stars
- 3.6k
- Forks
- 1.1k
- Avg merge
- 2d 22h
- Merged PRs (30d)
- 141
Description
### Description
**Setup**
- IP: `spi_device` TPM FIFO interface (`TPM_CFG = 0x00000001`, return-by-HW enabled, `hw_reg_dis=0`).
- Host: Raspberry Pi (spidev), mode 0, tried 100 Hz to 10 MHz (same result).
- SW on device pre-programs return-by-HW regs, uses polling (no IRQs).
**What works**
- Return-by-HW reads OK:
- `INTF_CAP @ 0x0014`
- `DID_VID @ 0x0F00`
- `RID @ 0x0F04`
**What fails**
- `Read FIFO @ 0x24` : trying to return 4 bytes ### `0xDEADBEEF`.
- `INTF_ID @ 0x30` : SW-handled register never yields data.
**Minimal host repro (Python/spidev)**
```
import spidev
spi = spidev.SpiDev(); spi.open(0,0)
spi.mode = 0
spi.max_speed_hz = 100 # also tried higher up to 10MHz
# Works: DID_VID read (example)
print(bytes(spi.xfer2([0x83, 0xD4, 0x0F, 0x00] + [0]*5)).hex())
# STS says data is available (device sets burstCount=4, stsValid=1, dataAvail=1)
print(bytes(spi.xfer2([0x84, 0xD4, 0x00, 0x18] + [0]*5)).hex())
# Attempt to read DATA FIFO (4 bytes). Tried 0x8C (len=12) and 0x83 (len=4) headers.
print(bytes(spi.xfer2([0x83, 0xD4, 0x00, 0x24] + [0]*N)).hex()) # always zeros (WAIT) 0 < N < 4096
```
**Device FW behavior (snippet)**
```
if (TPM_STATUS.bit0 /* cmdaddr_notempty */) {
uint32_t hdr = mmio_read32(TPM_CMD_ADDR); // observed 0x83D40024
mmio_write32(TPM_READ_FIFO, 0xDEADBEEF); // prime 4 bytes
// Tried both:
// (A) Program TPM_STS = 0x000004D0 (burst=4, stsValid=1, dataAvail=1)
// (B) Do NOT touch TPM_STS (leave as-is)
}
// In both A/B: readback often 0x00000000 first; later I see rdfifo_aborted=1 (bit2).
// INTR_STATE shows 0x00000040 during/after the attempt.
```
**Observed**
- Host sees STS with `burst=4, stsValid=1, dataAvail=1` as expected.
- Reading `DATA FIFO @ 0x24` clocks only `0x00` bytes (WAIT), never a START byte nor payload.
- After the attempt, device’s `TPM_STATUS.rdfifo_aborted` becomes 1.
- `INTF_ID @ 0x30` also returns all zeros (never START/data), despite SW trying to serve it.
**Questions**
1. For a 4-byte read, should the first header byte encode length−1 in the low 6 bits (i.e., 0x83 for 4 bytes) or should it be much longer?
2. Are there additional `TPM_STS` bits required for a plain FIFO read beyond `stsValid=1`, `dataAvail=1`, and `burstCount>=4`?
3. Is there a required ordering with CS# (e.g., SW must prime RDFIFO and set STS before the host’s read header; host must deassert CS between header and data)? With current flow, SW primes after seeing `TPM_CMD_ADDR=0x83D40024`, then host reads in a new transaction, but still only gets WAIT and then `rdfifo_aborted`.
Thanks!
-- Klim
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the provided Python/spidev transactions and trace the TPM_CMD_ADDR, TPM_READ_FIFO, TPM_STS, and INTR_STATE interactions for DATA FIFO and INTF_ID reads. Verify the header length encoding, required status bits, and CS# ordering against the observed WAIT bytes and rdfifo_aborted flag. Done means establishing the required transaction and firmware sequence, or identifying the implementation defect that prevents the expected START byte and payload.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- embedded-iot, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100