os/kernel/cpu/i386/tasking_helpers.asm

76 lines
2.4 KiB
NASM
Raw Normal View History

2019-05-21 19:16:19 -05:00
section .text
2020-07-20 09:51:30 -05:00
global switch_to_thread_asm
extern currentThread
2019-05-21 19:16:19 -05:00
extern tss
;WARNING: Caller is expected to disable IRQs before calling, and enable IRQs again after function returns
2020-07-20 09:51:30 -05:00
switch_to_thread_asm:
2019-05-21 19:16:19 -05:00
;Save previous thread's state
2019-05-21 19:16:19 -05:00
;Notes:
; For cdecl; EAX, ECX, and EDX are already saved by the caller and don't need to be saved again
; EIP is already saved on the stack by the caller's "CALL" instruction
; The thread isn't able to change CR3 so it doesn't need to be saved
2019-05-21 19:16:19 -05:00
; Segment registers are constants (while running kernel code) so they don't need to be saved
push ebx
push esi
push edi
push ebp
mov edi,[currentThread] ;edi = address of the previous thread's data structure
mov [edi],esp ;Save ESP for the thread's kernel stack in the thread's data structure
2019-05-21 19:16:19 -05:00
;Load next thread's state
2019-05-21 19:16:19 -05:00
mov esi,[esp+(4+1)*4] ;esi = address of the next thread's data structure
mov [currentThread],esi ;Set the current thread to the thread we are switching to
2019-05-21 19:16:19 -05:00
mov esp,[esi] ;Load ESP for next thread's kernel stack from the thread's data structure
mov eax,[esi+8] ;eax = address of page directory for next thread
mov ebx,[esi+4] ;ebx = address for the top of the next thread's kernel stack
2019-05-21 19:16:19 -05:00
mov [tss+4],ebx ;Adjust the ESP0 field in the TSS (used by CPU for for CPL=3 -> CPL=0 privilege level changes)
mov ecx,cr3 ;ecx = previous thread's virtual address space
2019-05-21 19:16:19 -05:00
cmp eax,ecx ;Does the virtual address space need to being changed?
je .doneVAS ; no, virtual address space is the same, so don't reload it and cause TLB flushes
mov cr3,eax ; yes, load the next thread's virtual address space
2019-05-21 19:16:19 -05:00
.doneVAS:
pop ebp
pop edi
pop esi
pop ebx
ret ;Load next thread's EIP from its kernel stack
2019-05-21 19:16:19 -05:00
global task_init
task_init:
pop ecx
pop ebx
cli
mov ax, 0x23
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, ecx
push 0x23
push eax
pushf
pop eax
or eax, 0x200
push eax
push 0x1B
push ebx
iret
2020-07-22 19:26:55 -05:00
global wait_for_unblocked_thread_asm
wait_for_unblocked_thread_asm:
sti ;As interrupts are stopped in tasking code, re-enable them
hlt ;Wait for an interrupt handler to run and return.
cli ;Clear interrupts, as tasking code must not be run with interrupts on.