blob: a7a717c45938a10c20389315ed8898ee953d2f6a [file] [log] [blame]
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -07001/*
2 * Copyright (c) 2008 Travis Geiselbrecht
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#include <ctype.h>
25#include <debug.h>
26#include <stdlib.h>
27#include <printf.h>
28#include <list.h>
29#include <string.h>
30#include <arch/ops.h>
31#include <platform.h>
32#include <kernel/thread.h>
33
34void spin(uint32_t usecs)
35{
36 bigtime_t start = current_time_hires();
37
38 while ((current_time_hires() - start) < usecs)
39 ;
40}
41
42void halt(void)
43{
44 enter_critical_section(); // disable ints
45 for(;;);
46}
47
48void _panic(void *caller, const char *fmt, ...)
49{
50 dprintf("panic (caller %p): ", caller);
51
52 va_list ap;
53 va_start(ap, fmt);
54 dvprintf(fmt, ap);
55 va_end(ap);
56
57 halt();
58}
59
60int dputs(const char *str)
61{
62 while(*str != 0) {
63 dputc(*str++);
64 }
65
66 return 0;
67}
68
69int dprintf(const char *fmt, ...)
70{
71 char buf[256];
72 int err;
73
74 va_list ap;
75 va_start(ap, fmt);
76 err = vsprintf(buf, fmt, ap);
77 va_end(ap);
78
79 dputs(buf);
80
81 return err;
82}
83
84int dvprintf(const char *fmt, va_list ap)
85{
86 char buf[256];
87 int err;
88
89 err = vsprintf(buf, fmt, ap);
90
91 dputs(buf);
92
93 return err;
94}
95
96void hexdump(const void *ptr, size_t len)
97{
98 addr_t address = (addr_t)ptr;
99 size_t count;
100 int i;
101
102 for (count = 0 ; count < len; count += 16) {
103 printf("0x%08lx: ", address);
104 printf("%08x %08x %08x %08x |", *(const uint32_t *)address, *(const uint32_t *)(address + 4), *(const uint32_t *)(address + 8), *(const uint32_t *)(address + 12));
105 for (i=0; i < 16; i++) {
106 char c = *(const char *)(address + i);
107 if (isalpha(c)) {
108 printf("%c", c);
109 } else {
110 printf(".");
111 }
112 }
113 printf("|\n");
114 address += 16;
115 }
116}
117
118void hexdump8(const void *ptr, size_t len)
119{
120 addr_t address = (addr_t)ptr;
121 size_t count;
122 int i;
123
124 for (count = 0 ; count < len; count += 16) {
125 printf("0x%08lx: ", address);
126 for (i=0; i < 16; i++) {
127 printf("0x%02hhx ", *(const uint8_t *)(address + i));
128 }
129 printf("\n");
130 address += 16;
131 }
132}
133
134#ifdef WITH_APP_CONSOLE
135#include <app/console.h>
136
137static int cmd_display_mem(int argc, const cmd_args *argv);
138static int cmd_modify_mem(int argc, const cmd_args *argv);
139static int cmd_fill_mem(int argc, const cmd_args *argv);
140static int cmd_reset(int argc, const cmd_args *argv);
141static int cmd_memtest(int argc, const cmd_args *argv);
142static int cmd_copy_mem(int argc, const cmd_args *argv);
143
144STATIC_COMMAND_START
145#if DEBUGLEVEL > 0
146 { "dw", "display memory in words", &cmd_display_mem },
147 { "dh", "display memory in halfwords", &cmd_display_mem },
148 { "db", "display memory in bytes", &cmd_display_mem },
149 { "mw", "modify word of memory", &cmd_modify_mem },
150 { "mh", "modify halfword of memory", &cmd_modify_mem },
151 { "mb", "modify byte of memory", &cmd_modify_mem },
152 { "fw", "fill range of memory by word", &cmd_fill_mem },
153 { "fh", "fill range of memory by halfword", &cmd_fill_mem },
154 { "fb", "fill range of memory by byte", &cmd_fill_mem },
155 { "mc", "copy a range of memory", &cmd_copy_mem },
156#endif
157#if DEBUGLEVEL > 1
158 { "mtest", "simple memory test", &cmd_memtest },
159#endif
160STATIC_COMMAND_END(mem);
161
162static int cmd_display_mem(int argc, const cmd_args *argv)
163{
164 int size;
165
166 if (argc < 3) {
167 printf("not enough arguments\n");
168 printf("%s <address> <length>\n", argv[0].str);
169 return -1;
170 }
171
172 if (strcmp(argv[0].str, "dw") == 0) {
173 size = 4;
174 } else if (strcmp(argv[0].str, "dh") == 0) {
175 size = 2;
176 } else {
177 size = 1;
178 }
179
180 unsigned long address = argv[1].u;
181 size_t len = argv[2].u;
182 unsigned long stop = address + len;
183 int count = 0;
184
185 if ((address & (size - 1)) != 0) {
186 printf("unaligned address, cannot display\n");
187 return -1;
188 }
189
190 for ( ; address < stop; address += size) {
191 if (count == 0)
192 printf("0x%08lx: ", address);
193 switch (size) {
194 case 4:
195 printf("%08x ", *(uint32_t *)address);
196 break;
197 case 2:
198 printf("%04hx ", *(uint16_t *)address);
199 break;
200 case 1:
201 printf("%02hhx ", *(uint8_t *)address);
202 break;
203 }
204 count += size;
205 if (count == 16) {
206 printf("\n");
207 count = 0;
208 }
209 }
210
211 if (count != 0)
212 printf("\n");
213
214 return 0;
215}
216
217static int cmd_modify_mem(int argc, const cmd_args *argv)
218{
219 int size;
220
221 if (argc < 3) {
222 printf("not enough arguments\n");
223 printf("%s <address> <val>\n", argv[0].str);
224 return -1;
225 }
226
227 if (strcmp(argv[0].str, "mw") == 0) {
228 size = 4;
229 } else if (strcmp(argv[0].str, "mh") == 0) {
230 size = 2;
231 } else {
232 size = 1;
233 }
234
235 unsigned long address = argv[1].u;
236 unsigned int val = argv[2].u;
237
238 if ((address & (size - 1)) != 0) {
239 printf("unaligned address, cannot modify\n");
240 return -1;
241 }
242
243 switch (size) {
244 case 4:
245 *(uint32_t *)address = (uint32_t)val;
246 break;
247 case 2:
248 *(uint16_t *)address = (uint16_t)val;
249 break;
250 case 1:
251 *(uint8_t *)address = (uint8_t)val;
252 break;
253 }
254
255 return 0;
256}
257
258static int cmd_fill_mem(int argc, const cmd_args *argv)
259{
260 int size;
261
262 if (argc < 4) {
263 printf("not enough arguments\n");
264 printf("%s <address> <len> <val>\n", argv[0].str);
265 return -1;
266 }
267
268 if (strcmp(argv[0].str, "fw") == 0) {
269 size = 4;
270 } else if (strcmp(argv[0].str, "fh") == 0) {
271 size = 2;
272 } else {
273 size = 1;
274 }
275
276 unsigned long address = argv[1].u;
277 unsigned long len = argv[2].u;
278 unsigned long stop = address + len;
279 unsigned int val = argv[3].u;
280
281 if ((address & (size - 1)) != 0) {
282 printf("unaligned address, cannot modify\n");
283 return -1;
284 }
285
286 for ( ; address < stop; address += size) {
287 switch (size) {
288 case 4:
289 *(uint32_t *)address = (uint32_t)val;
290 break;
291 case 2:
292 *(uint16_t *)address = (uint16_t)val;
293 break;
294 case 1:
295 *(uint8_t *)address = (uint8_t)val;
296 break;
297 }
298 }
299
300 return 0;
301}
302
303static int cmd_copy_mem(int argc, const cmd_args *argv)
304{
305 if (argc < 4) {
306 printf("not enough arguments\n");
307 printf("%s <source address> <target address> <len>\n", argv[0].str);
308 return -1;
309 }
310
311 addr_t source = argv[1].u;
312 addr_t target = argv[2].u;
313 size_t len = argv[3].u;
314
315 memcpy((void *)target, (const void *)source, len);
316
317 return 0;
318}
319
320static int cmd_memtest(int argc, const cmd_args *argv)
321{
322 if (argc < 3) {
323 printf("not enough arguments\n");
324 printf("%s <base> <len>\n", argv[0].str);
325 return -1;
326 }
327
328 uint32_t *ptr;
329 size_t len;
330
331 ptr = (uint32_t *)argv[1].u;
332 len = (size_t)argv[2].u;
333
334 size_t i;
335 // write out
336 printf("writing first pass...");
337 for (i = 0; i < len / 4; i++) {
338 ptr[i] = i;
339 }
340 printf("done\n");
341
342 // verify
343 printf("verifying...");
344 for (i = 0; i < len / 4; i++) {
345 if (ptr[i] != i)
346 printf("error at %p\n", &ptr[i]);
347 }
348 printf("done\n");
349
350 return 0;
351}
352
353#endif
354