diff options
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); } |
