gpf after receiving irq
Posted: Wed Jan 19, 2011 12:56 pm
Hi,
I've got a problem with idt in pmode: after receiving any irq, the cpu reports general protection fault.
The error code refers to the idt of received irq. List of steps I'm doing after setting gdt and entering pmode:
1. set all segment registers
2. remap irqs
3. load idt
4. enable interrupts
5. jump to the furher code (not involving OS at all)
The thing is that after first gpf, cpu seems to ignore next irqs - I obtain only a single error message.
The code is being emulated with QEMU PC emulator version 0.10.0.
Below the listing of 32 bit code (execution starts at start_system32):
do you have any suggestions what I'm doing wrong?,
thank you in advance,
pompon
I've got a problem with idt in pmode: after receiving any irq, the cpu reports general protection fault.
The error code refers to the idt of received irq. List of steps I'm doing after setting gdt and entering pmode:
1. set all segment registers
2. remap irqs
3. load idt
4. enable interrupts
5. jump to the furher code (not involving OS at all)
The thing is that after first gpf, cpu seems to ignore next irqs - I obtain only a single error message.
The code is being emulated with QEMU PC emulator version 0.10.0.
Below the listing of 32 bit code (execution starts at start_system32):
Code: Select all
[bits 32]
extern _Z3runv
global outb
global inb
global start_system32
global handle_master
outb:
.DATA equ 6
.PORT equ 4
mov dx, [esp+.PORT]
mov al, [esp+.DATA]
out dx, al
ret
inb:
.PORT equ 4
mov dx, [esp+.PORT]
in al, dx
ret
PIC_M_COMM equ 0x20
PIC_M_DATA equ 0x21
PIC_S_COMM equ 0xA0
PIC_S_DATA equ 0xA1
PIC_EOI equ 0x20
ICW1_INIT equ 0x10 ; initialization sequence
ICW1_ICW4 equ 0x1 ; ICW4 will be provided
ICW3_M_IRQ2 equ 0x4 ; slave at IRQ2
ICW3_S_ID2 equ 0x2 ; slave ID = 2
ICW4_8086 equ 0x1 ; 8086/8080 mode
%macro IN 1 ; [port]
in al, %1
%endmacro
%macro OUT 2 ; [port] [code]
mov al, %2
out %1, al
%endmacro
extern irq_handler
handle_master:
pushad
call irq_handler
OUT PIC_M_COMM, PIC_EOI
popad
iretd
handle_slave:
pushad
call irq_handler
OUT PIC_S_COMM, PIC_EOI
OUT PIC_M_COMM, PIC_EOI
popad
iretd
PIC_M_OFFSET equ 0x20
PIC_S_OFFSET equ 0x28
init_PIC:
;master
OUT PIC_M_COMM, ICW1_INIT | ICW1_ICW4
OUT PIC_M_DATA, PIC_M_OFFSET
OUT PIC_M_DATA, ICW3_M_IRQ2
OUT PIC_M_DATA, ICW4_8086
OUT PIC_M_DATA, 0
;slave
OUT PIC_S_COMM, ICW1_INIT | ICW1_ICW4
OUT PIC_S_DATA, PIC_S_OFFSET
OUT PIC_S_DATA, ICW3_S_ID2
OUT PIC_S_DATA, ICW4_8086
OUT PIC_S_DATA, 0
ret
; offset = handler
; segment = 0x8 (CODE)
;
; offset-- -------- P DPL 0 D 110 000 reserved
; ???????? ???????? 1 00 0 1 110 000 ?????
;
; segment- -------- offset-- --------
; 00000000 00001000 ???????? ????????
IDT times 256 dw 0x0, 0x0008, 0x8e00, 0x0
IDT_size equ ($-IDT)-1
IDTR dw IDT_size ; size
dd IDT ; offset
extern exception_handler
handler:
pushad
popad
iretd
%macro handler_standard 2 ; [handler name] [interrupt index]
%1:
pushad
push long %2
call exception_handler
pop eax
popad
iretd
%endmacro
%macro handler_code 2 ; [handler name] [interrupt_index]
%1:
.ERROR_CODE equ 0x20
pushad
push long [esp+.ERROR_CODE]
push long %2
call exception_handler
pop eax
pop eax
popad
add esp, 4
iretd
%endmacro
%macro fill_specific 2 ; [handler name] [interrupt index]
mov eax, %1
mov ebx, eax
shr ebx, 16
mov edx, IDT
mov [edx+8*%2], ax
mov [edx+8*%2+6], bx
%endmacro
handler_code h8, 8
handler_code h10, 10
handler_code h11, 11
handler_code h12, 12
handler_code h13, 13
handler_code h14, 14
handler_standard h0, 0
handler_standard h1, 1
handler_standard h2, 2
handler_standard h3, 3
handler_standard h4, 4
handler_standard h5, 5
handler_standard h6, 6
handler_standard h7, 7
handler_standard h9, 9
handler_standard h15, 15
handler_standard h16, 16
handler_standard h17, 17
handler_standard h18, 18
handler_standard h19, 19
set_IDTR:
mov eax, handler
mov ebx, eax
shr ebx, 16
mov edx, IDT
mov ecx, 256
.fill:
mov [edx], ax
mov [edx+6], bx
add edx, 8
loop .fill
fill_specific h0, 0
fill_specific h1, 1
fill_specific h2, 2
fill_specific h3, 3
fill_specific h4, 4
fill_specific h5, 5
fill_specific h6, 6
fill_specific h7, 7
fill_specific h8, 8
fill_specific h9, 9
fill_specific h10, 10
fill_specific h11, 11
fill_specific h12, 12
fill_specific h13, 13
fill_specific h14, 14
fill_specific h15, 15
fill_specific h16, 16
fill_specific h17, 17
fill_specific h18, 18
fill_specific h19, 19
fill_specific handle_master, PIC_M_OFFSET+0
fill_specific handle_master, PIC_M_OFFSET+1
fill_specific handle_master, PIC_M_OFFSET+2
fill_specific handle_master, PIC_M_OFFSET+3
fill_specific handle_master, PIC_M_OFFSET+4
fill_specific handle_master, PIC_M_OFFSET+5
fill_specific handle_master, PIC_M_OFFSET+6
fill_specific handle_master, PIC_M_OFFSET+7
fill_specific handle_slave, PIC_S_OFFSET+0
fill_specific handle_slave, PIC_S_OFFSET+1
fill_specific handle_slave, PIC_S_OFFSET+2
fill_specific handle_slave, PIC_S_OFFSET+3
fill_specific handle_slave, PIC_S_OFFSET+4
fill_specific handle_slave, PIC_S_OFFSET+5
fill_specific handle_slave, PIC_S_OFFSET+6
fill_specific handle_slave, PIC_S_OFFSET+7
lidt [IDTR]
ret
start_system32:
mov ax, 0x10
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
call init_PIC
call set_IDTR
sti
jmp _Z3runv
thank you in advance,
pompon