revert between 56095 -> 55830 in arch
[AROS.git] / rom / exec / debug.c
blob40c5fd1a7e351fd846558f2754467c1d7f907393
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Internal debugger.
6 Lang: english
7 */
9 #include <aros/debug.h>
10 #include <exec/interrupts.h>
11 #include <libraries/debug.h>
12 #include <proto/exec.h>
13 #include <proto/debug.h>
15 #include <ctype.h>
16 #include <string.h>
18 #include "exec_intern.h"
19 #include "exec_util.h"
21 /****************************************************************************************/
23 char GetK();
24 UQUAD GetQ(char *);
25 ULONG GetL(char *);
26 UWORD GetW(char *);
27 UBYTE GetB(char *);
28 int get_irq_list(char *buf);
30 #if __WORDSIZE == 64
31 #define GetA (APTR)GetQ
32 #else
33 #define GetA (APTR)GetL
34 #endif
36 /****************************************************************************************/
38 static char *NextWord(char *s)
40 /* Skip to first space or EOL */
41 while (*s != ' ')
43 if (!*s)
44 return s;
45 s++;
48 /* Then skip to first non-space */
49 while (*++s == ' ');
51 return s;
54 /*****************************************************************************
56 NAME */
58 AROS_LH1(void, Debug,
60 /* SYNOPSIS */
61 AROS_LHA(unsigned long, flags, D0),
63 /* LOCATION */
64 struct ExecBase *, SysBase, 19, Exec)
66 /* FUNCTION
67 Runs SAD - internal debuger.
69 INPUTS
70 flags not used. Should be 0 now.
72 RESULT
74 NOTES
76 EXAMPLE
78 BUGS
80 SEE ALSO
82 INTERNALS
84 HISTORY
85 18-01-99 initial PC version.
87 *****************************************************************************/
89 AROS_LIBFUNC_INIT
91 char comm[128];
92 char *data;
93 BOOL ignorelf = FALSE;
96 * Try to obtain debug input from the kernel.
97 * If it failed, we will hang up in RawMayGetChar(), so exit immediately.
99 if (!KrnObtainInput())
100 return;
102 RawIOInit();
104 for (;;)
106 int i = 0;
108 kprintf("SAD(%d,%d)>", TDNESTCOUNT_GET, IDNESTCOUNT_GET);
110 /* Get Command code */
113 char key = GetK(SysBase);
114 BOOL t = ignorelf;
116 /* We skip only single LF which immediately follows the CR. So we remember
117 previous value of the flag and reset it when any character arrives. */
118 ignorelf = FALSE;
119 if (key == '\n') {
120 if (t)
121 continue;
122 else
123 break;
126 /* TABs are problematic to deal with, we ignore them */
127 else if (key == 0x09)
128 continue;
130 /* If we've just got CR, we may get LF next and we'll need to skip it */
131 else if (key == '\r') {
132 ignorelf = TRUE;
133 break;
136 /* Process backspace */
137 else if (key == 0x08)
139 if (i > 0) {
140 /* Go backwards, erase the character, then go backwards again */
141 RawPutChar(key);
142 RawPutChar(' ');
143 RawPutChar(key);
144 i--;
146 continue;
149 RawPutChar(key);
150 comm[i++] = key;
152 while (i < (int)sizeof(comm)-1);
153 comm[i] = 0;
154 RawPutChar('\n');
156 /* Now get data for command */
157 data = NextWord(comm);
158 comm[2] = 0;
160 /* Reboot command */
161 if (strcmp(comm, "RE") == 0 && strcmp(data, "AAAAAAAA") == 0)
162 ColdReboot();
163 /* Restart command */
164 else if (strcmp(comm, "RS") == 0 && strcmp(data, "FFFFFFFF") == 0)
165 ShutdownA(SD_ACTION_COLDREBOOT);
166 /* Forbid command */
167 else if (strcmp(comm, "FO") == 0)
168 Forbid();
169 /* Permit command */
170 else if (strcmp(comm, "PE") == 0)
171 Permit();
172 /* Disable command */
173 else if (strcmp(comm, "DI") == 0)
174 Disable();
175 /* Show task information */
176 else if (strcmp(comm, "TI") == 0)
178 struct Task *t = GetA(data);
180 if (!Exec_CheckTask(t, SysBase))
182 kprintf("Task 0x%P not found\n", t);
183 continue;
186 kprintf("Task status (%p = '%s'):\n"
187 "tc_Node.ln_Pri = %d\n"
188 "tc_Flags = %p\n"
189 "tc_SigAlloc = %04.4lx\n"
190 "tc_SigWait = %04.4lx\n"
191 "tc_SPLower = %p\n"
192 "tc_SPReg = %p\n"
193 "tc_SPUpper = %p\n"
194 "tc_IDNestCnt = %d\n"
195 "tc_TDNestCnt = %d\n",
196 t, t->tc_Node.ln_Name,
197 t->tc_Node.ln_Pri,
198 t->tc_Flags,
199 t->tc_SigAlloc,
200 t->tc_SigWait,
201 t->tc_SPLower,
202 t->tc_SPReg,
203 t->tc_SPUpper,
204 t->tc_IDNestCnt,
205 t->tc_TDNestCnt);
207 else if (strcmp(comm,"RI") == 0)
209 struct Task *t = GetA(data);
211 if (!Exec_CheckTask(t, SysBase))
213 kprintf("Task 0x%P not found\n", t);
214 continue;
217 kprintf("Task context (%p = '%s'):\n", t, t->tc_Node.ln_Name);
218 FormatCPUContext(NULL, t->tc_UnionETask.tc_ETask->et_RegFrame, SysBase);
219 RawPutChar('\n');
221 /* Enable command */
222 else if (strcmp(comm, "EN") == 0)
223 Enable();
224 /* ShowLibs command */
225 else if (strcmp(comm, "SL") == 0)
227 struct Node * node;
229 kprintf("Available libraries:\n");
231 /* Look through the list */
232 for (node = GetHead(&SysBase->LibList); node; node = GetSucc(node))
234 kprintf("0x%p : %s\n", node, node->ln_Name);
237 else if (strcmp(comm, "SI") == 0)
239 /* char buf[512];
241 kprintf("Available interrupts:\n");
243 get_irq_list(&buf);
244 kprintf(buf);*/
245 kprintf("Not implemented\n");
247 /* ShowResources command */
248 else if (strcmp(comm, "SR") == 0)
250 struct Node * node;
252 kprintf("Available resources:\n");
254 /* Look through the list */
255 for (node = GetHead(&SysBase->ResourceList); node; node = GetSucc(node))
257 kprintf("0x%p : %s\n", node, node->ln_Name);
260 /* ShowDevices command */
261 else if (strcmp(comm,"SD") == 0)
263 struct Node * node;
265 kprintf("Available devices:\n");
267 /* Look through the list */
268 for (node=GetHead(&SysBase->DeviceList); node; node = GetSucc(node))
270 kprintf("0x%p : %s\n", node, node->ln_Name);
273 /* ShowTasks command */
274 else if (strcmp(comm, "ST") == 0)
276 struct Node * node;
278 kprintf("Task List:\n");
280 #if defined(__AROSEXEC_SMP__)
281 ForeachNode(&PrivExecBase(SysBase)->TaskRunning, node)
283 #else
284 node = (struct Node *)GET_THIS_TASK;
285 #endif
286 kprintf("0x%p T %d %s\n", node, node->ln_Pri, node->ln_Name);
287 #if defined(__AROSEXEC_SMP__)
289 #endif
290 /* Look through the list */
291 for (node = GetHead(&SysBase->TaskReady); node; node = GetSucc(node))
293 kprintf("0x%p R %d %s\n", node, node->ln_Pri, node->ln_Name);
296 for (node = GetHead(&SysBase->TaskWait); node; node = GetSucc(node))
298 kprintf("0x%p W %d %s\n", node, node->ln_Pri, node->ln_Name);
301 kprintf("Idle called %d times\n", SysBase->IdleCount);
303 /* Help command */
304 else if (strcmp(comm, "HE") == 0)
306 kprintf("SAD Help:\n");
307 kprintf("RE AAAAAAAA - reboots AROS - ColdReboot()\n"
308 "RS FFFFFFFF - RESET\n"
309 "FO - Forbid()\n"
310 "PE - Permit()\n"
311 "DI - Disable()\n"
312 "EN - Enable()\n"
313 "SI - Show IRQ lines status\n"
314 "TI - Show Active task info\n"
315 "RI xxxxxxxx - Show registers inside task's context\n"
316 "AM xxxxxxxx yyyyyyyy - AllocVec - size=xxxxxxxx, "
317 "requiments=yyyyyyyy\n"
318 "FM xxxxxxxx - FreeVec from xxxxxxxx\n"
319 "RB xxxxxxxx - read byte from xxxxxxxx\n"
320 "RW xxxxxxxx - read word from xxxxxxxx\n"
321 "RL xxxxxxxx - read long from xxxxxxxx\n"
322 "WB xxxxxxxx bb - write byte bb at xxxxxxxx\n"
323 "WW xxxxxxxx wwww - write word wwww at xxxxxxxx\n"
324 "WL xxxxxxxx llllllll - write long llllllll at xxxxxxxx\n"
325 "RA xxxxxxxx ssssssss - read array(ssssssss bytes long) "
326 "from xxxxxxxx\n"
327 "RC xxxxxxxx ssssssss - read ascii (ssssssss bytes long) "
328 "from xxxxxxxx\n"
329 "QT 00000000 - quit SAD\n"
330 "SL - show all available libraries (libbase : libname)\n"
331 "SR - show all available resources (resbase : resname)\n"
332 "SD - show all available devices (devbase : devname)\n"
333 "SS xxxxxxxx - show symbol for xxxxxxxx\n"
334 "ST - show tasks (T - this, R - ready, W - wait)\n"
335 "HE - this help.\n");
337 /* AllocMem command */
338 else if (strcmp(comm, "AM") == 0)
340 ULONG size = GetL(data);
341 ULONG requim = GetL(NextWord(data));
343 kprintf("Allocated at 0x%p\n", AllocVec(size, requim));
345 /* FreeMem command */
346 else if (strcmp(comm, "FM") == 0)
348 APTR base = GetA(&data[0]);
350 kprintf("Freed at 0x%p\n", base);
351 FreeVec(base);
353 /* ReadByte */
354 else if (strcmp(comm, "RB") == 0)
356 UBYTE *addr = GetA(data);
358 kprintf("Byte at 0x%p: %02X\n", addr, *addr);
360 /* ReadWord */
361 else if (strcmp(comm, "RW") == 0)
363 UWORD *addr = GetA(data);
365 kprintf("Word at 0x%p: %04X\n", addr, *addr);
367 /* ReadLong */
368 else if (strcmp(comm, "RL") == 0)
370 ULONG *addr = GetA(data);
372 kprintf("Long at 0x%p: %08X\n", addr, *addr);
374 /* WriteByte */
375 else if (strcmp(comm,"WB") == 0)
377 UBYTE *addr = GetA(data);
378 UBYTE val = GetB(NextWord(data));
380 kprintf("Byte at 0x%p: %02X\n", addr, val);
381 *addr = val;
383 /* WriteWord */
384 else if (strcmp(comm, "WW") == 0)
386 UWORD *addr = GetA(data);
387 UWORD val = GetW(NextWord(data));
389 kprintf("Word at 0x%p: %04X\n", addr, val);
390 *addr = val;
392 /* WriteLong */
393 else if (strcmp(comm, "WL") == 0)
395 ULONG *addr = GetA(data);
396 ULONG val = GetL(NextWord(data));
398 kprintf("Long at 0x%p: %08X\n", addr, val);
399 *addr = val;
401 /* ReadArray */
402 else if (strcmp(comm, "RA") == 0)
404 UBYTE *ptr = GetA(data);
405 ULONG cnt = GetL(NextWord(data));
406 ULONG t;
408 kprintf("Array from 0x%p (size=0x%08lX):\n", ptr, cnt);
410 for(t = 1; t <= cnt; t++)
412 kprintf("%02X ", *ptr++);
413 if(!(t % 16)) kprintf("\n");
415 kprintf("\n");
417 /* ReadASCII */
418 else if (strcmp(comm, "RC") == 0)
420 char *ptr = GetA(data);
421 ULONG cnt = GetL(NextWord(data));
422 ULONG t;
424 kprintf("ASCII from 0x%p (size=%08X):\n", ptr, cnt);
426 for(t = 1; t <= cnt; t++)
428 RawPutChar(*ptr++);
429 if(!(t % 70)) kprintf(" \n");
431 kprintf(" \n");
433 else if (strcmp(comm, "SS") == 0) {
434 char *ptr = GetA(data);
435 STRPTR modname = "(unknown)";
436 STRPTR symname = "(unknown)";
437 APTR sym_l = (APTR)(IPTR)0;
438 APTR sym_h = (APTR)~(IPTR)0;
439 struct TagItem tags[] = {
440 { DL_ModuleName, (IPTR)&modname },
441 { DL_SymbolName, (IPTR)&symname },
442 { DL_SymbolStart, (IPTR)&sym_l },
443 { DL_SymbolEnd, (IPTR)&sym_h },
444 { TAG_END }
447 if (DebugBase) {
448 DecodeLocationA(ptr, tags);
451 kprintf("%p %s %s+0x%x\n", sym_l, sym_h, modname, symname, (APTR)ptr - (APTR)sym_l);
453 else if (strcmp(comm, "QT") == 0 && strcmp(data, "00000000") == 0)
455 kprintf("Quitting SAD...\n");
456 KrnReleaseInput(); /* Release debug input */
457 return;
459 else kprintf("?? Type HE for help\n");
462 AROS_LIBFUNC_EXIT
463 } /* Debug */
465 /****************************************************************************************/
467 char GetK(struct ExecBase *SysBase)
469 int i;
473 i = RawMayGetChar();
474 } while(i == -1);
476 return (char)i;
479 /****************************************************************************************/
481 UQUAD GetQ(char* string)
483 UQUAD ret = 0;
484 int i;
485 char digit;
487 for(i = 0; i < 16; i++)
489 digit = toupper(string[i]);
491 if (!isxdigit(digit))
492 break;
494 digit -= '0';
495 if (digit > 9) digit -= 'A' - '0' - 10;
496 ret = (ret << 4) + digit;
499 return ret;
502 /****************************************************************************************/
504 ULONG GetL(char* string)
506 ULONG ret = 0;
507 int i;
508 char digit;
510 for(i = 0; i < 8; i++)
512 digit = toupper(string[i]);
514 if (!isxdigit(digit))
515 break;
517 digit -= '0';
518 if (digit > 9) digit -= 'A' - '0' - 10;
519 ret = (ret << 4) + digit;
522 return ret;
525 /****************************************************************************************/
527 UWORD GetW(char* string)
529 UWORD ret = 0;
530 int i;
531 char digit;
533 for(i = 0; i < 4; i++)
535 digit = toupper(string[i]);
537 if (!isxdigit(digit))
538 break;
540 digit -= '0';
541 if (digit > 9) digit -= 'A' - '0' - 10;
542 ret = (ret << 4) + digit;
545 return ret;
548 /****************************************************************************************/
550 UBYTE GetB(char* string)
552 UBYTE ret = 0;
553 int i;
554 char digit;
556 for(i = 0; i < 2; i++)
558 digit = toupper(string[i]);
560 if (!isxdigit(digit))
561 break;
563 digit -= '0';
564 if (digit > 9) digit -= 'A' - '0' - 10;
565 ret = (ret << 4) + digit;
568 return ret;