kernel: implement support for magenta_debug over serial

This commit is contained in:
2026-06-06 17:51:44 +01:00
parent eb15d2ffa3
commit c425d6e389
7 changed files with 216 additions and 2 deletions
+165
View File
@@ -0,0 +1,165 @@
#include "kernel/panic.h"
#include <kernel/debug.h>
#include <kernel/libc/stdio.h>
#include <kernel/machine/cpu.h>
#include <kernel/machine/debug.h>
#include <kernel/printk.h>
#include <kernel/sched.h>
#include <kernel/task.h>
#include <kernel/thread.h>
#include <magenta/debug/host.h>
#include <magenta/debug/packet.h>
static volatile bool initial_continue = false;
static volatile bool debug_enabled = false;
static spin_lock_t debug_io_lock = SPIN_LOCK_INIT;
static enum mxdbg_status read_remote(
struct mxdbg_host *host,
void *buf,
size_t count,
size_t *nr_read)
{
debug_read(buf, count, nr_read);
return MXDBG_SUCCESS;
}
static enum mxdbg_status write_remote(
struct mxdbg_host *host,
const void *buf,
size_t count,
size_t *nr_written)
{
spin_lock(&debug_io_lock);
debug_write(buf, count, nr_written);
spin_unlock(&debug_io_lock);
return MXDBG_SUCCESS;
}
static enum mxdbg_status identify(
struct mxdbg_host *host,
enum mxdbg_identity_key key,
void *out,
size_t max)
{
switch (key) {
case MXDBG_IDENTITY_KERNEL_NAME:
snprintf(out, max, "%s", KERNEL_NAME);
break;
case MXDBG_IDENTITY_KERNEL_VERSION:
snprintf(out, max, "%s", KERNEL_VERSION);
break;
case MXDBG_IDENTITY_KERNEL_ARCH:
snprintf(out, max, "%s", KERNEL_ARCH);
break;
default:
return MXDBG_ERR_INVALID_ARGUMENT;
}
return MXDBG_SUCCESS;
}
static enum mxdbg_status identify_task(
struct mxdbg_host *host,
tid_t tid,
enum mxdbg_identity_key key,
void *out,
size_t max)
{
struct task *task = task_from_tid(tid);
if (!task) {
return MXDBG_ERR_INVALID_ARGUMENT;
}
switch (key) {
case MXDBG_IDENTITY_TASK_NAME:
snprintf(out, max, "%s", task->t_name);
break;
case MXDBG_IDENTITY_TASK_PARENT:
*(uint16_t *)out = task->t_parent ? task->t_parent->t_id : -1;
break;
case MXDBG_IDENTITY_TASK_NR_THREADS:
*(uint16_t *)out = queue_length(&task->t_threads);
break;
default:
return MXDBG_ERR_INVALID_ARGUMENT;
}
return MXDBG_SUCCESS;
}
static enum mxdbg_status resume(struct mxdbg_host *host)
{
initial_continue = true;
return MXDBG_SUCCESS;
}
static struct mxdbg_host dbg_host = {
.read_remote = read_remote,
.write_remote = write_remote,
.identify = identify,
.identify_task = identify_task,
.resume = resume,
};
static void debugger(void)
{
ml_int_enable();
while (1) {
mxdbg_host_handle_request(&dbg_host);
}
}
kern_status_t debug_await(void)
{
debug_enabled = true;
printk("debug: waiting for connection...");
while (!initial_continue) {
mxdbg_host_handle_request(&dbg_host);
}
return KERN_OK;
}
kern_status_t debug_create_task(void)
{
struct task *kernel_task = get_current_task();
struct thread *debug_thread = task_create_thread(kernel_task);
thread_init_kernel(debug_thread, (virt_addr_t)debugger);
schedule_thread_on_cpu(debug_thread);
put_current_task(kernel_task);
return KERN_OK;
}
kern_status_t debug_event_task_created(tid_t id)
{
if (!debug_enabled) {
return KERN_OK;
}
struct mxdbg_packet_event ev = {0};
mxdbg_packet_init(&ev.ev_base, sizeof ev, MXDBG_PACKET_EVENT, 0);
ev.ev_type = MXDBG_EVENT_TASK_CREATED;
ev.ev_task = id;
size_t w;
write_remote(&dbg_host, &ev, sizeof ev, &w);
return KERN_OK;
}
kern_status_t debug_event_task_started(void)
{
return KERN_OK;
}
kern_status_t debug_event_task_stopped(void)
{
return KERN_OK;
}
kern_status_t debug_event_task_destroyed(void)
{
return KERN_OK;
}