14,212 → 14,206 |
$Revision$ |
|
|
align 4 |
idtreg: |
dw 8*0x41-1 |
dd idts+8 |
|
align 4 ;3A08 |
build_interrupt_table: |
|
mov edi, idts+8 |
mov edi, idts |
mov esi, sys_int |
mov ecx, 0x40 |
@@: |
lodsd |
mov [edi], ax ; lower part of offset |
mov [edi+2], word os_code ; segment selector |
mov ax, word 10001110b shl 8 ; type: interrupt gate |
mov [edi+4], eax |
add edi, 8 |
mov eax, (10001110b shl 24) + os_code |
@@: movsw ;low word of code-entry |
stosd ;interrupt gate type : os_code selector |
movsw ;high word of code-entry |
loop @b |
|
;mov edi,8*0x40+idts+8 |
mov dword [edi], (i40 and 0xFFFF) or (os_code shl 16) |
mov dword [edi+4], (11101111b shl 8) or (i40 and 0xFFFF0000) |
; type: trap gate |
movsd ;copy low dword of trap gate for int 0x40 |
movsd ;copy high dword of trap gate for int 0x40 |
lidt [esi] |
ret |
|
iglobal |
|
msg_sel_ker db "kernel", 0 |
msg_sel_app db "application", 0 |
|
align 4 |
sys_int: |
dd e0,debug_exc,e2,e3 |
dd e4,e5,e6,e7 |
dd e8,e9,e10,e11 |
dd e12,e13,page_fault_handler,e15 |
;exception handlers addresses (for interrupt gate construction) |
dd e0,e1,e2,e3,e4,e5,e6,except_7 |
dd e8,e9,e10,e11,e12,e13,page_fault_exc,e15 |
dd e16, e17,e18, e19 |
times 12 dd unknown_interrupt ;int_20..int_31 |
|
dd except_16, e17,e18, except_19 |
times 12 dd unknown_interrupt |
|
;interrupt handlers addresses (for interrupt gate construction) |
dd irq0, irq_serv.irq_1, irq_serv.irq_2 |
if USE_COM_IRQ |
dd irq_serv.irq_3, irq_serv.irq_4 |
else |
dd p_irq3, p_irq4 |
dd p_irq3, p_irq4 ;??? íåñòûêîâêà |
end if |
dd irq_serv.irq_5, p_irq6, irq_serv.irq_7 |
dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10 |
dd irq_serv.irq_11, irq_serv.irq_12,irqD ,p_irq14,p_irq15 |
times 16 dd unknown_interrupt ;int_0x30..int_0x3F |
|
times 16 dd unknown_interrupt |
;int_0x40 gate trap (for directly copied) |
dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16 |
|
dd i40 |
idtreg: ; data for LIDT instruction (must be immediately below sys_int data) |
dw 2*($-sys_int-4)-1 |
dd idts ;0x8000B100 |
dw 0 ;ïðîñòî âûðàâíèâàíèå |
|
msg_fault_sel dd msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b |
dd msg_exc_c,msg_exc_d,msg_exc_e |
|
msg_exc_8 db "Double fault", 0 |
msg_exc_u db "Undefined Exception", 0 |
msg_exc_a db "Invalid TSS", 0 |
msg_exc_b db "Segment not present", 0 |
msg_exc_c db "Stack fault", 0 |
msg_exc_d db "General protection fault", 0 |
msg_exc_e db "Page fault", 0 |
|
msg_sel_ker db "kernel", 0 |
msg_sel_app db "application", 0 |
|
endg |
|
macro save_ring3_context |
{ |
macro save_ring3_context { |
pushad |
} |
macro restore_ring3_context |
{ |
macro restore_ring3_context { |
popad |
} |
|
; simply return control to interrupted process |
unknown_interrupt: |
iret |
|
macro exc_wo_code [num] |
{ |
forward |
macro exc_wo_code [num] { |
e#num : |
save_ring3_context |
mov bl, num |
jmp exc_c |
} |
} exc_wo_code 0,1,2,3,4,5,6,15,16,19 |
|
macro exc_w_code [num] |
{ |
forward |
macro exc_w_code [num] { |
e#num : |
add esp, 4 |
save_ring3_context |
mov bl, num |
jmp exc_c |
} |
} exc_w_code 8,9,10,11,12,13,17,18 |
|
exc_wo_code 0, 2, 3, 4, 5, 6, 9, 15, 18 |
exc_w_code 8, 10, 11, 12, 13, 14, 17 |
|
exc_c: |
mov ax, app_data ;èñêëþ÷åíèå |
mov ds, ax ;çàãðóçèì ïðàâèëüíûå çíà÷åíè |
mov es, ax ;â ðåãèñòðû |
uglobal |
pf_err_code dd ? |
endg |
|
page_fault_exc: |
pop [pf_err_code] ;äåéñòâèòåëüíî äî ñëåäóþùåãî #PF |
save_ring3_context |
mov bl,14 |
exc_c: ;èñêëþ÷åíèå |
; Ôðýéì ñòåêà ïðè èñêëþ÷åíèè/ïðåðûâàíèè èç 3-ãî êîëüöà + pushad (ò.å., èìåííî çäåñü) |
reg_ss equ esp+0x30 |
reg_esp3 equ esp+0x2C |
reg_eflags equ esp+0x28 |
reg_cs3 equ esp+0x24 |
reg_eip equ esp+0x20 |
; ýòî ôðýéì îò pushad |
reg_eax equ esp+0x1C |
reg_ecx equ esp+0x18 |
reg_edx equ esp+0x14 |
reg_ebx equ esp+0x10 |
reg_esp0 equ esp+0x0C |
reg_ebp equ esp+0x08 |
reg_esi equ esp+0x04 |
reg_edi equ esp+0x00 |
|
Mov ds,ax,app_data ; çàãðóçèì ïðàâèëüíûå çíà÷åíèÿ |
mov es,ax ; â ñåãìåíòíûå ðåãèñòðû |
cld ; è ïðèâîäèì DF ê ñòàíäàðòó |
; redirect to V86 manager? (EFLAGS & 0x20000) != 0? |
test byte [esp+20h+8+2], 2 |
test byte[reg_eflags+2],2 |
jnz v86_exc_c |
|
; test if debugging |
cli |
mov eax, [current_slot] |
mov eax, [eax+APPDATA.debugger_slot] |
cmp bl,14 ; #PF |
jne .l0 |
call page_fault_handler |
.l0: mov esi, [current_slot] |
mov eax,[esi+APPDATA.fpu_handler] |
cmp bl,16 ; #MF |
je .l1 |
cmp bl,19 ; #XF |
jne .l2 |
mov eax,[esi+APPDATA.sse_handler] |
.l1: test eax, eax |
jnz IRetToUserHook |
.l2: cli |
mov eax, [esi+APPDATA.debugger_slot] |
test eax, eax |
jnz .debug |
sti |
; not debuggee => say error and terminate |
movzx eax, bl |
mov [error_interrupt], eax |
call show_error_parameters |
add esp, 0x20 |
mov edx, [TASK_BASE] |
mov [edx + TASKDATA.state], byte 4 |
|
jmp change_task |
|
call show_error_parameters ;; only ONE using, inline ??? |
;mov edx, [TASK_BASE] |
mov [edx + TASKDATA.state], byte 4 ; terminate |
jmp change_task ; stack - here it does not matter at all |
.debug: |
; we are debugged process, notify debugger and suspend ourself |
; eax=debugger PID |
cld |
movzx ecx, bl |
push ecx |
mov ecx, [TASK_BASE] |
push dword [ecx+TASKDATA.pid] ; PID of current process |
push 12 |
pop ecx |
push 1 ; 1=exception |
call debugger_notify |
pop ecx |
pop ecx |
pop ecx |
mov edx, [TASK_BASE] |
mov byte [edx+TASKDATA.state], 1 ; suspended |
call change_task |
cmp bl,1 ; #DB |
je debug_ex |
movzx edx, bl ; debug_message data=Number_Of_Exception |
mov ecx,1 ; debug_message code=other_exception |
jmp debug_ex.notify ; notify debugger and suspend ourself |
|
IRetToUserHook: |
xchg eax, [reg_eip] |
sub dword[reg_esp3], 4 |
mov edi, [reg_esp3] |
stosd |
restore_ring3_context |
unknown_interrupt: |
iretd |
|
iglobal |
hexletters db '0123456789ABCDEF' |
error_interrupt dd -1 |
endg |
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
show_error_parameters: |
mov eax,[CURRENT_TASK] |
shl eax, 5 |
DEBUGF 1, "K : Process - forced terminate PID: %x\n", [CURRENT_TASK + TASKDATA.pid + eax] |
mov eax, [error_interrupt] |
cmp al, 0x08 |
jne @f |
DEBUGF 1, "K : Double fault\n" |
jmp defined_error |
@@: |
cmp al, 0x0a |
jne @f |
DEBUGF 1, "K : Invalid TSS\n" |
jmp defined_error |
@@: |
cmp al, 0x0b |
jne @f |
DEBUGF 1, "K : Segment not present\n" |
jmp defined_error |
@@: |
cmp al, 0x0c |
jne @f |
DEBUGF 1, "K : Stack fault\n" |
jmp defined_error |
@@: |
cmp al, 0x0d |
jne @f |
DEBUGF 1, "K : General protection fault\n" |
jmp defined_error |
@@: |
cmp al, 0x0e |
jne @f |
DEBUGF 1, "K : Page fault\n" |
jmp defined_error |
@@: |
DEBUGF 1, "K : Undefined Exception\n" |
defined_error: |
DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [esp + 0x20], [esp - 12 + 0x20], [esp - 4 + 0x20] |
DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [esp - 8 + 0x20], [esp - 24 + 0x20], [esp - 28 + 0x20] |
DEBUGF 1, "K : EBP : %x EIP : %x ", [esp - 20 + 0x20], [esp + 4 + 0x20] |
|
mov eax, [esp + 8 + 0x20] |
mov edx,[TASK_BASE] ;not scratched below |
DEBUGF 1, "K : Process - forced terminate PID: %x\n", [edx+TASKDATA.pid] |
cmp bl, 0x08 |
jb .l0 |
cmp bl, 0x0e |
jbe .l1 |
.l0: mov bl, 0x09 |
.l1: movzx eax,bl |
mov eax,[msg_fault_sel+eax*4 - 0x08*4] |
DEBUGF 1, "K : %s\n", eax |
mov eax, [reg_cs3+4] |
mov edi, msg_sel_app |
mov ebx, [esp + 16 + 0x20] |
mov ebx, [reg_esp3+4] |
cmp eax, app_code |
je @f |
mov edi, msg_sel_ker |
mov ebx, [esp - 16 + 0x20] |
@@: |
DEBUGF 1, "ESP : %x\nK : Flags : %x CS : %x (%s)\n", ebx, [esp + 12 + 0x20], eax, edi |
mov ebx, [reg_esp0+4] |
@@: DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4] |
DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4] |
DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx |
DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi |
ret |
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
|
restore reg_ss |
restore reg_esp3 |
restore reg_eflags |
restore reg_cs |
restore reg_eip |
restore reg_eax |
restore reg_ecx |
restore reg_edx |
restore reg_ebx |
restore reg_esp0 |
restore reg_ebp |
restore reg_esi |
restore reg_edi |
|
; irq1 -> hid/keyboard.inc |
macro irqh [num] |
{ |
forward |
macro irqh [num] { |
p_irq#num : |
mov edi, num |
jmp irqhandler |
} |
|
irqh 2,3,4,5,7,8,9,10,11 |
|
|
p_irq6: |
277,26 → 271,18 |
ret |
|
irqD: |
save_ring3_context |
mov ax, app_data ;os_data |
mov ds, ax |
mov es, ax |
|
mov dx,0xf0 |
push eax |
mov al,0 |
out dx,al |
|
mov dx,0xa0 |
out 0xf0,al |
mov al,0x20 |
out dx,al |
mov dx,0x20 |
out dx,al |
out 0xa0,al |
out 0x20,al |
pop eax |
iret |
|
restore_ring3_context |
|
iret |
irqh 2,3,4,5,7,8,9,10,11 |
|
|
irqhandler: |
|
mov esi,edi ; 1 |