How to mask/unmask IRQ?

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
david

How to mask/unmask IRQ?

Post by david »

Bochs tells me only my IDT[0?`4] are set correctly.

so, after mask all the IRQs by the following code:
        mov al, 0xFF ; mask all irq
out 0x21, al
out 0xA1, al
I wonna enable IRQ 0?`4, then "sti" to see what will happen.

How can I do that?

Any help is appreciated.
jcmatias

RE:How to mask/unmask IRQ?

Post by jcmatias »

Do you remap your pic ??

Try this:

#define PORT_8259M 0x20
#define PORT_8259S 0xA0

#define PORT_8259_IMR_M 0x21
#define PORT_8259_IMR_S 0xA1


void disable_irq(byte irq_num)
{
   byte irq_bit , pic_mask ;

   // read the current mask
   if ( irq_num <= 7)  
pic_mask = inportb( PORT_8259_IMR_M );
   else  
   pic_mask = inportb( PORT_8259_IMR_S)  ;

   //set the apropriate bit 1 - disable 0 enable
   irq_bit =  1 << ( irq_num % 8 )  ;

   pic_mask = irq_bit | pic_mask ;

   // write to pic controler
   if ( irq_num <= 7)  
outportb( PORT_8259_IMR_M,pic_mask);
    else
outportb(PORT_8259_IMR_S,pic_mask )   ;
}


void enable_irq(byte irq_num)
{
   byte irq_bit ,pic_mask ;

   // read the current mask
   if ( irq_num <= 7)  pic_mask = inportb( PORT_8259_IMR_M );
   else  pic_mask = inportb( PORT_8259_IMR_S)  ;

   //clear the apropriate bit
   irq_bit = ~ ( 1 << ( irq_num % 8 ) ) ;

   pic_mask = irq_bit & pic_mask ;

   // write to pic controler
   if ( irq_num <= 7)  outportb( PORT_8259_IMR_M,pic_mask);
   else outportb(PORT_8259_IMR_S,pic_mask )   ;
}
david

RE:How to mask/unmask IRQ?

Post by david »

I didn't remap my PIC.   :-(

IDT was set in my kernel.asm.
After loading IDTR, we can see that IDT[0x1a - 0x1f] are still invalid.

It seems really strange and drove me crazy.
-----------------------------------------------------------------------------------
<bochs:2> info idt
Interrupt Descriptor Table (0x0000112a):
IDT[0x00]=32-Bit Interrupt Gate target=0x0008:0x000000bc, DPL=0
... ...
IDT[0x19]=32-Bit Interrupt Gate target=0x0008:0x000000bc, DPL=0
IDT[0x1a]=32-Bit Interrupt Gate target=0x0008:0xc88c00bc, DPL=0
IDT[0x1b]=Data segment, linearaddr=f28ec08e, len=ad88e * 4Kbytes, Read-Only
IDT[0x1c]=16-Bit TSS (Busy) at ffb4eec0, length 0x03003
IDT[0x1d]=??? descriptor hi=368800fc, lo=168810cd
IDT[0x1e]=LDT
IDT[0x1f]=16-Bit Call Gate target=0x64e6:0x02a8d1b0, DPL=3
-------------------------------------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; kernel.asm do some initialization.
;
; David   [email protected]   2004.5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[bits 16]

present equ 10000000b
ring0 equ 00000000b
intgate equ 00001110b

sys_interrupt equ present+ring0+intgate

%macro empty_8042 0
%%wait:
in al, 0x64
test al, 2
jnz %%wait ;wait until input_buffer is free!
%endmacro

;system loaded at 0x1000 (4096).

mov ax,cs
mov ds,ax ;set DS, ES
mov es,ax ;CS=0x0100 IP=0x0000
mov ss,ax

;kill floppy motor
mov dx,0x03F2
xor al,al
out dx,al

;read cursor_pos and save it
mov ah,3
xor bh,bh
int 0x10
mov [cursor_pos.x],dl
mov [cursor_pos.y],dh

;enable A20
empty_8042
mov al,0xD1 ;command write
out 0x64,al
empty_8042
mov al,0xDF
out 0x60,al
empty_8042
mov al, 0xFF
out 0x64, al
empty_8042

; switch to protected mode
cli ; no interrupt allowed!

        xor eax, eax ; convert DS value to linear mode
        mov eax, ds
        shl eax, 4               ; ds * 16

        add [idtr+2], eax ; add the linear location of ds
        lidt [idtr]         ; to the IDT linear location

        add [gdtr+2], eax     ; add the linear location of ds
lgdt [gdtr]         ; to the GDT linear location

; set PE to enter protected mode
mov eax, cr0
or eax, 1
mov cr0, eax

jmp dword code_desc:go32 ; flush the queue of prefetched instructions
[bits 32]
go32:
mov ax, data_desc
mov ds, ax
mov fs, ax
        mov gs, ax
        
        mov ss, ax        
        mov esp, 0x90000

        mov ax, video_desc
        mov es, ax

sti ; sti only allowed after IDT was set

; edi += cursor_pos.x * 2 + cursor_pos.y * 160
xor ebx,ebx
mov bx, word[cursor_pos]

shl ebx, 1                  ; y*=2, x*=2
   movzx   edi, bh                 ; edi = y*2
   shl     edi, 4                  ; edi = (y*2)*16
mov     eax, edi                ; eax = (y*2)*16
     shl     edi, 2                  ; edi = (y*2)*64
     add     edi, eax                ; edi = (y*2)*80
     movzx   ebx, bl                 ; ebx = x*2
     add     edi, ebx                ; edi = (y*80+x)*2

mov ah, textattr
mov esi, msg_pm_done
next:
lodsb
or al, al
jz spin
stosw
jmp next

spin:
jmp $ ;spin

;----------- [ Interrupt Service Routine(s) ]-----------
isr_test:
pusha
push es

mov ax,video_desc
mov es,eax

mov word [es:0xF50],0x649 ; display brown "I" at the bottom of screen

mov al,0x20 ; send EOI command
out 0x20,al

pop es
popa

iret

;----------------- [ data area ] ---------------------
msg_pm_done db "Switch to protected mode successfully.",0

cursor_pos:
.x db 0
.y db 0

textattr equ 0x0A ;enhanced green

gdtr dw gdt_end-gdt-1
dd gdt
gdt:
dummy_desc dd 0 ; Dummy descriptor
dd 0

code_desc equ $-gdt
dw      0xFFFF ; Code descriptor
   dw 0x1000
   db 0x0
   db 0x9A
   db 0xCF
   db 0

data_desc equ $-gdt
dw 0xFFFF ; Data descriptor
   dw 0x1000
   db 0x0
   db 0x92
   db 0xCF
   db 0

video_desc equ $-gdt ; Access video ram
dw 3999
dw 0x8000
db 0x0B ; base = 0xB8000
db 0x92
db 0
db 0
gdt_end:

idtr dw idt_end-idt-1
dd idt
idt:
%rep 32
dw isr_test ; offset 15:0
dw code_desc ; selector, linear code selector
db 0     ; (always 0 for interrupt gates)
db sys_interrupt ; present,ring 0,'386 interrupt gate
dw 0x0000 ; offset 31:16
%endrep
idt_end:
Post Reply