Skip to content

Commit 9ef37a1

Browse files
committed
[ot] hw/opentitan: ot_spi_device: Update the SRAM definition
Based on the table in the spi_device/doc/programmers_guide Signed-off-by: Douglas Reis <[email protected]>
1 parent 81955d4 commit 9ef37a1

File tree

1 file changed

+86
-59
lines changed

1 file changed

+86
-59
lines changed

hw/opentitan/ot_spi_device.c

Lines changed: 86 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,12 @@
4444
#include "trace.h"
4545

4646
#define PARAM_SRAM_DEPTH 1024u
47-
#define PARAM_SRAM_OFFSET 4096u
48-
#define PARAM_SRAM_EGRESS_DEPTH 832u
49-
#define PARAM_SRAM_INGRESS_DEPTH 104u
47+
#define PARAM_SRAM_EGRESS_DEPTH 848u
48+
#define PARAM_SRAM_INGRESS_DEPTH 112u
5049
#define PARAM_NUM_CMD_INFO 24u
5150
#define PARAM_NUM_LOCALITY 5u
52-
#define PARAM_TPM_WR_FIFO_PTR_W 7u
53-
#define PARAM_TPM_RD_FIFO_PTR_W 5u
54-
#define PARAM_TPM_RD_FIFO_WIDTH 32u
51+
#define PARAM_TPM_RD_FIFO_DEPTH 16u
52+
#define PARAM_TPM_WR_FIFO_DEPTH 16u
5553
#define PARAM_NUM_IRQS 8u
5654
#define PARAM_NUM_ALERTS 1u
5755
#define PARAM_REG_WIDTH 32u
@@ -235,6 +233,8 @@ REG32(TPM_WRITE_FIFO, 0x38u)
235233

236234
#define SPI_BUS_PROTO_VER 0
237235
#define SPI_BUS_HEADER_SIZE (2u * sizeof(uint32_t))
236+
#define SPI_TPM_READ_FIFO_SIZE_BYTES \
237+
(PARAM_TPM_RD_FIFO_DEPTH * sizeof(uint32_t))
238238
/**
239239
* Delay for handling non-aligned generic data transfer and flush the FIFO.
240240
* Generic mode is deprecated anyway. Arbitrarily set to 1 ms.
@@ -251,62 +251,84 @@ REG32(TPM_WRITE_FIFO, 0x38u)
251251
*/
252252
#define SPI_BUS_FLASH_READ_DELAY_NS 100000000u
253253

254-
/*
255-
* New scheme (Egress + Ingress) Old Scheme (DPSRAM)
256-
* +-----------------------------+ +-----------------------+
257-
* | Flash / Passthru modes | | Flash / Passthru modes|
258-
* 0x000 -+----------------+------+-----+ -+----------------+------+
259-
* | Read Command 0 | 1KiB | Out | | Read Command 0 | 1KiB |
260-
* 0x400 -+----------------+------+-----+ -+----------------+------+
261-
* | Read Command 1 | 1KiB | Out | | Read Command 1 | 1KiB |
262-
* 0x800 -+----------------+------+-----+ -+----------------+------+
263-
* | Mailbox | 1KiB | Out | | Mailbox | 1KiB |
264-
* 0xc00 -+----------------+------+-----+ -+----------------+------+
265-
* | SFDP | 256B | Out | | SFDP | 256B |
266-
* 0xd00 -+----------------+------+-----+ -+----------------+------+
267-
* | | | Payload FIFO | 256B |
268-
* 0xe00 -+----------------+------+-----+ -+----------------+------+
269-
* | Payload FIFO | 256B | In | | Command FIFO | 64B |
270-
* 0xe40 -+----------------+------+-----+ -+----------------+------+
271-
* | Command FIFO | 64B | In | | Address FIFO | 64B |
272-
* 0xe80 -+----------------+------+-----+ -+----------------+------+
273-
* | Address FIFO | 64B | In |
274-
* 0xe80 -+----------------+------+-----+
254+
/* Memory layout extracted from the documentation:
255+
* opentitan.org/book/hw/ip/spi_device/doc/programmers_guide.html#dual-port-sram-layout
275256
*
257+
* New scheme (Egress + Ingress) Old Scheme (DPSRAM)
258+
* +--------------------------------+ +-----------------------+
259+
* | Flash / Passthru modes | | Flash / Passthru modes|
260+
* 0x000 -+-------------------+------+-----+ -+----------------+------+
261+
* | Read Command 0 | 1KiB | Out | | Read Command 0 | 1KiB |
262+
* 0x400 -+-------------------+------+-----+ -+----------------+------+
263+
* | Read Command 1 | 1KiB | Out | | Read Command 1 | 1KiB |
264+
* 0x800 -+-------------------+------+-----+ -+----------------+------+
265+
* | Mailbox | 1KiB | Out | | Mailbox | 1KiB |
266+
* 0xc00 -+-------------------+------+-----+ -+----------------+------+
267+
* | SFDP | 256B | Out | | SFDP | 256B |
268+
* 0xd00 -+-------------------+------+-----+ -+----------------+------+
269+
* | TPM Read Buffer | 64B | Out | | Payload FIFO | 256B |
270+
* 0xd40 -+-------------------+------+-----+ -+----------------+------+
271+
* | | | | | Command FIFO | 64B |
272+
* 0xe00 -+-------------------+------+-----+ -+----------------+------+
273+
* | Payload FIFO | 256B | In | | Address FIFO | 64B |
274+
* 0xf00 -+-------------------+------+-----+ -+----------------+------+
275+
* | Command FIFO | 64B | In |
276+
* 0xf40 -+-------------------+------+-----+
277+
* | Address FIFO | 64B | In |
278+
* 0xf80 -+-------------------+------+-----+
279+
* | TPM Write Buffer | 64B | In |
280+
* 0xfc0 -+-------------------+------+-----+
276281
*
277282
*/
278283
#define SPI_SRAM_READ0_OFFSET 0x0
279284
#define SPI_SRAM_READ_SIZE 0x400u
285+
280286
#define SPI_SRAM_READ1_OFFSET (SPI_SRAM_READ0_OFFSET + SPI_SRAM_READ_SIZE)
281287
#define SPI_SRAM_READ1_SIZE 0x400u
282-
#define SPI_SRAM_MBX_OFFSET (SPI_SRAM_READ1_OFFSET + SPI_SRAM_READ_SIZE)
283-
#define SPI_SRAM_MBX_SIZE 0x400u
284-
#define SPI_SRAM_SFDP_OFFSET (SPI_SRAM_MBX_OFFSET + SPI_SRAM_MBX_SIZE)
285-
#define SPI_SRAM_SFDP_SIZE 0x100u
288+
289+
#define SPI_SRAM_MBX_OFFSET (SPI_SRAM_READ1_OFFSET + SPI_SRAM_READ_SIZE)
290+
#define SPI_SRAM_MBX_SIZE 0x400u
291+
292+
#define SPI_SRAM_SFDP_OFFSET (SPI_SRAM_MBX_OFFSET + SPI_SRAM_MBX_SIZE)
293+
#define SPI_SRAM_SFDP_SIZE 0x100u
294+
295+
#define SPI_SRAM_TPM_READ_OFFSET (SPI_SRAM_SFDP_OFFSET + SPI_SRAM_SFDP_SIZE)
296+
#define SPI_SRAM_TPM_READ_SIZE 0x40u
286297
/* with new scheme (no dual part SRAM, the following offsets are shifted...) */
287-
#define SPI_SRAM_INGRESS_OFFSET 0x100u
288-
#define SPI_SRAM_PAYLOAD_OFFSET (SPI_SRAM_SFDP_OFFSET + SPI_SRAM_SFDP_SIZE)
298+
#define SPI_SRAM_INGRESS_OFFSET 0xE00u
299+
300+
static_assert(SPI_SRAM_INGRESS_OFFSET >=
301+
(SPI_SRAM_TPM_READ_OFFSET + SPI_SRAM_TPM_READ_SIZE),
302+
"SPI SRAM Egress buffers overflow into Ingress buffers");
303+
304+
#define SPI_SRAM_PAYLOAD_OFFSET SPI_SRAM_INGRESS_OFFSET
289305
#define SPI_SRAM_PAYLOAD_SIZE 0x100u
290-
#define SPI_SRAM_CMD_OFFSET (SPI_SRAM_PAYLOAD_OFFSET + SPI_SRAM_PAYLOAD_SIZE)
291-
#define SPI_SRAM_CMD_SIZE 0x40u
292-
#define SPI_SRAM_ADDR_OFFSET (SPI_SRAM_CMD_OFFSET + SPI_SRAM_CMD_SIZE)
293-
#define SPI_SRAM_ADDR_SIZE 0x40u
294-
#define SPI_SRAM_ADDR_END (SPI_SRAM_ADDR_OFFSET + SPI_SRAM_ADDR_SIZE)
295-
#define SPI_SRAM_END_OFFSET (SPI_SRAM_ADDR_END)
296-
static_assert(SPI_SRAM_END_OFFSET == 0xe80u, "Invalid SRAM definition");
306+
307+
#define SPI_SRAM_CMD_OFFSET (SPI_SRAM_PAYLOAD_OFFSET + SPI_SRAM_PAYLOAD_SIZE)
308+
#define SPI_SRAM_CMD_SIZE 0x40u
309+
310+
#define SPI_SRAM_ADDR_OFFSET (SPI_SRAM_CMD_OFFSET + SPI_SRAM_CMD_SIZE)
311+
#define SPI_SRAM_ADDR_SIZE 0x40u
312+
313+
#define SPI_SRAM_TPM_WRITE_OFFSET (SPI_SRAM_ADDR_OFFSET + SPI_SRAM_ADDR_SIZE)
314+
#define SPI_SRAM_TPM_WRITE_SIZE 0x40u
315+
316+
#define SPI_SRAM_ADDR_END (SPI_SRAM_TPM_WRITE_OFFSET + SPI_SRAM_TPM_WRITE_SIZE)
317+
#define SPI_SRAM_END_OFFSET (SPI_SRAM_ADDR_END)
318+
static_assert(SPI_SRAM_END_OFFSET == 0xfc0u, "Invalid SRAM definition");
297319

298320
#define SPI_DEVICE_SIZE 0x2000u
299321
#define SPI_DEVICE_SPI_REGS_OFFSET 0u
300322
#define SPI_DEVICE_TPM_REGS_OFFSET 0x800u
301323
#define SPI_DEVICE_SRAM_OFFSET 0x1000u
302324

303-
#define SRAM_SIZE PARAM_SRAM_OFFSET
304-
#define EGRESS_BUFFER_SIZE_BYTES \
305-
(SPI_SRAM_PAYLOAD_OFFSET - SPI_SRAM_READ0_OFFSET)
306-
#define EGRESS_BUFFER_SIZE_WORDS (EGRESS_BUFFER_SIZE_BYTES / sizeof(uint32_t))
307-
#define INGRESS_BUFFER_SIZE_BYTES \
308-
(SPI_SRAM_END_OFFSET - SPI_SRAM_PAYLOAD_OFFSET)
309-
#define INGRESS_BUFFER_SIZE_WORDS (INGRESS_BUFFER_SIZE_BYTES / sizeof(uint32_t))
325+
#define SRAM_SIZE (PARAM_SRAM_DEPTH * sizeof(uint32_t))
326+
327+
#define EGRESS_BUFFER_SIZE_BYTES (PARAM_SRAM_EGRESS_DEPTH * sizeof(uint32_t))
328+
#define EGRESS_BUFFER_SIZE_WORDS PARAM_SRAM_EGRESS_DEPTH
329+
330+
#define INGRESS_BUFFER_SIZE_BYTES (PARAM_SRAM_INGRESS_DEPTH * sizeof(uint32_t))
331+
#define INGRESS_BUFFER_SIZE_WORDS PARAM_SRAM_INGRESS_DEPTH
310332

311333
#define FLASH_READ_BUFFER_SIZE (2u * SPI_SRAM_READ_SIZE)
312334

@@ -710,7 +732,6 @@ static void ot_spi_device_clear_modes(OtSPIDeviceState *s)
710732
f->type = SPI_FLASH_CMD_NONE;
711733
g_assert(s->sram);
712734
f->payload = &((uint8_t *)s->sram)[SPI_SRAM_PAYLOAD_OFFSET];
713-
f->payload += SPI_SRAM_INGRESS_OFFSET;
714735
memset(f->buffer, 0u, SPI_FLASH_BUFFER_SIZE);
715736

716737
memset(s->sram, 0u, SRAM_SIZE);
@@ -1821,27 +1842,33 @@ static MemTxResult ot_spi_device_buf_read_with_attrs(
18211842
(void)attrs;
18221843
uint32_t val32;
18231844

1824-
hwaddr last = addr + size - 1u;
1845+
hwaddr last = (hwaddr)((uint32_t)addr + size - 1u);
18251846

1826-
if (last < SPI_SRAM_PAYLOAD_OFFSET + SPI_SRAM_INGRESS_OFFSET) {
1847+
if (addr < SPI_SRAM_INGRESS_OFFSET) {
18271848
qemu_log_mask(LOG_GUEST_ERROR,
18281849
"%s: cannot read egress buffer 0x%" HWADDR_PRIx "\n",
18291850
__func__, addr);
18301851
return MEMTX_DECODE_ERROR;
18311852
}
1832-
if (last < SPI_SRAM_CMD_OFFSET + SPI_SRAM_INGRESS_OFFSET) {
1833-
/* payload buffer */
1853+
1854+
if ((addr >= SPI_SRAM_PAYLOAD_OFFSET &&
1855+
last < (SPI_SRAM_PAYLOAD_OFFSET + SPI_SRAM_PAYLOAD_SIZE)) ||
1856+
(addr >= SPI_SRAM_TPM_WRITE_OFFSET &&
1857+
last < (SPI_SRAM_TPM_WRITE_OFFSET + SPI_SRAM_TPM_WRITE_SIZE))) {
18341858
val32 = s->sram[addr >> 2u];
1835-
} else if (last < SPI_SRAM_ADDR_OFFSET + SPI_SRAM_INGRESS_OFFSET) {
1859+
} else if (addr >= SPI_SRAM_CMD_OFFSET &&
1860+
last < (SPI_SRAM_CMD_OFFSET + SPI_SRAM_CMD_SIZE)) {
18361861
/* command FIFO */
18371862
val32 = ((const uint32_t *)s->flash.cmd_fifo.data)[addr >> 2u];
1838-
} else if (last < SPI_SRAM_ADDR_END + SPI_SRAM_INGRESS_OFFSET) {
1863+
} else if (addr >= SPI_SRAM_ADDR_OFFSET &&
1864+
last < (SPI_SRAM_ADDR_OFFSET + SPI_SRAM_ADDR_SIZE)) {
18391865
/* address FIFO */
18401866
val32 = s->flash.address_fifo.data[addr >> 2u];
18411867
} else {
1842-
/* TPM or not used area */
1843-
qemu_log_mask(LOG_UNIMP, "%s: TPM not supported 0x%" HWADDR_PRIx "\n",
1844-
__func__, addr);
1868+
qemu_log_mask(LOG_UNIMP,
1869+
"%s: Invalid ingress buffer access to 0x%" HWADDR_PRIx
1870+
"-0x%" HWADDR_PRIx "\n",
1871+
__func__, addr, last);
18451872
val32 = 0;
18461873
}
18471874

@@ -1869,9 +1896,9 @@ static MemTxResult ot_spi_device_buf_write_with_attrs(
18691896
uint32_t pc = ibex_get_current_pc();
18701897
trace_ot_spi_device_buf_write_in(s->ot_id, (uint32_t)addr, size, val32, pc);
18711898

1872-
hwaddr last = addr + size - 1u;
1899+
hwaddr last = (hwaddr)((uint32_t)addr + size - 1u);
18731900

1874-
if (last >= SPI_SRAM_PAYLOAD_OFFSET) {
1901+
if (last >= SPI_SRAM_INGRESS_OFFSET) {
18751902
qemu_log_mask(LOG_GUEST_ERROR,
18761903
"%s: cannot write ingress buffer 0x%" HWADDR_PRIx "\n",
18771904
__func__, addr);

0 commit comments

Comments
 (0)