-#include <hal/acpi/acpi.h>
-#include <hal/ioapic.h>
-#include <klibc/stdio.h>
-#include <lunaix/isrm.h>
-#include <lunaix/lxconsole.h>
-#include <lunaix/peripheral/serial.h>
+// FIXME Re-design needed!!
+
+#include <hal/serial.h>
+#include <klibc/strfmt.h>
#include <lunaix/syslog.h>
#include <sdbg/gdbstub.h>
#include <sdbg/lsdbg.h>
#include <sdbg/protocol.h>
+#include <lunaix/isrm.h>
+
// #define USE_LSDBG_BACKEND
LOG_MODULE("SDBG")
volatile int debug_mode = 0;
-void
-sdbg_loop(const isr_param* param)
+// begin: @cmc
+#define DBG_START 0x636d6340UL
+
+// begin: @yay
+#define DBG_END 0x79617940UL
+
+static int
+sdbg_serial_callback(struct serial_dev* sdev)
{
- // This is importnat, because we will handle any subsequent RX/TX in a
- // synchronized way. And we don't want these irq queue up at our APIC and
- // confuse the CPU after ACK with APIC.
- serial_disable_irq(SERIAL_COM1);
- struct exec_param* execp = param->execp;
- if (execp->vector == 1 || execp->vector == 3) {
- goto cont;
- }
+ u32_t dbg_sig = *(u32_t*)sdev->rw.buf;
- if (!debug_mode) {
- // Oh... C.M.C. is about to help the debugging!
- if (serial_rx_byte(SERIAL_COM1) != '@') {
- goto done;
- }
- if (serial_rx_byte(SERIAL_COM1) != 'c') {
- goto done;
- }
- if (serial_rx_byte(SERIAL_COM1) != 'm') {
- goto done;
- }
- if (serial_rx_byte(SERIAL_COM1) != 'c') {
- goto done;
- }
+ if (dbg_sig == DBG_START) {
debug_mode = 1;
- } else {
- if (serial_rx_byte(SERIAL_COM1) != '@') {
- goto cont;
- }
- if (serial_rx_byte(SERIAL_COM1) != 'y') {
- goto cont;
- }
- if (serial_rx_byte(SERIAL_COM1) != 'a') {
- goto cont;
- }
- if (serial_rx_byte(SERIAL_COM1) != 'y') {
- goto cont;
- }
+ } else if (dbg_sig == DBG_END) {
debug_mode = 0;
- goto done;
}
-cont:
- kprint_dbg(" DEBUG");
-#ifdef USE_LSDBG_BACKEND
- lunaix_sdbg_loop(param);
-#else
- gdbstub_loop(param);
-#endif
- console_flush();
+ // Debugger should be run later
+ // TODO implement a defer execution mechanism (i.e., soft interrupt)
-done:
- serial_enable_irq(SERIAL_COM1);
+ return SERIAL_AGAIN;
}
void
sdbg_imm(const isr_param* param)
{
struct exec_param* execp = param->execp;
- kprintf(KDEBUG "Quick debug mode\n");
- kprintf(KDEBUG "cs=%p eip=%p eax=%p ebx=%p\n",
+ DEBUG("Quick debug mode\n");
+ DEBUG("cs=%p eip=%p eax=%p ebx=%p\n",
execp->cs,
execp->eip,
param->registers.eax,
param->registers.ebx);
- kprintf(KDEBUG "ecx=%p edx=%p edi=%p esi=%p\n",
+ DEBUG("ecx=%p edx=%p edi=%p esi=%p\n",
param->registers.ecx,
param->registers.edx,
param->registers.edi,
param->registers.esi);
- kprintf(KDEBUG "u.esp=%p k.esp=%p ebp=%p ps=%p\n",
+ DEBUG("u.esp=%p k.esp=%p ebp=%p ps=%p\n",
param->esp,
execp->esp,
param->registers.ebp,
execp->eflags);
- kprintf(KDEBUG "ss=%p ds=%p es=%p fs=%p gs=%p\n",
+ DEBUG("ss=%p ds=%p es=%p fs=%p gs=%p\n",
execp->ss,
param->registers.ds,
param->registers.es,
param->registers.fs,
param->registers.gs);
- console_flush();
while (1)
;
}
+
+static char buf[4];
+
+static void
+__sdbg_breakpoint(const isr_param* param)
+{
+ gdbstub_loop(param);
+}
+
void
sdbg_init()
{
- isrm_bindiv(INSTR_DEBUG, sdbg_loop); // #DB
- isrm_bindiv(INSTR_BREAK, sdbg_loop); // #BRK
+ struct serial_dev* sdev = serial_get_avilable();
+
+ if (!sdev) {
+ ERROR("no serial port available\n");
+ return;
+ }
+
+ kprintf("listening: %s\n", sdev->dev->name.value);
- isrm_bindirq(COM1_IRQ, sdbg_loop);
+ serial_rwbuf_async(sdev, buf, 4, sdbg_serial_callback, SERIAL_RW_RX);
}
\ No newline at end of file