Skip to content

Commit

Permalink
Michael Shavit hit a problem with 8 byte wide writes, so switch from
Browse files Browse the repository at this point in the history
signed atolx() to unsigned strtoul() which has the side effect of not
parsing the kmg suffixes. (Poke me if I should mention that in the help
text...)

Test cases (with results from another implementation):

$ devmem 0x000000008b300000 8 0x8FFFFFFFFFFFFFFF
$ devmem 0x000000008b300000 8
0x8fffffffffffffff

$ devmem 0x000000008b300000 8 500k
$ devmem 0x000000008b300000 8
0x0000000007d000

$ devmem 0x000000008b300000 8 0xFFFFFFFFFFFFFFFF
$ devmem 0x000000008b300000 8
0xffffffffffffffff

$ devmem 0x000000008b300000 4 0xFFFFFFFF
$ devmem 0x000000008b300000 4
0xffffffff

$ devmem 0x000000008b300000  4 0x1FFFFFFFF
devmem: data: 8589934591 exceeds write width: 4

Dunno how to set up a qemu instance that can devmem for
testing under mkroot, so no tests/devmem.test yet. (And it
wouldn't be target agnostic like the rest of the tests
anyway. Hmmm...)
  • Loading branch information
landley committed Aug 31, 2023
1 parent 495a33e commit ad36c87
Showing 1 changed file with 14 additions and 4 deletions.
18 changes: 14 additions & 4 deletions toys/other/devmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,20 @@ config DEVMEM
#define FOR_devmem
#include "toys.h"

unsigned long long atollu(char *str)
{
char *end = str;
unsigned long long llu = strtoul(str, &end, 0);

if (*end) error_exit("bad %s", str);

return llu;
}

void devmem_main(void)
{
int writing = toys.optc == 3, page_size = sysconf(_SC_PAGESIZE), bytes = 4,fd;
unsigned long long data = 0, map_off, map_len;
unsigned long addr = atolx(*toys.optargs);
unsigned long long data = 0, map_off, map_len, addr = atollu(*toys.optargs);
void *map, *p;

// WIDTH?
Expand All @@ -34,13 +43,14 @@ void devmem_main(void)
}

// DATA? Report out of range values as errors rather than truncating.
if (writing) data = atolx_range(toys.optargs[2], 0, (1ULL<<(8*bytes))-1);
if (writing && (data = atollu(toys.optargs[2]))>(~0ULL)>>(64-8*bytes))
error_exit("%llx>%d bytes", data, bytes);

// Map in just enough.
if (CFG_TOYBOX_FORK) {
fd = xopen("/dev/mem", (writing ? O_RDWR : O_RDONLY) | O_SYNC);

map_off = addr & ~(page_size - 1);
map_off = addr & ~(page_size - 1ULL);
map_len = (addr+bytes-map_off);
map = xmmap(0, map_len, writing ? PROT_WRITE : PROT_READ, MAP_SHARED, fd,
map_off);
Expand Down

0 comments on commit ad36c87

Please sign in to comment.