feat: (ahci) support multiple AHCI controller
[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     if (param->vector == 1 || param->vector == 3) {
26         goto cont;
27     }
28
29     if (!debug_mode) {
30         // Oh... C.M.C. is about to help the debugging!
31         if (serial_rx_byte(SERIAL_COM1) != '@') {
32             goto done;
33         }
34         if (serial_rx_byte(SERIAL_COM1) != 'c') {
35             goto done;
36         }
37         if (serial_rx_byte(SERIAL_COM1) != 'm') {
38             goto done;
39         }
40         if (serial_rx_byte(SERIAL_COM1) != 'c') {
41             goto done;
42         }
43         debug_mode = 1;
44     } else {
45         if (serial_rx_byte(SERIAL_COM1) != '@') {
46             goto cont;
47         }
48         if (serial_rx_byte(SERIAL_COM1) != 'y') {
49             goto cont;
50         }
51         if (serial_rx_byte(SERIAL_COM1) != 'a') {
52             goto cont;
53         }
54         if (serial_rx_byte(SERIAL_COM1) != 'y') {
55             goto cont;
56         }
57         debug_mode = 0;
58         goto done;
59     }
60
61 cont:
62     kprint_dbg(" DEBUG");
63 #ifdef USE_LSDBG_BACKEND
64     lunaix_sdbg_loop(param);
65 #else
66     gdbstub_loop(param);
67 #endif
68     console_flush();
69
70 done:
71     serial_enable_irq(SERIAL_COM1);
72 }
73
74 void
75 sdbg_imm(const isr_param* param)
76 {
77     kprintf(KDEBUG "Quick debug mode\n");
78     kprintf(KDEBUG "cs=%p eip=%p eax=%p ebx=%p\n",
79             param->cs,
80             param->eip,
81             param->registers.eax,
82             param->registers.ebx);
83     kprintf(KDEBUG "ecx=%p edx=%p edi=%p esi=%p\n",
84             param->registers.ecx,
85             param->registers.edx,
86             param->registers.edi,
87             param->registers.esi);
88     kprintf(KDEBUG "u.esp=%p k.esp=%p ebp=%p ps=%p\n",
89             param->registers.esp,
90             param->esp,
91             param->registers.ebp,
92             param->eflags);
93     kprintf(KDEBUG "ss=%p ds=%p es=%p fs=%p gs=%p\n",
94             param->ss,
95             param->registers.ds,
96             param->registers.es,
97             param->registers.fs,
98             param->registers.gs);
99     console_flush();
100     while (1)
101         ;
102 }
103 void
104 sdbg_init()
105 {
106     isrm_bindiv(INSTR_DEBUG, sdbg_loop); // #DB
107     isrm_bindiv(INSTR_BREAK, sdbg_loop); // #BRK
108
109     isrm_bindirq(COM1_IRQ, sdbg_loop);
110 }