diff options
Diffstat (limited to 'kernel/asm.s')
| -rw-r--r-- | kernel/asm.s | 120 |
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 |
