forked from KolibriOS/kolibrios
63 lines
1.7 KiB
PHP
63 lines
1.7 KiB
PHP
|
iglobal
|
||
|
prev_user_of_fpu dd 0x1 ; set to OS
|
||
|
endg
|
||
|
|
||
|
label fpu_tss at 0xB080
|
||
|
label fpu_stack dword at 0xB060
|
||
|
|
||
|
|
||
|
align 4
|
||
|
fpu_handler:
|
||
|
|
||
|
; clear TS flag in CR0 -> for task switching
|
||
|
clts
|
||
|
|
||
|
; save FPU context of the previous task
|
||
|
mov eax,[prev_user_of_fpu]
|
||
|
shl eax,8
|
||
|
add eax,0x80000+0x10
|
||
|
fsave [eax]
|
||
|
|
||
|
; next task switch save our FPU context
|
||
|
; now restore context of current task (if exists)
|
||
|
mov eax,[0x3000]
|
||
|
mov [prev_user_of_fpu],eax
|
||
|
shl eax,8
|
||
|
add eax,0x80000
|
||
|
cmp [eax+0x7f],byte 0
|
||
|
je bs7_first_fpu
|
||
|
frstor [eax+0x10]
|
||
|
bs7_first_fpu:
|
||
|
mov [eax+0x7f],byte 1
|
||
|
|
||
|
; prepare structure in stack for proper IRET
|
||
|
movzx eax,word [fpu_tss+l.ss-tss_sceleton] ; push ss
|
||
|
push eax
|
||
|
mov eax,[fpu_tss+l.esp-tss_sceleton] ; push esp
|
||
|
push eax
|
||
|
mov eax,[fpu_tss+l.eflags-tss_sceleton] ; push eflags
|
||
|
push eax
|
||
|
|
||
|
movzx eax,word [fpu_tss+l.cs-tss_sceleton] ; push cs
|
||
|
push eax
|
||
|
mov eax,[fpu_tss+l.eip-tss_sceleton] ; push eip
|
||
|
push eax
|
||
|
|
||
|
; save eax
|
||
|
push dword [fpu_tss+l.eax-tss_sceleton]
|
||
|
|
||
|
; restore all segment registers
|
||
|
mov ax,[fpu_tss+l.es-tss_sceleton]
|
||
|
mov es,ax
|
||
|
mov ax,[fpu_tss+l.fs-tss_sceleton]
|
||
|
mov fs,ax
|
||
|
mov ax,[fpu_tss+l.gs-tss_sceleton]
|
||
|
mov gs,ax
|
||
|
mov ax,[fpu_tss+l.ds-tss_sceleton]
|
||
|
mov ds,ax
|
||
|
|
||
|
; restore eax
|
||
|
pop eax
|
||
|
|
||
|
iret
|