ISR's ;/

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
mrkaktus
Member
Member
Posts: 102
Joined: Thu Jan 06, 2005 12:00 am
Location: Poland - Gdansk
Contact:

ISR's ;/

Post by mrkaktus »

I have remap IRQ, set PIT and then load IDT (which has all selectors set to non present). At end I turn on all Master and Slave IRQ's and NMI. (Code below).
And when I'm calling STI there ocurrs 3rd general protection fault ;/.
So I don't know what Is wrong ;/. Please help.

Code: Select all

; (Inicjacja PIC)
; Przemapowanie IRQ na odpowiednie numery INT

; ICW 1
mov al,0x11 ; Komputer AT/PS-2 z kaskada ukladow
out 0x20,al ; |-Master i Slawe. IRQ inicjowane zboczem.
out 0xA0,al ;/ Bedzie wyslany bajt ICW4.

mov al,0x20 ; ICW 2
out 0x21,al ; |_Ustawiamy nowe numery INT dla IRQ.
mov al,0x28 ; | IRQ 0-7 maja numery 0x20-0x27 (32-39)
out 0xA1,al ;/ IRQ 8-15 maja numery 0x28-0x2F (40-47)

mov al,0x04 ; ICW 3
out 0x21,al ; |_Ustawiamy polaczenie Slave z Master.
mov al,0x02 ; | Master ma traktowac IRQ2 jako wywolanie Slave.
out 0xA1,al ;/ Slave ma wysylac IRQ2 do Mastera.

mov al,0x01 ; ICW 4
out 0x21,al ; |-Tryb pracy zgodny z 8086/88,
out 0xA1,al ;/ wysylamy 8bitowy numer INT.


; (Inicjacja PIT)
; Ustawienie generatora 8253/8254 na generowanie
; przerwania IRQ0 z czestotliwoscia 100Hz (99.998Hz)

mov al, 0x34 ;_Wysylamy rozkaz zaprogramowania
out 0x43, al ;/ generatora 0, na tryb 2. (00110100b)
mov al, 156 ;_Wysyla LSB (156)
out 0x40, al ;/
mov al, 46 ;_Wysyla MSB (46)
out 0x40, al ;/ [ (46*256)+156=11932 - dzielnik zegara]


; (Inicjacja IDT)
; Zaladowanie do rejestru LIDT adresu tablicy IDT
; i odblokowanie wszystkich linii IRQ oraz NMI.

lidt [IDT_Reg] ; Zaladowanie tablicy IDT

xor al, al ;Odblokowujemy wszystkie IRQ
out 0x21, al ;/dla ukladu 8259A Master
xor al, al ;Odblokowujemy wszystkie IRQ
out 0xA1, al ;/dla ukladu 8259A Slave

in al, 0x70 ;
and al, 0x7F ; |-Wlaczamy przerwanie NMI
out 0x70, al ;/

sti ; Wlaczamy obsluge przerwan

jmp $


.
.
.


IDT_Tab:

; Na poczatku IDT jest pelne pustych wpisow

%rep 0x40 ; 0x38
dw 0x0000 ; Offset 0-15
dw 0x08 ; Selektor segmentu kodu DPL 0
db 00000000b ; Wyzerowane, Reserved
db 00001110b ; NIE-OBECNY , DPL0, 32bit
dw 0x0000 ; Offset 16-31
%endrep

IDT_End:

IDT_Reg: dw IDT_End - IDT_Tab - 1
dd IDT_Tab

End of code.
[/code]
User avatar
deadmutex
Member
Member
Posts: 85
Joined: Wed Sep 28, 2005 11:00 pm

Re: ISR's ;/

Post by deadmutex »

You are trying to turn on interrupts without interrupt handlers. The PIT is probably firing, but the IDT says that there isn't a handler present. You are missing the present bit.

Code: Select all

%rep 0x40 ; 0x38
dw 0x0000 ; Offset 0-15
dw 0x08 ; Selektor segmentu kodu DPL 0
db 00000000b ; Wyzerowane, Reserved
db 00001110b ; NIE-OBECNY , DPL0, 32bit
dw 0x0000 ; Offset 16-31
%endrep
should be:

Code: Select all

%rep 0x40 ; 0x38
dw 0x0000 ; Offset 0-15
dw 0x08 ; Selektor segmentu kodu DPL 0
db 00000000b ; Wyzerowane, Reserved
db 10001110b ; NIE-OBECNY , DPL0, 32bit
dw 0x0000 ; Offset 16-31
%endrep
Make sure you have a handler for the PIT at the address that you specified in the IDT (0x08:0x00000000 in your case). If you want to put the handler somewhere else, change the selector and offset values.
mrkaktus
Member
Member
Posts: 102
Joined: Thu Jan 06, 2005 12:00 am
Location: Poland - Gdansk
Contact:

Re: ISR's ;/

Post by mrkaktus »

Do you really think I didn't do this ? ;]
I have write ISR for 0x20 INT but there was all the time 3rd general fault. So I DISABLE all entries in IDT. I have solwed this by setting one clean ISR for all INTs and now I will set them one by one to get which was called.
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: ISR's ;/

Post by JAAman »

you can't disable entries in the IDT: anytime there is a call to a "dissabled" entry, it will automatically call entry #8 (#DF), if this is also "disabled" there will be a tripple-fault, its the natural course of action -- you cannot simply ignore interupts, you can only redirect them -- and only to the double-fault handler

the only way to 'disable' external interupts is with 'cli' or masking the PIC

we already know which one got called: irq0 is called 18.2 times per second (by default) and is certain to be called instantly when you 'sti' (the CPU queues the interupts, and calls them immediately when you 'sti'

also if you touched the keyboard at any time, you will get a irq1

if these are 'disabled' in you IDT, then this will cause a #DF, and if this one is also 'disabled' that will cause a tripple-fault
mrkaktus
Member
Member
Posts: 102
Joined: Thu Jan 06, 2005 12:00 am
Location: Poland - Gdansk
Contact:

Re: ISR's ;/

Post by mrkaktus »

at beginnig I have set ISR for irq0 and the rest of IDT entries set to DISABLED. It works on 486 but didn't on P2 and P4 and this was the reason why i do what i do. Now It works when it redirect all of them to one empty ISR and now I'm redirecting them one by one to theyr's onw ISRs.

I have another question. This code works:

Code: Select all

    ; Inicjacja przerwan

    mov eax, ISR_0x20
    mov edx, eax
    shr edx, 16          ; AX, DX - adres

    mov ebx, IDT_Tab
    mov edi, ebx         ; EDI - adres IDT

    mov cx, 48
    ppet:

    mov word [es:edi], ax
    add edi, 6
    mov word [es:edi], dx
    add edi, 2

    loop ppet

.
. (here is LIDT and the rest like in first post)
.

IDT_Tab:

%rep 0x30   
     dw 0x0000     ; Offset 0-15
     dw 0x08       ; Selektor segmentu kodu DPL 0
     db 00000000b  ; Wyzerowane, Reserved
     db 10001110b  ; OBECNY , DPL0, 32bit
     dw 0x0000     ; Offset 16-31
%endrep

IDT_End:

IDT_Reg: dw IDT_End - IDT_Tab - 1        
         dd IDT_Tab                             
But when I modyfy it to this one, it generates triple fault ;/ :

Code: Select all

    ; Inicjacja przerwan

    mov eax, ISR_0x20
    mov edx, eax
    shr edx, 16          ; AX, DX - adres

    mov ebx, IDT_Tab
    mov edi, ebx         ; EDI - adres IDT

    mov bl, 10001110b 

    mov cx, 48
    ppet:

    mov word [es:edi], ax
    add edi, 5
    mov byte [es:edi], bl
    add edi, 1
    mov word [es:edi], dx
    add edi, 2

    loop ppet

.
. (here is LIDT and the rest like in first post)
.

IDT_Tab:

%rep 0x30   
     dw 0x0000       ; Offset 0-15
     dw 0x08          ; Selektor segmentu kodu DPL 0
     db 00000000b  ; Wyzerowane, Reserved
     db 0                ; OBECNY , DPL0, 32bit
     dw 0x0000       ; Offset 16-31
%endrep

IDT_End:

IDT_Reg: dw IDT_End - IDT_Tab - 1        
         dd IDT_Tab                        
I don't know why ;/.

I was tring it on all directions, but when I will make some MOV
between this two one, I always have triple fault ;/.
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: ISR's ;/

Post by JAAman »

well your structures look correct, (didn't check your PIC remap) don't know, the difference between those two code pieces shouldn't make a difference

the only thing i see is that your assigning a 32bit value to a 16bit data:

Code: Select all

IDT_Reg: dw IDT_End - IDT_Tab - 1 
but that should either work or not (depending on your assembler -- its not required to work, just a warning) and shouldn't change with that code change
mrkaktus
Member
Member
Posts: 102
Joined: Thu Jan 06, 2005 12:00 am
Location: Poland - Gdansk
Contact:

Re: ISR's ;/

Post by mrkaktus »

When you are loading data to the LIDT register you are using such structure where Size i DW and offset is DD (6 bytes all). So it is ok. I have leave that part of code by initiating it only by saving Offset in descriptors of IDT. The rest of data is initiated when IDT is created (under the " IDT_Tab: " marker).

The new problem I found is about NMI ISR.

I read that some PC have second 8254 clock generator, that is generating NMI in some distances of time to give OS a "Fail-Safe Timer" interrupt. Then OS need to determine is that NMI was called by that second 8254 (then continue execution) or by : parity chceksum of RAM, coprocessor or other cards in slots (then stop the OS execution).

So my question is, does somebody know how to detect that there is second 8254 generator, and if there is second one, how to detect if the NMI int was called from him or something other device ?
Post Reply