Attention is currently required from: Angel Pons, Arthur Heymans, Ashish Kumar Mishra, Jérémy Compostella, Patrick Rudolph, Saurabh Mishra.
Subrata Banik has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/81959?usp=email )
Change subject: [MTL-x64]arch/x86: Update X86_64 memcpy for 4 byte copy ......................................................................
Patch Set 3:
(1 comment)
Patchset:
PS3:
OK, unless it can be proven that `len` is always a multiple of 4, this is actually quite tricky to fix: one needs to treat the last register read/write as a partial write.
I think this should work, but I haven't tested it at all:
/* Fill FDATAn FIFO in preparation for a write transaction. */ static void fill_xfer_fifo(struct fast_spi_flash_ctx *ctx, const uint8_t *data, size_t len) { /* FDATAn requires 32-bit accesses */ const uint32_t *dwords = (const uint32_t *)data; for (size_t i = 0; i < len / 4; i++) write32p(ctx->mmio_base + SPIBAR_FDATA(i), dwords[i]); if (len % 4) { uint32_t last_dword = 0; for (size_t i = 0; i < len % 4; i++) last_dword |= data[len / 4 + i] << (i * 8); write32p(ctx->mmio_base + SPIBAR_FDATA(len / 4), last_dword); } } /* Drain FDATAn FIFO after a read transaction populates data. */ static void drain_xfer_fifo(struct fast_spi_flash_ctx *ctx, uint8_t *dest, size_t len) { /* FDATAn requires 32-bit accesses */ uint32_t *dwords = (uint32_t *)data; for (size_t i = 0; i < len / 4; i++) dwords[i] = read32p(ctx->mmio_base + SPIBAR_FDATA(i)); if (len % 4) { const uint32_t last_dword = read32p(ctx->mmio_base + SPIBAR_FDATA(len / 4)); for (size_t i = 0; i < len % 4; i++) data[len / 4 + i] = (uint8_t)(last_dword >> (i * 8)); } }
You beat me on this @Angel (amazing work), but just note SPIBAR_FDATA(0) itself a register hence, index won't be working there `ctx->mmio_base + SPIBAR_FDATA(i)`.
you can assume `ctx->mmio_base + SPIBAR_FDATA(0)` is a uintptr_t