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