From f21fea6c32e803d75f74f0b4b7e922f29aea5c05 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 Signed-off-by: Jukka Laitinen --- 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..ab9bc6ab 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 + 1) = *((uint32_t *)va + 1); + } 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 + 1) = *((uint32_t *)src + 1); + } else + memcpy(va, src, len); + metal_cache_flush(va, len); return len;