60a89f360a40cffc3b4e1fe91fd790ff802a16e7
[lunaix-os.git] / lunaix-os / debug / sdbg.c
1 #include <hal/acpi/acpi.h>
2 #include <hal/ioapic.h>
3 #include <klibc/stdio.h>
4 #include <lunaix/isrm.h>
5 #include <lunaix/lxconsole.h>
6 #include <lunaix/peripheral/serial.h>
7 #include <lunaix/syslog.h>
8 #include <sdbg/gdbstub.h>
9 #include <sdbg/lsdbg.h>
10 #include <sdbg/protocol.h>
11
12 // #define USE_LSDBG_BACKEND
13
14 LOG_MODULE("SDBG")
15
16 volatile int debug_mode = 0;
17
18 void
19 sdbg_loop(const isr_param* param)
20 {
21     // This is importnat, because we will handle any subsequent RX/TX in a
22     // synchronized way. And we don't want these irq queue up at our APIC and
23     // confuse the CPU after ACK with APIC.
24     serial_disable_irq(SERIAL_COM1);
25     struct exec_param* execp = param->execp;
26     if (execp->vector == 1 || execp->vector == 3) {
27         goto cont;
28     }
29
30     if (!debug_mode) {
31         // Oh... C.M.C. is about to help the debugging!
32         if (serial_rx_byte(SERIAL_COM1) != '@') {
33             goto done;
34         }
35         if (serial_rx_byte(SERIAL_COM1) != 'c') {
36             goto done;
37         }
38         if (serial_rx_byte(SERIAL_COM1) != 'm') {
39             goto done;
40         }
41         if (serial_rx_byte(SERIAL_COM1) != 'c') {
42             goto done;
43         }
44         debug_mode = 1;
45     } else {
46         if (serial_rx_byte(SERIAL_COM1) != '@') {
47             goto cont;
48         }
49         if (serial_rx_byte(SERIAL_COM1) != 'y') {
50             goto cont;
51         }
52         if (serial_rx_byte(SERIAL_COM1) != 'a') {
53             goto cont;
54         }
55         if (serial_rx_byte(SERIAL_COM1) != 'y') {
56             goto cont;
57         }
58         debug_mode = 0;
59         goto done;
60     }
61
62 cont:
63     kprint_dbg(" DEBUG");
64 #ifdef USE_LSDBG_BACKEND
65     lunaix_sdbg_loop(param);
66 #else
67     gdbstub_loop(param);
68 #endif
69     console_flush();
70
71 done:
72     serial_enable_irq(SERIAL_COM1);
73 }
74
75 void
76 sdbg_imm(const isr_param* param)
77 {
78     struct exec_param* execp = param->execp;
79     kprintf(KDEBUG "Quick debug mode\n");
80     kprintf(KDEBUG "cs=%p eip=%p eax=%p ebx=%p\n",
81             execp->cs,
82             execp->eip,
83             param->registers.eax,
84             param->registers.ebx);
85     kprintf(KDEBUG "ecx=%p edx=%p edi=%p esi=%p\n",
86             param->registers.ecx,
87             param->registers.edx,
88             param->registers.edi,
89             param->registers.esi);
90     kprintf(KDEBUG "u.esp=%p k.esp=%p ebp=%p ps=%p\n",
91             param->esp,
92             execp->esp,
93             param->registers.ebp,
94             execp->eflags);
95     kprintf(KDEBUG "ss=%p ds=%p es=%p fs=%p gs=%p\n",
96             execp->ss,
97             param->registers.ds,
98             param->registers.es,
99             param->registers.fs,
100             param->registers.gs);
101     console_flush();
102     while (1)
103         ;
104 }
105 void
106 sdbg_init()
107 {
108     isrm_bindiv(INSTR_DEBUG, sdbg_loop); // #DB
109     isrm_bindiv(INSTR_BREAK, sdbg_loop); // #BRK
110
111     isrm_bindirq(COM1_IRQ, sdbg_loop);
112 }