summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-09-16 20:53:43 -0400
committerIan Moffett <ian@osmora.org>2025-09-16 20:53:43 -0400
commite3fba3a2fc865a5b4d6fa622fd383b6d612e8c85 (patch)
tree36a0309a727b315a912e771d71a3a06b40a3e395
parent3ed526d5ae90130bcc8e12c53d970c503eab9004 (diff)
kern: proc: Add initialization code for ring 3
This commit introduces several new functions for switching the processor into a ring three context along with its task's respective process descriptors to be implemented correctly. - Add md_set_ip() to update proc instruction pointer - Add stack definitions - Add stack mapping logic ... Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--src/sys/arch/amd64/os/os_proc.c88
-rw-r--r--src/sys/include/sys/proc.h18
2 files changed, 106 insertions, 0 deletions
diff --git a/src/sys/arch/amd64/os/os_proc.c b/src/sys/arch/amd64/os/os_proc.c
index 8fad7b6..7a65b34 100644
--- a/src/sys/arch/amd64/os/os_proc.c
+++ b/src/sys/arch/amd64/os/os_proc.c
@@ -30,8 +30,44 @@
#include <sys/errno.h>
#include <sys/proc.h>
#include <sys/syslog.h>
+#include <sys/cdefs.h>
#include <vm/mmu.h>
+#include <vm/map.h>
#include <machine/pcb.h>
+#include <machine/gdt.h>
+#include <machine/frame.h>
+#include <string.h>
+
+/*
+ * Put the current process into userland for its first
+ * run. The catch is that we have never been in userland
+ * from this context so we'll have to fake an IRET frame
+ * to force the processor to have a CPL of 3.
+ *
+ * @tfp: Trapframe of context to enter
+ */
+static inline void
+__proc_kick(struct trapframe *tfp)
+{
+ __ASMV(
+ "sti\n"
+ "mov %0, %%rax\n"
+ "push %1\n"
+ "push %2\n"
+ "push %3\n"
+ "push %%rax\n"
+ "push %4\n"
+ "lfence\n"
+ "swapgs\n"
+ "iretq"
+ :
+ : "r" (tfp->cs),
+ "i" (USER_DS | 3),
+ "r" (tfp->rsp),
+ "m" (tfp->rflags),
+ "r" (tfp->rip)
+ );
+}
/*
* MD proc init code
@@ -40,6 +76,9 @@ int
md_proc_init(struct proc *procp, int flags)
{
struct md_pcb *pcbp;
+ struct trapframe *tfp;
+ struct mmu_map spec;
+ uint8_t cs, ds;
int error;
if (procp == NULL) {
@@ -51,5 +90,54 @@ md_proc_init(struct proc *procp, int flags)
printf("md_proc_init: could not create new vas\n");
return error;
}
+
+ ds = USER_DS | 3;
+ cs = USER_CS | 3;
+
+ /*
+ * Set up the mapping specifier, we'll use zero
+ * to allocate new pages.
+ */
+ spec.pa = 0;
+ spec.va = STACK_TOP;
+
+ /* Put the trapframe in a known state */
+ tfp = &pcbp->tf;
+ memset(tfp, 0, sizeof(*tfp));
+ tfp->rflags = 0x202;
+ tfp->cs = cs;
+ tfp->ss = ds;
+
+ /* Map the stack */
+ vm_map(
+ &pcbp->vas, &spec,
+ STACK_LEN,
+ PROT_READ
+ | PROT_WRITE
+ | PROT_USER
+ );
+
+ tfp->rsp = STACK_TOP;
+ return 0;
+}
+
+/*
+ * Set process instruction pointer
+ */
+int
+md_set_ip(struct proc *procp, uintptr_t ip)
+{
+ struct md_pcb *pcbp;
+ struct trapframe *tfp;
+
+ if (procp == NULL) {
+ return -EINVAL;
+ }
+
+ pcbp = &procp->pcb;
+ tfp = &pcbp->tf;
+ tfp->rip = ip;
+ mmu_write_vas(&procp->pcb.vas);
+ __proc_kick(tfp);
return 0;
}
diff --git a/src/sys/include/sys/proc.h b/src/sys/include/sys/proc.h
index deed09b..d09e459 100644
--- a/src/sys/include/sys/proc.h
+++ b/src/sys/include/sys/proc.h
@@ -35,6 +35,12 @@
#include <machine/pcb.h> /* standard */
/*
+ * The stack starts here and grows down
+ */
+#define STACK_TOP 0xBFFFFFFF
+#define STACK_LEN 4096
+
+/*
* A process describes a running program image
* on the system.
*
@@ -69,4 +75,16 @@ int proc_init(struct proc *procp, int flags);
*/
int md_proc_init(struct proc *procp, int flags);
+/*
+ * Set the instruction pointer field of a specific
+ * process
+ *
+ * @procp: Process to update
+ * @ip: Instruction pointer to write
+ *
+ * Returns zero on success, otherwise a less than
+ * zero value to indicate failure.
+ */
+int md_set_ip(struct proc *procp, uintptr_t ip);
+
#endif /* !_SYS_PROC_H_ */