+#ifndef PROCESS_H_
+#define PROCESS_H_
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include <sys/types.h>
+
+#include <mem.h>
+
+/* 8 MB stack */
+#define RLIMIT_STACK_VAL 0x800000
+
+#define TASK_KERNEL 0x1
+#define TASK_NOSCHED 0x2
+
+/*
+ * memory map for processes
+ * 0xFFFFFFFF8000000 and up, kernel, can copy kernel pml4 entries
+ * program load at 4 MB
+ * stack at 128 TB = 8000 0000 0000 (and down)
+ * mmaps at 127 TB = 7F00 0000 0000 (and down)
+ * heap at 96 TB = 6000 0000 0000 (and up)
+ * heap at 2 TB?
+ * heap after program load...
+ * program at 4 MB = 40 0000
+ */
+
+/* so, to create a process,
+ * allocate 2 MB for stack,
+ * allocate whatever is needed for the code
+ * load in the code to the code base
+ * set up the registers
+ * set up the stack for the iretq or sysret
+ * iretq or sysret to start the task
+ */
+
+struct registers {
+ uint64_t kerrno;
+ uint64_t rax;
+ uint64_t rbx;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rdi;
+ uint64_t rsi;
+ uint64_t rsp;
+ uint64_t rbp;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t rip;
+ uint64_t rflags;
+ uint64_t cr3;
+ uint64_t kernel_stack;
+ uint64_t cs;
+ uint64_t ss;
+ __attribute__((aligned(16))) uint8_t fpuenv[512];
+} __attribute__((packed));
+
+/* flags bits */
+
+/* user or kernel process */
+#define TM_USER 0x1
+/* needs re-scheduled */
+#define TM_SCHEDULE 0x2
+/* in syscall */
+#define TM_SYSCALL 0x4
+/* in interrupt */
+#define TM_INTERRUPTED 0x8
+
+#define TM_RUNNABLE 0x10
+
+struct process {
+ pid_t pid;
+ pid_t ppid;
+
+ /* todo just use a user or kernel process, maybe a flag */
+ int pl; /* privilege level, 0 for kernel, 3 for users */
+ uint64_t flags; /* bit flags */
+
+ struct registers reg;
+ vaddr_t kstack; /* pointer to the kernel stack */
+ vaddr_t stacks;
+ vaddr_t usp; /* user stack pointer */
+ vaddr_t heap;
+ struct process *next, *prev; /* scheduling */
+
+ /* sleep should probably be a struct timespec */
+ uint64_t sleep; /* don't need to sleep for 64 bits of ticks */
+
+ int status; /* return status from main/exit */
+ unsigned int quantum; /* how many more ticks */
+ // struct inode *cwd;
+ // struct sigaction_t sigaction[NUM_SIGNALS];
+ // uint64_t signal_pending;
+ int (*main)(int ac, char **av);
+};
+
+uint64_t getrflags(); /* assembly */
+void init_tasking();
+
+pid_t create_task(struct process *task, void (*main)(), uint64_t rflags, uint64_t pagedir, uint64_t flags);
+struct process *new_task(void (*entry)(), uint64_t rflags, uint64_t pagedir, uint64_t flags);
+
+void sleep(uint32_t ticks);
+void schedule();
+void do_schedule();
+int need_schedule();
+void preempt(); // Switch task frontend
+void switch_task(struct registers *old, struct registers *new);
+void switch_task_iret(struct registers *old, struct registers *new);
+
+/* in assembly */
+void usermodetrampoline(void (*main)(), uint64_t rflags);
+#endif