diff options
author | Bin Meng <bmeng.cn@gmail.com> | 2015-11-06 10:04:49 (GMT) |
---|---|---|
committer | Bin Meng <bmeng.cn@gmail.com> | 2015-11-13 14:46:22 (GMT) |
commit | 487485956b1f980e8147283069a7af920f25a52c (patch) | |
tree | 46d2d14dcb4850ff6d35c1757269c09af372b579 /arch/x86/cpu/qemu/qemu.c | |
parent | 20cbafa6fab07303d525a3473a27c90c67e85ed6 (diff) | |
download | u-boot-487485956b1f980e8147283069a7af920f25a52c.tar.xz |
x86: qemu: Move chipset-specific codes from pci.c to qemu.c
Move chipset-specific codes such as PAM init, PCIe ECAM and MP table
from pci.c to qemu.c, to prepare for DM PCI conversion.
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'arch/x86/cpu/qemu/qemu.c')
-rw-r--r-- | arch/x86/cpu/qemu/qemu.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c index 7c03e02..84fb082 100644 --- a/arch/x86/cpu/qemu/qemu.c +++ b/arch/x86/cpu/qemu/qemu.c @@ -6,8 +6,58 @@ #include <common.h> #include <asm/irq.h> +#include <asm/pci.h> #include <asm/post.h> #include <asm/processor.h> +#include <asm/arch/device.h> +#include <asm/arch/qemu.h> + +static bool i440fx; + +static void qemu_chipset_init(void) +{ + u16 device, xbcs; + int pam, i; + + /* + * i440FX and Q35 chipset have different PAM register offset, but with + * the same bitfield layout. Here we determine the offset based on its + * PCI device ID. + */ + device = x86_pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID); + i440fx = (device == PCI_DEVICE_ID_INTEL_82441); + pam = i440fx ? I440FX_PAM : Q35_PAM; + + /* + * Initialize Programmable Attribute Map (PAM) Registers + * + * Configure legacy segments C/D/E/F to system RAM + */ + for (i = 0; i < PAM_NUM; i++) + x86_pci_write_config8(PCI_BDF(0, 0, 0), pam + i, PAM_RW); + + if (i440fx) { + /* + * Enable legacy IDE I/O ports decode + * + * Note: QEMU always decode legacy IDE I/O port on PIIX chipset. + * However Linux ata_piix driver does sanity check on these two + * registers to see whether legacy ports decode is turned on. + * This is to make Linux ata_piix driver happy. + */ + x86_pci_write_config16(PIIX_IDE, IDE0_TIM, IDE_DECODE_EN); + x86_pci_write_config16(PIIX_IDE, IDE1_TIM, IDE_DECODE_EN); + + /* Enable I/O APIC */ + xbcs = x86_pci_read_config16(PIIX_ISA, XBCS); + xbcs |= APIC_EN; + x86_pci_write_config16(PIIX_ISA, XBCS, xbcs); + } else { + /* Configure PCIe ECAM base address */ + x86_pci_write_config32(PCI_BDF(0, 0, 0), PCIEX_BAR, + CONFIG_PCIE_ECAM_BASE | BAR_EN); + } +} int arch_cpu_init(void) { @@ -39,7 +89,39 @@ void reset_cpu(ulong addr) x86_full_reset(); } +int arch_early_init_r(void) +{ + qemu_chipset_init(); + + return 0; +} + int arch_misc_init(void) { return pirq_init(); } + +#ifdef CONFIG_GENERATE_MP_TABLE +int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq) +{ + u8 irq; + + if (i440fx) { + /* + * Not like most x86 platforms, the PIRQ[A-D] on PIIX3 are not + * connected to I/O APIC INTPIN#16-19. Instead they are routed + * to an irq number controled by the PIRQ routing register. + */ + irq = x86_pci_read_config8(PCI_BDF(bus, dev, func), + PCI_INTERRUPT_LINE); + } else { + /* + * ICH9's PIRQ[A-H] are not consecutive numbers from 0 to 7. + * PIRQ[A-D] still maps to [0-3] but PIRQ[E-H] maps to [8-11]. + */ + irq = pirq < 8 ? pirq + 16 : pirq + 12; + } + + return irq; +} +#endif |