rename src/kernel/panic to src/kernel/debug, add serial logging
This commit is contained in:
parent
527498a491
commit
a69dbc3c7a
20 changed files with 344 additions and 34 deletions
|
|
@ -4,3 +4,5 @@
|
||||||
dependencies/limine
|
dependencies/limine
|
||||||
-I
|
-I
|
||||||
include
|
include
|
||||||
|
-D
|
||||||
|
CALCITE_DEBUG
|
||||||
|
|
|
||||||
|
|
@ -3,23 +3,23 @@
|
||||||
COMMON_CC_EXTRA_FLAGS="-Wall -Wextra"
|
COMMON_CC_EXTRA_FLAGS="-Wall -Wextra"
|
||||||
COMMON_LD_EXTRA_FLAGS=""
|
COMMON_LD_EXTRA_FLAGS=""
|
||||||
|
|
||||||
|
COMMON_CC_FLAGS="-std=c23 -ffreestanding -I include ${COMMON_CC_EXTRA_FLAGS}"
|
||||||
|
COMMON_LD_FLAGS="${COMMON_LD_EXTRA_FLAGS}"
|
||||||
|
|
||||||
if [ "$1" = debug ]; then
|
if [ "$1" = debug ]; then
|
||||||
COMMON_CC_EXTRA_FLAGS="-O0 -ggdb ${COMMON_CC_EXTRA_FLAGS}"
|
COMMON_CC_FLAGS="-O0 -ggdb -D CALCITE_DEBUG ${COMMON_CC_FLAGS}"
|
||||||
elif [ "$1" = release ]; then
|
elif [ "$1" = release ]; then
|
||||||
COMMON_CC_EXTRA_FLAGS="-O3 ${COMMON_CC_EXTRA_FLAGS}"
|
COMMON_CC_FLAGS="-O3 -D CALCITE_RELEASE ${COMMON_CC_FLAGS}"
|
||||||
COMMON_LD_EXTRA_FLAGS="-s ${COMMON_LD_EXTRA_FLAGS}"
|
COMMON_LD_FLAGS="-s ${COMMON_LD_FLAGS}"
|
||||||
else
|
else
|
||||||
echo pass either "debug" or "release" as an argument.
|
echo pass either "debug" or "release" as an argument.
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
COMMON_CC_FLAGS="-std=c23 -ffreestanding -I include ${COMMON_CC_EXTRA_FLAGS}"
|
|
||||||
KERNEL_CC_FLAGS="-mno-sse -I dependencies/limine ${COMMON_CC_FLAGS}"
|
KERNEL_CC_FLAGS="-mno-sse -I dependencies/limine ${COMMON_CC_FLAGS}"
|
||||||
#in the future user code will be allowed to use sse
|
#in the future user code will be allowed to use sse
|
||||||
USER_CC_FLAGS="-mno-sse ${COMMON_CC_FLAGS}"
|
USER_CC_FLAGS="-mno-sse ${COMMON_CC_FLAGS}"
|
||||||
|
|
||||||
COMMON_LD_FLAGS="${COMMON_LD_EXTRA_FLAGS}"
|
|
||||||
|
|
||||||
if [ -e build.ninja ]; then
|
if [ -e build.ninja ]; then
|
||||||
echo build.ninja already exists.
|
echo build.ninja already exists.
|
||||||
exit
|
exit
|
||||||
|
|
|
||||||
109
src/kernel/debug.c
Normal file
109
src/kernel/debug.c
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
/* Calcite, src/kernel/debug.c
|
||||||
|
* Copyright 2025 Benji Dial
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "serial.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
void log_core(const char *file, const char *function, const char *format, ...) {
|
||||||
|
|
||||||
|
int file_length = 0;
|
||||||
|
while (file[file_length] != 0)
|
||||||
|
++file_length;
|
||||||
|
|
||||||
|
int function_length = 0;
|
||||||
|
while (function[function_length] != 0)
|
||||||
|
++function_length;
|
||||||
|
|
||||||
|
write_serial_string_n(file, file_length);
|
||||||
|
write_serial_string_n(" ", 1);
|
||||||
|
write_serial_string_n(function, function_length);
|
||||||
|
|
||||||
|
write_serial_string_n(" -", 2);
|
||||||
|
for (int i = file_length + function_length + 3; i < 49; ++i)
|
||||||
|
write_serial_string_n("-", 1);
|
||||||
|
write_serial_string_n(" ", 1);
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
int next_percent = 0;
|
||||||
|
while (format[next_percent] != '%') {
|
||||||
|
if (format[next_percent] == 0) {
|
||||||
|
write_serial_string_n(format, next_percent);
|
||||||
|
va_end(args);
|
||||||
|
write_serial_string_n("\r\n", 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
++next_percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_serial_string_n(format, next_percent);
|
||||||
|
|
||||||
|
switch (format[next_percent + 1]) {
|
||||||
|
case 's': {
|
||||||
|
const char *arg = va_arg(args, const char *);
|
||||||
|
write_serial_string(arg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'd': {
|
||||||
|
int arg = va_arg(args, int);
|
||||||
|
write_serial_integer(arg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'h': {
|
||||||
|
uint64_t arg1 = va_arg(args, uint64_t);
|
||||||
|
int arg2 = va_arg(args, int);
|
||||||
|
write_serial_hex(arg1, arg2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'B': {
|
||||||
|
uint64_t arg = va_arg(args, uint64_t);
|
||||||
|
if (arg < 10000) {
|
||||||
|
write_serial_integer(arg);
|
||||||
|
write_serial_string_n(" B", 2);
|
||||||
|
}
|
||||||
|
else if ((arg + 512) / 1024 < 10000) {
|
||||||
|
write_serial_integer((arg + 512) / 1024);
|
||||||
|
write_serial_string_n(" kiB", 4);
|
||||||
|
}
|
||||||
|
else if ((arg + 512 * 1024) / (1024 * 1024) < 10000) {
|
||||||
|
write_serial_integer((arg + 512 * 1024) / (1024 * 1024));
|
||||||
|
write_serial_string_n(" MiB", 4);
|
||||||
|
}
|
||||||
|
else if ((arg + 512 * 1024 * 1024) / (1024 * 1024 * 1024) < 10000) {
|
||||||
|
write_serial_integer((arg + 512 * 1024 * 1024) / (1024 * 1024 * 1024));
|
||||||
|
write_serial_string_n(" GiB", 4);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
write_serial_integer((arg + 512 * 1024 * 1024 * 1024ULL) / (1024 * 1024 * 1024 * 1024ULL));
|
||||||
|
write_serial_string_n(" TiB", 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic("bad format string")
|
||||||
|
}
|
||||||
|
|
||||||
|
format = &format[next_percent + 2];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* Calcite, src/kernel/panic.h
|
/* Calcite, src/kernel/debug.h
|
||||||
* Copyright 2025 Benji Dial
|
* Copyright 2025 Benji Dial
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
|
@ -17,10 +17,23 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
[[noreturn]] void panic_core(
|
void log_core(const char *file, const char *function, const char *format, ...);
|
||||||
const char *file, const char *function, int line, const char *message);
|
|
||||||
|
|
||||||
#define panic(message) panic_core(__FILE__, __func__, __LINE__, message);
|
#ifdef CALCITE_DEBUG
|
||||||
|
#define debug_log(...) { \
|
||||||
|
log_core(__FILE__, __func__, __VA_ARGS__); \
|
||||||
|
}
|
||||||
|
#elif CALCITE_RELEASE
|
||||||
|
#define debug_log(format, ...) {}
|
||||||
|
#else
|
||||||
|
#error neither CALCITE_DEBUG nor CALCITE_RELEASE defined
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define panic(message) { \
|
||||||
|
log_core(__FILE__, __func__, "kernel panic: %s", message); \
|
||||||
|
while (1) \
|
||||||
|
__asm__ ("hlt"); \
|
||||||
|
}
|
||||||
|
|
||||||
#define assert(condition) \
|
#define assert(condition) \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -23,8 +23,9 @@
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "drives.h"
|
#include "drives.h"
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
|
#include "serial.h"
|
||||||
|
#include "debug.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "panic.h"
|
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
|
|
@ -187,6 +188,8 @@ static const char *cmdline_look_up(const char *key) {
|
||||||
|
|
||||||
[[noreturn]] static void with_kernel_page_tables() {
|
[[noreturn]] static void with_kernel_page_tables() {
|
||||||
|
|
||||||
|
init_serial();
|
||||||
|
|
||||||
//store cmdline as key-value pairs
|
//store cmdline as key-value pairs
|
||||||
|
|
||||||
if (cmdline_copy[0] == 0)
|
if (cmdline_copy[0] == 0)
|
||||||
|
|
@ -242,6 +245,10 @@ static const char *cmdline_look_up(const char *key) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug_log("command line:")
|
||||||
|
for (int i = 0; i < cmdline_pair_count; ++i)
|
||||||
|
debug_log(" %s = %s", cmdline_pairs[i].key, cmdline_pairs[i].value)
|
||||||
|
|
||||||
//set up interrupts
|
//set up interrupts
|
||||||
|
|
||||||
init_timer();
|
init_timer();
|
||||||
|
|
@ -302,6 +309,10 @@ static const char *cmdline_look_up(const char *key) {
|
||||||
if (start_elf("root://calcite/apps/init/init.elf") == 0)
|
if (start_elf("root://calcite/apps/init/init.elf") == 0)
|
||||||
panic("could not start init.elf")
|
panic("could not start init.elf")
|
||||||
|
|
||||||
|
debug_log("about to switch to init")
|
||||||
|
debug_log(" free physical memory %B", count_free_pram())
|
||||||
|
debug_log(" free kernel virtual memory %B", count_free_kernel_vram())
|
||||||
|
|
||||||
resume_next_continuation();
|
resume_next_continuation();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include "iso9660.h"
|
#include "iso9660.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "panic.h"
|
#include "debug.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
#include "debug.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "panic.h"
|
|
||||||
|
|
||||||
static int is_somebody_waiting_for_mouse_packet = 0;
|
static int is_somebody_waiting_for_mouse_packet = 0;
|
||||||
static struct continuation_info waiting_continuation;
|
static struct continuation_info waiting_continuation;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
// https://osdev.wiki/wiki/Task_State_Segment
|
// https://osdev.wiki/wiki/Task_State_Segment
|
||||||
|
|
||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
#include "panic.h"
|
#include "debug.h"
|
||||||
|
|
||||||
struct [[gnu::packed]] exception_parameter {
|
struct [[gnu::packed]] exception_parameter {
|
||||||
uint64_t r15;
|
uint64_t r15;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
#include "ipc-dgram.h"
|
#include "ipc-dgram.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "panic.h"
|
#include "debug.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
|
|
||||||
#include <kernel-public/ipc.h>
|
#include <kernel-public/ipc.h>
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "iso9660.h"
|
#include "iso9660.h"
|
||||||
|
#include "kernel-public/files.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "drives.h"
|
#include "drives.h"
|
||||||
#include "panic.h"
|
#include "debug.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
|
||||||
|
|
@ -370,6 +371,12 @@ enum fs_access_result create_iso9660_info(const struct drive_info *drive, struct
|
||||||
fs_out->look_up_file = &look_up_file_iso9660;
|
fs_out->look_up_file = &look_up_file_iso9660;
|
||||||
fs_out->stat_file = &stat_file_iso9660;
|
fs_out->stat_file = &stat_file_iso9660;
|
||||||
fs_out->read_file = &read_file_iso9660;
|
fs_out->read_file = &read_file_iso9660;
|
||||||
|
|
||||||
|
debug_log("created iso9660 file system")
|
||||||
|
debug_log(" drive name %s", drive->name)
|
||||||
|
debug_log(" path table start block %d", path_table_start)
|
||||||
|
debug_log(" path table block count %d", path_table_length_rounded_up / 2048)
|
||||||
|
|
||||||
return FAR_SUCCESS;
|
return FAR_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#include "panic.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define MAX_PHYSICAL_GB 64ULL
|
#define MAX_PHYSICAL_GB 64ULL
|
||||||
|
|
||||||
|
|
@ -203,3 +203,20 @@ void destroy_syscall_stack(void *stack_top) {
|
||||||
for (uint64_t i = 0; i < SYSCALL_STACK_BYTES; i += 4096)
|
for (uint64_t i = 0; i < SYSCALL_STACK_BYTES; i += 4096)
|
||||||
unmap_and_free_kernel_page(stack_top - SYSCALL_STACK_BYTES + i * 4096);
|
unmap_and_free_kernel_page(stack_top - SYSCALL_STACK_BYTES + i * 4096);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t count_free_pram() {
|
||||||
|
uint64_t total = 0;
|
||||||
|
for (uint64_t i = 0; i < (MAX_PHYSICAL_GB << 15); ++i)
|
||||||
|
for (int j = 0; j < 8; ++j)
|
||||||
|
if (physical_map[i] & (1 << j))
|
||||||
|
total += 4096;
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t count_free_kernel_vram() {
|
||||||
|
uint64_t total = 0;
|
||||||
|
for (uint64_t i = 0; i < 512 * 512; ++i)
|
||||||
|
if (kernel_p1s[i] == 0)
|
||||||
|
total += 4096;
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,3 +52,9 @@ uint64_t take_free_physical_page();
|
||||||
//returns the top
|
//returns the top
|
||||||
void *create_syscall_stack();
|
void *create_syscall_stack();
|
||||||
void destroy_syscall_stack(void *stack_top);
|
void destroy_syscall_stack(void *stack_top);
|
||||||
|
|
||||||
|
//return value in bytes
|
||||||
|
uint64_t count_free_pram();
|
||||||
|
|
||||||
|
//return value in bytes
|
||||||
|
uint64_t count_free_kernel_vram();
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@
|
||||||
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pci.h"
|
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "drives.h"
|
#include "drives.h"
|
||||||
#include "panic.h"
|
#include "debug.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "pata.h"
|
#include "pata.h"
|
||||||
|
#include "pci.h"
|
||||||
|
|
||||||
//some relevant sources:
|
//some relevant sources:
|
||||||
// https://www.isdaman.com/alsos/hardware/hdc/pciide.pdf
|
// https://www.isdaman.com/alsos/hardware/hdc/pciide.pdf
|
||||||
|
|
@ -211,6 +211,14 @@ static void probe_pata_drive(uint16_t command_block_base, uint8_t device_byte) {
|
||||||
|
|
||||||
di->read_blocks = &read_blocks_patapi;
|
di->read_blocks = &read_blocks_patapi;
|
||||||
|
|
||||||
|
debug_log("added pata drive:")
|
||||||
|
debug_log(" drive name %s", di->name)
|
||||||
|
debug_log(" command block base 0x%h", command_block_base, 4)
|
||||||
|
debug_log(" device byte 0x%h", device_byte, 2)
|
||||||
|
debug_log(" block size %d", di->block_size)
|
||||||
|
debug_log(" block count %d", di->block_count)
|
||||||
|
debug_log(" total size %B", di->block_count * di->block_size)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void probe_pata_drives(uint32_t pci_address_base, uint32_t pci_class_etc) {
|
void probe_pata_drives(uint32_t pci_address_base, uint32_t pci_class_etc) {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
#include "pata.h"
|
#include "pata.h"
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
|
|
||||||
|
|
@ -40,6 +41,7 @@ static void probe_bus(uint32_t bus_address_base) {
|
||||||
else if ((header_type & 0x7f) == 0x00) {
|
else if ((header_type & 0x7f) == 0x00) {
|
||||||
//this is a normal function
|
//this is a normal function
|
||||||
uint32_t class_etc = read_pci_config(function_address_base | 0x08);
|
uint32_t class_etc = read_pci_config(function_address_base | 0x08);
|
||||||
|
debug_log("pci device with class %h:%h", class_etc >> 24, 2, class_etc >> 16, 2);
|
||||||
switch (class_etc & 0xffff0000) {
|
switch (class_etc & 0xffff0000) {
|
||||||
case 0x01010000:
|
case 0x01010000:
|
||||||
probe_pata_drives(function_address_base, class_etc);
|
probe_pata_drives(function_address_base, class_etc);
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#include "panic.h"
|
#include "debug.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
|
||||||
|
|
@ -399,6 +399,12 @@ void syscall_create_thread(void (*f)(uint64_t), uint64_t x) {
|
||||||
|
|
||||||
add_to_queue(&ready_continuations, &ci);
|
add_to_queue(&ready_continuations, &ci);
|
||||||
|
|
||||||
|
debug_log("started thread")
|
||||||
|
debug_log(" process struct at 0xffffffff.%h", thread->process, 8)
|
||||||
|
debug_log(" thread struct at 0xffffffff.%h", thread, 8)
|
||||||
|
debug_log(" free physical memory %B", count_free_pram())
|
||||||
|
debug_log(" free kernel virtual memory %B", count_free_kernel_vram())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int syscall_start_elf(const char *path, const struct process_start_info *info) {
|
int syscall_start_elf(const char *path, const struct process_start_info *info) {
|
||||||
|
|
@ -439,6 +445,12 @@ int syscall_start_elf(const char *path, const struct process_start_info *info) {
|
||||||
for (int i = 0; i < info->set_envvar_count; ++i)
|
for (int i = 0; i < info->set_envvar_count; ++i)
|
||||||
set_envvar(process, info->set_envvars[2 * i], info->set_envvars[2 * i + 1]);
|
set_envvar(process, info->set_envvars[2 * i], info->set_envvars[2 * i + 1]);
|
||||||
|
|
||||||
|
debug_log("started process")
|
||||||
|
debug_log(" path %s", path)
|
||||||
|
debug_log(" process struct at 0xffffffff.%h", process, 8)
|
||||||
|
debug_log(" free physical memory %B", count_free_pram())
|
||||||
|
debug_log(" free kernel virtual memory %B", count_free_kernel_vram())
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "panic.h"
|
#include "debug.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
|
|
||||||
struct continuation_queue ready_continuations;
|
struct continuation_queue ready_continuations;
|
||||||
|
|
|
||||||
73
src/kernel/serial.asm
Normal file
73
src/kernel/serial.asm
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
; Calcite, src/kernel/serial.asm
|
||||||
|
; Copyright 2025 Benji Dial
|
||||||
|
;
|
||||||
|
; This program is free software: you can redistribute it and/or modify
|
||||||
|
; it under the terms of the GNU General Public License as published by
|
||||||
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
; (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
; for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License along
|
||||||
|
; with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
bits 64
|
||||||
|
default rel
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
global init_serial
|
||||||
|
init_serial:
|
||||||
|
mov dx, 0x03f9
|
||||||
|
mov al, 0x00
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
mov dl, 0xfb
|
||||||
|
mov al, 0x80
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
mov dl, 0xf8
|
||||||
|
mov al, 0x03
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
mov dl, 0xf9
|
||||||
|
mov al, 0x00
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
mov dl, 0xfb
|
||||||
|
mov al, 0x03
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
mov dl, 0xfa
|
||||||
|
mov al, 0xc7
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
global write_serial_string_n
|
||||||
|
write_serial_string_n:
|
||||||
|
test esi, esi
|
||||||
|
jz .ret
|
||||||
|
movzx rcx, esi
|
||||||
|
|
||||||
|
.wait_ready:
|
||||||
|
mov dx, 0x03fd
|
||||||
|
in al, dx
|
||||||
|
test al, 0x20
|
||||||
|
jnz .ready
|
||||||
|
pause
|
||||||
|
jmp .wait_ready
|
||||||
|
|
||||||
|
.ready:
|
||||||
|
mov dl, 0xf8
|
||||||
|
mov al, byte [rdi]
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
inc rdi
|
||||||
|
loop .wait_ready
|
||||||
|
.ret:
|
||||||
|
ret
|
||||||
54
src/kernel/serial.c
Normal file
54
src/kernel/serial.c
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* Calcite, src/kernel/serial.c
|
||||||
|
* Copyright 2025 Benji Dial
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "serial.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
void write_serial_string(const char *string) {
|
||||||
|
int n = 0;
|
||||||
|
while (string[n] != 0)
|
||||||
|
++n;
|
||||||
|
write_serial_string_n(string, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_serial_integer(int integer) {
|
||||||
|
|
||||||
|
if (integer == 0) {
|
||||||
|
write_serial_string_n("0", 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[10];
|
||||||
|
char *ptr = &buffer[9];
|
||||||
|
|
||||||
|
while (integer != 0) {
|
||||||
|
*ptr = '0' + integer % 10;
|
||||||
|
integer /= 10;
|
||||||
|
--ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_serial_string_n(ptr + 1, (buffer + 10) - (ptr + 1));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_serial_hex(uint64_t value, int places) {
|
||||||
|
assert(places <= 16)
|
||||||
|
char buffer[16];
|
||||||
|
for (int i = 0; i < places; ++i)
|
||||||
|
buffer[i] = "0123456789abcdef"[(value >> (4 * (places - i - 1))) & 0xf];
|
||||||
|
write_serial_string_n(buffer, places);
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* Calcite, src/kernel/panic.c
|
/* Calcite, src/kernel/serial.h
|
||||||
* Copyright 2025 Benji Dial
|
* Copyright 2025 Benji Dial
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
|
@ -15,16 +15,12 @@
|
||||||
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[[noreturn]] void panic_core(
|
#pragma once
|
||||||
const char *file, const char *function, int line, const char *message) {
|
|
||||||
|
|
||||||
//TODO
|
#include <stdint.h>
|
||||||
|
|
||||||
(void)file;
|
void init_serial();
|
||||||
(void)function;
|
void write_serial_string(const char *string);
|
||||||
(void)line;
|
void write_serial_string_n(const char *string, int n);
|
||||||
(void)message;
|
void write_serial_integer(int integer);
|
||||||
while (1)
|
void write_serial_hex(uint64_t value, int places);
|
||||||
__asm__ ("hlt");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "syscalls.h"
|
#include "syscalls.h"
|
||||||
#include "panic.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define MAX_SYSCALL_NUMBER 99
|
#define MAX_SYSCALL_NUMBER 99
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue