blob: ff4e135bc30c50908f30b03c8b15a9d6a5bc8077 [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>
Travis Geiselbrechteb946052008-09-07 22:32:49 -070032#include <platform/debug.h>
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070033#include <kernel/thread.h>
34
35void spin(uint32_t usecs)
36{
37 bigtime_t start = current_time_hires();
38
39 while ((current_time_hires() - start) < usecs)
40 ;
41}
42
43void halt(void)
44{
45 enter_critical_section(); // disable ints
Travis Geiselbrechteb946052008-09-07 22:32:49 -070046 platform_halt();
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070047}
48
49void _panic(void *caller, const char *fmt, ...)
50{
Travis Geiselbrechteb946052008-09-07 22:32:49 -070051 dprintf(ALWAYS, "panic (caller %p): ", caller);
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070052
53 va_list ap;
54 va_start(ap, fmt);
Travis Geiselbrechteb946052008-09-07 22:32:49 -070055 _dvprintf(fmt, ap);
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070056 va_end(ap);
57
58 halt();
59}
60
Travis Geiselbrechteb946052008-09-07 22:32:49 -070061int _dputs(const char *str)
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070062{
63 while(*str != 0) {
Travis Geiselbrechteb946052008-09-07 22:32:49 -070064 _dputc(*str++);
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070065 }
66
67 return 0;
68}
69
Travis Geiselbrechteb946052008-09-07 22:32:49 -070070int _dprintf(const char *fmt, ...)
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070071{
72 char buf[256];
73 int err;
74
75 va_list ap;
76 va_start(ap, fmt);
Travis Geiselbrecht6c5fa8a2008-12-30 23:39:26 -080077 err = vsnprintf(buf, sizeof(buf), fmt, ap);
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070078 va_end(ap);
79
Travis Geiselbrechteb946052008-09-07 22:32:49 -070080 dputs(ALWAYS, buf);
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070081
82 return err;
83}
84
Travis Geiselbrechteb946052008-09-07 22:32:49 -070085int _dvprintf(const char *fmt, va_list ap)
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070086{
87 char buf[256];
88 int err;
89
Travis Geiselbrecht6c5fa8a2008-12-30 23:39:26 -080090 err = vsnprintf(buf, sizeof(buf), fmt, ap);
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070091
Travis Geiselbrechteb946052008-09-07 22:32:49 -070092 dputs(ALWAYS, buf);
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070093
94 return err;
95}
96
97void hexdump(const void *ptr, size_t len)
98{
99 addr_t address = (addr_t)ptr;
100 size_t count;
101 int i;
102
103 for (count = 0 ; count < len; count += 16) {
104 printf("0x%08lx: ", address);
105 printf("%08x %08x %08x %08x |", *(const uint32_t *)address, *(const uint32_t *)(address + 4), *(const uint32_t *)(address + 8), *(const uint32_t *)(address + 12));
106 for (i=0; i < 16; i++) {
107 char c = *(const char *)(address + i);
108 if (isalpha(c)) {
109 printf("%c", c);
110 } else {
111 printf(".");
112 }
113 }
114 printf("|\n");
115 address += 16;
116 }
117}
118
119void hexdump8(const void *ptr, size_t len)
120{
121 addr_t address = (addr_t)ptr;
122 size_t count;
123 int i;
124
125 for (count = 0 ; count < len; count += 16) {
126 printf("0x%08lx: ", address);
127 for (i=0; i < 16; i++) {
128 printf("0x%02hhx ", *(const uint8_t *)(address + i));
129 }
130 printf("\n");
131 address += 16;
132 }
133}
134
Travis Geiselbrecht39deded2009-01-24 20:12:27 -0800135#ifdef WITH_LIB_CONSOLE
136#include <lib/console.h>
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700137
138static int cmd_display_mem(int argc, const cmd_args *argv);
139static int cmd_modify_mem(int argc, const cmd_args *argv);
140static int cmd_fill_mem(int argc, const cmd_args *argv);
141static int cmd_reset(int argc, const cmd_args *argv);
142static int cmd_memtest(int argc, const cmd_args *argv);
143static int cmd_copy_mem(int argc, const cmd_args *argv);
144
145STATIC_COMMAND_START
146#if DEBUGLEVEL > 0
147 { "dw", "display memory in words", &cmd_display_mem },
148 { "dh", "display memory in halfwords", &cmd_display_mem },
149 { "db", "display memory in bytes", &cmd_display_mem },
150 { "mw", "modify word of memory", &cmd_modify_mem },
151 { "mh", "modify halfword of memory", &cmd_modify_mem },
152 { "mb", "modify byte of memory", &cmd_modify_mem },
153 { "fw", "fill range of memory by word", &cmd_fill_mem },
154 { "fh", "fill range of memory by halfword", &cmd_fill_mem },
155 { "fb", "fill range of memory by byte", &cmd_fill_mem },
156 { "mc", "copy a range of memory", &cmd_copy_mem },
157#endif
158#if DEBUGLEVEL > 1
159 { "mtest", "simple memory test", &cmd_memtest },
160#endif
161STATIC_COMMAND_END(mem);
162
163static int cmd_display_mem(int argc, const cmd_args *argv)
164{
165 int size;
166
167 if (argc < 3) {
168 printf("not enough arguments\n");
169 printf("%s <address> <length>\n", argv[0].str);
170 return -1;
171 }
172
173 if (strcmp(argv[0].str, "dw") == 0) {
174 size = 4;
175 } else if (strcmp(argv[0].str, "dh") == 0) {
176 size = 2;
177 } else {
178 size = 1;
179 }
180
181 unsigned long address = argv[1].u;
182 size_t len = argv[2].u;
183 unsigned long stop = address + len;
184 int count = 0;
185
186 if ((address & (size - 1)) != 0) {
187 printf("unaligned address, cannot display\n");
188 return -1;
189 }
190
191 for ( ; address < stop; address += size) {
192 if (count == 0)
193 printf("0x%08lx: ", address);
194 switch (size) {
195 case 4:
196 printf("%08x ", *(uint32_t *)address);
197 break;
198 case 2:
199 printf("%04hx ", *(uint16_t *)address);
200 break;
201 case 1:
202 printf("%02hhx ", *(uint8_t *)address);
203 break;
204 }
205 count += size;
206 if (count == 16) {
207 printf("\n");
208 count = 0;
209 }
210 }
211
212 if (count != 0)
213 printf("\n");
214
215 return 0;
216}
217
218static int cmd_modify_mem(int argc, const cmd_args *argv)
219{
220 int size;
221
222 if (argc < 3) {
223 printf("not enough arguments\n");
224 printf("%s <address> <val>\n", argv[0].str);
225 return -1;
226 }
227
228 if (strcmp(argv[0].str, "mw") == 0) {
229 size = 4;
230 } else if (strcmp(argv[0].str, "mh") == 0) {
231 size = 2;
232 } else {
233 size = 1;
234 }
235
236 unsigned long address = argv[1].u;
237 unsigned int val = argv[2].u;
238
239 if ((address & (size - 1)) != 0) {
240 printf("unaligned address, cannot modify\n");
241 return -1;
242 }
243
244 switch (size) {
245 case 4:
246 *(uint32_t *)address = (uint32_t)val;
247 break;
248 case 2:
249 *(uint16_t *)address = (uint16_t)val;
250 break;
251 case 1:
252 *(uint8_t *)address = (uint8_t)val;
253 break;
254 }
255
256 return 0;
257}
258
259static int cmd_fill_mem(int argc, const cmd_args *argv)
260{
261 int size;
262
263 if (argc < 4) {
264 printf("not enough arguments\n");
265 printf("%s <address> <len> <val>\n", argv[0].str);
266 return -1;
267 }
268
269 if (strcmp(argv[0].str, "fw") == 0) {
270 size = 4;
271 } else if (strcmp(argv[0].str, "fh") == 0) {
272 size = 2;
273 } else {
274 size = 1;
275 }
276
277 unsigned long address = argv[1].u;
278 unsigned long len = argv[2].u;
279 unsigned long stop = address + len;
280 unsigned int val = argv[3].u;
281
282 if ((address & (size - 1)) != 0) {
283 printf("unaligned address, cannot modify\n");
284 return -1;
285 }
286
287 for ( ; address < stop; address += size) {
288 switch (size) {
289 case 4:
290 *(uint32_t *)address = (uint32_t)val;
291 break;
292 case 2:
293 *(uint16_t *)address = (uint16_t)val;
294 break;
295 case 1:
296 *(uint8_t *)address = (uint8_t)val;
297 break;
298 }
299 }
300
301 return 0;
302}
303
304static int cmd_copy_mem(int argc, const cmd_args *argv)
305{
306 if (argc < 4) {
307 printf("not enough arguments\n");
308 printf("%s <source address> <target address> <len>\n", argv[0].str);
309 return -1;
310 }
311
312 addr_t source = argv[1].u;
313 addr_t target = argv[2].u;
314 size_t len = argv[3].u;
315
316 memcpy((void *)target, (const void *)source, len);
317
318 return 0;
319}
320
321static int cmd_memtest(int argc, const cmd_args *argv)
322{
323 if (argc < 3) {
324 printf("not enough arguments\n");
325 printf("%s <base> <len>\n", argv[0].str);
326 return -1;
327 }
328
329 uint32_t *ptr;
330 size_t len;
331
332 ptr = (uint32_t *)argv[1].u;
333 len = (size_t)argv[2].u;
334
335 size_t i;
336 // write out
337 printf("writing first pass...");
338 for (i = 0; i < len / 4; i++) {
339 ptr[i] = i;
340 }
341 printf("done\n");
342
343 // verify
344 printf("verifying...");
345 for (i = 0; i < len / 4; i++) {
346 if (ptr[i] != i)
347 printf("error at %p\n", &ptr[i]);
348 }
349 printf("done\n");
350
351 return 0;
352}
353
354#endif
355