From eba85b955e9bca3080068f7ae844b1ea9989ac2a Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Mon, 20 Apr 2026 10:05:07 -0700 Subject: [PATCH] Be explicit about the size when reading or writing a word ('w'). On 64-bit cpus 'long' will be compiled as 64-bit which can cause the cpu to inadvertently issue 64-bit loads/stores when the intent was to read/write a 32-bit location in /dev/mem. This was seen when trying to read from the PCI ECAM (memory mapped config space). Prior to this patch the load/store to any register offset would fail when trying to do a 'w' read or write. This is because of ECAM accesses crossing DW boundaries (4 byte in PCI world) are not required to be supported by the chipset. --- devmem2.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/devmem2.c b/devmem2.c index 9bcb79d..3edd9c0 100644 --- a/devmem2.c +++ b/devmem2.c @@ -28,6 +28,7 @@ */ #include +#include #include #include #include @@ -48,7 +49,7 @@ int main(int argc, char **argv) { int fd; void *map_base, *virt_addr; - unsigned long read_result, writeval; + uint32_t read_result, writeval; off_t target; int access_type = 'w'; @@ -85,7 +86,7 @@ int main(int argc, char **argv) { read_result = *((unsigned short *) virt_addr); break; case 'w': - read_result = *((unsigned long *) virt_addr); + read_result = *((uint32_t *) virt_addr); break; default: fprintf(stderr, "Illegal data type '%c'.\n", access_type); @@ -106,8 +107,8 @@ int main(int argc, char **argv) { read_result = *((unsigned short *) virt_addr); break; case 'w': - *((unsigned long *) virt_addr) = writeval; - read_result = *((unsigned long *) virt_addr); + *((uint32_t *) virt_addr) = writeval; + read_result = *((uint32_t *) virt_addr); break; } printf("Written 0x%X; readback 0x%X\n", writeval, read_result);