1#include <rtconfig.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <stdarg.h>
6#include <fcntl.h>
7#include <unistd.h>
8#include <errno.h>
9
10#include <sys/types.h>
11#include <sys/stat.h>
12#include <sys/poll.h>
13#include <sys/mman.h>
14
15int page_size;
16#define PAGE_SIZE page_size
17#define PAGE_MASK (~(PAGE_SIZE-1))
18
19static char *cmdname;
20
21static void usage(void)
22{
23 printf("Usage: %s [[-l length] [-u 1|2|4]] [address]\n", cmdname);
24 exit(-1);
25}
26
27static unsigned long limit_length(unsigned long addr, unsigned long len)
28{
29#if defined(RTCONFIG_QCA)
30 unsigned long boundary_addr;
31 struct region_s {
32 unsigned long first_addr;
33 unsigned long last_addr;
34 } region_tbl[] = {
35 { 0x18000000, 0x1800015C },
36 { 0x18018000, 0x18018080 },
37 { 0x18020000, 0x18020018 },
38 { 0x18030000, 0x1803000C },
39 { 0x18040000, 0x1804006C },
40 { 0x18050000, 0x18050048 },
41 { 0x18060000, 0x1806405C },
42 { 0x18070000, 0x18070010 },
43 { 0x18080000, 0x1808305C },
44 { 0x180A0000, 0x180A006C },
45 { 0x180A9000, 0x180A9030 },
46 { 0x180B0000, 0x180B0018 },
47 { 0x180B8000, 0x180B8024 },
48 { 0x180F0000, 0x180F005C },
49 { 0x18100008, 0x18100104 },
50 { 0x18100800, 0x18100A44 },
51 { 0x18101000, 0x18101F04 },
52 { 0x18104000, 0x1810409C },
53 { 0x18107000, 0x18107058 },
54 { 0x18108000, 0x1810E000 },
55 { 0x180C0000, 0x180C003E },
56 { 0x18116200, 0x18116C88 },
57 { 0x18116CC0, 0x18116CC4 },
58 { 0x18116DC0, 0x18116DC8 },
59 { 0x18116D00, 0x18116D08 },
60 { 0x18400000, 0x18400054 },
61 { 0x18500000, 0x18500010 },
62 { 0x19000000, 0x190001D8 },
63 { 0x1A000000, 0x1A0001D8 },
64 { 0x1B000000, 0x1B0001FC },
65 { 0x1B400000, 0x1B4001FC },
66 { 0x1B000200, 0x1B0002B4 },
67 { 0x18127800, 0x18127D18 },
68 { 0x00000000, 0x00000F18 },
69 { 0x1F000000, 0x1F000F18 },
70 { 0x18116180, 0x18116188 },
71 { 0x181161C0, 0x181161C8 },
72 { 0x18116200, 0x18116208 },
73 { 0x18116240, 0x18116248 },
74 { 0x18116C00, 0x18116C08 },
75
76 { 0, 0 },
77 }, *p;
78
79 addr &= 0x3FFFFFFF; /* strip highest two bit */
80 for (p = ®ion_tbl[0]; p->last_addr; ++p) {
81 if (addr < p->first_addr || addr > p->last_addr)
82 continue;
83
84 boundary_addr = p->last_addr + 4;
85 if ((addr + len) >= boundary_addr) {
86 len = boundary_addr - addr;
87 printf("Adjust length to 0x%lx\n", len);
88 }
89 break;
90 }
91#elif defined(RTCONFIG_RALINK)
92#endif
93
94 return len;
95}
96
97int get_var(unsigned long addr, int len, int unit)
98{
99 off_t offset = addr & PAGE_MASK;
100 int i = 0, ret, l;
101 char *map;
102 static int kfd = -1;
103 unsigned int *p4;
104 unsigned char *p1;
105 unsigned short int *p2;
106
107 if (len <= 0 || !(unit == 1 || unit == 2 || unit == 4))
108 return -1;
109
110 kfd = open("/dev/mem", O_RDONLY);
111 if (kfd < 0) {
112 perror("open");
113 return -2;
114 }
115
116 map = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, kfd, offset);
117 if (map == MAP_FAILED) {
118 perror("mmap");
119 exit(-1);
120 }
121 p4 = (unsigned int*) (map + (addr - offset));
122 p2 = (unsigned short*) p4;
123 p1 = (unsigned char*) p4;
124
125 for (i = 0, l = len; l > 0; i += unit, l -= unit) {
126 if (!(i % 16))
127 printf("\n0x%08lx: ", addr + i);
128
129 switch (unit) {
130 case 4:
131 printf("%08x ", *p4++);
132 break;
133 case 2:
134 printf("%04x ", *p2++);
135 break;
136 case 1:
137 printf("%02x%c", *p1++, (((i+1) % 16) && !((i+1) % 8) && (l - unit))? '-':' ');
138 break;
139 }
140 }
141 printf("\n");
142
143 ret = munmap(map, PAGE_SIZE);
144 if (ret)
145 printf("munmap() return %d errno %d(%s)\n", ret, errno, strerror(errno));
146
147 return 0;
148}
149
150int readmem_main(int argc, char **argv)
151{
152 int len = 128, unit = 4, tmp, opt, ret;
153 char *addr_str = "0x18040000";
154 unsigned long addr;
155
156 cmdname = argv[0];
157 page_size = getpagesize();
158 while ((opt = getopt(argc, argv, "l:u:")) != -1) {
159 switch (opt) {
160 case 'u':
161 tmp = atoi(optarg);
162 if (tmp == 1 || tmp == 2 || tmp == 4)
163 unit = tmp;
164 else
165 usage();
166 break;
167 case 'l':
168 tmp = atoi(optarg);
169 if (tmp > 0 && tmp <= PAGE_SIZE)
170 len = tmp;
171 else
172 usage();
173 break;
174 default:
175 usage();
176 }
177 }
178 argc -= optind;
179 argv += optind;
180 if (argc > 0)
181 addr_str = argv[0];
182
183 addr = strtoul(addr_str, NULL, 16);
184 printf("addr: 0x%08lx, length: 0x%x, unit: %d\n", addr, len, unit);
185 len = limit_length(addr, len);
186 ret = get_var(addr, len, unit);
187
188 return ret;
189}
190