summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksa Vuckovic <aleksa@vuckovic.cc>2023-02-26 11:52:55 +0100
committerAleksa Vuckovic <aleksa@vuckovic.cc>2023-02-26 11:52:55 +0100
commit950649760927a7c33ddecd1944fd0ad20e731ee9 (patch)
tree26c36460a91a128879de7ebf68fbcfcc50ef08fd
parenta362a43899040a3848427c4d1f3bd1d3e53f46ec (diff)
save/restore context from rsp
-rw-r--r--kernel/Makefile1
-rw-r--r--kernel/include/regs.h28
-rw-r--r--kernel/include/x86_64_regs.S16
-rw-r--r--kernel/src/check/panic.c50
-rw-r--r--kernel/src/scheduler/process.c0
-rw-r--r--kernel/src/scheduler/switch.S44
6 files changed, 102 insertions, 37 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index 86c4893..741e158 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -42,6 +42,7 @@ OBJS = \
src/scheduler/ap_startup.o \
src/scheduler/atomic.o \
src/scheduler/scheduler.o \
+ src/scheduler/switch.o \
src/sys/syscall_asm.o \
src/sys/syscall.o \
src/sys/userspace_asm.o \
diff --git a/kernel/include/regs.h b/kernel/include/regs.h
index 81b8a69..ec2ed89 100644
--- a/kernel/include/regs.h
+++ b/kernel/include/regs.h
@@ -1,6 +1,8 @@
#ifndef REGS_H
#define REGS_H
+#include <types.h>
+
#define R15_OFF 0x0
#define R14_OFF 0x08
#define R13_OFF 0x10
@@ -24,4 +26,30 @@
#define RSP_OFF 0x100
#define SS_OFF 0x108
+struct regs_t {
+ uint64_t r15;
+ uint64_t r14;
+ uint64_t r13;
+ uint64_t r12;
+ uint64_t rbp;
+ uint64_t rbx;
+ uint64_t seg;
+ uint64_t r11;
+ uint64_t r10;
+ uint64_t r9;
+ uint64_t r8;
+ uint64_t rdi;
+ uint64_t rsi;
+ uint64_t rdx;
+ uint64_t rcx;
+ uint64_t rax;
+ uint64_t error;
+ uint64_t rip;
+ uint64_t cs;
+ uint64_t rflags;
+ uint64_t rsp;
+ uint64_t ss;
+} __attribute__((packed));
+typedef struct regs_t regs_t;
+
#endif
diff --git a/kernel/include/x86_64_regs.S b/kernel/include/x86_64_regs.S
index 4b20539..644f4f8 100644
--- a/kernel/include/x86_64_regs.S
+++ b/kernel/include/x86_64_regs.S
@@ -8,6 +8,22 @@
* else use push/pop_callee_saved with push/pop_caller_saved
*/
+.set R15_OFF, 0x0
+.set R14_OFF, 0x08
+.set R13_OFF, 0x10
+.set R12_OFF, 0x18
+.set RBP_OFF, 0x20
+.set RBX_OFF, 0x28
+.set SEG_OFF, 0x30
+.set R11_OFF, 0x38
+.set R10_OFF, 0x40
+.set R9_OFF, 0x48
+.set R8_OFF, 0x50
+.set RDI_OFF, 0x58
+.set RSI_OFF, 0x60
+.set RDX_OFF, 0x68
+.set RCX_OFF, 0x70
+.set RAX_OFF, 0x78
.set ERROR_OFF, 0x80
.set RIP_OFF, 0x88
.set CS_OFF, 0x90
diff --git a/kernel/src/check/panic.c b/kernel/src/check/panic.c
index ac40078..b5e02a2 100644
--- a/kernel/src/check/panic.c
+++ b/kernel/src/check/panic.c
@@ -15,33 +15,33 @@ __attribute__((noreturn)) void panic(uint64_t rsp, const char *s, ...)
va_end(list);
if (rsp) {
- uint64_t seg = *(uint64_t *)(rsp + SEG_OFF);
+ regs_t *regs = (regs_t *)rsp;
printf("info regs:\n");
- printf("rax: 0x%x; ", *(uint64_t *)(rsp + RAX_OFF));
- printf("rbx: 0x%x; ", *(uint64_t *)(rsp + RBX_OFF));
- printf("rcx: 0x%x; ", *(uint64_t *)(rsp + RCX_OFF));
- printf("rdx: 0x%x; ", *(uint64_t *)(rsp + RDX_OFF));
- printf("rdi: 0x%x; ", *(uint64_t *)(rsp + RDI_OFF));
- printf("rsi: 0x%x; ", *(uint64_t *)(rsp + RSI_OFF));
- printf("rsp: 0x%x; ", *(uint64_t *)(rsp + RSP_OFF));
- printf("rbp: 0x%x; ", *(uint64_t *)(rsp + RBP_OFF));
- printf("r8: 0x%x; ", *(uint64_t *)(rsp + R8_OFF));
- printf("r9: 0x%x; ", *(uint64_t *)(rsp + R9_OFF));
- printf("r10: 0x%x; ", *(uint64_t *)(rsp + R10_OFF));
- printf("r11: 0x%x; ", *(uint64_t *)(rsp + R11_OFF));
- printf("r12: 0x%x; ", *(uint64_t *)(rsp + R12_OFF));
- printf("r13: 0x%x; ", *(uint64_t *)(rsp + R13_OFF));
- printf("r14: 0x%x; ", *(uint64_t *)(rsp + R14_OFF));
- printf("r15: 0x%x; ", *(uint64_t *)(rsp + R15_OFF));
- printf("rip: 0x%x; ", *(uint64_t *)(rsp + RIP_OFF));
- printf("cs: 0x%x; ", *(uint64_t *)(rsp + CS_OFF));
- printf("ds: 0x%x; ", seg >> 48);
- printf("ss: 0x%x; ", *(uint64_t *)(rsp + SS_OFF));
- printf("es: 0x%x; ", (seg >> 32) & 0xFFFF);
- printf("fs: 0x%x; ", (seg >> 16) & 0xFFFF);
- printf("gs: 0x%x; ", seg & 0xFFFF);
- printf("rflags: 0x%x; ", *(uint64_t *)(rsp + RFLAGS_OFF));
+ printf("rax: 0x%x; ", regs->rax);
+ printf("rbx: 0x%x; ", regs->rbx);
+ printf("rcx: 0x%x; ", regs->rcx);
+ printf("rdx: 0x%x; ", regs->rdx);
+ printf("rdi: 0x%x; ", regs->rdi);
+ printf("rsi: 0x%x; ", regs->rsi);
+ printf("rsp: 0x%x; ", regs->rsp);
+ printf("rbp: 0x%x; ", regs->rbp);
+ printf("r8: 0x%x; ", regs->r8);
+ printf("r9: 0x%x; ", regs->r9);
+ printf("r10: 0x%x; ", regs->r10);
+ printf("r11: 0x%x; ", regs->r11);
+ printf("r12: 0x%x; ", regs->r12);
+ printf("r13: 0x%x; ", regs->r13);
+ printf("r14: 0x%x; ", regs->r14);
+ printf("r15: 0x%x; ", regs->r15);
+ printf("rip: 0x%x; ", regs->rip);
+ printf("cs: 0x%x; ", regs->cs);
+ printf("ds: 0x%x; ", regs->seg >> 48);
+ printf("ss: 0x%x; ", regs->ss);
+ printf("es: 0x%x; ", (regs->seg >> 32) & 0xFFFF);
+ printf("fs: 0x%x; ", (regs->seg >> 16) & 0xFFFF);
+ printf("gs: 0x%x; ", regs->seg & 0xFFFF);
+ printf("rflags: 0x%x; ", regs->rflags);
}
disable_interrupts();
diff --git a/kernel/src/scheduler/process.c b/kernel/src/scheduler/process.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/kernel/src/scheduler/process.c
diff --git a/kernel/src/scheduler/switch.S b/kernel/src/scheduler/switch.S
index f4d0e79..4e216e0 100644
--- a/kernel/src/scheduler/switch.S
+++ b/kernel/src/scheduler/switch.S
@@ -1,18 +1,38 @@
#include "x86_64_regs.S"
-.global context_switch
-context_switch:
- /* switch rsp to old task's %rsp */
+/* %rdi - irq's rsp */
+/* %rsi - task's rsp */
+.global save_to_rsp
+save_context_to_rsp:
+ mov %rsi, %rsp
+ push SS_OFF(%rdi)
+ push RSP_OFF(%rdi)
+ push RFLAGS_OFF(%rdi)
+ push CS_OFF(%rdi)
+ push RIP_OFF(%rdi)
+ push $0
+ push RAX_OFF(%rdi)
+ push RCX_OFF(%rdi)
+ push RDX_OFF(%rdi)
+ push RSI_OFF(%rdi)
+ push RDI_OFF(%rdi)
+ push R8_OFF(%rdi)
+ push R9_OFF(%rdi)
+ push R10_OFF(%rdi)
+ push R11_OFF(%rdi)
+ push SEG_OFF(%rdi)
+ push RBX_OFF(%rdi)
+ push RBP_OFF(%rdi)
+ push R12_OFF(%rdi)
+ push R13_OFF(%rdi)
+ push R14_OFF(%rdi)
+ push R15_OFF(%rdi)
- /* save all old task's registers */
- push_caller_saved
- push_callee_saved
-
- /* save old task's rsp & rip */
- call schedule
- /* get new task's rsp & rip */
-
- /* restore all new task's registers */
+/* %rdi - task's rsp */
+.global restore_from_rsp
+restore_context_from_rsp:
+ mov %rdi, %rsp
pop_callee_saved
pop_caller_saved
+ add $8, %rsp
iretq