aboutsummaryrefslogtreecommitdiff
path: root/src/core/scheduler_asm.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/scheduler_asm.S')
-rw-r--r--src/core/scheduler_asm.S28
1 files changed, 24 insertions, 4 deletions
diff --git a/src/core/scheduler_asm.S b/src/core/scheduler_asm.S
index 1f916ec..2fdf3e5 100644
--- a/src/core/scheduler_asm.S
+++ b/src/core/scheduler_asm.S
@@ -5,6 +5,24 @@
// to this process
task_switch:
pop %esi
+
+ // Switch to the new task kernel stack
+ mov 72(%esi), %ss
+ mov 76(%esi), %esp
+
+ // If we where in kernel mode we should keep using the same
+ // stack which is stored in regs.ss and regs.esp by schedule
+ mov 24(%esi), %eax
+ cmp $0x08, %eax # Check if we were in kernel mode
+ jne skip_kernel_stack
+ mov 32(%esi), %ss
+ mov 36(%esi), %esp
+ skip_kernel_stack:
+
+ // Setup process page directory to be able to use task stack
+ mov 4(%esi), %eax
+ mov %eax, %cr3
+
push 8(%esi) # eax (cf PROC struct)
push 12(%esi) # ebx
push 16(%esi) # ecx
@@ -20,10 +38,6 @@ task_switch:
movb $0x20, %al
outb %al, $0x20
- // Setup process page directory
- mov 4(%esi), %eax
- mov %eax, %cr3
-
// Setup registers
pop %gs
pop %fs
@@ -37,8 +51,14 @@ task_switch:
pop %eax
// Perform the task switch
+ push %eax
+ mov 24(%esi), %eax
+ cmp $0x08, %eax # Check if we were in kernel mode
+ pop %eax
+ je skip_stack
push 32(%esi) # ss
push 36(%esi) # esp
+ skip_stack:
push 68(%esi) # eflags
push 24(%esi) # cs
push 28(%esi) # eip