From 5124f246d565e9e64322716bc5aa67cbb5a5835e Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Thu, 16 Nov 2023 14:52:48 +0800 Subject: [PATCH] libmetal/nuttx/io.c: width matched access when read/write size = 1,2,4,8 Follow the virtio spec v1.2: The driver MUST only use 32 bit wide and aligned reads and writes to access the control registers described in table 4.1. For the device-specific configuration space, the driver MUST use 8 bit wide accesses for 8 bit wide fields, 16 bit wide and aligned accesses for 16 bit wide fields and 32 bit wide and aligned accesses for 32 and 64 bit wide fields. Signed-off-by: Bowen Wang --- lib/system/nuttx/io.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/system/nuttx/io.c b/lib/system/nuttx/io.c index 4fa4727e..3ce9cbe2 100644 --- a/lib/system/nuttx/io.c +++ b/lib/system/nuttx/io.c @@ -37,7 +37,17 @@ static int metal_io_block_read_(struct metal_io_region *io, void *va = metal_io_virt(io, offset); metal_cache_invalidate(va, len); - memcpy(dst, va, len); + if (len == 1) + *(uint8_t *)dst = *(uint8_t *)va; + else if (len == 2) + *(uint16_t *)dst = *(uint16_t *)va; + else if (len == 4) + *(uint32_t *)dst = *(uint32_t *)va; + else if (len == 8) { + *(uint32_t *)dst = *(uint32_t *)va; + *(uint32_t *)(dst + 4) = *(uint32_t *)(va + 4); + } else + memcpy(dst, va, len); return len; } @@ -50,7 +60,18 @@ static int metal_io_block_write_(struct metal_io_region *io, { void *va = metal_io_virt(io, offset); - memcpy(va, src, len); + if (len == 1) + *(uint8_t *)va = *(uint8_t *)src; + else if (len == 2) + *(uint16_t *)va = *(uint16_t *)src; + else if (len == 4) + *(uint32_t *)va = *(uint32_t *)src; + else if (len == 8) { + *(uint32_t *)va = *(uint32_t *)src; + *(uint32_t *)(va + 4) = *(uint32_t *)(src + 4); + } else + memcpy(va, src, len); + metal_cache_flush(va, len); return len;