diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-11-10 03:10:57 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-11-10 03:10:57 +0800 |
| commit | c3c996300c7c9231363ed1450ef63c9bd7a52f46 (patch) | |
| tree | 0db3f82a7fc08fd41f2e11a11f00396b13b33d5b /mubios/drivers | |
| parent | 7ecf4901b486693e525d3daafc7d6e9c3a4abcd0 (diff) | |
| download | rcc-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')
| -rw-r--r-- | mubios/drivers/ata.c | 54 | ||||
| -rw-r--r-- | mubios/drivers/ioapic.c | 22 |
2 files changed, 55 insertions, 21 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) { diff --git a/mubios/drivers/ioapic.c b/mubios/drivers/ioapic.c index 552f497..6f1de64 100644 --- a/mubios/drivers/ioapic.c +++ b/mubios/drivers/ioapic.c @@ -28,14 +28,6 @@ #define IOAPIC_REDIRECTION_BASE 0x10u #define IOAPIC_REDIRECTION_MASK 0x00010000u -#define IOAPIC_IRQ0_LOW 0x10u -#define IOAPIC_IRQ0_HIGH 0x11u -#define IOAPIC_IRQ1_LOW 0x12u -#define IOAPIC_IRQ1_HIGH 0x13u - -#define IOAPIC_IRQ0_EXTINT 0x00000700u -#define IOAPIC_IRQ1_EXTINT 0x00000700u - #define IA32_APIC_BASE_MSR 0x0000001Bu #define APIC_BASE 0xFEE00000u #define APIC_SVR_OFFSET 0x000000F0u @@ -111,19 +103,7 @@ ioapic_init (void) *(volatile u32 *)(APIC_BASE + APIC_LVT0_OFFSET) = 0x00000700u; /* - * Mask every IOAPIC input before enabling the explicitly configured lines. + * Keep every IOAPIC input masked so legacy interrupts use only LVT0. */ ioapic_mask_all (); - - /* - * Route IOAPIC pin 0 to the legacy PIC ExtINT path. - */ - ioapic_write (IOAPIC_IRQ0_HIGH, 0x00000000u); - ioapic_write (IOAPIC_IRQ0_LOW, IOAPIC_IRQ0_EXTINT); - - /* - * Route the keyboard IRQ through the legacy PIC ExtINT path. - */ - ioapic_write (IOAPIC_IRQ1_HIGH, 0x00000000u); - ioapic_write (IOAPIC_IRQ1_LOW, IOAPIC_IRQ1_EXTINT); } |
