use GET_THIS_TASK internally throughout exec - since it will result in faster/smaller...
[AROS.git] / rom / exec / debug.c
blob90605743e5fadd46c2dbf240f3c98df98e3be466
1 /*
2 Copyright © 1995-2015, 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/kernel.h>
14 #include <proto/debug.h>
16 #include <ctype.h>
17 #include <string.h>
19 #include "exec_intern.h"
20 #include "exec_util.h"
22 /****************************************************************************************/
24 char GetK();
25 UQUAD GetQ(char *);
26 ULONG GetL(char *);
27 UWORD GetW(char *);
28 UBYTE GetB(char *);
29 int get_irq_list(char *buf);
31 #if __WORDSIZE == 64
32 #define GetA (APTR)GetQ
33 #else
34 #define GetA (APTR)GetL
35 #endif
37 /****************************************************************************************/
39 static char *NextWord(char *s)
41 /* Skip to first space or EOL */
42 while (*s != ' ')
44 if (!*s)
45 return s;
46 s++;
49 /* Then skip to first non-space */
50 while (*++s == ' ');
52 return s;
55 /*****************************************************************************
57 NAME */
59 AROS_LH1(void, Debug,
61 /* SYNOPSIS */
62 AROS_LHA(unsigned long, flags, D0),
64 /* LOCATION */
65 struct ExecBase *, SysBase, 19, Exec)
67 /* FUNCTION
68 Runs SAD - internal debuger.
70 INPUTS
71 flags not used. Should be 0 now.
73 RESULT
75 NOTES
77 EXAMPLE
79 BUGS
81 SEE ALSO
83 INTERNALS
85 HISTORY
86 18-01-99 initial PC version.
88 *****************************************************************************/
90 AROS_LIBFUNC_INIT
92 char comm[128];
93 char *data;
94 BOOL ignorelf = FALSE;
97 * Try to obtain debug input from the kernel.
98 * If it failed, we will hang up in RawMayGetChar(), so exit immediately.
100 if (!KrnObtainInput())
101 return;
103 RawIOInit();
105 for (;;)
107 int i = 0;
109 kprintf("SAD(%d,%d)>", TDNESTCOUNT_GET, IDNESTCOUNT_GET);
111 /* Get Command code */
114 char key = GetK(SysBase);
115 BOOL t = ignorelf;
117 /* We skip only single LF which immediately follows the CR. So we remember
118 previous value of the flag and reset it when any character arrives. */
119 ignorelf = FALSE;
120 if (key == '\n') {
121 if (t)
122 continue;
123 else
124 break;
127 /* TABs are problematic to deal with, we ignore them */
128 else if (key == 0x09)
129 continue;
131 /* If we've just got CR, we may get LF next and we'll need to skip it */
132 else if (key == '\r') {
133 ignorelf = TRUE;
134 break;
137 /* Process backspace */
138 else if (key == 0x08)
140 if (i > 0) {
141 /* Go backwards, erase the character, then go backwards again */
142 RawPutChar(key);
143 RawPutChar(' ');
144 RawPutChar(key);
145 i--;
147 continue;
150 RawPutChar(key);
151 comm[i++] = key;
153 while (i < (int)sizeof(comm)-1);
154 comm[i] = 0;
155 RawPutChar('\n');
157 /* Now get data for command */
158 data = NextWord(comm);
159 comm[2] = 0;
161 /* Reboot command */
162 if (strcmp(comm, "RE") == 0 && strcmp(data, "AAAAAAAA") == 0)
163 ColdReboot();
164 /* Restart command */
165 else if (strcmp(comm, "RS") == 0 && strcmp(data, "FFFFFFFF") == 0)
166 ShutdownA(SD_ACTION_COLDREBOOT);
167 /* Forbid command */
168 else if (strcmp(comm, "FO") == 0)
169 Forbid();
170 /* Permit command */
171 else if (strcmp(comm, "PE") == 0)
172 Permit();
173 /* Disable command */
174 else if (strcmp(comm, "DI") == 0)
175 Disable();
176 /* Show task information */
177 else if (strcmp(comm, "TI") == 0)
179 struct Task *t = GetA(data);
181 if (!Exec_CheckTask(t, SysBase))
183 kprintf("Task 0x%P not found\n", t);
184 continue;
187 kprintf("Task status (%p = '%s'):\n"
188 "tc_Node.ln_Pri = %d\n"
189 "tc_Flags = %p\n"
190 "tc_SigAlloc = %04.4lx\n"
191 "tc_SigWait = %04.4lx\n"
192 "tc_SPLower = %p\n"
193 "tc_SPReg = %p\n"
194 "tc_SPUpper = %p\n"
195 "tc_IDNestCnt = %d\n"
196 "tc_TDNestCnt = %d\n",
197 t, t->tc_Node.ln_Name,
198 t->tc_Node.ln_Pri,
199 t->tc_Flags,
200 t->tc_SigAlloc,
201 t->tc_SigWait,
202 t->tc_SPLower,
203 t->tc_SPReg,
204 t->tc_SPUpper,
205 t->tc_IDNestCnt,
206 t->tc_TDNestCnt);
208 else if (strcmp(comm,"RI") == 0)
210 struct Task *t = GetA(data);
212 if (!Exec_CheckTask(t, SysBase))
214 kprintf("Task 0x%P not found\n", t);
215 continue;
218 kprintf("Task context (%p = '%s'):\n", t, t->tc_Node.ln_Name);
219 FormatCPUContext(NULL, t->tc_UnionETask.tc_ETask->et_RegFrame, SysBase);
220 RawPutChar('\n');
222 /* Enable command */
223 else if (strcmp(comm, "EN") == 0)
224 Enable();
225 /* ShowLibs command */
226 else if (strcmp(comm, "SL") == 0)
228 struct Node * node;
230 kprintf("Available libraries:\n");
232 /* Look through the list */
233 for (node = GetHead(&SysBase->LibList); node; node = GetSucc(node))
235 kprintf("0x%p : %s\n", node, node->ln_Name);
238 else if (strcmp(comm, "SI") == 0)
240 /* char buf[512];
242 kprintf("Available interrupts:\n");
244 get_irq_list(&buf);
245 kprintf(buf);*/
246 kprintf("Not implemented\n");
248 /* ShowResources command */
249 else if (strcmp(comm, "SR") == 0)
251 struct Node * node;
253 kprintf("Available resources:\n");
255 /* Look through the list */
256 for (node = GetHead(&SysBase->ResourceList); node; node = GetSucc(node))
258 kprintf("0x%p : %s\n", node, node->ln_Name);
261 /* ShowDevices command */
262 else if (strcmp(comm,"SD") == 0)
264 struct Node * node;
266 kprintf("Available devices:\n");
268 /* Look through the list */
269 for (node=GetHead(&SysBase->DeviceList); node; node = GetSucc(node))
271 kprintf("0x%p : %s\n", node, node->ln_Name);
274 /* ShowTasks command */
275 else if (strcmp(comm, "ST") == 0)
277 struct Node * node;
279 kprintf("Task List:\n");
281 #if defined(__AROSEXEC_SMP__)
282 ForeachNode(&PrivExecBase(SysBase)->TaskRunning, node)
284 #else
285 node = (struct Node *)GET_THIS_TASK;
286 #endif
287 kprintf("0x%p T %d %s\n", node, node->ln_Pri, node->ln_Name);
288 #if defined(__AROSEXEC_SMP__)
290 #endif
291 /* Look through the list */
292 for (node = GetHead(&SysBase->TaskReady); node; node = GetSucc(node))
294 kprintf("0x%p R %d %s\n", node, node->ln_Pri, node->ln_Name);
297 for (node = GetHead(&SysBase->TaskWait); node; node = GetSucc(node))
299 kprintf("0x%p W %d %s\n", node, node->ln_Pri, node->ln_Name);
302 kprintf("Idle called %d times\n", SysBase->IdleCount);
304 /* Help command */
305 else if (strcmp(comm, "HE") == 0)
307 kprintf("SAD Help:\n");
308 kprintf("RE AAAAAAAA - reboots AROS - ColdReboot()\n"
309 "RS FFFFFFFF - RESET\n"
310 "FO - Forbid()\n"
311 "PE - Permit()\n"
312 "DI - Disable()\n"
313 "EN - Enable()\n"
314 "SI - Show IRQ lines status\n"
315 "TI - Show Active task info\n"
316 "RI xxxxxxxx - Show registers inside task's context\n"
317 "AM xxxxxxxx yyyyyyyy - AllocVec - size=xxxxxxxx, "
318 "requiments=yyyyyyyy\n"
319 "FM xxxxxxxx - FreeVec from xxxxxxxx\n"
320 "RB xxxxxxxx - read byte from xxxxxxxx\n"
321 "RW xxxxxxxx - read word from xxxxxxxx\n"
322 "RL xxxxxxxx - read long from xxxxxxxx\n"
323 "WB xxxxxxxx bb - write byte bb at xxxxxxxx\n"
324 "WW xxxxxxxx wwww - write word wwww at xxxxxxxx\n"
325 "WL xxxxxxxx llllllll - write long llllllll at xxxxxxxx\n"
326 "RA xxxxxxxx ssssssss - read array(ssssssss bytes long) "
327 "from xxxxxxxx\n"
328 "RC xxxxxxxx ssssssss - read ascii (ssssssss bytes long) "
329 "from xxxxxxxx\n"
330 "QT 00000000 - quit SAD\n"
331 "SL - show all available libraries (libbase : libname)\n"
332 "SR - show all available resources (resbase : resname)\n"
333 "SD - show all available devices (devbase : devname)\n"
334 "SS xxxxxxxx - show symbol for xxxxxxxx\n"
335 "ST - show tasks (T - this, R - ready, W - wait)\n"
336 "HE - this help.\n");
338 /* AllocMem command */
339 else if (strcmp(comm, "AM") == 0)
341 ULONG size = GetL(data);
342 ULONG requim = GetL(NextWord(data));
344 kprintf("Allocated at 0x%p\n", AllocVec(size, requim));
346 /* FreeMem command */
347 else if (strcmp(comm, "FM") == 0)
349 APTR base = GetA(&data[0]);
351 kprintf("Freed at 0x%p\n", base);
352 FreeVec(base);
354 /* ReadByte */
355 else if (strcmp(comm, "RB") == 0)
357 UBYTE *addr = GetA(data);
359 kprintf("Byte at 0x%p: %02X\n", addr, *addr);
361 /* ReadWord */
362 else if (strcmp(comm, "RW") == 0)
364 UWORD *addr = GetA(data);
366 kprintf("Word at 0x%p: %04X\n", addr, *addr);
368 /* ReadLong */
369 else if (strcmp(comm, "RL") == 0)
371 ULONG *addr = GetA(data);
373 kprintf("Long at 0x%p: %08X\n", addr, *addr);
375 /* WriteByte */
376 else if (strcmp(comm,"WB") == 0)
378 UBYTE *addr = GetA(data);
379 UBYTE val = GetB(NextWord(data));
381 kprintf("Byte at 0x%p: %02X\n", addr, val);
382 *addr = val;
384 /* WriteWord */
385 else if (strcmp(comm, "WW") == 0)
387 UWORD *addr = GetA(data);
388 UWORD val = GetW(NextWord(data));
390 kprintf("Word at 0x%p: %04X\n", addr, val);
391 *addr = val;
393 /* WriteLong */
394 else if (strcmp(comm, "WL") == 0)
396 ULONG *addr = GetA(data);
397 ULONG val = GetL(NextWord(data));
399 kprintf("Long at 0x%p: %08X\n", addr, val);
400 *addr = val;
402 /* ReadArray */
403 else if (strcmp(comm, "RA") == 0)
405 UBYTE *ptr = GetA(data);
406 ULONG cnt = GetL(NextWord(data));
407 ULONG t;
409 kprintf("Array from 0x%p (size=0x%08lX):\n", ptr, cnt);
411 for(t = 1; t <= cnt; t++)
413 kprintf("%02X ", *ptr++);
414 if(!(t % 16)) kprintf("\n");
416 kprintf("\n");
418 /* ReadASCII */
419 else if (strcmp(comm, "RC") == 0)
421 char *ptr = GetA(data);
422 ULONG cnt = GetL(NextWord(data));
423 ULONG t;
425 kprintf("ASCII from 0x%p (size=%08X):\n", ptr, cnt);
427 for(t = 1; t <= cnt; t++)
429 RawPutChar(*ptr++);
430 if(!(t % 70)) kprintf(" \n");
432 kprintf(" \n");
434 else if (strcmp(comm, "SS") == 0) {
435 char *ptr = GetA(data);
436 STRPTR modname = "(unknown)";
437 STRPTR symname = "(unknown)";
438 APTR sym_l = (APTR)(IPTR)0;
439 APTR sym_h = (APTR)~(IPTR)0;
440 struct TagItem tags[] = {
441 { DL_ModuleName, (IPTR)&modname },
442 { DL_SymbolName, (IPTR)&symname },
443 { DL_SymbolStart, (IPTR)&sym_l },
444 { DL_SymbolEnd, (IPTR)&sym_h },
445 { TAG_END }
448 if (DebugBase) {
449 DecodeLocationA(ptr, tags);
452 kprintf("%p %s %s+0x%x\n", sym_l, sym_h, modname, symname, (APTR)ptr - (APTR)sym_l);
454 else if (strcmp(comm, "QT") == 0 && strcmp(data, "00000000") == 0)
456 kprintf("Quitting SAD...\n");
457 KrnReleaseInput(); /* Release debug input */
458 return;
460 else kprintf("?? Type HE for help\n");
463 AROS_LIBFUNC_EXIT
464 } /* Debug */
466 /****************************************************************************************/
468 char GetK(struct ExecBase *SysBase)
470 int i;
474 i = RawMayGetChar();
475 } while(i == -1);
477 return (char)i;
480 /****************************************************************************************/
482 UQUAD GetQ(char* string)
484 UQUAD ret = 0;
485 int i;
486 char digit;
488 for(i = 0; i < 16; i++)
490 digit = toupper(string[i]);
492 if (!isxdigit(digit))
493 break;
495 digit -= '0';
496 if (digit > 9) digit -= 'A' - '0' - 10;
497 ret = (ret << 4) + digit;
500 return ret;
503 /****************************************************************************************/
505 ULONG GetL(char* string)
507 ULONG ret = 0;
508 int i;
509 char digit;
511 for(i = 0; i < 8; i++)
513 digit = toupper(string[i]);
515 if (!isxdigit(digit))
516 break;
518 digit -= '0';
519 if (digit > 9) digit -= 'A' - '0' - 10;
520 ret = (ret << 4) + digit;
523 return ret;
526 /****************************************************************************************/
528 UWORD GetW(char* string)
530 UWORD ret = 0;
531 int i;
532 char digit;
534 for(i = 0; i < 4; i++)
536 digit = toupper(string[i]);
538 if (!isxdigit(digit))
539 break;
541 digit -= '0';
542 if (digit > 9) digit -= 'A' - '0' - 10;
543 ret = (ret << 4) + digit;
546 return ret;
549 /****************************************************************************************/
551 UBYTE GetB(char* string)
553 UBYTE ret = 0;
554 int i;
555 char digit;
557 for(i = 0; i < 2; i++)
559 digit = toupper(string[i]);
561 if (!isxdigit(digit))
562 break;
564 digit -= '0';
565 if (digit > 9) digit -= 'A' - '0' - 10;
566 ret = (ret << 4) + digit;
569 return ret;