summaryrefslogtreecommitdiff
path: root/kc/core/cpu
diff options
context:
space:
mode:
authorAda Christine <adachristine18@gmail.com>2022-01-16 03:27:38 +0000
committerAda Christine <adachristine18@gmail.com>2022-01-16 03:27:38 +0000
commit8fe5dedec3c03a59809d8970362200a1f7b033ce (patch)
tree3f31b2d70138f54ec9eb2189e63c3a5fd5127280 /kc/core/cpu
parent069a9bfecc4161a1a08b5116a5baf3189d8c0efa (diff)
hide needlessly exported symbols
Diffstat (limited to 'kc/core/cpu')
-rw-r--r--kc/core/cpu/cpu_task.S45
1 files changed, 45 insertions, 0 deletions
diff --git a/kc/core/cpu/cpu_task.S b/kc/core/cpu/cpu_task.S
new file mode 100644
index 0000000..f2fb473
--- /dev/null
+++ b/kc/core/cpu/cpu_task.S
@@ -0,0 +1,45 @@
+/* thread switching routines for x86_64
+* adapted from:
+* https://wiki.osdev.org/Brendan%27s_Multi-tasking_Tutorial
+*
+*
+*/
+
+.hidden cpu_set_thread
+.global cpu_set_thread
+.type cpu_set_thread, @function
+cpu_set_thread:
+ /* x86_64 SysV ABI
+ * must save the following registers to the stack:
+ * rbx, rsp, rbp, r12, r13, r14, r15
+ * the following are the parameters for switching tasks
+ * rdi: pointer to control block of thread being switched to
+ * rsi: pointer to control block of the current thread
+ * rdx: pointer to this cpu's task state segment esp0 field
+ */
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ push %rbp
+ /* the current task will be in rsi */
+ mov %esp, 0(%rsi) // save the stack pointer for the current task
+ mov 0(%rdi),%rsp // new stack is the next's task's stack
+ mov 8(%rdi),%rbx // top of the next task's kernel stack
+ mov %rbx,0(%rdx) // save the esp0 to the tss
+ mov 16(%rdi),%rax // page map for the next task
+ mov %cr3, %rcx // in case we need to change the page map
+ cmp %rax,%rcx
+ je .Lfinish
+ mov %rax,%cr3 // if the page maps are not the same, reload
+.Lfinish:
+ pop %rbp // get all the registers off the new task's stack
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbx
+ ret // leave into the new task
+.size cpu_set_thread, . - cpu_set_thread
+