aboutsummaryrefslogtreecommitdiff
path: root/mubios/drivers/ata.c
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-11-10 03:10:57 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-11-10 03:10:57 +0800
commitc3c996300c7c9231363ed1450ef63c9bd7a52f46 (patch)
tree0db3f82a7fc08fd41f2e11a11f00396b13b33d5b /mubios/drivers/ata.c
parent7ecf4901b486693e525d3daafc7d6e9c3a4abcd0 (diff)
downloadrcc-project-c3c996300c7c9231363ed1450ef63c9bd7a52f46.tar.gz
rcc-project-c3c996300c7c9231363ed1450ef63c9bd7a52f46.tar.xz
[mubios] Fix legacy interrupt routing and enable PIIX IDE channels
Keep IOAPIC inputs masked and deliver legacy PIC interrupts through LVT0 only, avoiding extra ExtINT routes that leave PIC and APIC interrupts in service. Enumerate the root PCI bus for the PIIX3 IDE controller during POST. Enable I/O decoding and both IDE channels while preserving their timing configuration so Linux ata_piix probes the disks. Signed-off-by: Richard Qin <richard.qin.x@gmail.com>
Diffstat (limited to 'mubios/drivers/ata.c')
-rw-r--r--mubios/drivers/ata.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/mubios/drivers/ata.c b/mubios/drivers/ata.c
index 7d23a9c..c31c06e 100644
--- a/mubios/drivers/ata.c
+++ b/mubios/drivers/ata.c
@@ -22,6 +22,16 @@
#include "bios.h"
#include "io.h"
+#define PCI_CONFIG_ADDRESS 0x0CF8u
+#define PCI_CONFIG_DATA 0x0CFCu
+#define PCI_VENDOR_DEVICE 0x00u
+#define PCI_COMMAND 0x04u
+#define PCI_COMMAND_IO 0x0001u
+#define PIIX3_IDE_ID 0x70108086u
+#define PIIX_IDETIM_PRIMARY 0x40u
+#define PIIX_IDETIM_SECONDARY 0x42u
+#define PIIX_IDETIM_ENABLE 0x8000u
+
#define ATA_DATA 0x1F0u
#define ATA_SECTOR_COUNT 0x1F2u
#define ATA_LBA_LOW 0x1F3u
@@ -40,6 +50,50 @@
#define ATA_CMD_IDENTIFY 0xECu
#define ATA_CONTROL_SRST 0x04u
+static u32
+ata_pci_read (u16 devfn, u8 offset)
+{
+ io_out32 (PCI_CONFIG_ADDRESS,
+ 0x80000000u | ((u32)devfn << 8) | (offset & 0xFCu));
+ return io_in32 (PCI_CONFIG_DATA);
+}
+
+static void
+ata_pci_write16 (u16 devfn, u8 offset, u16 value)
+{
+ io_out32 (PCI_CONFIG_ADDRESS,
+ 0x80000000u | ((u32)devfn << 8) | (offset & 0xFCu));
+ io_out16 ((u16)(PCI_CONFIG_DATA + (offset & 2u)), value);
+}
+
+void
+ata_init (void)
+{
+ u16 devfn;
+ u16 command;
+ u32 timing;
+
+ /* Enumerate the root PCI bus used by QEMU's pc machine. */
+ for (devfn = 0; devfn < 256u; ++devfn)
+ {
+ /* IDETIM is specific to the PIIX3 IDE controller. */
+ if (ata_pci_read (devfn, PCI_VENDOR_DEVICE) != PIIX3_IDE_ID)
+ continue;
+
+ command = (u16)ata_pci_read (devfn, PCI_COMMAND);
+ /* Use a word write to leave the write-one-to-clear status untouched. */
+ ata_pci_write16 (devfn, PCI_COMMAND, (u16)(command | PCI_COMMAND_IO));
+
+ /* Linux's ata_piix requires IDETIM bit 15 to probe each channel. */
+ timing = ata_pci_read (devfn, PIIX_IDETIM_PRIMARY);
+ ata_pci_write16 (devfn, PIIX_IDETIM_PRIMARY,
+ (u16)((u16)timing | PIIX_IDETIM_ENABLE));
+ ata_pci_write16 (devfn, PIIX_IDETIM_SECONDARY,
+ (u16)((timing >> 16) | PIIX_IDETIM_ENABLE));
+ return;
+ }
+}
+
static u8
ata_wait_not_busy (void)
{