summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2025-07-30 14:32:01 -0400
committerJon Santmyer <jon@jonsantmyer.com>2025-07-30 14:32:01 -0400
commitb905869a35f062a4e5072f10bec3a2ba3db0e365 (patch)
tree0666691804878857b4bb07daca8a54f5ddb8ae0b /include
downloadjove-kernel-b905869a35f062a4e5072f10bec3a2ba3db0e365.tar.gz
jove-kernel-b905869a35f062a4e5072f10bec3a2ba3db0e365.tar.bz2
jove-kernel-b905869a35f062a4e5072f10bec3a2ba3db0e365.zip
working userland with some invoke syscalls
Diffstat (limited to 'include')
-rw-r--r--include/arch/x86_64/idt.h18
-rw-r--r--include/arch/x86_64/object.h26
-rw-r--r--include/arch/x86_64/page.h41
-rw-r--r--include/arch/x86_64/processor.h66
-rw-r--r--include/arch/x86_64/tables.h51
-rw-r--r--include/boot.h7
-rw-r--r--include/bootargs.h13
-rw-r--r--include/device/initrd.h29
-rw-r--r--include/device/portio.h26
-rw-r--r--include/device/portio_uart.h27
-rw-r--r--include/device/processor.h22
-rw-r--r--include/device/uart.h11
-rw-r--r--include/error.h8
-rw-r--r--include/init.h10
-rw-r--r--include/jove.h15
-rw-r--r--include/memory.h17
-rw-r--r--include/object.h61
-rw-r--r--include/panic.h9
-rw-r--r--include/print.h17
-rw-r--r--include/string.h25
-rw-r--r--include/syscall.h46
-rw-r--r--include/tcb.h18
22 files changed, 563 insertions, 0 deletions
diff --git a/include/arch/x86_64/idt.h b/include/arch/x86_64/idt.h
new file mode 100644
index 0000000..90ce48b
--- /dev/null
+++ b/include/arch/x86_64/idt.h
@@ -0,0 +1,18 @@
+#ifndef _JOVE_x86_64_IDT_H
+#define _JOVE_x86_64_IDT_H 1
+
+#include "processor.h"
+
+typedef struct jove_IVTState
+{
+ uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
+ uint64_t rbp, rdi, rsi, rdx, rcx, rbx, rax;
+ uint64_t rip, cs, rflags, rsp, ss;
+} ivt_state_t;
+
+void kpanic_state(ivt_state_t *state, const char *fmt, ...);
+
+void ivt_setup(void);
+void idt_setup(processor_t *processor);
+
+#endif
diff --git a/include/arch/x86_64/object.h b/include/arch/x86_64/object.h
new file mode 100644
index 0000000..8d5af33
--- /dev/null
+++ b/include/arch/x86_64/object.h
@@ -0,0 +1,26 @@
+#ifndef _JOVE_x86_64_OBJECT_H
+#define _JOVE_x86_64_OBJECT_H 1
+
+#include <stdint.h>
+
+typedef struct jove_InitData
+{
+ uint8_t log_object;
+ uint8_t untyped_data_dir;
+ uint8_t processor_dir;
+ uint8_t pm_object; //Page mapping object.
+ uint8_t initrd_dir; //Init ramdisk files directory.
+ uint8_t tcb_object;
+ uint8_t kernel_stack_object;
+ uint8_t message_object;
+ uintptr_t message_object_address;
+} init_data_t;
+
+typedef struct jove_ThreadControlBlock
+{
+ void *stack;
+ uintptr_t sp, ksp;
+ void *pml4;
+} tcb_t;
+
+#endif
diff --git a/include/arch/x86_64/page.h b/include/arch/x86_64/page.h
new file mode 100644
index 0000000..99bc691
--- /dev/null
+++ b/include/arch/x86_64/page.h
@@ -0,0 +1,41 @@
+#ifndef _JOVE_ARCH_x86_64_PAGE_H
+#define _JOVE_ARCH_x86_64_PAGE_H 1
+
+#include <stdint.h>
+#include "include/object.h"
+
+typedef union jove_PageMapLevelEntry
+{
+ struct {
+ uint8_t p : 1; /* Present */
+ uint8_t rw : 1; /* Read/write. 0 for RO.*/
+ uint8_t us : 1; /* User/supervisor. 0 for DPL3 forbid */
+ uint8_t pwt : 1;
+ uint8_t pcd : 1;
+ uint8_t a : 1; /* Accessed */
+ uint8_t d : 1; /* Dirty */
+ uint8_t ps_pat : 1;
+ uint8_t g : 1; /* Global */
+ uint8_t _r0 : 2;
+ uint8_t r : 1;
+ uint64_t paddr : 35;
+ uint8_t _r1;
+ uint8_t pk : 4;
+ uint8_t xd : 1;
+ }__attribute__((packed));
+ uint64_t value;
+} __attribute__((packed)) pmle_t;
+
+typedef uint16_t pmli_t;
+
+#define PML_SHL(l) ((l * 9) + 3)
+#define PML_I_FOR_LAYER(v, l) ((v >> PML_SHL(l)) % 512)
+
+uintptr_t vmem_ident_tophys(void *vptr);
+void *vmem_phys_tovirt(uintptr_t pptr);
+
+void *pmle_get_page(pmle_t entry);
+
+int untyped_retype_page(objdir_entry_t *untyped_entry, void **dest_ptr);
+
+#endif
diff --git a/include/arch/x86_64/processor.h b/include/arch/x86_64/processor.h
new file mode 100644
index 0000000..f8a93ce
--- /dev/null
+++ b/include/arch/x86_64/processor.h
@@ -0,0 +1,66 @@
+#ifndef _JOVE_ARCH_x86_64_PROCESSOR_H
+#define _JOVE_ARCH_x86_64_PROCESSOR_H 1
+
+#include "memory.h"
+#include "tables.h"
+#include "object.h"
+#include <stdint.h>
+
+#define MSR_FS_BASE 0xC0000100
+#define MSR_GS_BASE 0xC0000101
+#define MSR_KGS_BASE 0xC0000102
+
+#define MSR_EFER 0xC0000080
+#define MSR_STAR 0xC0000081
+#define MSR_LSTAR 0xC0000082
+#define MSR_SFMASK 0xC0000084
+
+typedef struct jove_TSS
+{
+ uint32_t resv0;
+ uint64_t rsp[3];
+ uint32_t resv1;
+ uint64_t ist[8];
+ uint32_t resv2[2];
+ uint16_t resv3;
+ uint16_t iopb;
+} tss_t;
+
+enum
+{
+ GDT_ENTRY_KERNEL_NULL = 0,
+ GDT_ENTRY_KERNEL_CODE,
+ GDT_ENTRY_KERNEL_DATA,
+ GDT_ENTRY_USER_NULL,
+ GDT_ENTRY_USER_DATA,
+ GDT_ENTRY_USER_CODE,
+ GDT_ENTRY_TSS_LOW,
+ GDT_ENTRY_TSS_HIGH,
+ GDT_ENTRY_COUNT
+};
+
+typedef struct jove_Processor
+{
+ physptr_t pdir;
+ struct jove_ObjectDirectory *odir;
+
+ segment_descriptor_t gdt[GDT_ENTRY_COUNT];
+ struct {
+ uint16_t length;
+ uint64_t base;
+ } __attribute__((packed)) gdtr;
+ struct {
+ uint16_t length;
+ uint64_t base;
+ } __attribute__((packed)) idtr;
+
+ tss_t tss;
+ tcb_t *tcb;
+} processor_t;
+
+void gdt_setup(processor_t *processor);
+
+void rdmsr(uint32_t msr, uint32_t *lo, uint32_t *hi);
+void wrmsr(uint32_t msr, uint32_t lo, uint32_t hi);
+
+#endif
diff --git a/include/arch/x86_64/tables.h b/include/arch/x86_64/tables.h
new file mode 100644
index 0000000..42651a1
--- /dev/null
+++ b/include/arch/x86_64/tables.h
@@ -0,0 +1,51 @@
+#ifndef _JOVE_ARCH_x86_64_TABLES_H
+#define _JOVE_ARCH_x86_64_TABLES_H 1
+
+#include <stdint.h>
+
+#define CD_SEGMENT_TYPE_ACCESSED 1
+#define CD_SEGMENT_TYPE_WRITEABLE 2
+#define CD_SEGMENT_TYPE_DATA_EXPAND_DOWN 4
+#define CD_SEGMENT_TYPE_CODE_CONFORMING 4
+#define CD_SEGMENT_TYPE_CODE 8
+
+#define S_SEGMENT_TYPE_LDT 2
+#define S_SEGMENT_TYPE_TSS_AVAIL 9
+#define S_SEGMENT_TYPE_TSS_BUSY 11
+#define S_SEGMENT_TYPE_CALLGATE 12
+#define S_SEGMENT_TYPE_INT_GATE 14
+#define S_SEGMENT_TYPE_TRAP_GATE 15
+
+typedef struct jove_SegmentDescriptor
+{
+ uint16_t limit_0_15; /* Segment limit. */
+ uint16_t base_0_15; /* Segment base. */
+ uint8_t base_16_23;
+ uint8_t type : 4; /* Segment type. */
+ uint8_t s : 1; /* Descriptor type (0 = system, 1 = code/data)*/
+ uint8_t dpl : 2; /* Descriptor privilege level. */
+ uint8_t p : 1; /* Present. */
+ uint8_t limit_16_19 : 4;
+ uint8_t avl : 1; /* Available for use by system software. */
+ uint8_t l : 1; /* 64-bit segment (Ext). */
+ uint8_t d_b : 1; /* Default operation size (0 = 16-bit, 1 = 32-bit)*/
+ uint8_t g : 1; /* Granularity. */
+ uint8_t base_24_31;
+}__attribute__((packed)) segment_descriptor_t;
+
+typedef struct jove_InterruptGate
+{
+ uint16_t base_0_15;
+ uint16_t segment_selector;
+ uint8_t ist : 3;
+ uint8_t zero_0 : 5;
+ uint8_t type : 4;
+ uint8_t zero_1 : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint16_t base_16_31;
+ uint32_t base_32_63;
+ uint32_t resv;
+}__attribute__((packed)) interrupt_gate_t;
+
+#endif
diff --git a/include/boot.h b/include/boot.h
new file mode 100644
index 0000000..989b4b9
--- /dev/null
+++ b/include/boot.h
@@ -0,0 +1,7 @@
+#ifndef _JOVE_BOOT_H
+#define _JOVE_BOOT_H 1
+
+extern char *jove_bootargs;
+extern int jove_bootargs_len;
+
+#endif
diff --git a/include/bootargs.h b/include/bootargs.h
new file mode 100644
index 0000000..94910f4
--- /dev/null
+++ b/include/bootargs.h
@@ -0,0 +1,13 @@
+#ifndef _JOVE_BOOTARGS_H
+#define _JOVE_BOOTARGS_H 1
+
+/*Layout:
+ * [KEY]=[VALUE]
+ * All values are seperated by spaces.*/
+
+/**@FUNC Get the value associated with the given key.
+ * @PARAM key string to search for.
+ * @RETURN value associated with key. */
+char *bootargs_getarg(const char *key);
+
+#endif
diff --git a/include/device/initrd.h b/include/device/initrd.h
new file mode 100644
index 0000000..eaf3157
--- /dev/null
+++ b/include/device/initrd.h
@@ -0,0 +1,29 @@
+#ifndef _JOVE_DEV_INITRD_H
+#define _JOVE_DEV_INITRD_H 1
+
+#include <stddef.h>
+
+typedef struct tarHeader
+{
+ char name[100];
+ char mode[8];
+ char owner[8];
+ char group[8];
+ char size[12];
+ char modified[12];
+ char checksum[8];
+ char link;
+ char linkname[100];
+} tar_header_t;
+
+typedef union tarBlock {
+ tar_header_t header;
+ char data[512];
+} tar_block_t;
+
+void initrd_setup(void);
+
+tar_header_t *initrd_find_file(const char *filename);
+int initrd_file_size(tar_header_t *header);
+
+#endif
diff --git a/include/device/portio.h b/include/device/portio.h
new file mode 100644
index 0000000..76b28c4
--- /dev/null
+++ b/include/device/portio.h
@@ -0,0 +1,26 @@
+#ifndef _JOVE_PORTIO_H
+#define _JOVE_PORTIO_H 1
+
+#include <stdint.h>
+
+typedef uint16_t ioport_t;
+
+static inline uint8_t port_inb(ioport_t port)
+{ uint8_t r; __asm__ volatile("inb %w1, %b0": "=a"(r): "Nd"(port): "memory"); return r; }
+
+static inline uint16_t port_inw(ioport_t port)
+{ uint16_t r; __asm__ volatile("inw %w1, %w0": "=a"(r): "Nd"(port): "memory"); return r; }
+
+static inline uint32_t port_inl(ioport_t port)
+{ uint32_t r; __asm__ volatile("inl %d1, %l0": "=a"(r): "Nd"(port): "memory"); return r; }
+
+static inline void port_outb(ioport_t port, uint8_t v)
+{ __asm__ volatile("outb %b0, %w1":: "a"(v), "Nd"(port): "memory"); }
+
+static inline void port_outw(ioport_t port, uint16_t v)
+{ __asm__ volatile("outb %w0, %w1":: "a"(v), "Nd"(port): "memory"); }
+
+static inline void port_outl(ioport_t port, uint32_t v)
+{ __asm__ volatile("outb %d0, %w1":: "a"(v), "Nd"(port): "memory"); }
+
+#endif
diff --git a/include/device/portio_uart.h b/include/device/portio_uart.h
new file mode 100644
index 0000000..1b521a1
--- /dev/null
+++ b/include/device/portio_uart.h
@@ -0,0 +1,27 @@
+#ifndef _JOVE_DEVICE_PORTIO_UART
+#define _JOVE_DEVICE_PORTIO_UART 1
+
+#include <stdint.h>
+
+#define PORTIO_UART_COM1 0x3F8
+
+#define PORTIO_UART_COM_THR(COM) COM
+#define PORTIO_UART_COM_RBR(COM) COM
+#define PORTIO_UART_COM_DLAB_DLL(COM) COM
+#define PORTIO_UART_COM_IER(COM) (COM + 1)
+#define PORTIO_UART_COM_DLAB_DLH(COM) (COM + 1)
+#define PORTIO_UART_COM_IIR(COM) (COM + 2)
+#define PORTIO_UART_COM_FCR(COM) (COM + 2)
+#define PORTIO_UART_COM_LCR(COM) (COM + 3)
+#define PORTIO_UART_COM_MCR(COM) (COM + 4)
+#define PORTIO_UART_COM_LSR(COM) (COM + 5)
+#define PORTIO_UART_COM_MSR(COM) (COM + 6)
+#define PORTIO_UART_COM_SR(COM) (COM + 7)
+
+void
+portio_uart_setup(void);
+
+void
+portio_uart_write(uint64_t dev, const char *s, int n);
+
+#endif
diff --git a/include/device/processor.h b/include/device/processor.h
new file mode 100644
index 0000000..33deed4
--- /dev/null
+++ b/include/device/processor.h
@@ -0,0 +1,22 @@
+#ifndef _JOVE_DEVICE_PROCESSOR_H
+#define _JOVE_DEVICE_PROCESSOR_H 1
+
+#if defined(__x86_64__)
+#include "arch/x86_64/processor.h"
+#endif
+
+/**@FUNC Initialize the bootstrap processor.*/
+void bsp_setup(void);
+/**@FUNC Initialize the given processor with kernel-specific values.
+ * Generically:
+ * Instantiates a new kernel object representing the passed processor.
+ * For x86_64:
+ * Loads and uses the generic GDT and IDT.
+ * @PARAM processor processor to initialize.*/
+void processor_setup(void* processor);
+
+/**@FUNC Returns the processor struct this function is called by.
+ * @RET pointer to current processor.*/
+void *processor_current(void);
+
+#endif
diff --git a/include/device/uart.h b/include/device/uart.h
new file mode 100644
index 0000000..3d481a2
--- /dev/null
+++ b/include/device/uart.h
@@ -0,0 +1,11 @@
+#ifndef _JOVE_DEVICE_UART_H
+#define _JOVE_DEVICE_UART_H 1
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "object.h"
+
+void uart_write(objdir_t *dir, uint64_t entryi, const char *s, size_t w);
+
+#endif
diff --git a/include/error.h b/include/error.h
new file mode 100644
index 0000000..8aa087c
--- /dev/null
+++ b/include/error.h
@@ -0,0 +1,8 @@
+#ifndef _JOVE_ERROR_H
+#define _JOVE_ERROR_H 1
+
+#define E_OK 0
+#define E_BADOBJ 1
+#define E_ARGUMENT 2
+
+#endif
diff --git a/include/init.h b/include/init.h
new file mode 100644
index 0000000..aa722b1
--- /dev/null
+++ b/include/init.h
@@ -0,0 +1,10 @@
+#ifndef _JOVE_INIT_H
+#define _JOVE_INIT_H 1
+
+#ifdef __x86_64__
+
+#endif
+
+void init_load(void);
+
+#endif
diff --git a/include/jove.h b/include/jove.h
new file mode 100644
index 0000000..cbe1a77
--- /dev/null
+++ b/include/jove.h
@@ -0,0 +1,15 @@
+#ifndef _JOVE_H
+#define _JOVE_H 1
+
+#define NORETURN __attribute__((noreturn))
+
+extern void (*_kernel_start)(void);
+extern void (*_kernel_end)(void);
+
+#include "object.h"
+extern objdir_t _initDirectory;
+extern init_data_t _initData;
+
+NORETURN void hcf(void);
+
+#endif
diff --git a/include/memory.h b/include/memory.h
new file mode 100644
index 0000000..e29c41b
--- /dev/null
+++ b/include/memory.h
@@ -0,0 +1,17 @@
+#ifndef _JOVE_MEMORY_H
+#define _JOVE_MEMORY_H 1
+
+#include <stdint.h>
+#include "object.h"
+
+typedef uintptr_t physptr_t;
+typedef uintptr_t virtptr_t;
+
+#define KERNEL_STACK_SIZE 0x1000
+
+void pmem_setup(void);
+void vmem_setup(void);
+
+int untyped_retype_kernel_stack(objdir_entry_t *untyped_entry, objdir_entry_t *dest_entry);
+
+#endif
diff --git a/include/object.h b/include/object.h
new file mode 100644
index 0000000..0a71b5f
--- /dev/null
+++ b/include/object.h
@@ -0,0 +1,61 @@
+#ifndef _JOVE_OBJECT_H
+#define _JOVE_OBJECT_H
+
+#include <stdint.h>
+
+#if defined(__x86_64__)
+#include "arch/x86_64/object.h"
+#endif
+
+enum
+{
+ /* Generic objects */
+ KO_NONE = 0,
+ KO_OBJECT_DIRECTORY,
+ KO_INIT_DATA,
+ KO_MEMORY_UNTYPED,
+ KO_MEMORY_MAPPED_PAGE, //4KiB Fixed Width
+ KO_MEMORY_MAPPING_PAGE, //4Kib Fixed Width
+ KO_INITRD_FILE,
+ KO_TCB,
+ KO_KERNEL_STACK,
+ KO_MESSAGE,
+ /* Device objects*/
+ KO_DEV_INVALID = 0x100,
+ KO_DEV_PROCESSOR,
+ KO_DEV_UART
+};
+
+typedef uintmax_t obj_path_t;
+typedef uint16_t obj_type_t;
+
+typedef struct jove_ObjectDirectoryEntry
+{
+ obj_type_t type;
+ union {
+ struct {
+ char lock : 1;
+ char u0 : 7;
+ char u1;
+};
+ unsigned short flg;
+ };
+ uintmax_t data;
+} objdir_entry_t;
+
+#define OBJECT_DIRECTORY_MAX_ENTRIES 256
+
+//The first entry always represents itself, which allows the kernel to ignore
+//some checks.
+//The data variable also contains the next free index for this directory.
+typedef struct jove_ObjectDirectory
+{
+ union {
+ objdir_entry_t self;
+ objdir_entry_t entries[OBJECT_DIRECTORY_MAX_ENTRIES];
+ };
+} objdir_t;
+
+objdir_entry_t *objdir_seek(objdir_t *dir, uintmax_t index);
+
+#endif
diff --git a/include/panic.h b/include/panic.h
new file mode 100644
index 0000000..076a425
--- /dev/null
+++ b/include/panic.h
@@ -0,0 +1,9 @@
+#ifndef _JOVE_PANIC_H
+#define _JOVE_PANIC_H 1
+
+#include "jove.h"
+
+#define kpanic(...) _kpanic(__FILE__, __LINE__, __VA_ARGS__)
+NORETURN void _kpanic(const char *file, int line, const char *fmt, ...);
+
+#endif
diff --git a/include/print.h b/include/print.h
new file mode 100644
index 0000000..f4c942c
--- /dev/null
+++ b/include/print.h
@@ -0,0 +1,17 @@
+#ifndef _JOVE_LIB_PRINT_H
+#define _JOVE_LIB_PRINT_H 1
+
+#include <stdarg.h>
+
+void _klogf(const char *file, const char *func, int line, const char *fmt, ...);
+#define klogf(...) _klogf(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+
+int kprintf(const char *fmt, ...);
+int ksprintf(char *s, const char *fmt, ...);
+int ksnprintf(char *s, int size, const char *fmt, ...);
+
+int kvprintf(const char *fmt, va_list ap);
+int kvsprintf(char *s, const char *fmt, va_list ap);
+int kvsnprintf(char *s, int size, const char *fmt, va_list ap);
+
+#endif
diff --git a/include/string.h b/include/string.h
new file mode 100644
index 0000000..a821f1c
--- /dev/null
+++ b/include/string.h
@@ -0,0 +1,25 @@
+#ifndef _JOVE_STRING_H
+#define _JOVE_STRING_H 1
+
+#include <stdbool.h>
+#include <stddef.h>
+
+/**@FUNC Writes the given integer to the string using a custom base.
+ * If the integer is larger than size, s will stop being written to at s[size-1].
+ * Returns the number of characters written, or would have been written.
+ * @PARAM s buffer to write to.
+ * @PARAM size size of buffer to write to.
+ * @PARAM l integer to write.
+ * @PARAM sign whether the integer is signed or unsigned.
+ * @PARAM radix base to write at.
+ * @RETURN number of characters in number.*/
+int ltostr(char *s, int size, unsigned long l, bool sign, int radix);
+
+size_t strlen(const char *s);
+int strcmp(const char *s1, const char *s2);
+
+void *memset(void *dest, char c, size_t n);
+void *memcpy(void *dest, const void *src, size_t n);
+void *memmove(void *dest, const void *src, size_t n);
+
+#endif
diff --git a/include/syscall.h b/include/syscall.h
new file mode 100644
index 0000000..c9c26d8
--- /dev/null
+++ b/include/syscall.h
@@ -0,0 +1,46 @@
+#ifndef _JOVE_SYSCALL_H
+#define _JOVE_SYSCALL_H 1
+
+#include <stdint.h>
+#include <stddef.h>
+#include "object.h"
+
+enum
+{
+ SYSCALL_NONE = 0,
+ SYSCALL_INVOKE,
+ SYSCALL_SEND,
+ SYSCALL_RECV,
+
+ SYSCALL_DEBUG_PUTC,
+ SYSCALL_DEBUG_IDENTIFY
+};
+
+typedef uint16_t invokeid_t;
+
+struct syscallInvokeHeader
+{
+ obj_path_t target_path;
+ invokeid_t func_id;
+};
+
+enum
+{
+ INVOKE_OBJDIR_NMEMB = 0,
+ INVOKE_OBJDIR_GETMEMB
+};
+
+struct syscallInvoke_objdir_nmemb
+{
+ struct syscallInvokeHeader header;
+ size_t value;
+};
+
+struct syscallInvoke_objdir_getmemb
+{
+ struct syscallInvokeHeader header;
+ uint8_t member;
+ obj_type_t value;
+};
+
+#endif
diff --git a/include/tcb.h b/include/tcb.h
new file mode 100644
index 0000000..6545083
--- /dev/null
+++ b/include/tcb.h
@@ -0,0 +1,18 @@
+#ifndef _JOVE_TCB_H
+#define _JOVE_TCB_H 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+typedef struct jove_ThreadControlBlock
+{
+ uintmax_t id;
+ struct jove_ThreadControlBlock *children;
+ struct jove_ThreadControlBlock *next;
+
+ void *stack;
+ uintptr_t sp, ksp;
+ void *pml4;
+} tcb_t;
+
+#endif