diff options
| author | Aleksa Vuckovic <aleksa@vuckovic.cc> | 2023-02-26 11:52:55 +0100 |
|---|---|---|
| committer | Aleksa Vuckovic <aleksa@vuckovic.cc> | 2023-02-26 11:52:55 +0100 |
| commit | 950649760927a7c33ddecd1944fd0ad20e731ee9 (patch) | |
| tree | 26c36460a91a128879de7ebf68fbcfcc50ef08fd | |
| parent | a362a43899040a3848427c4d1f3bd1d3e53f46ec (diff) | |
save/restore context from rsp
| -rw-r--r-- | kernel/Makefile | 1 | ||||
| -rw-r--r-- | kernel/include/regs.h | 28 | ||||
| -rw-r--r-- | kernel/include/x86_64_regs.S | 16 | ||||
| -rw-r--r-- | kernel/src/check/panic.c | 50 | ||||
| -rw-r--r-- | kernel/src/scheduler/process.c | 0 | ||||
| -rw-r--r-- | kernel/src/scheduler/switch.S | 44 |
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 |
