Skip to content

Commit

Permalink
libmetal/nuttx/io.c: width matched access when read/write size = 1, 2…
Browse files Browse the repository at this point in the history
…, 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 <wangbowen6@xiaomi.com>
  • Loading branch information
CV-Bowen committed Dec 4, 2023
1 parent f3f365d commit 51e1585
Showing 1 changed file with 23 additions and 2 deletions.
25 changes: 23 additions & 2 deletions lib/system/nuttx/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
Expand Down

0 comments on commit 51e1585

Please sign in to comment.