summaryrefslogtreecommitdiff
path: root/kernel/core
diff options
context:
space:
mode:
authorDanny Holman <dholman@gymli.org>2025-01-12 01:17:36 -0600
committerDanny Holman <dholman@gymli.org>2025-01-12 01:19:11 -0600
commit95cd78840f0891e60f5ebecc8a8eb4fbaf3c2ebf (patch)
treec8c35347b50477929727fa5be9f5d0f55cbe18fd /kernel/core
parent5e166f3042a8e7b3031aae4da7006f80caa53ecc (diff)
PROJECT RESTRUCTURING
Move the entire kernel into its own directory. Create new directories for system commands, libraries and other required essentials for a complete Unix-like operating system. Signed-off-by: Danny Holman <dholman@gymli.org>
Diffstat (limited to 'kernel/core')
-rw-r--r--kernel/core/interrupt.c21
-rw-r--r--kernel/core/panic.c31
-rw-r--r--kernel/core/sched.c74
3 files changed, 126 insertions, 0 deletions
diff --git a/kernel/core/interrupt.c b/kernel/core/interrupt.c
new file mode 100644
index 0000000..6d9e69d
--- /dev/null
+++ b/kernel/core/interrupt.c
@@ -0,0 +1,21 @@
+#include <kernel/interrupt.h>
+#include <kernel/panic.h>
+#include <kernel/asm.h>
+
+static void (*isr_handlers[MAX_ISR])(struct isr_frame *frame);
+
+void register_isr_handler(unsigned int isr, void (*handler)(struct isr_frame *frame)) {
+ if (isr > MAX_ISR)
+ panic("Attempted to set non-existant interrupt vector");
+ isr_handlers[isr] = handler;
+}
+
+void clear_isr_handler(unsigned int isr) {
+ if (isr > MAX_ISR)
+ panic("Attempted to clear non-existant interrupt vector");
+ isr_handlers[isr] = NULL;
+}
+
+void isr_dispatch(struct isr_frame frame) {
+ (*isr_handlers[frame.isr_vector])(&frame);
+}
diff --git a/kernel/core/panic.c b/kernel/core/panic.c
new file mode 100644
index 0000000..a44a73c
--- /dev/null
+++ b/kernel/core/panic.c
@@ -0,0 +1,31 @@
+#include <kernel/panic.h>
+#include <kernel/spinlock.h>
+#include <libk/io.h>
+#include <stdint.h>
+#include <stddef.h>
+
+static struct spinlock panic_lock = {0};
+static int panicked = 0;
+
+void walk_stack(uintptr_t *addrs, size_t n);
+
+void stack_trace(void) {
+ kprintf("PRINTING STACK TRACE\n");
+ uintptr_t strace[32];
+ walk_stack(strace, 32);
+ for (int i = 0; i < 32; i++) {
+ if (strace[i] == 0)
+ break;
+ kprintf("#%d: %x\n", i, strace[i]);
+ }
+}
+
+void panic(const char *str) {
+ disable_ints();
+ spin_lock(&panic_lock);
+ panicked = 1;
+ spin_unlock(&panic_lock);
+ kprintf("KERNEL PANIC - NOT SYNCING: %s\n", str);
+ stack_trace();
+ while (1);
+}
diff --git a/kernel/core/sched.c b/kernel/core/sched.c
new file mode 100644
index 0000000..b6096da
--- /dev/null
+++ b/kernel/core/sched.c
@@ -0,0 +1,74 @@
+#include <kernel/sched.h>
+#include <kernel/kthread.h>
+#include <kernel/panic.h>
+#include <libk/io.h>
+#include <libk/kmalloc.h>
+#include <libk/string.h>
+#include <stddef.h>
+
+static struct kthread *run_queue = NULL;
+static struct kthread *wait_queue = NULL;
+static struct kthread *cur = NULL;
+
+static int scheduler_enabled = 0;
+static struct kmutex scheduler_lock;
+
+void sched_init(void) {
+ disable_ints();
+ cur = kthread_create(NULL, NULL);
+ cur->stack = NULL;
+ switch_thread(cur, cur);
+ cur->state = THREAD_RUNNING;
+ scheduler_enabled = 1;
+ enable_ints();
+}
+
+void schedule_next(void) {
+ if (scheduler_enabled == 0)
+ return;
+ if (run_queue == NULL)
+ return;
+
+ struct kthread *thread = cur;
+ schedule_thread(cur);
+ cur = run_queue;
+ run_queue = run_queue->next;
+ cur->next = NULL;
+ cur->state = THREAD_RUNNING;
+ switch_thread(thread, cur);
+}
+
+void schedule_thread(struct kthread *thread) {
+ if (run_queue == NULL) {
+ run_queue = thread;
+ return;
+ }
+
+ kmutex_lock(&scheduler_lock);
+ struct kthread *temp = run_queue;
+ while (temp->next != NULL)
+ temp = temp->next;
+ temp->next = thread;
+ thread->state = THREAD_READY;
+ kmutex_unlock(&scheduler_lock);
+}
+
+void block_thread(struct kthread *thread) {
+ kmutex_lock(&scheduler_lock);
+ thread->next = wait_queue;
+ wait_queue = thread;
+ kmutex_unlock(&scheduler_lock);
+}
+
+void unblock_thread(struct kthread *thread) {
+ kmutex_lock(&scheduler_lock);
+ struct kthread *temp = wait_queue;
+ while (temp != NULL) {
+ if (temp->next == thread) {
+ temp->next = thread->next;
+ return;
+ }
+ temp = temp->next;
+ }
+ kmutex_unlock(&scheduler_lock);
+}