Ata interrupt never stops firing on real hardware

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
User avatar
LoveProgramming
Posts: 7
Joined: Sun Jun 11, 2023 11:02 am

Ata interrupt never stops firing on real hardware

Post by LoveProgramming »

On virtual machines such as Qemu the IDE controller is in compatibility mode and uses these ports: 0x1F0, 0x170, and interrupts: IRQ14/IRQ15
To get my Ata driver to work on my real machine I had to scan the PCI to find the IDE controllers and then ports via the base address registers. That worked fine and I could now read from disk on real hardware. There is only one problem, Atapi requires interrupts so I need to get those working. By reading the interrupt line field on the PCI IDE controller I determined that IRQ11 is the one I should unmask.

When I unmask IRQ11 the entire system freezes. After changing the interrupt handler to writing a "B" on screen the screen gets compleatly filled over and over. By inserting wait statements in my Ata code I found that as soon as I issue an identify command (0xEC) I get an endless stream of IRQ11. I am a beginner, and I wounder if there is something curcial missing in my code?


Code in handler:

Code: Select all

 irq_handler_11:
  pushad

  mov al, 'B'
  mov ah, 0x0C
  push ax
  call write_char
  
  push word 0
  call update_screen
  
  push word 11
  call send_end_interrupt
  
  popad
  
  iret 


Code for issuing Identify command:

Code: Select all

ata_identify_master:
    mov dx, si
    add dx, 6
    mov al, 0xA0
    out dx, al ;Select drive
    
    jmp ata_identify_continue
  
  ata_identify_slave:
    mov dx, si
    add dx, 6
    mov al, 0xB0
    out dx, al ;Select drive
  
  ata_identify_continue:
    push 10 ;Make sure controller has time to process
    call wait_milliseconds
    
    ;Wiki says these should e set to 0
    
    ;(This could be written a bit shorter)
    mov dx, si
    add dx, 2
    mov al, 0
    out dx, al ;Set to 0

    mov dx, si
    add dx, 3
    mov al, 0
    out dx, al ;Set to 0
    
    mov dx, si
    add dx, 4
    mov al, 0
    out dx, al ;Set to 0
    
    mov dx, si
    add dx, 5
    mov al, 0
    out dx, al ;Set to 0

    ;Send identify command
    mov dx, si
    add dx, 7
    mov al, 0xEC
    out dx, al
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: Ata interrupt never stops firing on real hardware

Post by Octocontrabass »

PCI interrupt lines are level-triggered and your interrupt handler is sending an EOI to the interrupt controller before acknowledging the hard disk.

There's a nice diagram on the wiki explaining the problem.

(You might recall programming the 8259 PICs to use edge-triggered interrupts, but the PICs ignore that bit for PCI interrupts.)
User avatar
LoveProgramming
Posts: 7
Joined: Sun Jun 11, 2023 11:02 am

Re: Ata interrupt never stops firing on real hardware

Post by LoveProgramming »

Can't thank you enought, works flawlessly now :D
Post Reply