Commit Diff


commit - 17683e896fc6162a038d5fb2711ca94055188dfb
commit + d06837bca243482704cb1f5077d0c180a88f17f9
blob - 89788503a89a7d78c692d45b4e8240c5b2eaa64f
blob + 0cedacc0e680a7dd1060bcee065eeaf36a744393
--- alpha/main.c
+++ alpha/main.c
@@ -22,18 +22,13 @@ void
 alpha_main(struct mmap *km)
 {
 	struct task *t = task_new((void *)XHCI_ENTRY);
-	struct sysc_context_switch scs;
+	u64 *ptr = (u64 *)0;
 
 	if (t == nil)
 		send_msg("alpha: failed to create task!\n");
 
 	send_msg("alpha: running\n");
 
-	scs.sysc.type = SYSC_CONTEXT_SWITCH;
-	scs.threadid = t->thread;
-
-	sys_send((struct sysc *)&scs);
-
 	for (;;);
 }
 
blob - c03eeaa10e4b75159709cacf3ae014e5987bf1f1
blob + 30b8a7dd5b4fe5fe44a7d27e8602741b79984258
--- kernel/idt.c
+++ kernel/idt.c
@@ -1,5 +1,7 @@
 #include "kdebug.h"
 #include "types.h"
+#include "kpic.h"
+#include "kthreads.h"
 
 #define APIC_EOI_REG ((volatile u32*)0xFEE000B0)
 
@@ -112,10 +114,19 @@ general_protection_handler_c()
 
 u64 tint = 0;
 
-void
+struct thread*
 timer_handler_c()
 {
-	kprint("Timer interrupt: "); kprinti(tint++); kprint("\n");
+	struct thread *next;
 
+	next = thread_next();
+
+	if (next != nil) {
+		tss_switch_rsp0((u64)next->base + PAGE_SIZE * 3);
+		cthread = next;
+	}
+
 	*APIC_EOI_REG = 0; // Tells register interrupt was received
+
+	return next;
 }
blob - 34ebc5a87627fa395b52dc5677e1bf73d40d3eaa
blob + b2366e527a26372c6ecb83786edcd572fdce0e7c
--- kernel/kgdt.c
+++ kernel/kgdt.c
@@ -122,3 +122,9 @@ setup_tss()
 	gdt.tss.ubase = (base >> 32) & 0xff;
 	gdt.tss.reserved = 0;
 }
+
+void
+tss_switch_rsp0(u64 rsp0)
+{
+	tss.rsp0 = rsp0;
+}
blob - 5ebcf6e1480e25bb0cbe91bb902bdc7fb8c72303
blob + cdc2d5b4dc9a349890c07f32c786f010284c9a41
--- kernel/kmain.c
+++ kernel/kmain.c
@@ -50,10 +50,8 @@ kloop(struct module *amodule, struct mmap *ammap)
 {
 	struct thread *athread = thread_create((void (*)(void))(u64)amodule->entry);
 
-	if (athread == nil) {
+	if (athread == nil)
 		kprint("Failed to create thread\n");
-		repeat: goto repeat;
-	}
 
 	thread_schedule(ammap, athread);
 }
blob - d211bc91c43c414d564c555a3e919631416d419e
blob + 5d47634680e64c171b408ace77a8a70e18c5ad0f
--- kernel/kpic.h
+++ kernel/kpic.h
@@ -1,3 +1,4 @@
 #pragma once
 
 void kpic_setup(void);
+void tss_switch_rsp0(u64 rsp0);
blob - 2accf334df9298693dd6ee50980ab5275610c0a0
blob + fe438fa7f5b494e80edf47a178b5aaf4e06d97f9
--- kernel/kthreads.c
+++ kernel/kthreads.c
@@ -1,4 +1,5 @@
 #include "types.h"
+#include "kpic.h"
 #include "kmmap.h"
 #include "kdebug.h"
 #include "kthreads.h"
@@ -6,7 +7,7 @@
 #define MAX_USER_THREADS	64
 
 static struct thread uthreads[MAX_USER_THREADS];
-static struct thread *cthread;
+struct thread *cthread;
 
 struct thread*
 thread_create(void (*entry)(void))
@@ -28,7 +29,7 @@ thread_create(void (*entry)(void))
 		return nil;
 	}
 
-	thread->base = allocate_memory(PAGE_SIZE);
+	thread->base = allocate_memory(PAGE_SIZE * 3);
 
 	if (thread->base == nil) {
 		thread->assigned = 0;
@@ -36,11 +37,13 @@ thread_create(void (*entry)(void))
 	}
 
 	usp = (u64)thread->base + PAGE_SIZE;
-	sp = (u64 *)((u8*)thread->base + PAGE_SIZE);
+	sp = (u64 *)((u8*)thread->base + PAGE_SIZE * 3);
 
+	*(--sp) = 0x1B; // user SS/DS see kgdt.c
 	*(--sp) = usp; // user sp
-	*(--sp) = (u64)entry; // RIP
 	*(--sp) = 0x202; // RFLAGS
+	*(--sp) = 0x23; // User CS
+	*(--sp) = (u64)entry; // RIP
 
 	*(--sp) = 0; // rbp
 	*(--sp) = 0; // rbx
@@ -50,6 +53,7 @@ thread_create(void (*entry)(void))
 	*(--sp) = 0; // r15
 	thread->top = sp;
 	thread->rsp = (u64)sp;
+	thread->state = THREAD_READY;
 
 	return thread;
 }
@@ -68,32 +72,15 @@ thread_getuid(struct thread *th)
 // This is defined in switch.s
 
 void start_alpha(struct mmap *ammap, struct thread *thread);
-void switch_context(struct thread *old, struct thread *new);
 
 void
 thread_schedule(struct mmap *ammap, struct thread *th)
 {
 	cthread = th;
+	tss_switch_rsp0((u64)th->base + PAGE_SIZE * 3);
 	start_alpha(ammap, th);
-
-	repeat: goto repeat;
 }
 
-void
-thread_switch(struct thread *th)
-{
-	struct thread *othread;
-
-	if (th == cthread) {
-		kprint("Huh?\n");
-		return;
-	}
-
-	othread = cthread;
-	cthread = th;
-	switch_context(othread, cthread);
-}
-
 struct thread*
 thread_get_uthread(u64 id)
 {
@@ -101,3 +88,20 @@ thread_get_uthread(u64 id)
 		return &uthreads[id];
 	return nil;
 }
+
+struct thread*
+thread_next()
+{
+	s64 cid = thread_getuid(cthread);
+	s64 uid = cid;
+
+	for (u64 count = 0; count < MAX_USER_THREADS; count++) {
+	uid = (uid + 1) % MAX_USER_THREADS;
+
+	struct thread *th = &uthreads[uid];
+
+	if (th->assigned)
+		return th;
+	}
+	return nil;
+}
blob - b962ab43fc5883d0f878a41c640fde2977e15761
blob + db7769a823069ca6a111484422253a3d2584125a
--- kernel/kthreads.h
+++ kernel/kthreads.h
@@ -13,11 +13,13 @@ struct thread {
 	u64 rsp;
 
 	u8 assigned;
-	enum thread_state sate;
+	enum thread_state state;
 };
 
+extern struct thread *cthread;
+
 struct thread *thread_create(void (*entry)(void));
 s64 thread_getuid(struct thread *th);
 void thread_schedule(struct mmap *, struct thread *);
-void thread_switch(struct thread *);
+struct thread* thread_next(void);
 struct thread *thread_get_uthread(u64 id);
blob - 086afdfc65590671baca91ac1a342feeec475041
blob + f575e2ff8206bacbd765276605e8d4a67a36add4
--- kernel/lidt.s
+++ kernel/lidt.s
@@ -1,6 +1,7 @@
 [bits 64]
 
 global load_idt
+extern cthread
 
 global debug_exception_handler
 extern debug_exception_handler_c
@@ -38,5 +39,35 @@ general_protection_handler:
 	hlt
 
 timer_handler:
+	cli
+	push rbp
+	push rbx
+	push r12
+	push r13
+	push r14
+	push r15
+
+	mov rax, [rel cthread]
+	test rax, rax
+	jz .schedule
+
+	mov [rax + RSP_OFFSET], rsp
+
+.schedule:
 	call timer_handler_c
+
+	test rax, rax
+	jz .same_thread
+	mov rsp, [rax + RSP_OFFSET]
+
+.same_thread:
+	pop r15
+	pop r14
+	pop r13
+	pop r12
+	pop rbx
+	pop rbp
+
 	iretq
+
+RSP_OFFSET equ 16
blob - 3f9d9b17844b3cce85cd36d45a2155f652ce8dbd
blob + 616bc48d63becb64fdcaab0c1cbdb7d1689e51f1
--- kernel/switch.s
+++ kernel/switch.s
@@ -2,36 +2,11 @@
 ;
 ; We are forced to push rbp-r15 because SystemV
 
-global switch_context
 global start_alpha
 
 start_alpha:
 	cli
-	push rbp
-	push rbx
-	push r12
-	push r13
-	push r14
-	push r15
-
-	jmp switch_context.load
-
-switch_context:
-	cli
-	push rbp
-	push rbx
-	push r12
-	push r13
-	push r14
-	push r15
-
-	test rdi, rdi
-	jz .load
-	mov [rdi + RSP_OFFSET], rsp ; Save stack
-
-.load:
-	mov rsp, [rsi + RSP_OFFSET] ; Loads stack
-
+	mov rsp, [rsi + RSP_OFFSET]
 	pop r15
 	pop r14
 	pop r13
@@ -39,13 +14,7 @@ switch_context:
 	pop rbx
 	pop rbp
 
-	pop r11 ; pop RFLAGS in r11
-	pop rcx ; pop RIP into RCX
-	pop rax ; pop userspace rsp into rax
+	iretq
 
-	mov rsp, rax
-
-	o64 sysret
-
 ; See kthread struct
 RSP_OFFSET equ 16
blob - 97983d5a50a7c11a00eb9b8167610e5a3babe57c
blob + 506f0acdbc5f659191e10538612fa9e4b82aa5cd
--- kernel/syscalls.c
+++ kernel/syscalls.c
@@ -51,19 +51,6 @@ syscall_new_thread_h(struct sysc_new_thread *nthread)
 }
 
 void
-syscall_context_switch_h(struct sysc_context_switch *scs)
-{
-	struct thread *cthread = thread_get_uthread(scs->threadid);
-
-	if (cthread == nil) {
-		kprint("No current thread :/\n");
-		return;
-	}
-
-	thread_switch(cthread);
-}
-
-void
 syscall_handler(struct sysc *call)
 {
 	switch (call->type) {
@@ -73,9 +60,6 @@ syscall_handler(struct sysc *call)
 	case SYSC_NEW_THREAD:
 		syscall_new_thread_h((struct sysc_new_thread *)call);
 		break;
-	case SYSC_CONTEXT_SWITCH:
-		syscall_context_switch_h((struct sysc_context_switch *)call);
-		break;
 	default:
 		break;
 	}
blob - 21f83e7165a15cd1c685c241a710f00554ce5f0a
blob + 9e460d889acdd7664a8a494521a753f1e9ed08d5
--- kernel/sysentry.s
+++ kernel/sysentry.s
@@ -1,5 +1,6 @@
 [bits 64]
 
+extern cthread
 extern syscall_handler
 
 global rdmsr
@@ -8,8 +9,10 @@ global syscall_entry
 
 syscall_entry:
 	mov rax, rsp
-	mov rsp, 0x90000
 
+	mov r10, [rel cthread]
+	mov rsp, [r10 + RSP_OFFSET]
+
 	push rax
 	push rcx
 	push r11
@@ -35,3 +38,5 @@ rdmsr:
 	shl rdx, 32
 	or rax, rdx
 	ret
+
+RSP_OFFSET equ 16 ; see kthreads.h
blob - da421226ae4e2a0a08618efb2483844a76f2533d
blob + ee332a1157cd391ca49fd5dec16b823f91d3c4dd
--- syscalls/syscalls.s
+++ syscalls/syscalls.s
@@ -7,11 +7,5 @@ sys_send:
 	ret
 
 sys_recv:
-	mov rax, SYS_RECV
 	syscall
 	ret
-
-; List of system calls IDs
-
-SYS_SEND equ 1
-SYS_RECV equ 2