]> pd.if.org Git - zos/blobdiff - process.h
processes and multitasking
[zos] / process.h
diff --git a/process.h b/process.h
new file mode 100644 (file)
index 0000000..49d24a5
--- /dev/null
+++ b/process.h
@@ -0,0 +1,120 @@
+#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