3f4bd2f495d0ecd16479eefdc131300445956a8e
[AROS.git] / arch / i386-pc / exec / debug.c
blob3f4bd2f495d0ecd16479eefdc131300445956a8e
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Start the internal debugger.
6 Lang: english
7 */
9 #include <string.h>
10 #include "exec_intern.h"
11 #include <proto/exec.h>
12 #include <exec/types.h>
13 #include <asm/speaker.h>
15 /****************************************************************************************/
17 #define Prompt kprintf("SAD(%ld,%ld)>",SysBase->TDNestCnt,SysBase->IDNestCnt)
19 /*#define GetHead(l) (void *)(((struct List *)l)->lh_Head->ln_Succ \
20 ? ((struct List *)l)->lh_Head \
21 : (struct Node *)0)
22 #define GetSucc(n) (void *)(((struct Node *)n)->ln_Succ->ln_Succ \
23 ? ((struct Node *)n)->ln_Succ \
24 : (struct Node *)0)
26 /****************************************************************************************/
28 void InitKeyboard(void);
29 char GetK();
30 void UnGetK();
31 void DumpRegs();
32 ULONG GetL(char*);
33 UWORD GetW(char*);
34 UBYTE GetB(char*);
35 int get_irq_list(char *buf);
37 /****************************************************************************************/
40 /*****************************************************************************
42 NAME */
44 AROS_LH1(void, Debug,
46 /* SYNOPSIS */
47 AROS_LHA(unsigned long, flags, D0),
49 /* LOCATION */
50 struct ExecBase *, SysBase, 19, Exec)
52 /* FUNCTION
53 Runs SAD - internal debuger.
55 INPUTS
56 flags not used. Should be 0 now.
58 RESULT
60 NOTES
62 EXAMPLE
64 BUGS
66 SEE ALSO
68 INTERNALS
70 HISTORY
71 18-01-99 initial PC version.
73 *****************************************************************************/
75 AROS_LIBFUNC_INIT
77 char key;
78 /* KeyCode -> ASCII conversion table */
79 static char transl[] =
80 { ' ', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', ' ', ' ', ' ',
81 ' ', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', ' ', ' ', 10,
82 ' ', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ' ', ' ', ' ', ' ',
83 ' ', 'Z', 'X', 'C', 'V', 'B', 'N', 'M' };
85 static char command[3] = {0, 0, 0};
86 static char data[70];
88 char *comm = &command[0];
89 char *dat = &data[0];
91 InitKeyboard();
95 int i;
97 Prompt;
99 /* Get Command code */
101 for(i = 0; i < 2; i++)
103 key = transl[GetK() - 1];
104 kprintf("%c", key);
105 UnGetK();
106 command[i] = key;
108 command[2] = 0;
110 kprintf(" ");
111 i = 0;
113 /* Now get data for command */
117 key = GetK();
118 key = transl[(key == 0x39) ? 1 : key - 1];
119 if (key != 10) kprintf("%c",key);
120 else kprintf("\n");
121 UnGetK();
122 if(key != ' ') data[i++]=key;
123 } while(key !=10 && i < 70);
124 data[i - 1] = 0;
126 /* Reboot command */
127 if (strcmp(comm, "RE") == 0 && strcmp(dat, "AAAAAAAA") == 0) ColdReboot();
128 /* Restart command, pulse reset signal */
129 else if (strcmp(comm, "RS") == 0 && strcmp(dat, "FFFFFFFF") == 0)
130 asm("movb $0xfe,%%al;outb %%al,$0x64":::"eax");
131 /* Forbid command */
132 else if (strcmp(comm, "FO") == 0)
133 Forbid();
134 /* Permit command */
135 else if (strcmp(comm, "PE") == 0)
136 Permit();
137 /* Disable command */
138 else if (strcmp(comm, "DI") == 0)
139 Disable();
140 /* Dump regs command */
141 else if (strcmp(comm, "DU") == 0)
142 DumpRegs();
143 else if (strcmp(comm, "MO") == 0)
144 asm("movb $0xa8,%%al;outb %%al,$0x64":::"eax");
145 /* Show active task information */
146 else if (strcmp(comm, "TI") == 0)
148 struct Task *t = SysBase->ThisTask;
150 kprintf("Active task (%p = '%s'):\n"
151 "tc_Node.ln_Pri = %d\n"
152 "tc_SigAlloc = %04.4lx\n"
153 "tc_SPLower = %p\n"
154 "tc_SPUpper = %p\n"
155 "tc_Flags = %08.8lx\n"
156 "tc_SPReg = %p\n",
157 t, t->tc_Node.ln_Name,
158 t->tc_Node.ln_Pri,
159 t->tc_SigAlloc,
160 t->tc_SPLower,
161 t->tc_SPUpper,
162 t->tc_Flags,
163 t->tc_SPReg);
165 /* else if (strcmp(comm,"RI") == 0)
168 struct pt_regs *r = (struct pt_regs *)SysBase->ThisTask->tc_UnionETask.tc_ETask->et_RegFrame;
170 kprintf("Active task's registers dump:\n"
171 "EAX=%p ECX=%p EDX=%p EIP=%p\n"
172 "CS=%04.4lx DS=%04.4lx ES=%04.4lx\n"
173 "SS=%04.4lx EFLAGS=%p\n",
174 r->eax, r->ecx, r->edx,
175 r->eip, r->xcs, r->xds, r->xes,
176 r->xss, r->eflags);
177 } */
178 /* Enable command */
179 else if (strcmp(comm, "EN") == 0)
180 Enable();
181 /* ShowLibs command */
182 else if (strcmp(comm, "SL") == 0)
184 struct Node * node;
186 kprintf("Available libraries:\n");
188 /* Look through the list */
189 for (node = GetHead(&SysBase->LibList); node; node = GetSucc(node))
191 kprintf("0x%08.8lx : %s\n", node, node->ln_Name);
194 else if (strcmp(comm, "SI") == 0)
196 // char buf[512];
198 kprintf("Available interrupts:\n");
200 // get_irq_list(&buf);
202 // kprintf(buf);
204 /* ShowResources command */
205 else if (strcmp(comm, "SR") == 0)
207 struct Node * node;
209 kprintf("Available resources:\n");
211 /* Look through the list */
212 for (node = GetHead(&SysBase->ResourceList); node; node = GetSucc(node))
214 kprintf("0x%08.8lx : %s\n", node, node->ln_Name);
217 /* ShowDevices command */
218 else if (strcmp(comm,"SD") == 0)
220 struct Node * node;
222 kprintf("Available devices:\n");
224 /* Look through the list */
225 for (node=GetHead(&SysBase->DeviceList); node; node = GetSucc(node))
227 kprintf("0x%08.8lx : %s\n", node, node->ln_Name);
230 /* ShowTasks command */
231 else if (strcmp(comm, "ST") == 0)
233 struct Node * node;
235 kprintf("Task List:\n");
237 kprintf("0x%08.8lx T %d %s\n",SysBase->ThisTask,
238 SysBase->ThisTask->tc_Node.ln_Pri,
239 SysBase->ThisTask->tc_Node.ln_Name);
241 /* Look through the list */
242 for (node = GetHead(&SysBase->TaskReady); node; node = GetSucc(node))
244 kprintf("0x%08.8lx R %d %s\n", node, node->ln_Pri, node->ln_Name);
247 for (node = GetHead(&SysBase->TaskWait); node; node = GetSucc(node))
249 kprintf("0x%08.8lx W %d %s\n", node, node->ln_Pri, node->ln_Name);
252 kprintf("Idle called %d times\n", SysBase->IdleCount);
254 /* Help command */
255 else if (strcmp(comm, "HE") == 0)
257 kprintf("SAD Help:\n");
258 kprintf("RE AAAAAAAA - reboots AROS - ColdReboot()\n"
259 "RS FFFFFFFF - RESET\n"
260 "FO - Forbid()\n"
261 "PE - Permit()\n"
262 "DI - Disable()\n"
263 "EN - Enable()\n"
264 "DU - Dump most important registers\n"
265 "SI - Show IRQ lines status\n"
266 "TI - Show Active task info\n"
267 "RI - Show registers inside task's context\n"
268 "AM xxxxxxxx yyyyyyyy - AllocVec - size=xxxxxxxx, "
269 "requirements=yyyyyyyy\n"
270 "FM xxxxxxxx - FreeVec from xxxxxxxx\n"
271 "RB xxxxxxxx - read byte from xxxxxxxx\n"
272 "RW xxxxxxxx - read word from xxxxxxxx\n"
273 "RL xxxxxxxx - read long from xxxxxxxx\n"
274 "WB xxxxxxxx bb - write byte bb at xxxxxxxx\n"
275 "WW xxxxxxxx wwww - write word wwww at xxxxxxxx\n"
276 "WL xxxxxxxx llllllll - write long llllllll at xxxxxxxx\n"
277 "RA xxxxxxxx ssssssss - read array(ssssssss bytes long) "
278 "from xxxxxxxx\n"
279 "RC xxxxxxxx ssssssss - read ascii (ssssssss bytes long) "
280 "from xxxxxxxx\n"
281 "QT 00000000 - quit SAD\n"
282 "SL - show all available libraries (libbase : libname)\n"
283 "SR - show all available resources (resbase : resname)\n"
284 "SD - show all available devices (devbase : devname)\n"
285 "ST - show tasks (T - this, R - ready, W - wait)\n"
286 "BE - beep\n"
287 "HE - this help.\n");
289 /* AllocMem command */
290 else if (strcmp(comm, "AM") == 0)
292 ULONG size = GetL(&data[0]);
293 ULONG requim = GetL(&data[8]);
295 kprintf("Allocated at %08.8lx\n", AllocVec(size, requim));
297 /* FreeMem command */
298 else if (strcmp(comm, "FM") == 0)
300 APTR base = (APTR)GetL(&data[0]);
301 kprintf("Freed at %08.8lx\n", base);
302 FreeVec(base);
304 /* ReadByte */
305 else if (strcmp(comm, "RB") == 0)
306 kprintf("Byte at %08.8lx:%02.8lx\n", GetL(&data[0]),
307 *(UBYTE*)(GetL(&data[0])));
308 /* ReadWord */
309 else if (strcmp(comm, "RW") == 0)
310 kprintf("Word at %08.8lx:%04.8lx\n", GetL(&data[0]),
311 *(UWORD*)(GetL(&data[0])));
312 /* ReadLong */
313 else if (strcmp(comm, "RL") == 0)
314 kprintf("Long at %08.8lx:%08.8lx\n", GetL(&data[0]),
315 *(ULONG*)(GetL(&data[0])));
316 /* WriteByte */
317 else if (strcmp(comm,"WB") == 0)
319 kprintf("Byte at %08.8lx:%02.8lx\n", GetL(&data[0]),
320 GetB(&data[8]));
321 *(UBYTE*)(GetL(&data[0])) = GetB(&data[8]);
323 /* WriteWord */
324 else if (strcmp(comm, "WW") == 0)
326 kprintf("Word at %08.8lx:%04.8lx\n", GetL(&data[0]),
327 GetW(&data[8]));
328 *(UWORD*)(GetL(&data[0])) = GetW(&data[8]);
330 /* WriteLong */
331 else if (strcmp(comm, "WL") == 0)
333 kprintf("Long at %08.8lx:%08.8lx\n", GetL(&data[0]),
334 GetL(&data[8]));
335 *(ULONG*)(GetL(&data[0])) = GetL(&data[8]);
337 /* ReadArray */
338 else if (strcmp(comm, "RA") == 0)
340 ULONG ptr;
341 int cnt, t;
343 kprintf("Array from %08.8lx (size=%08.8lx):\n", GetL(&data[0]),
344 GetL(&data[8]));
345 ptr = GetL(&data[0]);
346 cnt = (int)GetL(&data[8]);
347 for(t = 1; t <= cnt; t++)
349 kprintf("%02.2lx ", *(UBYTE*)ptr);
350 ptr++;
351 if(!(t % 16)) kprintf("\n");
353 kprintf("\n");
355 /* ReadASCII */
356 else if (strcmp(comm, "RC") == 0)
358 ULONG ptr;
359 int cnt, t;
361 kprintf("ASCII from %08.8lx (size=%08.8lx):\n", GetL(&data[0]),
362 GetL(&data[8]));
363 ptr = GetL(&data[0]);
364 cnt = (int)GetL(&data[8]);
365 for(t = 1; t <= cnt; t++)
367 kprintf("%c",*(char*)ptr);
368 ptr++;
369 if(!(t % 70)) kprintf(" \n");
371 kprintf(" \n");
373 else if (strcmp(comm, "BE") == 0)
375 ULONG i;
376 #define DELAY_1USEC() inb(0x80)
378 kprintf("Beeping...\n");
380 SetSpkFreq (400);
381 SpkOn();
382 for (i = 0; i < 2000000; i++)
383 DELAY_1USEC();
384 SpkOff();
385 for (i = 0; i < 1000000; i++)
386 DELAY_1USEC();
388 SetSpkFreq (500);
389 SpkOn();
390 for (i = 0; i < 2000000; i++)
391 DELAY_1USEC();
392 SpkOff();
393 for (i = 0; i < 1000000; i++)
394 DELAY_1USEC();
396 SetSpkFreq (592);
397 SpkOn();
398 for (i = 0; i < 2000000; i++)
399 DELAY_1USEC();
400 SpkOff();
401 for (i = 0; i < 1000000; i++)
402 DELAY_1USEC();
404 SetSpkFreq (788);
405 SpkOn();
406 for (i = 0; i < 2000000; i++)
407 DELAY_1USEC();
408 SpkOff();
411 else if (strcmp(comm, "QT") == 0 && strcmp(dat, "00000000") == 0)
414 else kprintf("?? Type HE for help\n");
416 } while(strcmp(comm, "QT") != 0 || strcmp(dat, "00000000") != 0);
418 kprintf("Quitting SAD...\n");
420 AROS_LIBFUNC_EXIT
421 } /* Debug */
423 /****************************************************************************************/
425 int getkey(void)
427 int i;
429 asm (
430 " xorl %%eax, %%eax \n"
431 " inb $0x64, %%al \n"
432 " andb $0x01, %%al \n"
433 " jz 2f \n"
434 " inb $0x60, %%al \n"
435 " movl %%eax, %0 \n"
436 " inb $0x61, %%al \n"
437 " movb %%al, %%ah \n"
438 " orb $0x80, %%al \n"
439 " outb %%al, $0x61 \n"
440 " movb %%ah, %%al \n"
441 " outb %%al, $0x61 \n"
442 " jmp 3f \n"
443 "2: movl $-1, %0 \n"
444 "3: \n"
445 : "=g" (i)
447 : "%eax"
450 return i;
453 /****************************************************************************************/
455 void InitKeyboard(void)
457 int i;
459 /* keyboard self test */
461 while(getkey() != -1);
463 asm (
464 "xorl %%eax,%%eax \n"
465 "movb $0xaa, %%al \n"
466 "outb %%al, $0x64 \n"
467 "inb $0x60, %%al \n"
468 "movl %%eax, %0 \n"
469 : "=g" (i)
471 : "%eax"
474 if(i == 0x55)
476 //kprintf("Debug(): Keyboard self-test okay :-)\n");
477 } else {
478 //kprintf("Debug(): Error: keyboard self-test failed.\n");
482 /****************************************************************************************/
484 void UnGetK()
488 /****************************************************************************************/
490 char GetK(void)
492 int i;
496 i = getkey();
497 } while((i == -1) || (i & 0x80));
499 return (char)i;
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 = (*string++) - '0';
513 if (digit > 9) digit -= 'A' - '0' - 10;
514 ret = (ret << 4) + digit;
517 return(ret);
520 /****************************************************************************************/
522 UWORD GetW(char* string)
524 UWORD ret = 0;
525 int i;
526 char digit;
528 for(i = 0; i < 4; i++)
530 digit = (*string++) - '0';
531 if (digit > 9) digit -= 'A' - '0' - 10;
532 ret = (ret << 4) + digit;
535 return(ret);
538 /****************************************************************************************/
540 UBYTE GetB(char* string)
542 UBYTE ret = 0;
543 int i;
544 char digit;
546 for(i = 0; i < 2; i++)
548 digit = (*string++) - '0';
549 if (digit > 9) digit -= 'A' - '0' - 10;
550 ret = (ret << 4) + digit;
553 return(ret);
556 /****************************************************************************************/
558 void DumpRegs()
560 int ds, cs, ss, eflags, esp;
562 asm("push %%ds\n\t"
563 "popl %0\n\t"
564 "push %%cs\n\t"
565 "popl %1\n\t"
566 "push %%ss\n\t"
567 "popl %2\n\t"
568 "pushfl\n\t"
569 "popl %3\n\t"
570 "pushl %%esp\n\t"
571 "popl %4"
572 :"=m"(ds),"=m"(cs),"=m"(ss),"=m"(eflags),"=m"(esp));
574 kprintf("DS=%04.4x CS=%04.4x SS=%04.4x ESP=%08.8x EFLAGS=%08.8x\n",
575 ds, cs, ss, esp, eflags);
578 /****************************************************************************************/