summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2021-07-24 21:18:33 +0200
committerdzwdz2021-07-24 21:18:33 +0200
commit687d18815da5742d201e876e71b8c0209a097a21 (patch)
treedcab88164939e2214d17a6d84eec766f685232dc
parent5ea03fb258a9952846e73f3061bb4fca36ef9fd6 (diff)
sysenter: save the registers into _sysexit_regs, makes the code cleaner (imo)
-rw-r--r--src/kernel/arch/i386/sysenter.c26
-rw-r--r--src/kernel/arch/i386/sysenter.s20
2 files changed, 21 insertions, 25 deletions
diff --git a/src/kernel/arch/i386/sysenter.c b/src/kernel/arch/i386/sysenter.c
index a7c7123..a2810b2 100644
--- a/src/kernel/arch/i386/sysenter.c
+++ b/src/kernel/arch/i386/sysenter.c
@@ -22,26 +22,16 @@ void sysexit(struct registers regs) {
_sysexit_real();
}
-void sysenter_stage2(int edi, int esi, void *ebp, void *esp,
- int ebx, int edx, int ecx, int eax)
-{
+_Noreturn void sysenter_stage2() {
uint64_t val;
- process_current->regs = (struct registers) {
- // EAX and EDX will get overriden with the return value later on
-
- .eax = eax,
- .ecx = ecx,
- .edx = edx,
- .ebx = ebx,
- .esi = esi,
- .edi = edi,
-
- .esp = (void*) ecx, // not a typo, part of my calling convention
- .eip = (void*) edx, // ^
- .ebp = ebp,
- };
+ struct registers *regs = &process_current->regs;
+
+ *regs = _sysexit_regs; // save the registers
+ regs->esp = regs->ecx; // fix them up
+ regs->eip = regs->edx;
- val = syscall_handler(eax, ebx, esi, edi);
+ val = syscall_handler(regs->eax, regs->ebx,
+ regs->esi, regs->edi);
regs_savereturn(&process_current->regs, val);
process_switch(process_current); // TODO process_resume
diff --git a/src/kernel/arch/i386/sysenter.s b/src/kernel/arch/i386/sysenter.s
index 24cbc89..db65a8c 100644
--- a/src/kernel/arch/i386/sysenter.s
+++ b/src/kernel/arch/i386/sysenter.s
@@ -24,7 +24,7 @@ _sysexit_real:
// restore the registers
mov $_sysexit_regs, %esp
- popal // probably a bad idea
+ popal
sysexit
@@ -48,11 +48,17 @@ sysenter_setup:
ret
sysenter_stage1:
- pushal // register dump
+ // disable paging
+ // I don't want to damage any of the registers passed in by the user,
+ // so i'm using ESP as a temporary register. At this point there's nothing
+ // useful in it, it's == _bss_end.
+ mov %cr0, %esp
+ and $0x7FFFFFFF, %esp // disable paging
+ mov %esp, %cr0
- mov %cr0, %eax
- and $0x7FFFFFFF, %eax // disable paging
- mov %eax, %cr0
+ // save the registers
+ mov $(_sysexit_regs + 32), %esp
+ pushal
- call sysenter_stage2
- jmp halt_cpu
+ mov $_bss_end, %esp
+ jmp sysenter_stage2