Attention is currently required from: Arthur Heymans, Ashish Kumar Mishra, Jérémy Compostella, Patrick Rudolph, Saurabh Mishra, Subrata Banik.
Angel Pons 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:
So the code that literally says […]
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)); } } ```