Compare commits
11 Commits
v1.0.0
...
bd6872d672
| Author | SHA1 | Date | |
|---|---|---|---|
| bd6872d672 | |||
| 2ca7a34a22 | |||
| c425d6e389 | |||
| eb15d2ffa3 | |||
| 249ac7a8cf | |||
| 44bcc8c805 | |||
| 4f0d3c1071 | |||
| 4d30949a4d | |||
| c90ee285cc | |||
| 6f178f1a60 | |||
| 5e9a165578 |
+30
-1
@@ -16,6 +16,23 @@ set(generic_src_dirs ds init kernel libc sched util vm syscall)
|
|||||||
set(kernel_sources "")
|
set(kernel_sources "")
|
||||||
set(kernel_headers "")
|
set(kernel_headers "")
|
||||||
|
|
||||||
|
set(version_args --arch ${CMAKE_SYSTEM_PROCESSOR})
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE)
|
||||||
|
if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||||
|
set(version_args ${version_args} "--release")
|
||||||
|
endif ()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/magenta.buildid
|
||||||
|
${version_args}
|
||||||
|
OUTPUT_VARIABLE kernel_version
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
|
||||||
|
message(STATUS "Magenta kernel version: ${kernel_version}")
|
||||||
|
|
||||||
foreach (dir ${generic_src_dirs})
|
foreach (dir ${generic_src_dirs})
|
||||||
file(GLOB_RECURSE dir_sources ${dir}/*.c)
|
file(GLOB_RECURSE dir_sources ${dir}/*.c)
|
||||||
file(GLOB_RECURSE dir_headers ${dir}/*.h)
|
file(GLOB_RECURSE dir_headers ${dir}/*.h)
|
||||||
@@ -52,7 +69,19 @@ add_custom_command(
|
|||||||
COMMAND ${CMAKE_STRIP} -g $<TARGET_FILE:${kernel_exe_name}>)
|
COMMAND ${CMAKE_STRIP} -g $<TARGET_FILE:${kernel_exe_name}>)
|
||||||
|
|
||||||
target_link_libraries(${kernel_exe_name} -nostdlib -ffreestanding -lgcc)
|
target_link_libraries(${kernel_exe_name} -nostdlib -ffreestanding -lgcc)
|
||||||
target_compile_definitions(${kernel_exe_name} PRIVATE BUILD_ID="0")
|
target_compile_definitions(${kernel_exe_name} PRIVATE
|
||||||
|
KERNEL_NAME="${kernel_name}"
|
||||||
|
KERNEL_VERSION="${kernel_version}"
|
||||||
|
KERNEL_ARCH="${kernel_arch}")
|
||||||
|
|
||||||
include(arch/${kernel_arch}/config.cmake)
|
include(arch/${kernel_arch}/config.cmake)
|
||||||
include(arch/${kernel_arch}/targets.cmake)
|
include(arch/${kernel_arch}/targets.cmake)
|
||||||
|
|
||||||
|
add_subdirectory(debug)
|
||||||
|
target_link_libraries(${kernel_exe_name} magenta_debug)
|
||||||
|
target_compile_definitions(magenta_debug PRIVATE KERNEL_VERSION="${kernel_version}")
|
||||||
|
target_include_directories(magenta_debug PRIVATE
|
||||||
|
include
|
||||||
|
libc/include
|
||||||
|
libmagenta/include
|
||||||
|
arch/${kernel_arch}/include)
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#include <arch/serial.h>
|
||||||
|
#include <kernel/machine/debug.h>
|
||||||
|
#include <magenta/status.h>
|
||||||
|
|
||||||
|
kern_status_t debug_read(void *buf, size_t max, size_t *nr_read)
|
||||||
|
{
|
||||||
|
return serial_read(COM1, buf, max, nr_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t debug_write(const void *buf, size_t max, size_t *nr_written)
|
||||||
|
{
|
||||||
|
return serial_write(COM1, buf, max, nr_written);
|
||||||
|
}
|
||||||
@@ -1,14 +1,21 @@
|
|||||||
#ifndef ARCH_SERIAL_H_
|
#ifndef ARCH_SERIAL_H_
|
||||||
#define ARCH_SERIAL_H_
|
#define ARCH_SERIAL_H_
|
||||||
|
|
||||||
|
#include <magenta/types.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SERIAL_PORT_A 0x3F8
|
#define COM(x) (x)
|
||||||
#define SERIAL_PORT_B 0x2F8
|
|
||||||
#define SERIAL_PORT_C 0x3E8
|
#define COM1 COM(1)
|
||||||
#define SERIAL_PORT_D 0x2E8
|
#define COM2 COM(2)
|
||||||
|
#define COM3 COM(3)
|
||||||
|
#define COM4 COM(4)
|
||||||
|
|
||||||
|
extern void serial_init(int baud);
|
||||||
|
|
||||||
extern void serial_putchar(int port, char ch);
|
extern void serial_putchar(int port, char ch);
|
||||||
|
|
||||||
@@ -18,7 +25,18 @@ extern char serial_recv_byte(int device);
|
|||||||
|
|
||||||
extern int serial_rcvd(int device);
|
extern int serial_rcvd(int device);
|
||||||
|
|
||||||
extern void early_serialcon_init(int baud);
|
extern kern_status_t serial_read(
|
||||||
|
int device,
|
||||||
|
void *buf,
|
||||||
|
size_t max,
|
||||||
|
size_t *nr_read);
|
||||||
|
extern kern_status_t serial_write(
|
||||||
|
int device,
|
||||||
|
const void *buf,
|
||||||
|
size_t count,
|
||||||
|
size_t *nr_written);
|
||||||
|
|
||||||
|
extern void early_serialcon_init(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef KERNEL_X86_64_DEBUG_H_
|
||||||
|
#define KERNEL_X86_64_DEBUG_H_
|
||||||
|
|
||||||
|
#include <magenta/types.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
extern kern_status_t debug_read(void *buf, size_t max, size_t *nr_read);
|
||||||
|
extern kern_status_t debug_write(const void *buf, size_t max, size_t *nr_read);
|
||||||
|
|
||||||
|
#endif
|
||||||
+11
-4
@@ -7,6 +7,7 @@
|
|||||||
#include <kernel/clock.h>
|
#include <kernel/clock.h>
|
||||||
#include <kernel/console.h>
|
#include <kernel/console.h>
|
||||||
#include <kernel/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
|
#include <kernel/debug.h>
|
||||||
#include <kernel/init.h>
|
#include <kernel/init.h>
|
||||||
#include <kernel/libc/stdio.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <kernel/machine/cpu.h>
|
#include <kernel/machine/cpu.h>
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
#include <kernel/types.h>
|
#include <kernel/types.h>
|
||||||
#include <kernel/util.h>
|
#include <kernel/util.h>
|
||||||
#include <kernel/vm.h>
|
#include <kernel/vm.h>
|
||||||
|
#include <magenta/debug/packet.h>
|
||||||
|
|
||||||
#define HARDWARE_RNG
|
#define HARDWARE_RNG
|
||||||
|
|
||||||
@@ -69,7 +71,8 @@ static void early_vm_init(uintptr_t reserve_end)
|
|||||||
void early_console_init(void)
|
void early_console_init(void)
|
||||||
{
|
{
|
||||||
const char *dest = arg_value("kernel.early-console");
|
const char *dest = arg_value("kernel.early-console");
|
||||||
if (!dest) {
|
bool debug = arg_is_set("kernel.enable-debugger");
|
||||||
|
if (!dest || debug) {
|
||||||
dest = "tty0";
|
dest = "tty0";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +81,7 @@ void early_console_init(void)
|
|||||||
vgacon_init();
|
vgacon_init();
|
||||||
} else if (!strcmp(dest, "ttyS0")) {
|
} else if (!strcmp(dest, "ttyS0")) {
|
||||||
/* write log messages to serial port */
|
/* write log messages to serial port */
|
||||||
early_serialcon_init(115200);
|
early_serialcon_init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,8 +95,6 @@ static void find_bsp(multiboot_info_t *mb, struct boot_module *out)
|
|||||||
{
|
{
|
||||||
memset(out, 0x0, sizeof *out);
|
memset(out, 0x0, sizeof *out);
|
||||||
|
|
||||||
printk("modules=%u: %llx", mb->mods_count, mb->mods_addr);
|
|
||||||
|
|
||||||
multiboot_module_t *mods = PTR32(mb->mods_addr);
|
multiboot_module_t *mods = PTR32(mb->mods_addr);
|
||||||
size_t nr_mods = mb->mods_count;
|
size_t nr_mods = mb->mods_count;
|
||||||
|
|
||||||
@@ -111,6 +112,7 @@ int ml_init(uintptr_t arg)
|
|||||||
|
|
||||||
parse_cmdline(PTR32(mb->cmdline));
|
parse_cmdline(PTR32(mb->cmdline));
|
||||||
|
|
||||||
|
serial_init(115200);
|
||||||
early_console_init();
|
early_console_init();
|
||||||
|
|
||||||
bootstrap_cpu_init();
|
bootstrap_cpu_init();
|
||||||
@@ -187,5 +189,10 @@ int ml_init(uintptr_t arg)
|
|||||||
pit_start(500);
|
pit_start(500);
|
||||||
ml_int_enable();
|
ml_int_enable();
|
||||||
|
|
||||||
|
if (arg_is_set("kernel.enable-debugger")) {
|
||||||
|
debug_await();
|
||||||
|
debug_create_task();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+145
-42
@@ -3,50 +3,78 @@
|
|||||||
#include <arch/serial.h>
|
#include <arch/serial.h>
|
||||||
#include <kernel/libc/stdio.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <kernel/printk.h>
|
#include <kernel/printk.h>
|
||||||
|
#include <kernel/ringbuf.h>
|
||||||
|
|
||||||
#define COM1 0x3F8
|
#define SERIAL_BUFFER_SIZE 1024
|
||||||
#define COM2 0x2F8
|
|
||||||
#define COM3 0x3E8
|
|
||||||
#define COM4 0x2E8
|
|
||||||
|
|
||||||
static int transmit_empty(int device)
|
RINGBUF_DECLARE(com1_queue, SERIAL_BUFFER_SIZE);
|
||||||
|
RINGBUF_DECLARE(com2_queue, SERIAL_BUFFER_SIZE);
|
||||||
|
RINGBUF_DECLARE(com3_queue, SERIAL_BUFFER_SIZE);
|
||||||
|
RINGBUF_DECLARE(com4_queue, SERIAL_BUFFER_SIZE);
|
||||||
|
|
||||||
|
static const uint16_t port_addresses[] = {
|
||||||
|
[COM1] = 0x3F8,
|
||||||
|
[COM2] = 0x2F8,
|
||||||
|
[COM3] = 0x3E8,
|
||||||
|
[COM4] = 0x2E8,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int port_active[] = {
|
||||||
|
[COM1] = 0,
|
||||||
|
[COM2] = 0,
|
||||||
|
[COM3] = 0,
|
||||||
|
[COM4] = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ringbuf *port_buffer[] = {
|
||||||
|
[COM1] = &com1_queue,
|
||||||
|
[COM2] = &com2_queue,
|
||||||
|
[COM3] = &com3_queue,
|
||||||
|
[COM4] = &com4_queue,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int transmit_empty(int port)
|
||||||
{
|
{
|
||||||
return inportb(device + 5) & 0x20;
|
return inportb(port_addresses[port] + 5) & 0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int serial_received(int device)
|
static int serial_received(int port)
|
||||||
{
|
{
|
||||||
return inportb(device + 5) & 0x1;
|
return inportb(port_addresses[port] + 5) & 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_send_byte(int device, char out)
|
void serial_send_byte(int port, char out)
|
||||||
{
|
{
|
||||||
|
uint16_t address = port_addresses[port];
|
||||||
volatile unsigned int _count = 0;
|
volatile unsigned int _count = 0;
|
||||||
while (!transmit_empty(device)) {
|
while (!transmit_empty(port)) {
|
||||||
_count++;
|
_count++;
|
||||||
}
|
}
|
||||||
|
(void)_count;
|
||||||
|
|
||||||
outportb(device, out);
|
outportb(address, out);
|
||||||
|
|
||||||
if (device == COM1) {
|
if (port == COM1) {
|
||||||
outportb(0xe9, out);
|
outportb(0xe9, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!transmit_empty(device)) {
|
while (!transmit_empty(port)) {
|
||||||
_count++;
|
_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char serial_recv_byte(int device)
|
char serial_recv_byte(int port)
|
||||||
{
|
{
|
||||||
|
uint16_t address = port_addresses[port];
|
||||||
volatile unsigned int _count = 0;
|
volatile unsigned int _count = 0;
|
||||||
while (!serial_received(device)) {
|
while (!serial_received(port)) {
|
||||||
_count++;
|
_count++;
|
||||||
}
|
}
|
||||||
|
(void)_count;
|
||||||
|
|
||||||
char c = inportb(device);
|
char c = inportb(address);
|
||||||
|
|
||||||
outportb(device + 5, inportb(device + 5) & ~0x1);
|
outportb(address + 5, inportb(address + 5) & ~0x1);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -100,37 +128,75 @@ static int get_baud_divisor(int baud)
|
|||||||
|
|
||||||
static void init_serial_port(int port, int baud)
|
static void init_serial_port(int port, int baud)
|
||||||
{
|
{
|
||||||
|
uint16_t address = port_addresses[port];
|
||||||
int baud_div = get_baud_divisor(baud);
|
int baud_div = get_baud_divisor(baud);
|
||||||
outportb(port + 1, 0x00); // Disable all interrupts
|
outportb(address + 1, 0x00); // Disable all interrupts
|
||||||
outportb(port + 3, 0x80); // Enable DLAB (set baud rate divisor)
|
outportb(address + 3, 0x80); // Enable DLAB (set baud rate divisor)
|
||||||
outportb(port + 0, baud_div); // Set divisor
|
outportb(address + 0, baud_div); // Set divisor
|
||||||
outportb(port + 1, 0x00);
|
outportb(address + 1, 0x00);
|
||||||
outportb(port + 3, 0x03); // 8 bits, no parity, one stop bit
|
outportb(address + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||||
outportb(
|
outportb(
|
||||||
port + 2,
|
address + 2,
|
||||||
0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
||||||
outportb(port + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
outportb(address + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
||||||
outportb(
|
outportb(
|
||||||
port + 4,
|
address + 4,
|
||||||
0x1E); // Set in loopback mode, test the serial chip
|
0x1E); // Set in loopback mode, test the serial chip
|
||||||
outportb(port + 0, 0xAE); // Test serial chip (send byte 0xAE and
|
outportb(address + 0, 0xAE); // Test serial chip (send byte 0xAE and
|
||||||
// check if serial returns same byte)
|
// check if serial returns same byte)
|
||||||
|
|
||||||
volatile unsigned int q = 0;
|
volatile unsigned int q = 0;
|
||||||
while (!serial_received(port)) {
|
while (!serial_received(port)) {
|
||||||
q++;
|
q++;
|
||||||
}
|
}
|
||||||
|
(void)q;
|
||||||
|
|
||||||
// Check if serial is faulty (i.e: not same byte as sent)
|
// Check if serial is faulty (i.e: not same byte as sent)
|
||||||
if (inportb(port + 0) != 0xAE) {
|
if (inportb(address + 0) != 0xAE) {
|
||||||
|
printk("serial: COM%d is faulty", port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If serial is not faulty set it in normal operation mode
|
// If serial is not faulty set it in normal operation mode
|
||||||
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
|
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
|
||||||
outportb(port + 1, 0x01);
|
outportb(address + 1, 0x01);
|
||||||
outportb(port + 4, 0x0F);
|
outportb(address + 4, 0x0F);
|
||||||
printk("serial: port %x initialised", port);
|
port_active[port] = 1;
|
||||||
|
printk("serial: COM%d initialised", port);
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t serial_read(int device, void *buf, size_t max, size_t *nr_read)
|
||||||
|
{
|
||||||
|
struct ringbuf *src = port_buffer[device];
|
||||||
|
|
||||||
|
unsigned long flags;
|
||||||
|
ringbuf_lock(src, &flags);
|
||||||
|
kern_status_t status = ringbuf_read(src, buf, max, nr_read, &flags);
|
||||||
|
ringbuf_unlock(src, flags);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t serial_write(
|
||||||
|
int device,
|
||||||
|
const void *buf,
|
||||||
|
size_t count,
|
||||||
|
size_t *nr_written)
|
||||||
|
{
|
||||||
|
if (!port_active[device]) {
|
||||||
|
return KERN_BAD_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned char *p = buf;
|
||||||
|
|
||||||
|
size_t w = 0;
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
serial_send_byte(device, p[i]);
|
||||||
|
w++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*nr_written = w;
|
||||||
|
return KERN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct console serialcon = {
|
static struct console serialcon = {
|
||||||
@@ -140,30 +206,67 @@ static struct console serialcon = {
|
|||||||
.c_lock = SPIN_LOCK_INIT,
|
.c_lock = SPIN_LOCK_INIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int serial_irq1(void)
|
static int serial_irq_com1_com3(void)
|
||||||
{
|
{
|
||||||
#if 0
|
unsigned long flags;
|
||||||
if (serial_received(COM1)) {
|
|
||||||
|
if (port_active[COM1] && serial_received(COM1)) {
|
||||||
unsigned char c = serial_recv_byte(COM1);
|
unsigned char c = serial_recv_byte(COM1);
|
||||||
printk("serial: COM1 received %c", c);
|
ringbuf_lock(&com1_queue, &flags);
|
||||||
|
ringbuf_write(&com1_queue, &c, 1, NULL, &flags);
|
||||||
|
ringbuf_unlock(&com1_queue, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serial_received(COM3)) {
|
if (port_active[COM3] && serial_received(COM3)) {
|
||||||
unsigned char c = serial_recv_byte(COM3);
|
unsigned char c = serial_recv_byte(COM3);
|
||||||
printk("serial: COM3 received %c", c);
|
ringbuf_lock(&com3_queue, &flags);
|
||||||
|
ringbuf_write(&com3_queue, &c, 1, NULL, &flags);
|
||||||
|
ringbuf_unlock(&com3_queue, flags);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct irq_hook irq1_hook = {
|
static int serial_irq_com2_com4(void)
|
||||||
.irq_callback = serial_irq1,
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (port_active[COM2] && serial_received(COM2)) {
|
||||||
|
unsigned char c = serial_recv_byte(COM2);
|
||||||
|
ringbuf_lock(&com2_queue, &flags);
|
||||||
|
ringbuf_write(&com2_queue, &c, 1, NULL, &flags);
|
||||||
|
ringbuf_unlock(&com2_queue, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port_active[COM4] && serial_received(COM4)) {
|
||||||
|
unsigned char c = serial_recv_byte(COM4);
|
||||||
|
ringbuf_lock(&com4_queue, &flags);
|
||||||
|
ringbuf_write(&com4_queue, &c, 1, NULL, &flags);
|
||||||
|
ringbuf_unlock(&com4_queue, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irq_hook irq_hook_com1_com3 = {
|
||||||
|
.irq_callback = serial_irq_com1_com3,
|
||||||
};
|
};
|
||||||
|
|
||||||
void early_serialcon_init(int baud)
|
static struct irq_hook irq_hook_com2_com4 = {
|
||||||
|
.irq_callback = serial_irq_com2_com4,
|
||||||
|
};
|
||||||
|
|
||||||
|
void serial_init(int baud)
|
||||||
{
|
{
|
||||||
hook_irq(IRQ4, &irq1_hook);
|
hook_irq(IRQ4, &irq_hook_com1_com3);
|
||||||
|
hook_irq(IRQ3, &irq_hook_com2_com4);
|
||||||
init_serial_port(COM1, baud);
|
init_serial_port(COM1, baud);
|
||||||
|
init_serial_port(COM2, baud);
|
||||||
|
init_serial_port(COM3, baud);
|
||||||
|
init_serial_port(COM4, baud);
|
||||||
|
}
|
||||||
|
|
||||||
|
void early_serialcon_init(void)
|
||||||
|
{
|
||||||
console_register(&serialcon);
|
console_register(&serialcon);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ kern_status_t ml_thread_clone_user_context(
|
|||||||
memcpy(regs, src_regs, sizeof *regs);
|
memcpy(regs, src_regs, sizeof *regs);
|
||||||
|
|
||||||
regs->rax = return_value;
|
regs->rax = return_value;
|
||||||
|
regs->ss = 0x1b;
|
||||||
|
regs->cs = 0x23;
|
||||||
|
|
||||||
dest_ml->tr_fsbase = src_ml->tr_fsbase;
|
dest_ml->tr_fsbase = src_ml->tr_fsbase;
|
||||||
dest_ml->tr_gsbase = src_ml->tr_gsbase;
|
dest_ml->tr_gsbase = src_ml->tr_gsbase;
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
file(GLOB sources *.c *.h include/magenta/debug/*.h)
|
||||||
|
|
||||||
|
add_library(magenta_debug STATIC ${sources})
|
||||||
|
target_include_directories(magenta_debug PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#include <magenta/debug/event.h>
|
||||||
|
|
||||||
|
const char *mxdbg_event_type_get_description(enum mxdbg_event_type type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case MXDBG_EVENT_TASK_CREATED:
|
||||||
|
return "task-create";
|
||||||
|
case MXDBG_EVENT_TASK_STARTED:
|
||||||
|
return "task-start";
|
||||||
|
case MXDBG_EVENT_TASK_STOPPED:
|
||||||
|
return "task-stop";
|
||||||
|
case MXDBG_EVENT_TASK_DESTROYED:
|
||||||
|
return "task-destroy";
|
||||||
|
case MXDBG_EVENT_THREAD_CREATED:
|
||||||
|
return "thread-create";
|
||||||
|
case MXDBG_EVENT_THREAD_STARTED:
|
||||||
|
return "thread-start";
|
||||||
|
case MXDBG_EVENT_THREAD_STOPPED:
|
||||||
|
return "thread-stop";
|
||||||
|
case MXDBG_EVENT_THREAD_DESTROYED:
|
||||||
|
return "thread-destroy";
|
||||||
|
case MXDBG_EVENT_THREAD_FAULT:
|
||||||
|
return "thread-fault";
|
||||||
|
case MXDBG_EVENT_PANIC:
|
||||||
|
return "panic";
|
||||||
|
default:
|
||||||
|
return "<unknown>";
|
||||||
|
}
|
||||||
|
}
|
||||||
+110
@@ -0,0 +1,110 @@
|
|||||||
|
#include "magenta/debug/util.h"
|
||||||
|
|
||||||
|
#include <magenta/debug/host.h>
|
||||||
|
#include <magenta/debug/packet.h>
|
||||||
|
#include <magenta/debug/request.h>
|
||||||
|
|
||||||
|
enum mxdbg_status mxdbg_host_handle_request(struct mxdbg_host *host)
|
||||||
|
{
|
||||||
|
struct mxdbg_packet packet = {0};
|
||||||
|
enum mxdbg_status status = mxdbg_host_recv(host, &packet);
|
||||||
|
if (status != MXDBG_SUCCESS) {
|
||||||
|
debug_printf("debug: failed to read packet");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet.pkt_magic != MXDBG_PACKET_MAGIC) {
|
||||||
|
debug_printf(
|
||||||
|
"debug: packet is malformed (magic=%08x)",
|
||||||
|
packet.pkt_magic);
|
||||||
|
return MXDBG_ERR_BAD_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mxdbg_handle_request(host, &packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mxdbg_status mxdbg_host_recv(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
struct mxdbg_packet *packet)
|
||||||
|
{
|
||||||
|
size_t r;
|
||||||
|
|
||||||
|
if (host->read_remote) {
|
||||||
|
return host->read_remote(host, packet, sizeof *packet, &r);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MXDBG_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mxdbg_status mxdbg_host_recv_packet_data(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
struct mxdbg_packet *packet)
|
||||||
|
{
|
||||||
|
if (packet->pkt_magic != MXDBG_PACKET_MAGIC) {
|
||||||
|
return MXDBG_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!packet->pkt_length) {
|
||||||
|
return MXDBG_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t r;
|
||||||
|
void *dest = packet + 1;
|
||||||
|
if (host->read_remote) {
|
||||||
|
return host->read_remote(
|
||||||
|
host,
|
||||||
|
dest,
|
||||||
|
packet->pkt_length - sizeof *packet,
|
||||||
|
&r);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MXDBG_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mxdbg_status mxdbg_host_send(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
const struct mxdbg_packet *packet)
|
||||||
|
{
|
||||||
|
size_t w;
|
||||||
|
if (host->write_remote) {
|
||||||
|
return host->write_remote(host, packet, packet->pkt_length, &w);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MXDBG_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mxdbg_status mxdbg_host_identify(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
enum mxdbg_identity_key key,
|
||||||
|
void *out,
|
||||||
|
size_t max)
|
||||||
|
{
|
||||||
|
if (host->identify) {
|
||||||
|
return host->identify(host, key, out, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MXDBG_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mxdbg_status mxdbg_host_identify_task(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
unsigned int tid,
|
||||||
|
enum mxdbg_identity_key key,
|
||||||
|
void *out,
|
||||||
|
size_t max)
|
||||||
|
{
|
||||||
|
if (host->identify_task) {
|
||||||
|
return host->identify_task(host, tid, key, out, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MXDBG_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mxdbg_status mxdbg_host_resume(struct mxdbg_host *host)
|
||||||
|
{
|
||||||
|
if (host->resume) {
|
||||||
|
return host->resume(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MXDBG_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef MAGENTA_DEBUG_EVENT_H_
|
||||||
|
#define MAGENTA_DEBUG_EVENT_H_
|
||||||
|
|
||||||
|
enum mxdbg_event_type {
|
||||||
|
MXDBG_EVENT_NONE = 0,
|
||||||
|
|
||||||
|
MXDBG_EVENT_TASK_CREATED,
|
||||||
|
MXDBG_EVENT_TASK_STARTED,
|
||||||
|
MXDBG_EVENT_TASK_STOPPED,
|
||||||
|
MXDBG_EVENT_TASK_DESTROYED,
|
||||||
|
|
||||||
|
MXDBG_EVENT_THREAD_CREATED,
|
||||||
|
MXDBG_EVENT_THREAD_STARTED,
|
||||||
|
MXDBG_EVENT_THREAD_STOPPED,
|
||||||
|
MXDBG_EVENT_THREAD_DESTROYED,
|
||||||
|
MXDBG_EVENT_THREAD_FAULT,
|
||||||
|
|
||||||
|
MXDBG_EVENT_PANIC,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const char *mxdbg_event_type_get_description(enum mxdbg_event_type type);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#ifndef MAGENTA_DEBUG_HOST_H_
|
||||||
|
#define MAGENTA_DEBUG_HOST_H_
|
||||||
|
|
||||||
|
#include <magenta/debug/identity.h>
|
||||||
|
#include <magenta/debug/status.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct mxdbg_packet;
|
||||||
|
struct mxdbg_packet_event;
|
||||||
|
|
||||||
|
struct mxdbg_host {
|
||||||
|
enum mxdbg_status (
|
||||||
|
*read_remote)(struct mxdbg_host *, void *, size_t, size_t *);
|
||||||
|
enum mxdbg_status (*write_remote)(
|
||||||
|
struct mxdbg_host *,
|
||||||
|
const void *,
|
||||||
|
size_t,
|
||||||
|
size_t *);
|
||||||
|
enum mxdbg_status (*identify)(
|
||||||
|
struct mxdbg_host *,
|
||||||
|
enum mxdbg_identity_key,
|
||||||
|
void *,
|
||||||
|
size_t);
|
||||||
|
enum mxdbg_status (*identify_task)(
|
||||||
|
struct mxdbg_host *,
|
||||||
|
unsigned int,
|
||||||
|
enum mxdbg_identity_key,
|
||||||
|
void *,
|
||||||
|
size_t);
|
||||||
|
enum mxdbg_status (*resume)(struct mxdbg_host *);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern enum mxdbg_status mxdbg_host_handle_request(struct mxdbg_host *host);
|
||||||
|
|
||||||
|
extern enum mxdbg_status mxdbg_host_recv(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
struct mxdbg_packet *packet);
|
||||||
|
extern enum mxdbg_status mxdbg_host_recv_packet_data(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
struct mxdbg_packet *packet);
|
||||||
|
extern enum mxdbg_status mxdbg_host_send(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
const struct mxdbg_packet *packet);
|
||||||
|
extern enum mxdbg_status mxdbg_host_identify(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
enum mxdbg_identity_key key,
|
||||||
|
void *out,
|
||||||
|
size_t max);
|
||||||
|
extern enum mxdbg_status mxdbg_host_identify_task(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
unsigned int task,
|
||||||
|
enum mxdbg_identity_key key,
|
||||||
|
void *out,
|
||||||
|
size_t max);
|
||||||
|
extern enum mxdbg_status mxdbg_host_resume(struct mxdbg_host *host);
|
||||||
|
extern enum mxdbg_status mxdbg_host_send_event(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
struct mxdbg_packet_event *ev);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef MAGENTA_DEBUG_IDENTITY_H_
|
||||||
|
#define MAGENTA_DEBUG_IDENTITY_H_
|
||||||
|
|
||||||
|
enum mxdbg_identity_key {
|
||||||
|
MXDBG_IDENTITY_NONE = 0,
|
||||||
|
MXDBG_IDENTITY_KERNEL_NAME,
|
||||||
|
MXDBG_IDENTITY_KERNEL_VERSION,
|
||||||
|
MXDBG_IDENTITY_KERNEL_ARCH,
|
||||||
|
|
||||||
|
/* identify_task keys */
|
||||||
|
MXDBG_IDENTITY_TASK_NAME,
|
||||||
|
MXDBG_IDENTITY_TASK_PARENT,
|
||||||
|
MXDBG_IDENTITY_TASK_NR_THREADS,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#ifndef MAGENTA_DEBUG_PACKET_H_
|
||||||
|
#define MAGENTA_DEBUG_PACKET_H_
|
||||||
|
|
||||||
|
#include <magenta/debug/event.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MXDBG_PACKET_MAGIC 0xdecafbaf
|
||||||
|
|
||||||
|
enum mxdbg_packet_type {
|
||||||
|
MXDBG_PACKET_NONE = 0,
|
||||||
|
MXDBG_PACKET_IDENTIFY_KERNEL,
|
||||||
|
MXDBG_PACKET_IDENTIFY_TASK,
|
||||||
|
MXDBG_PACKET_LIST_TASK,
|
||||||
|
MXDBG_PACKET_RESUME,
|
||||||
|
MXDBG_PACKET_STOP,
|
||||||
|
MXDBG_PACKET_EVENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum mxdbg_packet_flags {
|
||||||
|
MXDBG_PACKET_F_NONE = 0,
|
||||||
|
MXDBG_PACKET_F_RESPONSE = 0x01u,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mxdbg_packet {
|
||||||
|
uint32_t pkt_magic;
|
||||||
|
uint16_t pkt_length;
|
||||||
|
uint8_t pkt_type;
|
||||||
|
uint8_t pkt_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mxdbg_packet_identify_kernel {
|
||||||
|
struct mxdbg_packet id_base;
|
||||||
|
char id_kernel_name[32];
|
||||||
|
char id_kernel_version[32];
|
||||||
|
char id_kernel_arch[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mxdbg_packet_list_task {
|
||||||
|
struct mxdbg_packet l_base;
|
||||||
|
uint16_t l_task_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mxdbg_packet_identify_task {
|
||||||
|
struct mxdbg_packet id_base;
|
||||||
|
uint16_t id_task, id_parent;
|
||||||
|
uint16_t id_thread_count;
|
||||||
|
char id_task_name[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mxdbg_packet_event {
|
||||||
|
struct mxdbg_packet ev_base;
|
||||||
|
uint16_t ev_type;
|
||||||
|
uint16_t ev_task, ev_thread;
|
||||||
|
uint32_t ev_code;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void mxdbg_packet_init(
|
||||||
|
struct mxdbg_packet *packet,
|
||||||
|
size_t size,
|
||||||
|
enum mxdbg_packet_type type,
|
||||||
|
enum mxdbg_packet_flags flags);
|
||||||
|
extern bool mxdbg_packet_validate(const struct mxdbg_packet *packet);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef MAGENTA_DEBUG_REQUEST_H_
|
||||||
|
#define MAGENTA_DEBUG_REQUEST_H_
|
||||||
|
|
||||||
|
struct mxdbg_host;
|
||||||
|
struct mxdbg_packet;
|
||||||
|
|
||||||
|
extern enum mxdbg_status mxdbg_handle_request(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
const struct mxdbg_packet *req);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef MAGENTA_DEBUG_STATUS_H_
|
||||||
|
#define MAGENTA_DEBUG_STATUS_H_
|
||||||
|
|
||||||
|
enum mxdbg_status {
|
||||||
|
MXDBG_SUCCESS = 0,
|
||||||
|
MXDBG_ERR_INVALID_ARGUMENT,
|
||||||
|
MXDBG_ERR_NOT_SUPPORTED,
|
||||||
|
MXDBG_ERR_BAD_FORMAT,
|
||||||
|
MXDBG_ERR_IO_FAILURE,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef MAGENTA_DEBUG_UTIL_H_
|
||||||
|
#define MAGENTA_DEBUG_UTIL_H_
|
||||||
|
|
||||||
|
#if defined(KERNEL_VERSION)
|
||||||
|
#include <kernel/libc/string.h>
|
||||||
|
#include <kernel/printk.h>
|
||||||
|
#define debug_printf(...) printk(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#define debug_printf(...) printf(__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#include <magenta/debug/packet.h>
|
||||||
|
#include <magenta/debug/util.h>
|
||||||
|
|
||||||
|
void mxdbg_packet_init(
|
||||||
|
struct mxdbg_packet *packet,
|
||||||
|
size_t size,
|
||||||
|
enum mxdbg_packet_type type,
|
||||||
|
enum mxdbg_packet_flags flags)
|
||||||
|
{
|
||||||
|
memset(packet, 0x0, sizeof *packet);
|
||||||
|
packet->pkt_magic = MXDBG_PACKET_MAGIC;
|
||||||
|
packet->pkt_length = size;
|
||||||
|
packet->pkt_type = type;
|
||||||
|
packet->pkt_flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mxdbg_packet_validate(const struct mxdbg_packet *packet)
|
||||||
|
{
|
||||||
|
return packet->pkt_magic == MXDBG_PACKET_MAGIC;
|
||||||
|
}
|
||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
#include <magenta/debug/host.h>
|
||||||
|
#include <magenta/debug/packet.h>
|
||||||
|
#include <magenta/debug/util.h>
|
||||||
|
|
||||||
|
static enum mxdbg_status identify_kernel(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
const struct mxdbg_packet *req)
|
||||||
|
{
|
||||||
|
struct mxdbg_packet_identify_kernel id = {0};
|
||||||
|
mxdbg_packet_init(
|
||||||
|
&id.id_base,
|
||||||
|
sizeof id,
|
||||||
|
MXDBG_PACKET_IDENTIFY_KERNEL,
|
||||||
|
MXDBG_PACKET_F_RESPONSE);
|
||||||
|
|
||||||
|
mxdbg_host_identify(
|
||||||
|
host,
|
||||||
|
MXDBG_IDENTITY_KERNEL_NAME,
|
||||||
|
id.id_kernel_name,
|
||||||
|
sizeof id.id_kernel_name);
|
||||||
|
mxdbg_host_identify(
|
||||||
|
host,
|
||||||
|
MXDBG_IDENTITY_KERNEL_VERSION,
|
||||||
|
id.id_kernel_version,
|
||||||
|
sizeof id.id_kernel_version);
|
||||||
|
mxdbg_host_identify(
|
||||||
|
host,
|
||||||
|
MXDBG_IDENTITY_KERNEL_ARCH,
|
||||||
|
id.id_kernel_arch,
|
||||||
|
sizeof id.id_kernel_arch);
|
||||||
|
|
||||||
|
mxdbg_host_send(host, &id.id_base);
|
||||||
|
|
||||||
|
return MXDBG_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mxdbg_status identify_task(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
const struct mxdbg_packet *packet)
|
||||||
|
{
|
||||||
|
struct mxdbg_packet_identify_task *req
|
||||||
|
= (struct mxdbg_packet_identify_task *)packet;
|
||||||
|
struct mxdbg_packet_identify_task id = {0};
|
||||||
|
id.id_base = *packet;
|
||||||
|
mxdbg_host_recv_packet_data(host, &id.id_base);
|
||||||
|
unsigned int tid = id.id_task;
|
||||||
|
|
||||||
|
mxdbg_packet_init(
|
||||||
|
&id.id_base,
|
||||||
|
sizeof id,
|
||||||
|
MXDBG_PACKET_IDENTIFY_TASK,
|
||||||
|
MXDBG_PACKET_F_RESPONSE);
|
||||||
|
|
||||||
|
mxdbg_host_identify_task(
|
||||||
|
host,
|
||||||
|
tid,
|
||||||
|
MXDBG_IDENTITY_TASK_NAME,
|
||||||
|
id.id_task_name,
|
||||||
|
sizeof id.id_task_name);
|
||||||
|
mxdbg_host_identify_task(
|
||||||
|
host,
|
||||||
|
tid,
|
||||||
|
MXDBG_IDENTITY_TASK_PARENT,
|
||||||
|
&id.id_parent,
|
||||||
|
sizeof id.id_parent);
|
||||||
|
mxdbg_host_identify_task(
|
||||||
|
host,
|
||||||
|
tid,
|
||||||
|
MXDBG_IDENTITY_TASK_NR_THREADS,
|
||||||
|
&id.id_thread_count,
|
||||||
|
sizeof id.id_thread_count);
|
||||||
|
|
||||||
|
size_t w;
|
||||||
|
mxdbg_host_send(host, &id.id_base);
|
||||||
|
debug_printf("debug: identify_task response sent");
|
||||||
|
|
||||||
|
return MXDBG_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mxdbg_status resume(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
const struct mxdbg_packet *req)
|
||||||
|
{
|
||||||
|
return mxdbg_host_resume(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mxdbg_status mxdbg_handle_request(
|
||||||
|
struct mxdbg_host *host,
|
||||||
|
const struct mxdbg_packet *req)
|
||||||
|
{
|
||||||
|
switch (req->pkt_type) {
|
||||||
|
case MXDBG_PACKET_IDENTIFY_KERNEL:
|
||||||
|
return identify_kernel(host, req);
|
||||||
|
case MXDBG_PACKET_IDENTIFY_TASK:
|
||||||
|
return identify_task(host, req);
|
||||||
|
case MXDBG_PACKET_RESUME:
|
||||||
|
return resume(host, req);
|
||||||
|
default:
|
||||||
|
debug_printf(
|
||||||
|
"debug: unrecognised packet 0x%02x",
|
||||||
|
req->pkt_type);
|
||||||
|
return MXDBG_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MXDBG_SUCCESS;
|
||||||
|
}
|
||||||
+323
@@ -0,0 +1,323 @@
|
|||||||
|
#include <kernel/ringbuf.h>
|
||||||
|
#include <kernel/sched.h>
|
||||||
|
#include <kernel/thread.h>
|
||||||
|
#include <kernel/wait.h>
|
||||||
|
#include <magenta/status.h>
|
||||||
|
|
||||||
|
#define BUF_LOCKED(buf) \
|
||||||
|
(((buf)->buf_flags & (RINGBUF_READ_LOCKED | RINGBUF_WRITE_LOCKED)) != 0)
|
||||||
|
|
||||||
|
enum ringbuf_flags {
|
||||||
|
RINGBUF_READ_LOCKED = 0x01u,
|
||||||
|
RINGBUF_WRITE_LOCKED = 0x02u,
|
||||||
|
};
|
||||||
|
|
||||||
|
kern_status_t ringbuf_lock(struct ringbuf *buf, unsigned long *flags)
|
||||||
|
{
|
||||||
|
spin_lock_irqsave(&buf->buf_lock, flags);
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t ringbuf_unlock(struct ringbuf *buf, unsigned long flags)
|
||||||
|
{
|
||||||
|
spin_unlock_irqrestore(&buf->buf_lock, flags);
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static kern_status_t ringbuf_clear(struct ringbuf *buf)
|
||||||
|
{
|
||||||
|
buf->buf_read = buf->buf_write = 0;
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t ringbuf_write_capacity_remaining(const struct ringbuf *buf)
|
||||||
|
{
|
||||||
|
if (buf->buf_read > buf->buf_write) {
|
||||||
|
return buf->buf_read - buf->buf_write - 1;
|
||||||
|
} else {
|
||||||
|
return buf->buf_capacity - buf->buf_write + buf->buf_read - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t ringbuf_available_data_remaining(const struct ringbuf *buf)
|
||||||
|
{
|
||||||
|
if (buf->buf_read < buf->buf_write) {
|
||||||
|
return buf->buf_write - buf->buf_read;
|
||||||
|
} else if (buf->buf_read > buf->buf_write) {
|
||||||
|
return buf->buf_capacity - buf->buf_read + buf->buf_write;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static kern_status_t ringbuf_open_read_buffer(
|
||||||
|
struct ringbuf *buf,
|
||||||
|
const void **ptr,
|
||||||
|
size_t *length)
|
||||||
|
{
|
||||||
|
if (BUF_LOCKED(buf)) {
|
||||||
|
return KERN_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t contiguous_capacity = 0;
|
||||||
|
if (buf->buf_read > buf->buf_write) {
|
||||||
|
contiguous_capacity = buf->buf_capacity - buf->buf_read;
|
||||||
|
} else {
|
||||||
|
contiguous_capacity = buf->buf_write - buf->buf_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contiguous_capacity == 0) {
|
||||||
|
return KERN_NO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->buf_opened_ptr = (unsigned char *)buf->buf_ptr + buf->buf_read;
|
||||||
|
buf->buf_opened_capacity = contiguous_capacity;
|
||||||
|
|
||||||
|
buf->buf_flags |= RINGBUF_READ_LOCKED;
|
||||||
|
*ptr = buf->buf_opened_ptr;
|
||||||
|
*length = contiguous_capacity;
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static kern_status_t ringbuf_close_read_buffer(
|
||||||
|
struct ringbuf *buf,
|
||||||
|
const void **ptr,
|
||||||
|
size_t nbuf_read)
|
||||||
|
{
|
||||||
|
if (!(buf->buf_flags & RINGBUF_READ_LOCKED)) {
|
||||||
|
return KERN_BAD_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ptr != buf->buf_opened_ptr) {
|
||||||
|
return KERN_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbuf_read > buf->buf_opened_capacity) {
|
||||||
|
return KERN_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->buf_read += nbuf_read;
|
||||||
|
if (buf->buf_read >= buf->buf_capacity) {
|
||||||
|
buf->buf_read = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->buf_read == buf->buf_write) {
|
||||||
|
/* the ringbuf is now empty. set both pointers to 0.
|
||||||
|
* this ensures that the whole buffer will be available
|
||||||
|
* contiguously to the next call to open_write_buffer */
|
||||||
|
buf->buf_read = 0;
|
||||||
|
buf->buf_write = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->buf_opened_ptr = NULL;
|
||||||
|
buf->buf_opened_capacity = 0;
|
||||||
|
buf->buf_flags &= ~RINGBUF_READ_LOCKED;
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static kern_status_t ringbuf_open_write_buffer(
|
||||||
|
struct ringbuf *buf,
|
||||||
|
void **ptr,
|
||||||
|
size_t *capacity)
|
||||||
|
{
|
||||||
|
if (BUF_LOCKED(buf)) {
|
||||||
|
return KERN_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t contiguous_capacity = 0;
|
||||||
|
if (buf->buf_write >= buf->buf_read) {
|
||||||
|
contiguous_capacity = buf->buf_capacity - buf->buf_write - 1;
|
||||||
|
|
||||||
|
if (buf->buf_read > 0) {
|
||||||
|
contiguous_capacity++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
contiguous_capacity = buf->buf_read - buf->buf_write - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contiguous_capacity == 0) {
|
||||||
|
return KERN_NO_SPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->buf_opened_ptr = (unsigned char *)buf->buf_ptr + buf->buf_write;
|
||||||
|
buf->buf_opened_capacity = contiguous_capacity;
|
||||||
|
|
||||||
|
buf->buf_flags |= RINGBUF_WRITE_LOCKED;
|
||||||
|
*ptr = buf->buf_opened_ptr;
|
||||||
|
*capacity = contiguous_capacity;
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static kern_status_t ringbuf_close_write_buffer(
|
||||||
|
struct ringbuf *buf,
|
||||||
|
void **ptr,
|
||||||
|
size_t nbuf_written)
|
||||||
|
{
|
||||||
|
if (!(buf->buf_flags & RINGBUF_WRITE_LOCKED)) {
|
||||||
|
return KERN_BAD_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ptr != buf->buf_opened_ptr) {
|
||||||
|
return KERN_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbuf_written > buf->buf_opened_capacity) {
|
||||||
|
return KERN_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->buf_write += nbuf_written;
|
||||||
|
if (buf->buf_write >= buf->buf_capacity) {
|
||||||
|
buf->buf_write = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->buf_opened_ptr = NULL;
|
||||||
|
buf->buf_opened_capacity = 0;
|
||||||
|
buf->buf_flags &= ~RINGBUF_WRITE_LOCKED;
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wait_for_data(struct ringbuf *buf, unsigned long *flags)
|
||||||
|
{
|
||||||
|
struct thread *self = get_current_thread();
|
||||||
|
struct wait_item waiter;
|
||||||
|
wait_item_init(&waiter, self);
|
||||||
|
for (;;) {
|
||||||
|
thread_wait_begin(&waiter, &buf->buf_read_queue);
|
||||||
|
if (ringbuf_available_data_remaining(buf) > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ringbuf_unlock(buf, *flags);
|
||||||
|
schedule(SCHED_NORMAL);
|
||||||
|
ringbuf_lock(buf, flags);
|
||||||
|
}
|
||||||
|
thread_wait_end(&waiter, &buf->buf_read_queue);
|
||||||
|
put_current_thread(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wait_for_capacity(struct ringbuf *buf, unsigned long *flags)
|
||||||
|
{
|
||||||
|
struct thread *self = get_current_thread();
|
||||||
|
struct wait_item waiter;
|
||||||
|
wait_item_init(&waiter, self);
|
||||||
|
for (;;) {
|
||||||
|
thread_wait_begin(&waiter, &buf->buf_write_queue);
|
||||||
|
if (ringbuf_write_capacity_remaining(buf) > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ringbuf_unlock(buf, *flags);
|
||||||
|
schedule(SCHED_NORMAL);
|
||||||
|
ringbuf_lock(buf, flags);
|
||||||
|
}
|
||||||
|
thread_wait_end(&waiter, &buf->buf_write_queue);
|
||||||
|
put_current_thread(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t ringbuf_read(
|
||||||
|
struct ringbuf *buf,
|
||||||
|
void *p,
|
||||||
|
size_t count,
|
||||||
|
size_t *nbuf_read,
|
||||||
|
unsigned long *irq_flags)
|
||||||
|
{
|
||||||
|
if (BUF_LOCKED(buf)) {
|
||||||
|
return KERN_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t r = 0;
|
||||||
|
unsigned char *dest = p;
|
||||||
|
size_t remaining = count;
|
||||||
|
kern_status_t status = KERN_OK;
|
||||||
|
|
||||||
|
while (remaining > 0) {
|
||||||
|
const void *src;
|
||||||
|
size_t available;
|
||||||
|
wait_for_data(buf, irq_flags);
|
||||||
|
|
||||||
|
status = ringbuf_open_read_buffer(buf, &src, &available);
|
||||||
|
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t to_copy = remaining;
|
||||||
|
if (to_copy > available) {
|
||||||
|
to_copy = available;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dest, src, to_copy);
|
||||||
|
|
||||||
|
remaining -= to_copy;
|
||||||
|
dest += to_copy;
|
||||||
|
r += to_copy;
|
||||||
|
|
||||||
|
ringbuf_close_read_buffer(buf, &src, to_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
wakeup_queue(&buf->buf_write_queue);
|
||||||
|
if (nbuf_read) {
|
||||||
|
*nbuf_read = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == KERN_NO_DATA && r > 0) {
|
||||||
|
status = KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t ringbuf_write(
|
||||||
|
struct ringbuf *buf,
|
||||||
|
const void *p,
|
||||||
|
size_t count,
|
||||||
|
size_t *nbuf_written,
|
||||||
|
unsigned long *irq_flags)
|
||||||
|
{
|
||||||
|
if (BUF_LOCKED(buf)) {
|
||||||
|
return KERN_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t w = 0;
|
||||||
|
const unsigned char *src = p;
|
||||||
|
size_t remaining = count;
|
||||||
|
kern_status_t status = KERN_OK;
|
||||||
|
|
||||||
|
while (remaining > 0) {
|
||||||
|
void *dest = NULL;
|
||||||
|
size_t available = 0;
|
||||||
|
wait_for_capacity(buf, irq_flags);
|
||||||
|
|
||||||
|
status = ringbuf_open_write_buffer(buf, &dest, &available);
|
||||||
|
|
||||||
|
if (status == KERN_NO_SPACE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t to_copy = remaining;
|
||||||
|
if (to_copy > available) {
|
||||||
|
to_copy = available;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dest, src, to_copy);
|
||||||
|
|
||||||
|
remaining -= to_copy;
|
||||||
|
src += to_copy;
|
||||||
|
w += to_copy;
|
||||||
|
|
||||||
|
ringbuf_close_write_buffer(buf, &dest, to_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
wakeup_queue(&buf->buf_read_queue);
|
||||||
|
if (nbuf_written) {
|
||||||
|
*nbuf_written = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == KERN_NO_SPACE && w > 0) {
|
||||||
|
status = KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef KERNEL_DEBUG_H_
|
||||||
|
#define KERNEL_DEBUG_H_
|
||||||
|
|
||||||
|
#include <magenta/status.h>
|
||||||
|
#include <magenta/types.h>
|
||||||
|
|
||||||
|
extern kern_status_t debug_await(void);
|
||||||
|
extern kern_status_t debug_create_task(void);
|
||||||
|
|
||||||
|
extern kern_status_t debug_event_task_created(tid_t id);
|
||||||
|
extern kern_status_t debug_event_task_started(void);
|
||||||
|
extern kern_status_t debug_event_task_stopped(void);
|
||||||
|
extern kern_status_t debug_event_task_destroyed(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef KERNEL_RINGBUF_H_
|
||||||
|
#define KERNEL_RINGBUF_H_
|
||||||
|
|
||||||
|
#include <kernel/wait.h>
|
||||||
|
#include <magenta/types.h>
|
||||||
|
|
||||||
|
struct ringbuf {
|
||||||
|
unsigned int buf_read;
|
||||||
|
unsigned int buf_write;
|
||||||
|
unsigned int buf_capacity;
|
||||||
|
|
||||||
|
unsigned int buf_flags;
|
||||||
|
unsigned char *buf_ptr;
|
||||||
|
struct waitqueue buf_read_queue;
|
||||||
|
struct waitqueue buf_write_queue;
|
||||||
|
spin_lock_t buf_lock;
|
||||||
|
|
||||||
|
unsigned char *buf_opened_ptr;
|
||||||
|
unsigned int buf_opened_capacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RINGBUF_DECLARE(name, size) \
|
||||||
|
static unsigned char __buf_##name[size] = {0}; \
|
||||||
|
static struct ringbuf name = { \
|
||||||
|
.buf_ptr = __buf_##name, \
|
||||||
|
.buf_capacity = size, \
|
||||||
|
}
|
||||||
|
|
||||||
|
extern kern_status_t ringbuf_lock(struct ringbuf *buf, unsigned long *flags);
|
||||||
|
extern kern_status_t ringbuf_unlock(struct ringbuf *buf, unsigned long flags);
|
||||||
|
|
||||||
|
extern kern_status_t ringbuf_read(
|
||||||
|
struct ringbuf *buf,
|
||||||
|
void *out,
|
||||||
|
size_t count,
|
||||||
|
size_t *nr_read,
|
||||||
|
unsigned long *irq_flags);
|
||||||
|
extern kern_status_t ringbuf_write(
|
||||||
|
struct ringbuf *buf,
|
||||||
|
const void *out,
|
||||||
|
size_t count,
|
||||||
|
size_t *nr_written,
|
||||||
|
unsigned long *irq_flags);
|
||||||
|
|
||||||
|
#endif
|
||||||
+1
-1
@@ -23,7 +23,7 @@ extern char __pstart[], __pend[];
|
|||||||
|
|
||||||
void print_kernel_banner(void)
|
void print_kernel_banner(void)
|
||||||
{
|
{
|
||||||
printk("Magenta kernel version " BUILD_ID);
|
printk(KERNEL_NAME " version " KERNEL_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hang(void)
|
static void hang(void)
|
||||||
|
|||||||
+165
@@ -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;
|
||||||
|
}
|
||||||
+1
-1
@@ -17,7 +17,7 @@ void panic_irq(struct ml_cpu_context *ctx, const char *fmt, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
printk("---[ kernel panic: %s", buf);
|
printk("---[ kernel panic: %s", buf);
|
||||||
printk("kernel: " BUILD_ID ", compiler version: " __VERSION__);
|
printk("kernel: " KERNEL_VERSION ", compiler version: " __VERSION__);
|
||||||
|
|
||||||
struct task *task = get_current_task();
|
struct task *task = get_current_task();
|
||||||
struct thread *thr = get_current_thread();
|
struct thread *thr = get_current_thread();
|
||||||
|
|||||||
@@ -17,5 +17,7 @@
|
|||||||
#define KERN_BAD_STATE (13)
|
#define KERN_BAD_STATE (13)
|
||||||
#define KERN_MEMORY_FAULT (14)
|
#define KERN_MEMORY_FAULT (14)
|
||||||
#define KERN_ACCESS_DENIED (15)
|
#define KERN_ACCESS_DENIED (15)
|
||||||
|
#define KERN_NO_DATA (16)
|
||||||
|
#define KERN_NO_SPACE (17)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <kernel/channel.h>
|
#include <kernel/channel.h>
|
||||||
#include <kernel/clock.h>
|
#include <kernel/clock.h>
|
||||||
#include <kernel/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
|
#include <kernel/debug.h>
|
||||||
#include <kernel/handle.h>
|
#include <kernel/handle.h>
|
||||||
#include <kernel/libc/stdio.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <kernel/locks.h>
|
#include <kernel/locks.h>
|
||||||
@@ -223,6 +224,8 @@ struct task *task_create(
|
|||||||
task_list_insert(&task_list, task);
|
task_list_insert(&task_list, task);
|
||||||
spin_unlock_irqrestore(&task_list_lock, flags);
|
spin_unlock_irqrestore(&task_list_lock, flags);
|
||||||
|
|
||||||
|
debug_event_task_created(task->t_id);
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ if is_arg_set('release'):
|
|||||||
build_type = 'release'
|
build_type = 'release'
|
||||||
|
|
||||||
current_tag = subprocess.check_output(['git', 'describe', '--tags', '--abbrev=0']).decode('utf-8').strip()
|
current_tag = subprocess.check_output(['git', 'describe', '--tags', '--abbrev=0']).decode('utf-8').strip()
|
||||||
current_tag = current_tag[1:]
|
revision = subprocess.check_output(['git', 'rev-list', '{}..HEAD'.format(current_tag), '--count']).decode('utf-8').strip()
|
||||||
|
|
||||||
build_id = '{}/{}_{}'.format(current_tag, build_type, arch)
|
build_id = '{}~{}/{}_{}'.format(current_tag[1:], revision, build_type, arch)
|
||||||
print('{}'.format(build_id.upper()))
|
print('{}'.format(build_id.upper()))
|
||||||
|
|||||||
@@ -105,11 +105,9 @@ static size_t zone_free_bytes(struct vm_zone *z)
|
|||||||
for (enum vm_page_order i = VM_PAGE_MIN_ORDER; i <= VM_PAGE_MAX_ORDER;
|
for (enum vm_page_order i = VM_PAGE_MIN_ORDER; i <= VM_PAGE_MAX_ORDER;
|
||||||
i++) {
|
i++) {
|
||||||
size_t page_bytes = vm_page_order_to_bytes(i);
|
size_t page_bytes = vm_page_order_to_bytes(i);
|
||||||
size_t nr_pages = 0;
|
|
||||||
queue_foreach(struct vm_page, pg, &z->z_free_pages[i], p_list)
|
queue_foreach(struct vm_page, pg, &z->z_free_pages[i], p_list)
|
||||||
{
|
{
|
||||||
free_bytes += page_bytes;
|
free_bytes += page_bytes;
|
||||||
nr_pages++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user