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.
How to mask/unmask IRQ?
RE:How to mask/unmask IRQ?
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 ) ;
}
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 ) ;
}
RE:How to mask/unmask IRQ?
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:
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: