Hard drive not firing IRQ in PCI compatibility mode
Posted: Wed Oct 10, 2018 8:52 am
Hello everyone,
my IDE driver works qemu, but on real hardware I don't get an interrupt. The drive is connected via SATA cable and I've set the the SATA Mode in BIOS to "IDE".
I read the PCI configuration space where I found the SATA controller in IDE mode (bus: 0, device: 0x1f, function: 0x2) with following values:
Prog IF has value 0x8F which means "PCI native mode controller, supports both channels switched to ISA compatibility mode, supports bus mastering", so
I changed its value to 0x8A (ISA Compatibility mode controller, supports both channels switched to PCI native mode, supports bus mastering) to enable ISA compatibility mode.
Now, I use these addresses for the driver:
First channel:
cmd: 0x1F0
cnl: 0x3F6
Second channel:
cmd: 0x170
cnl: 0x376
I followed the tutorial on PCI IDE [1] and ATA PIO [2] and found the drive on channel 0, drive 0 as ATA device. When trying to read I wait for BUSY bit to be cleared, set the drive/sector, wait for DRDY bit to be set, then send the command:
Now, I expect the interrupt 14 to happen, but it does not. The nIEN bit is cleared, the error register does not indicate any error, status register has value 0x58, command register also has value 0x58 (the same as in qemu).
Are there any other steps involved that I have missed?
I checked how linux handles this via lspci -v command. There, the sata controller is in PCI native mode (prog-if: 0x8f) and IRQ 19 is used so it seems IOAPIC is used? Do I also have to parse the MADT/APIC to get the mapping and use this instead of switching to PCI compatibility mode and use IRQ 14?
Thanks in advance!
[1] https://wiki.osdev.org/PCI_IDE_Controller
[2] https://wiki.osdev.org/ATA_PIO_Mode
my IDE driver works qemu, but on real hardware I don't get an interrupt. The drive is connected via SATA cable and I've set the the SATA Mode in BIOS to "IDE".
I read the PCI configuration space where I found the SATA controller in IDE mode (bus: 0, device: 0x1f, function: 0x2) with following values:
Code: Select all
Device ID 0x8c80
Vendor ID 0x8086
Status 0x2b0
Command 0x7
Class Code 0x1
Subclass 0x1
Prog IF 0x8f
Revision ID 0
Header Type 0
Bar0 0xf0b1
Bar1 0xf0a1
Bar2 0xf091
Bar3 0xf081
Bar4 0xf071
Bar5 0xf061
Interrupt pin 0x2
Interrupt Line 0xf
I changed its value to 0x8A (ISA Compatibility mode controller, supports both channels switched to PCI native mode, supports bus mastering) to enable ISA compatibility mode.
Now, I use these addresses for the driver:
First channel:
cmd: 0x1F0
cnl: 0x3F6
Second channel:
cmd: 0x170
cnl: 0x376
I followed the tutorial on PCI IDE [1] and ATA PIO [2] and found the drive on channel 0, drive 0 as ATA device. When trying to read I wait for BUSY bit to be cleared, set the drive/sector, wait for DRDY bit to be set, then send the command:
Code: Select all
outb(cmd + COMMAND_REGISTER, 0x20); // COMMAND_REGISTER = 0x7
Are there any other steps involved that I have missed?
I checked how linux handles this via lspci -v command. There, the sata controller is in PCI native mode (prog-if: 0x8f) and IRQ 19 is used so it seems IOAPIC is used? Do I also have to parse the MADT/APIC to get the mapping and use this instead of switching to PCI compatibility mode and use IRQ 14?
Thanks in advance!
[1] https://wiki.osdev.org/PCI_IDE_Controller
[2] https://wiki.osdev.org/ATA_PIO_Mode