IRQs on an dual-core AMD processor
Posted: Fri Nov 18, 2011 1:53 pm
I still have problems with missed IRQs on my Compaq Pressario CQ57 portable. First, it was only the missing AHCI PCI IRQ, but now it is also the MSI-based RTL8168 network chip driver that has the same problem. In both cases, the drivers work when I combine them with timers that does exactly the same thing as the IRQs do. I also checked the trigger-mode for PCI IRQs, and it is already set to level-triggered in the APIC module.
Here is the IRQ / MSI handlers (they are both essentially identical, "nr" stands for IRQ-number):
Here is the RTL8168 interrupt handler (the AHCI handler is similar):
Here is the IRQ / MSI handlers (they are both essentially identical, "nr" stands for IRQ-number):
Code: Select all
mem_irq&nr:
push ds
push es
push fs
pushad
;
EnterInt ; this call would lock the scheduler on the core the IRQ is executing on
push fs
sti
;
mov ax,irq_sys_sel
mov es,ax
mov bx,OFFSET irq_arr + nr * SIZE irq_struc
mov ax,word ptr es:[bx+4].user_handler
or ax,ax
jz mem_irq_default_error&nr
;
mov ds,es:[bx].user_data
xor eax,eax
mov ax,cs
push eax
mov ax,OFFSET mem_irq_handle_done&nr
push eax
push es:[bx+4].user_handler
push es:[bx].user_handler
xor ax,ax
mov es,ax
retf32 ; call the device-driver's registered IRQ handler
mem_irq_default_error&nr:
or es:bad_irqs, 1 SHL nr
mem_irq_handle_done&nr:
cli
;
mov ax,apic_mem_sel
mov ds,ax
xor eax,eax
mov ds:APIC_EOI,eax ; send EOI to APIC, memory-mapped mode
pop fs
LeaveInt ; unlock the scheduler
;
popad
pop fs
pop es
pop ds
iretd
Code: Select all
NetInt Proc far
niLoop:
mov dx,ds:IoBase
add dx,REG_ISR
in ax,dx ; read out the ISR bits
or ds:Isr,ax
out dx,ax ; clear ISR bits
test ax,IR_ROK OR IR_RDU
jz niNotRx
;
mov bx,ds:Handle
or bx,bx
jz niNotRx
;
NetReceived ; wake up the receiver
jmp niLoop
niNotRx:
test ax,IR_TOK OR IR_TER
jz niNotTx
;
mov bx,ds:TxThread
or bx,bx
jz niNotTx
;
Signal ; wake up any thread waiting for send completion
jmp niLoop
niNotTx:
retf32
NetInt Endp