summaryrefslogtreecommitdiff
path: root/kernel/asm.s
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/asm.s')
-rw-r--r--kernel/asm.s120
1 files changed, 68 insertions, 52 deletions
diff --git a/kernel/asm.s b/kernel/asm.s
index 4abe607..0bf9067 100644
--- a/kernel/asm.s
+++ b/kernel/asm.s
@@ -1,60 +1,76 @@
+global clear_tss
global switch_to
+global set_tss
+extern cstate
extern ctask
-extern tss
+extern gdt
+extern save_state
+; void switch_to(int n, struct task_struct *task);
switch_to:
push ebp
mov ebp, esp
- mov eax, [ebp+8]
- mov [ctask], eax
- mov esi, [ebp+12]
- mov ecx, 13
-.loop:
- lodsd
- push eax
- dec ecx
- jz .end
- jmp .loop
-.end:
- mov ax, 0x23
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
- popa
- iret
+ ; abort if we're switching to the current task
+ mov ebx, [ctask]
+ cmp ebx, [ebp+12]
+ jne .skip
+ pop ebp
+ ret
+.skip:
+ ; clear the busy flag in the current TSS
+ mov eax, 0
+ str ax
+ add ax, gdt+5
+ mov byte [eax], 0x89
+ ; set the current TSS to null so it won't be overwritten by the switch
+ mov ax, 0
+ ltr ax
+ ; copy the saved state into the previous TSS
+ call save_state
+ ; update ctask
+ mov ebx, [ebp+12]
+ mov [ctask], ebx
+ ; calculate the task segment index and jump to it
+ mov ebx, [ebp+8]
+ add ebx, 5
+ shl ebx, 3
+ mov [.tmp+4], bx
+ jmp far [.tmp]
+.tmp:
+ dq 0
-; uint32_t ss;
-; uint32_t esp;
-; uint32_t eflags;
-; uint32_t cs;
-; uint32_t eip;
-; uint32_t eax;
-; uint32_t ecx;
-; uint32_t edx;
-; uint32_t ebx;
-; uint32_t esp_garbage;
-; uint32_t ebp;
-; uint32_t esi;
-; uint32_t edi;
+; void set_tss(unsigned int n, void *tss);
+set_tss:
+ push ebp
+ mov ebp, esp
+ push ebx
+ mov eax, [ebp+12]
+ mov ebx, [ebp+8]
+ shl ebx, 3
+ add ebx, gdt+40
+ mov [ebx+2], ax
+ shr eax, 16
+ mov [ebx+4], al
+ mov [ebx+7], ah
+ mov eax, 103 ; limit - 1
+ mov [ebx], ax
+ shr eax, 16
+ and al, 0x0F
+ mov [ebx+6], al
+ mov byte [ebx+5], 0x89
+ pop ebx
+ pop ebp
+ ret
-; switch_to:
- ; push ebp
- ; mov ebp, esp
- ; cli
- ; mov ax, 0x23
- ; mov ds, ax
- ; mov es, ax
- ; mov fs, ax
- ; mov gs, ax
- ; mov eax, esp
- ; ; save ESP in the TSS
- ; mov [tss+4], eax
- ; push dword 0x23
- ; push dword 0x00180000
- ; pushf
- ; push dword 0x1B
- ; push dword 0x00100000
- ; iret
- ; pop ebp
- ; ret
+; void clear_tss(unsigned int n);
+clear_tss:
+ push ebp
+ mov ebp, esp
+ push ebx
+ mov ebx, [ebp+8]
+ shl ebx, 3
+ add ebx, gdt+40
+ mov byte [ebx+5], 0
+ pop ebx
+ pop ebp
+ ret