aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-10-26 17:26:55 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-10-26 17:26:55 +0000
commit043246560fcd5bb7bfb2caa2db270c3c0e8e06f4 (patch)
tree709f6baf5b3859310c3208fea502bcc10ca3e083
parente1ef89abada09b96fb79b167c5d60db718f9429e (diff)
downloadbusybox-w32-043246560fcd5bb7bfb2caa2db270c3c0e8e06f4.tar.gz
busybox-w32-043246560fcd5bb7bfb2caa2db270c3c0e8e06f4.tar.bz2
busybox-w32-043246560fcd5bb7bfb2caa2db270c3c0e8e06f4.zip
devmem: make it more script-friendly; don't do any reads
and output nothing if writing was requested. -100 bytes
-rw-r--r--miscutils/devmem.c79
1 files changed, 42 insertions, 37 deletions
diff --git a/miscutils/devmem.c b/miscutils/devmem.c
index 8b8edbe7c..4903b5dcb 100644
--- a/miscutils/devmem.c
+++ b/miscutils/devmem.c
@@ -6,9 +6,6 @@
6 6
7#include "libbb.h" 7#include "libbb.h"
8 8
9#define DEVMEM_MAP_SIZE 4096
10#define DEVMEM_MAP_MASK (off_t)(DEVMEM_MAP_SIZE - 1)
11
12int devmem_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 9int devmem_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
13int devmem_main(int argc UNUSED_PARAM, char **argv) 10int devmem_main(int argc UNUSED_PARAM, char **argv)
14{ 11{
@@ -16,10 +13,16 @@ int devmem_main(int argc UNUSED_PARAM, char **argv)
16 uint64_t read_result; 13 uint64_t read_result;
17 uint64_t writeval = writeval; /* for compiler */ 14 uint64_t writeval = writeval; /* for compiler */
18 off_t target; 15 off_t target;
16 unsigned page_size = getpagesize();
19 int fd; 17 int fd;
20 int width = 8 * sizeof(int); 18 int width = 8 * sizeof(int);
21 19
22 /* devmem ADDRESS [WIDTH [VALUE]] */ 20 /* devmem ADDRESS [WIDTH [VALUE]] */
21// TODO: options?
22// -r: read and output only the value in hex, with 0x prefix
23// -w: write only, no reads before or after, and no output
24// or make this behavior default?
25// Let's try this and see how users react.
23 26
24 /* ADDRESS */ 27 /* ADDRESS */
25 if (!argv[1]) 28 if (!argv[1])
@@ -54,67 +57,69 @@ int devmem_main(int argc UNUSED_PARAM, char **argv)
54 bb_show_usage(); /* bb_strtouXX failed */ 57 bb_show_usage(); /* bb_strtouXX failed */
55 58
56 fd = xopen("/dev/mem", argv[3] ? (O_RDWR | O_SYNC) : (O_RDONLY | O_SYNC)); 59 fd = xopen("/dev/mem", argv[3] ? (O_RDWR | O_SYNC) : (O_RDONLY | O_SYNC));
57
58 map_base = mmap(NULL, 60 map_base = mmap(NULL,
59 DEVMEM_MAP_SIZE * 2 /* in case value spans page */, 61 page_size * 2 /* in case value spans page */,
60 argv[3] ? (PROT_READ | PROT_WRITE) : PROT_READ, 62 argv[3] ? (PROT_READ | PROT_WRITE) : PROT_READ,
61 MAP_SHARED, 63 MAP_SHARED,
62 fd, 64 fd,
63 target & ~DEVMEM_MAP_MASK); 65 target & ~(off_t)(page_size - 1));
64 if (map_base == MAP_FAILED) 66 if (map_base == MAP_FAILED)
65 bb_perror_msg_and_die("mmap"); 67 bb_perror_msg_and_die("mmap");
66 68
67// printf("Memory mapped at address %p.\n", map_base); 69// printf("Memory mapped at address %p.\n", map_base);
68 70
69 virt_addr = (char*)map_base + (target & DEVMEM_MAP_MASK); 71 virt_addr = (char*)map_base + (target & (page_size - 1));
70
71 switch (width) {
72 case 8:
73 read_result = *(volatile uint8_t*)virt_addr;
74 break;
75 case 16:
76 read_result = *(volatile uint16_t*)virt_addr;
77 break;
78 case 32:
79 read_result = *(volatile uint32_t*)virt_addr;
80 break;
81 case 64:
82 read_result = *(volatile uint64_t*)virt_addr;
83 break;
84 default:
85 bb_error_msg_and_die("bad width");
86 }
87
88 printf("Value at address 0x%"OFF_FMT"X (%p): 0x%llX\n",
89 target, virt_addr,
90 (unsigned long long)read_result);
91 72
92 if (argv[3]) { 73 if (!argv[3]) {
93 switch (width) { 74 switch (width) {
94 case 8: 75 case 8:
95 *(volatile uint8_t*)virt_addr = writeval;
96 read_result = *(volatile uint8_t*)virt_addr; 76 read_result = *(volatile uint8_t*)virt_addr;
97 break; 77 break;
98 case 16: 78 case 16:
99 *(volatile uint16_t*)virt_addr = writeval;
100 read_result = *(volatile uint16_t*)virt_addr; 79 read_result = *(volatile uint16_t*)virt_addr;
101 break; 80 break;
102 case 32: 81 case 32:
103 *(volatile uint32_t*)virt_addr = writeval;
104 read_result = *(volatile uint32_t*)virt_addr; 82 read_result = *(volatile uint32_t*)virt_addr;
105 break; 83 break;
106 case 64: 84 case 64:
107 *(volatile uint64_t*)virt_addr = writeval;
108 read_result = *(volatile uint64_t*)virt_addr; 85 read_result = *(volatile uint64_t*)virt_addr;
109 break; 86 break;
87 default:
88 bb_error_msg_and_die("bad width");
89 }
90// printf("Value at address 0x%"OFF_FMT"X (%p): 0x%llX\n",
91// target, virt_addr,
92// (unsigned long long)read_result);
93 /* Zero-padded output shows the width of access just done */
94 printf("0x%0*llX\n", (width >> 2), (unsigned long long)read_result);
95 } else {
96 switch (width) {
97 case 8:
98 *(volatile uint8_t*)virt_addr = writeval;
99// read_result = *(volatile uint8_t*)virt_addr;
100 break;
101 case 16:
102 *(volatile uint16_t*)virt_addr = writeval;
103// read_result = *(volatile uint16_t*)virt_addr;
104 break;
105 case 32:
106 *(volatile uint32_t*)virt_addr = writeval;
107// read_result = *(volatile uint32_t*)virt_addr;
108 break;
109 case 64:
110 *(volatile uint64_t*)virt_addr = writeval;
111// read_result = *(volatile uint64_t*)virt_addr;
112 break;
113 default:
114 bb_error_msg_and_die("bad width");
110 } 115 }
111 printf("Written 0x%llX; readback 0x%llX\n", 116// printf("Written 0x%llX; readback 0x%llX\n",
112 (unsigned long long)writeval, 117// (unsigned long long)writeval,
113 (unsigned long long)read_result); 118// (unsigned long long)read_result);
114 } 119 }
115 120
116 if (ENABLE_FEATURE_CLEAN_UP) { 121 if (ENABLE_FEATURE_CLEAN_UP) {
117 if (munmap(map_base, DEVMEM_MAP_SIZE) == -1) 122 if (munmap(map_base, page_size) == -1)
118 bb_perror_msg_and_die("munmap"); 123 bb_perror_msg_and_die("munmap");
119 close(fd); 124 close(fd);
120 } 125 }