Page 1 of 1

Some questions about IRQ hanling in PM.

Posted: Tue Apr 12, 2011 4:04 am
by Igor1024
Hello. I have a problem with handling IRQ's.
So, bootloader loads my code to 1000h:0, then I built GDT and IDT, switch to PM. initialize PIC and try to handle IRQ.
The problem is how to put offset into gate of interrupt in IDT , cause I align PM code on the board of 10000h. egos advised me to place interrupt handles after protected mode entry. He offered to make gates like

Code: Select all

dw handler and 0FFFFh,10h,...,handler shr 16
but it doesn't work. Also he said that there should be macros "desc" that allows to desribe any descriptors, but I couldn't find it.
That's the whole code, that is loaded to 1000:0.

Code: Select all

format binary
       xor ax,ax
       cli        ;reinitialize segment registers
       mov ss,ax
       xor sp,sp
       sti

       jmp 1000h:@f
@@:

       mov ax,1000h
       mov ds,ax ; push cs/pop ds
       mov es,ax

       cli

       mov al,8Fh;disable NMI
       out 70h,al
       in al,71h



       lgdt fword [GDTR]
       lidt fword [IDTR]

       mov eax,cr0;enable PM
       or al,1
       mov cr0,eax

       jmp fword 08h:Startup32;jump to 32-bit world


     align 8                  ;align for speed
GDT:
        dq 0
        db 0FFh,0FFh,0,0,0,9Ah,0CFh,0 ; desc 0,0FFFFFh,DF_CODE32
        db 0FFh,0FFh,0,0,0,92h,0CFh,0 ; desc 0,0FFFFFh,DF_DATA32
        label GDT_SIZE at $-GDT

GDTR:
        dw GDT_SIZE-1
        dd GDT+10000h


IDT:
         dd 0,0 ; 0
         dw int_EOI and 0FFFFh, 08h, 1000111000000000b, 0 shr 16  ; 1
         dd 0,0 ; 2
         dd 0,0 ; 3
         dd 0,0 ; 4
         dd 0,0 ; 5
         dd 0,0 ; 6
         dd 0,0 ; 7
         dd 0,0 ; 8
         dd 0,0 ; 9
         dd 0,0 ; 10
         dd 0,0 ; 11
         dd 0,0 ; 12
         dw GP_handler and 0FFFFh,08h, 1000111000000000b, 0 shr 16  ; 13  #GP
         dd 0,0 ; 14
         dd 0,0 ; 15
         dd 0,0 ; 16
         dd 0,0 ; 17
         dd 0,0 ; 18
         dd 0,0 ; 19
         dd 0,0 ; 20
         dd 0,0 ; 21
         dd 0,0 ; 22
         dd 0,0 ; 23
         dd 0,0 ; 24
         dd 0,0 ; 25
         dd 0,0 ; 26
         dd 0,0 ; 27
         dd 0,0 ; 28
         dd 0,0 ; 29
         dd 0,0 ; 30
         dd 0,0 ; 31
         dw timer and 0FFFFh, 08h, 1000111000000000b, 0 shr 16  ; IRQ 0 timer
         dw int_EOI and 0FFFFh, 08h, 1000111000000000b, 0 shr 16  


         label IDT_size at $-IDT

IDTR dw IDT_size-1
dd IDT+10000h

        virtual
        rb 10000h-$
        end virtual
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;PM32 Entry;;;;;;;;;;;;;;;;;;;
        use32
        org $+10000h

Startup32:
        mov ax,10h
        mov ds,ax
        mov es,ax
        mov fs,ax
        mov gs,ax
        mov ss,ax
        mov esp,10000h

Init_PIC:
        mov al,11h;ICW1
        out 20h,al
        out 0A0h,al

        mov al,20h;ICW2
        out 21h,al
        mov al,28h
        out 0A1h,al

        mov al,04h;ICW3
        out 21h,al
        mov al,02h
        out 0A1h,al

        mov al,11h;ICW4
        out 21h,al
        mov al,01h
        out 0A1h,al

        xor al,al ;percieve as front signals
        mov dx,04D0h
        out dx,al
        inc dx
        out dx,al

        mov al,6bh
        out 20h,al
        out 0A0h,al


        mov al,0Fh      ;enable interrupts
        out 70h,al
        in al,71h
        sti

        mov al,"!"
        mov ah,07h
        mov word [es:0B8000h],ax
        jmp $


;;;;;;;;;;;;;;;;;;;;;;;Interrupt handlers;;;;;;;;;;;;;;;;;;;;;

int_EOI:
        push ax
        mov al,20h
        out 20h,al
        out 0a0h,al
        pop ax
        iretd

timer:
        push ax
        inc byte [es:0B8000h]
        pop ax
        jmp int_EOI

GP_handler:
        pop eax
        xor eax,eax
        iretd


;;;;;;;;;;;;;;;;;;;;;;;;;Data;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ascii    db    0,0,'1234567890-+',0,0,'QWERTYUIOP[]',0,0,'ASDFGHJKL;',"'`",0,0,'ZXCVBNM,./',0,'*',0,' ',0,0,0,0,0,0,0,0,0,0,0,0,0,'789-456+1230.',0,0
index    db    0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




Re: Some questions about IRQ hanling in PM.

Posted: Tue Apr 12, 2011 12:22 pm
by bewing
Your "GP_handler" changes the value of the stack pointer before doing an iret -- this will crash the system. Your "EOI_handler" for the keyboard will only work once, because it does not get the keyboard bytes -- but it should work once.

Your IDT entries are very wrong. Please look at http://wiki.osdev.org/IDT

Instead of using "and" in your IDT code, I think you want to use &

and instead of using "shr", I think you want to use >>

Re: Some questions about IRQ hanling in PM.

Posted: Thu Apr 14, 2011 4:49 am
by Igor1024
bewing wrote:Instead of using "and" in your IDT code, I think you want to use &

and instead of using "shr", I think you want to use >>
When exception occurs stack (the same; global;) is filled by this way:
;----------
EFLAGS
CS
EIP
ERROR_CODE
;----------
I just delete ERROR_CODE and perform 'iretd'. So, what's the problem?
ERROR_CODE is deleted, CS and EIP are popped by iret.
I'm writing in FASM, so there are not some C operators.

Re: Some questions about IRQ hanling in PM.

Posted: Thu Apr 14, 2011 5:01 am
by Igor1024
bewing wrote: Your IDT entries are very wrong. Please look at http://wiki.osdev.org/IDT
I said that when I describe IDT in real mode and locate handlers in another RM segment, problem appears: how to describe offset.

Re: Some questions about IRQ hanling in PM.

Posted: Thu Apr 14, 2011 5:27 am
by rdos
A couple of issues:
1. The GPF handler cannot just reexecute faulting code, as the same fault will happen again.
2. You should not send EOI to slave controller for IRQs in the primary controller.

Re: Some questions about IRQ hanling in PM.

Posted: Thu Apr 14, 2011 5:50 am
by Igor1024
rdos wrote:A couple of issues:
1. The GPF handler cannot just reexecute faulting code, as the same fault will happen again.
So... what should I do then? #GP will occur when there won't be any interrupt descriptor... I know that #GP will appear again and again but it's better than filling all 256 descriptors.

Re: Some questions about IRQ hanling in PM.

Posted: Thu Apr 14, 2011 8:07 am
by rdos
Igor1024 wrote:
rdos wrote:A couple of issues:
1. The GPF handler cannot just reexecute faulting code, as the same fault will happen again.
So... what should I do then? #GP will occur when there won't be any interrupt descriptor... I know that #GP will appear again and again but it's better than filling all 256 descriptors.
You should write some type of crash-dump when a GPF occurs, and then halt the system.

Re: Some questions about IRQ hanling in PM.

Posted: Thu Apr 14, 2011 12:06 pm
by rdos
Besides, if your OS restarts without the GPF handler, and then stops restarting as you put in the current handler, this is because the GPF handler is invoked correctly, and locks up the processor in a GPF loop. This is also why your IRQs never happens. The processor is reexecuting faulty code all the time.

Re: Some questions about IRQ hanling in PM.

Posted: Thu Apr 14, 2011 1:02 pm
by egos
rdos wrote:A couple of issues:
1. The GPF handler cannot just reexecute faulting code, as the same fault will happen again.
2. You should not send EOI to slave controller for IRQs in the primary controller.
Good notes.

Igor1024, I wrote:

Code: Select all

GDT:
  ...
  label KCODE at $-GDT
  db 0FFh,0FFh,0,0,0,9Ah,0CFh,0 ; desc 0,0FFFFFh,DF_CODE32
  ...
IDT:
  ...
  dw handler and 0FFFFh,KCODE,...,handler shr 16 ; desc KCODE,handler,DF_INT32
  ...
In your situation the KCODE selector should have value 8, not 10h. And what's mean "0 shr 16"? Compare with original. And setup all interrupt handlers as I said early.

Re: Some questions about IRQ hanling in PM.

Posted: Thu Apr 14, 2011 2:43 pm
by Igor1024
Ups. I've perpetrate a blunder in making up interrupt gates...
There should be

Code: Select all

dw GP_handler and 0FFFFh,08h, 1000111000000000b, GP_handler shr 16
That's my mistake... I left the last field empty. The problem is solved now.