summaryrefslogtreecommitdiff
path: root/src/kernel/proc
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/proc')
-rw-r--r--src/kernel/proc/proc.cc113
-rw-r--r--src/kernel/proc/swtch.S34
2 files changed, 147 insertions, 0 deletions
diff --git a/src/kernel/proc/proc.cc b/src/kernel/proc/proc.cc
new file mode 100644
index 0000000..469b7eb
--- /dev/null
+++ b/src/kernel/proc/proc.cc
@@ -0,0 +1,113 @@
+#include "kernel/proc.h"
+#include "kernel/pmm.h"
+#include "drivers/uart.h"
+
+#define NPROC 10
+
+void str_copy(char *dst, const char *src)
+{
+ while (*src)
+ *dst++ = *src++;
+ *dst = 0;
+}
+
+extern "C" void swtch(struct Context *old_ctx, struct Context *new_ctx);
+
+struct Proc procs[NPROC];
+struct Context main_context;
+
+namespace ProcManager
+{
+ void init()
+ {
+ for (int i = 0; i < NPROC; i++)
+ {
+ procs[i].state = UNUSED;
+ }
+ }
+
+ void create_kernel_thread(void (*func)(), const char *name)
+ {
+ struct Proc *p = nullptr;
+ for(int i = 0; i < NPROC; i++)
+ {
+ if(procs[i].state == UNUSED)
+ {
+ p = &procs[i];
+ p->pid = i + 1;
+ break;
+ }
+ }
+
+ if (!p)
+ {
+ Drivers::uart_puts("Error: No free process slots!\n");
+ return;
+ }
+
+ p->kstack = PMM::alloc_page();
+ if (!p->kstack)
+ {
+ Drivers::uart_puts("Error: Alloc kstack failed!\n");
+ return;
+ }
+
+ p->context.ra = (uint64)func;
+
+ p->context.sp = (uint64)p->kstack + 4096;
+
+ p->state = RUNNABLE;
+ str_copy(p->name, name);
+
+ Drivers::uart_puts("[Proc] Created thread: ");
+ Drivers::uart_puts(name);
+ Drivers::uart_puts("\n");
+ }
+
+ void yield()
+ {
+ struct Proc *p = nullptr;
+ for(int i = 0; i < NPROC; i++)
+ {
+ if (procs[i].state == RUNNING)
+ {
+ p = &procs[i];
+ break;
+ }
+ }
+ if(p)
+ {
+ p->state = RUNNABLE;
+ swtch(&p->context, &main_context);
+ }
+ }
+
+ void scheduler()
+ {
+ struct Proc *p = nullptr;
+ Drivers::uart_puts("[Proc] Scheduler started.\n");
+
+ for (;;)
+ {
+ // int nothing_to_run = 1;
+
+ intr_off();
+
+ for (p = procs; p < &procs[NPROC]; p++)
+ {
+ if (p->state == RUNNABLE)
+ {
+ // nothing_to_run = 0;
+
+ p->state = RUNNING;
+
+ intr_on();
+
+ swtch(&main_context, &p->context);
+
+ intr_off();
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/kernel/proc/swtch.S b/src/kernel/proc/swtch.S
new file mode 100644
index 0000000..f59de20
--- /dev/null
+++ b/src/kernel/proc/swtch.S
@@ -0,0 +1,34 @@
+.global swtch
+
+swtch:
+ sd ra, 0(a0)
+ sd sp, 8(a0)
+ sd s0, 16(a0)
+ sd s1, 24(a0)
+ sd s2, 32(a0)
+ sd s3, 40(a0)
+ sd s4, 48(a0)
+ sd s5, 56(a0)
+ sd s6, 64(a0)
+ sd s7, 72(a0)
+ sd s8, 80(a0)
+ sd s9, 88(a0)
+ sd s10, 96(a0)
+ sd s11, 104(a0)
+
+ ld ra, 0(a1)
+ ld sp, 8(a1)
+ ld s0, 16(a1)
+ ld s1, 24(a1)
+ ld s2, 32(a1)
+ ld s3, 40(a1)
+ ld s4, 48(a1)
+ ld s5, 56(a1)
+ ld s6, 64(a1)
+ ld s7, 72(a1)
+ ld s8, 80(a1)
+ ld s9, 88(a1)
+ ld s10, 96(a1)
+ ld s11, 104(a1)
+
+ ret