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