Commit Diff


commit - 7abd0aa7f90dfa1a7147252f69971b23d6a119c9
commit + 7b1f1314a4618908b79db56b86bae5c9306dc65f
blob - 3d351992d333c0c5df49bc4885d6bcd0b4f97c92
blob + 6574b6b771e87848e935b310dd24595b5227bcd1
--- alpha/libc.c
+++ alpha/libc.c
@@ -6,29 +6,36 @@ void (*sys_send)(struct sysc *call) = (void (*)(struct
 void
 output(const u8 *msg)
 {
-	struct sysc_echo echo;
-	echo.sysc.type = SYSC_ECHO;
-	echo.type = SYSC_ECHO_STRING;
-	echo.msg = msg;
-	sys_send((struct sysc *)&echo);
+	struct sysc sysc;
+	sysc.type = SYSC_ECHO;
+	sysc.echo.cmd = SYSC_ECHO_STRING;
+	for (int i = 0; i < SYSC_ECHO_MSG_LEN; i++) {
+		sysc.echo.msg[i] = msg[i];
+		if (msg[i] == '\0')
+			break;
+
+		if (i == SYSC_ECHO_MSG_LEN - 1)
+			sysc.echo.msg[i] = '\0';
+	}
+	sys_send(&sysc);
 }
 
 void
 outputi(u64 i)
 {
-	struct sysc_echo echo;
-	echo.sysc.type = SYSC_ECHO;
-	echo.type = SYSC_ECHO_INTEGER;
-	echo.number = i;
-	sys_send((struct sysc *)&echo);
+	struct sysc sysc;
+	sysc.type = SYSC_ECHO;
+	sysc.echo.cmd = SYSC_ECHO_INTEGER;
+	sysc.echo.number = i;
+	sys_send(&sysc);
 }
 
 void
 outputh(u64 i)
 {
-	struct sysc_echo echo;
-	echo.sysc.type = SYSC_ECHO;
-	echo.type = SYSC_ECHO_HEXADECIMAL;
-	echo.number = i;
-	sys_send((struct sysc *)&echo);
+	struct sysc sysc;
+	sysc.type = SYSC_ECHO;
+	sysc.echo.cmd = SYSC_ECHO_HEXADECIMAL;
+	sysc.echo.number = i;
+	sys_send(&sysc);
 }
blob - aa80895e24f1195b07f322154bb5f0f0912a0cb0
blob + e3c44299d8e2701bebb331312b659d8ccf0b5a63
--- alpha/libc.h
+++ alpha/libc.h
@@ -2,6 +2,15 @@
 
 #include "types.h"
 
+// Resources given to a thread on initialization
+struct contract {
+	u8 *memBlock; // This is guaranteed to be zero'd at entry point
+	u64 memSize;
+
+	u8 *sharedBlock; // Guaranteed to be zero'd at entry point as well
+	u64 sharedCount;
+};
+
 // If you come from Unix-like this is kinda
 // like print.
 
@@ -10,3 +19,5 @@ void output(const u8 *);
 void outputi(u64);
 
 void outputh(u64);
+
+// Memory allocation
blob - 8c5eb444d30483b9169d4472de388a9f08637b48
blob + 1a2e9694bafd83253434326ace1ffd76de2b7ae1
--- alpha/main.c
+++ alpha/main.c
@@ -35,23 +35,26 @@ alpha_main(struct mmap *km)
 
 	for (;;);
 }
+
 static struct task*
 task_new(void *entry)
 {
-	struct sysc_new_thread snt;
+	struct sysc sysc;
 
-	snt.sysc.type = SYSC_NEW_THREAD;
-	snt.entry = entry;
+	sysc.type = SYSC_NEW_THREAD;
+	sysc.new_thread.entry = entry;
+	sysc.new_thread.memsize = PAGE_SIZE;
+	sysc.new_thread.seats = 0;
 
 	for (int i = 0; i < MAX_TASKS; i++) {
 		if (tasks[i].assigned == 0) {
-			sys_send((struct sysc *)&snt);
+			sys_send(&sysc);
 
-			if (snt.retid == -1)
+			if (sysc.new_thread.ret_id == -1)
 				break;
 
 			tasks[i].assigned = 1;
-			tasks[i].thread = snt.retid;
+			tasks[i].thread = sysc.new_thread.ret_id;
 			return &tasks[i];
 		}
 	}
blob - 626656de7372e28c8776f0e056d187d7fdb35b4d
blob + f1d4f0c49a7a3c8123c165c16d1de3bc11dfb79d
--- build.sh
+++ build.sh
@@ -6,7 +6,7 @@ set -e
 
 KERNEL_DIR=kernel
 OS_NAME=49.bin
-INCS='-I common -I .'
+INCS='-I common -I . -I alpha'
 
 # Root task
 cd alpha
blob - cee74ed4f57f2cd2531915e4dc3972c890094c26
blob + 4bbea456c1fc5e1c47816117ea97cf496fac0d68
--- c449
+++ c449
@@ -73,7 +73,18 @@ main()
 In this example thread 1 `main` is not able to read thread 0 static
 `name` variable.
 
+[ ENTRY POINT ]
 
+In traditionnal C, the main function is the entry point. It allows
+argc and argv. In c449 it is different. Because of how the language
+is directly tied to the operating system. The entry point becomes.
+
+void main(struct contract *con, int argc, u8 *argv);
+
+Where con contains the data requested in the executable header for
+the thread to manage. Each thread entry follows this syntax.
+
+
 [ C PREPROCESSOR ]
 
 There are minor differences within C449. #define keyword does not
blob - 80dc8b3b55590067ed94ce974b03df157bb78893
blob + bb2f9923c7086b799d508df2928705ea6e57536a
--- kernel/kmain.c
+++ kernel/kmain.c
@@ -29,7 +29,6 @@ kmain(struct kinfo *kinfo, u8 drive)
 	}
 
 	kprint("IDT configured!\n");
-	syscall_init();
 
 	ammap = kmmap_init(kinfo);
 	if (ammap == nil) {
@@ -37,6 +36,7 @@ kmain(struct kinfo *kinfo, u8 drive)
 		return;
 	}
 
+	syscall_init();
 	kpic_setup();
 
 	kprint("Page tables configured!\n");
@@ -46,7 +46,8 @@ kmain(struct kinfo *kinfo, u8 drive)
 static void
 kloop(struct module *amodule, struct mmap *ammap)
 {
-	struct thread *athread = thread_create((void (*)(void))(u64)amodule->entry);
+	struct thread *athread = thread_create((void (*)(void))(u64)amodule->entry, nil);
+	athread->state = THREAD_RUNNING;
 
 	if (athread == nil)
 		kprint("Failed to create thread\n");
blob - 62195e7b1db99e5a7a72a440fefd5dd6630afab3
blob + 077a29ae933f75dc7207fb1a35d01863c1e87b4e
--- kernel/kmmap.c
+++ kernel/kmmap.c
@@ -100,10 +100,10 @@ allocate_memory(u64 bytes)
 			count++;
 
 			if (count == pages) {
-				for (u64 f = start; f < start + pages; f++)
+				for (u64 f = start; f < start + pages; f++) {
 					set_bitmap(f * PAGE_SIZE);
+				}
 
-				// kprint("Address: "); kprinth(vminfo.tables[start]); kprint("\n");
 				return (u64 *)(start * PAGE_SIZE);
 			}
 		} else {
blob - 2aaa27bd3d0a50f812e72284bcf53e13aaaad651
blob + f6fa1af4a7b0b7ba0d65afb136dece90e87f1654
--- kernel/kthreads.c
+++ kernel/kthreads.c
@@ -3,6 +3,7 @@
 #include "kmmap.h"
 #include "kdebug.h"
 #include "kthreads.h"
+#include "libc.h"
 
 #define MAX_USER_THREADS	64
 
@@ -10,7 +11,7 @@ static struct thread uthreads[MAX_USER_THREADS];
 struct thread *cthread;
 
 struct thread*
-thread_create(void (*entry)(void))
+thread_create(void (*entry)(void), struct sysc_new_thread *nthread)
 {
 	struct thread *thread = nil;
 	u64 *sp, usp;
@@ -30,12 +31,22 @@ thread_create(void (*entry)(void))
 	}
 
 	thread->base = allocate_memory(PAGE_SIZE * 2);
+	thread->con->memBlock = nil;
+	thread->con->memSize = 0;
 
 	if (thread->base == nil) {
 		thread->assigned = 0;
 		return nil;
 	}
 
+	if (nthread != nil) {
+		thread->con->memBlock = (u8 *)allocate_memory(nthread->memsize);
+		thread->con->memSize = nthread->memsize;
+
+		for (int i = 0; i < thread->con->memSize; i++)
+			thread->con->memBlock[i] = 0;
+	}
+
 	sp = (u64 *)((u8*)thread->base + PAGE_SIZE * 2);
 	usp = (u64)sp;
 
@@ -45,6 +56,7 @@ thread_create(void (*entry)(void))
 	*(--sp) = 0x08; // Kernel CS
 	*(--sp) = (u64)entry; // RIP
 
+	*(--sp) = (u64)thread->con; // rdi, this is the struct contract passed
 	*(--sp) = 0; // rbp
 	*(--sp) = 0; // rbx
 	*(--sp) = 0; // r12
@@ -58,6 +70,12 @@ thread_create(void (*entry)(void))
 	return thread;
 }
 
+void
+thread_delete(u64 threadid)
+{
+	struct thread uthreads[threadid];
+}
+
 s64 
 thread_getuid(struct thread *th)
 {
@@ -95,12 +113,12 @@ thread_next()
 	s64 uid = cid;
 
 	for (u64 count = 0; count < MAX_USER_THREADS; count++) {
-	uid = (uid + 1) % MAX_USER_THREADS;
+		uid = (uid + 1) % MAX_USER_THREADS;
 
-	struct thread *th = &uthreads[uid];
+		struct thread *th = &uthreads[uid];
 
-	if (th->assigned)
-		return th;
+		if (th->assigned && th->state == THREAD_RUNNING)
+			return th;
 	}
 	return nil;
 }
blob - db7769a823069ca6a111484422253a3d2584125a
blob + 19fbabd1b9e9124fcbbe564306ffed98b5414247
--- kernel/kthreads.h
+++ kernel/kthreads.h
@@ -1,6 +1,8 @@
 #pragma once
 
+#include "libc.h"
 #include "kmmap.h"
+#include "syscalls/syscalls.h"
 
 enum thread_state {
 	THREAD_READY,
@@ -12,13 +14,15 @@ struct thread {
 	u64 *top;
 	u64 rsp;
 
+	struct contract *con;
+
 	u8 assigned;
 	enum thread_state state;
 };
 
 extern struct thread *cthread;
 
-struct thread *thread_create(void (*entry)(void));
+struct thread *thread_create(void (*entry)(void), struct sysc_new_thread *);
 s64 thread_getuid(struct thread *th);
 void thread_schedule(struct mmap *, struct thread *);
 struct thread* thread_next(void);
blob - 2dc35b1e0b56da7ebf126adaf33be290cd292dc7
blob + 9a2536142cad0000aaa41b994eea2d2b3c4328b7
--- kernel/lidt.s
+++ kernel/lidt.s
@@ -41,6 +41,7 @@ general_protection_handler:
 timer_handler:
 	cli
 
+	push rdi
 	push rbp
 	push rbx
 	push r12
@@ -68,6 +69,7 @@ timer_handler:
 	pop r12
 	pop rbx
 	pop rbp
+	pop rdi
 
 	iretq
 
blob - 014a9a1f363403a2edea51c96f40aa503e2abfb4
blob + 478f81a77d1f715eab260debc263446726aeda1f
--- kernel/switch.s
+++ kernel/switch.s
@@ -5,14 +5,16 @@
 global start_alpha
 
 start_alpha:
+	cli
 	mov rsp, [rsi + RSP_OFFSET]
+	pop rdi
 	pop r15
 	pop r14
 	pop r13
 	pop r12
 	pop rbx
 	pop rbp
-
+	
 	iretq
 
 ; See kthread struct
blob - ef4077ea1afc937475b103521f2bd6c238d74b47
blob + af6e2abed99462469afc6841fd8300cd54b9c97c
--- kernel/syscalls.c
+++ kernel/syscalls.c
@@ -1,17 +1,34 @@
 #include "types.h"
+#include "kmmap.h"
 #include "kdebug.h"
 #include "kthreads.h"
 #include "syscalls/syscalls.h"
 
-#define MAX_SEATS 64
+#define MAX_SEATS	256
+#define MAX_SYSC_QUEUE	64
+#define THREADID_NONE	-1
 
 struct seatmap {
-	u64 send; // Sender Thread
-	u64 recv; // Receiver Thread
+	s64 send; // Sender Thread
+	s64 recv; // Receiver Thread
 };
 
 static struct seatmap seatmaps[MAX_SEATS];
+static u8 *sbuffers;
 
+s8
+seat_new(u64 threadid)
+{
+	for (int i = 0; i < MAX_SEATS; i++) {
+		if (seatmaps[i].recv == THREADID_NONE) {
+			seatmaps[i].recv = threadid;
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
 void syscall_handler(struct sysc *);
 
 // Trampoline
@@ -19,7 +36,19 @@ void syscall_init()
 {
 	u8 *jump = (u8 *)SYSC_BELL;
 	u64 addr = (u64)&syscall_handler;
+	sbuffers = (u8 *)allocate_memory(PAGE_SIZE * MAX_SEATS);
 
+	if (sbuffers == nil) {
+		kprint("Failed to create seat buffers!\n");
+		repeat:
+			goto repeat;
+	}
+
+	for (int i = 0; i < MAX_SEATS; i++) {
+		seatmaps[i].send = THREADID_NONE;
+		seatmaps[i].recv = THREADID_NONE;
+	}
+
 	// movabs rax, addr
 	jump[0] = 0x48;
 	jump[1] = 0xB8;
@@ -31,9 +60,10 @@ void syscall_init()
 }
 
 void
-syscall_echo_h(struct sysc_echo *echo)
+syscall_echo_h(struct sysc *call)
 {
-	switch (echo->type) {
+	struct sysc_echo *echo = &call->echo;
+	switch (echo->cmd) {
 	case SYSC_ECHO_STRING:
 		kprint(echo->msg);
 		break;
@@ -48,17 +78,30 @@ syscall_echo_h(struct sysc_echo *echo)
 	}
 }
 
+// This functions creates a thread with all the resources it
+// needs such as the amount of seats. If another thread wishes
+// to connect to a specific thread it just does SYSC_CONNECT
 void
-syscall_new_thread_h(struct sysc_new_thread *nthread)
+syscall_new_thread_h(struct sysc *call)
 {
-	struct thread *th = thread_create(nthread->entry);
+	struct sysc_new_thread *nthread = &call->new_thread;
+	struct thread *th = thread_create(nthread->entry, nthread);
 	s64 threadid;
 
 	if (th == nil)
 		kprint("failed to create thread from syscall!\n");
 
+	/*
+	if (seat_new(threadid) == -1) {
+		kprint("Failed to create new seat\n");
+		repeat:
+			goto repeat;
+	}
+	*/
+
 	threadid = thread_getuid(th);
-	nthread->retid = threadid;
+	nthread->ret_id = threadid;
+	th->state = THREAD_RUNNING;
 
 	kprint("Thread (id="); kprinti(threadid); kprint(") created!\n");
 }
@@ -68,10 +111,10 @@ syscall_handler(struct sysc *call)
 {
 	switch (call->type) {
 	case SYSC_ECHO:
-		syscall_echo_h((struct sysc_echo *)call);
+		syscall_echo_h(call);
 		break;
 	case SYSC_NEW_THREAD:
-		syscall_new_thread_h((struct sysc_new_thread *)call);
+		syscall_new_thread_h(call);
 		break;
 	default:
 		break;
blob - 9c4f59ed470664e3583932f89f1a9e98980ec009
blob + 355b272393886987af96ba873b5cab4a4589205e
--- servers/xhci/main.c
+++ servers/xhci/main.c
@@ -6,8 +6,14 @@
 #include "libc.h"
 
 void
-xhci_main()
+xhci_main(struct contract *con)
 {
 	output("xhci: running\n");
+
+	output("xhci: memory size is "); outputi(con->memSize);
+	output(" bytes\n");
+
+	output("Memory block location is : "); outputh((u64)con->memBlock[0]); output("\n");
+
 	for (;;);
 }
blob - d1edb04a4f5cfca5a1ece76b9ed6582ada0a95eb
blob + 4814d52593d770131e8ced32171fbab5cca710de
--- syscalls/syscalls.h
+++ syscalls/syscalls.h
@@ -1,19 +1,15 @@
 #pragma once
 
 #define SYSC_BELL	0xE00000
+#define SYSC_ECHO_MSG_LEN	256
 
 enum sysc_type {
 	SYSC_ECHO,
 	SYSC_NEW_THREAD,
 	SYSC_FREE_THREAD,
-	SYSC_CONTEXT_SWITCH, // This shouldn't be a thing its for testing before APIC and thread states
 };
 
-struct sysc {
-	enum sysc_type type;
-};
-
-enum sysc_echo_type {
+enum sysc_echo_cmd {
 	SYSC_ECHO_STRING,
 	SYSC_ECHO_INTEGER,
 	SYSC_ECHO_HEXADECIMAL,
@@ -21,30 +17,27 @@ enum sysc_echo_type {
 };
 
 struct sysc_echo {
-	struct sysc sysc;
-	enum sysc_echo_type type;
+	enum sysc_echo_cmd cmd;
 	union {
-		const char *msg;
+		u8 msg[SYSC_ECHO_MSG_LEN];
 		u64 number;
 	};
 };
 
 struct sysc_new_thread {
-	struct sysc sysc;
-	void *entry;
-	u64 size; // Unused for now
+	void *entry; // Entry point
+	u64 memsize;
+	u64 seats;
 
-	s64 retid; // The threadId returned
+	s64 ret_id;
 };
 
-struct sysc_free_thread {
-	struct sysc sysc;
-	u64 id;
+struct sysc {
+	enum sysc_type type;
+	union {
+		struct sysc_echo echo;
+		struct sysc_new_thread new_thread;
+	};
 };
 
-struct sysc_context_switch {
-	struct sysc sysc;
-	u64 threadid;
-};
-
 extern void (*sys_send)(struct sysc *call);