blob: c31c2fa0cd1999018ed388288feeb4dcf0e290a0 [file] [log] [blame]
Kevin O'Connor0525d292008-07-04 06:18:30 -04001// Initialize PCI devices (on emulators)
2//
3// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
4// Copyright (C) 2006 Fabrice Bellard
5//
Kevin O'Connorb1b7c2a2009-01-15 20:52:58 -05006// This file may be distributed under the terms of the GNU LGPLv3 license.
Kevin O'Connor0525d292008-07-04 06:18:30 -04007
Kevin O'Connor9a79b912014-01-15 11:08:22 -05008#include "byteorder.h" // le64_to_cpu
Kevin O'Connor2d2fa312013-09-14 21:55:26 -04009#include "config.h" // CONFIG_*
10#include "dev-q35.h" // Q35_HOST_BRIDGE_PCIEXBAR_ADDR
Paolo Bonzini40d03122014-05-15 13:22:26 +020011#include "dev-piix.h" // PIIX_*
Kevin O'Connorc167e542015-09-29 09:40:46 -040012#include "e820map.h" // e820_add
Kevin O'Connor4ade5232013-09-18 21:41:48 -040013#include "hw/ata.h" // PORT_ATA1_CMD_BASE
Kevin O'Connor5d369d82013-09-02 20:48:46 -040014#include "hw/pci.h" // pci_config_readl
15#include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL
16#include "hw/pci_regs.h" // PCI_COMMAND
Kevin O'Connora88c1972013-06-08 21:51:46 -040017#include "list.h" // struct hlist_node
Kevin O'Connor9dea5902013-09-14 20:23:54 -040018#include "malloc.h" // free
Kevin O'Connor2d2fa312013-09-14 21:55:26 -040019#include "output.h" // dprintf
20#include "paravirt.h" // RamSize
Kevin O'Connor9a79b912014-01-15 11:08:22 -050021#include "romfile.h" // romfile_loadint
Kevin O'Connorfa9c66a2013-09-14 19:10:40 -040022#include "string.h" // memset
Kevin O'Connor2d2fa312013-09-14 21:55:26 -040023#include "util.h" // pci_setup
Kevin O'Connor4ade5232013-09-18 21:41:48 -040024#include "x86.h" // outb
Isaku Yamahata72a590e2012-11-28 10:17:33 +010025
Gerd Hoffmann67a3c7c2013-11-26 13:12:04 +010026#define PCI_DEVICE_MEM_MIN (1<<12) // 4k == page size
27#define PCI_BRIDGE_MEM_MIN (1<<21) // 2M == hugepage size
28#define PCI_BRIDGE_IO_MIN 0x1000 // mandated by pci bridge spec
Isaku Yamahataaf0963d2010-06-22 17:57:53 +090029
Gerd Hoffmann82b39b22011-07-11 09:20:28 +020030static const char *region_type_name[] = {
31 [ PCI_REGION_TYPE_IO ] = "io",
32 [ PCI_REGION_TYPE_MEM ] = "mem",
33 [ PCI_REGION_TYPE_PREFMEM ] = "prefmem",
34};
35
Gerd Hoffmanne55c4e82012-06-07 10:34:32 +020036u64 pcimem_start = BUILD_PCIMEM_START;
37u64 pcimem_end = BUILD_PCIMEM_END;
38u64 pcimem64_start = BUILD_PCIMEM64_START;
39u64 pcimem64_end = BUILD_PCIMEM64_END;
Gerd Hoffmann7eac0c42014-05-13 14:09:00 +020040u64 pci_io_low_end = 0xa000;
Gerd Hoffmanne55c4e82012-06-07 10:34:32 +020041
Alexey Korolevfa51bcd2012-04-18 17:21:19 +120042struct pci_region_entry {
43 struct pci_device *dev;
44 int bar;
Alexey Korolev030288f2012-04-19 17:44:55 +120045 u64 size;
46 u64 align;
Alexey Korolevfa51bcd2012-04-18 17:21:19 +120047 int is64;
48 enum pci_region_type type;
Kevin O'Connora88c1972013-06-08 21:51:46 -040049 struct hlist_node node;
Alexey Korolevfa51bcd2012-04-18 17:21:19 +120050};
51
Alexey Korolev35a770f2012-04-19 17:47:19 +120052struct pci_region {
Alexey Korolev35a770f2012-04-19 17:47:19 +120053 /* pci region assignments */
54 u64 base;
Kevin O'Connora88c1972013-06-08 21:51:46 -040055 struct hlist_head list;
Alexey Korolev35a770f2012-04-19 17:47:19 +120056};
57
Kevin O'Connorb725dcb2011-10-15 11:53:38 -040058struct pci_bus {
Alexey Korolev35a770f2012-04-19 17:47:19 +120059 struct pci_region r[PCI_REGION_TYPE_COUNT];
Kevin O'Connor2c4c2112011-10-15 11:42:48 -040060 struct pci_device *bus_dev;
Kevin O'Connorb725dcb2011-10-15 11:53:38 -040061};
Gerd Hoffmann82b39b22011-07-11 09:20:28 +020062
Kevin O'Connorcbbdcf22011-10-01 13:13:29 -040063static u32 pci_bar(struct pci_device *pci, int region_num)
Isaku Yamahataa65821d2010-06-22 17:57:50 +090064{
65 if (region_num != PCI_ROM_SLOT) {
66 return PCI_BASE_ADDRESS_0 + region_num * 4;
67 }
Isaku Yamahata5d0de152010-06-22 17:57:51 +090068
69#define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80
Kevin O'Connorcbbdcf22011-10-01 13:13:29 -040070 u8 type = pci->header_type & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
Isaku Yamahata5d0de152010-06-22 17:57:51 +090071 return type == PCI_HEADER_TYPE_BRIDGE ? PCI_ROM_ADDRESS1 : PCI_ROM_ADDRESS;
Isaku Yamahataa65821d2010-06-22 17:57:50 +090072}
73
Kevin O'Connorcbbdcf22011-10-01 13:13:29 -040074static void
Alexey Korolev030288f2012-04-19 17:44:55 +120075pci_set_io_region_addr(struct pci_device *pci, int bar, u64 addr, int is64)
Kevin O'Connor0525d292008-07-04 06:18:30 -040076{
Alexey Korolev030288f2012-04-19 17:44:55 +120077 u32 ofs = pci_bar(pci, bar);
78 pci_config_writel(pci->bdf, ofs, addr);
79 if (is64)
80 pci_config_writel(pci->bdf, ofs + 4, addr >> 32);
Isaku Yamahatab9e47212010-06-22 17:57:47 +090081}
82
Kevin O'Connor5bab7e62011-10-01 11:33:31 -040083
84/****************************************************************
85 * Misc. device init
86 ****************************************************************/
87
88/* host irqs corresponding to PCI irqs A-D */
89const u8 pci_irqs[4] = {
90 10, 10, 11, 11
91};
92
Alex Williamsondbb7a662013-02-21 09:12:23 -070093static int dummy_pci_slot_get_irq(struct pci_device *pci, int pin)
94{
95 dprintf(1, "pci_slot_get_irq called with unknown routing\n");
96
97 return 0xff; /* PCI defined "unknown" or "no connection" for x86 */
98}
99
100static int (*pci_slot_get_irq)(struct pci_device *pci, int pin) =
101 dummy_pci_slot_get_irq;
Alex Williamsonb9490402013-02-15 14:11:41 -0700102
Kevin O'Connor0ce21382011-10-01 14:52:35 -0400103// Return the global irq number corresponding to a host bus device irq pin.
Alex Williamsonb9490402013-02-15 14:11:41 -0700104static int piix_pci_slot_get_irq(struct pci_device *pci, int pin)
Kevin O'Connor0525d292008-07-04 06:18:30 -0400105{
Gerd Hoffmann0c8f58d2012-05-04 17:33:36 +0200106 int slot_addend = 0;
107
108 while (pci->parent != NULL) {
109 slot_addend += pci_bdf_to_dev(pci->bdf);
110 pci = pci->parent;
111 }
112 slot_addend += pci_bdf_to_dev(pci->bdf) - 1;
Kevin O'Connor0ce21382011-10-01 14:52:35 -0400113 return pci_irqs[(pin - 1 + slot_addend) & 3];
Kevin O'Connor0525d292008-07-04 06:18:30 -0400114}
115
Alex Williamsonb9490402013-02-15 14:11:41 -0700116static int mch_pci_slot_get_irq(struct pci_device *pci, int pin)
117{
Kevin O'Connor9f505f72014-11-12 18:00:30 -0500118 int pin_addend = 0;
Alex Williamsonb9490402013-02-15 14:11:41 -0700119 while (pci->parent != NULL) {
120 pin_addend += pci_bdf_to_dev(pci->bdf);
121 pci = pci->parent;
122 }
Kevin O'Connor9f505f72014-11-12 18:00:30 -0500123 u8 slot = pci_bdf_to_dev(pci->bdf);
124 if (slot <= 24)
125 /* Slots 0-24 rotate slot:pin mapping similar to piix above, but
126 with a different starting index - see q35-acpi-dsdt.dsl */
127 return pci_irqs[(pin - 1 + pin_addend + slot) & 3];
Alex Williamsonb9490402013-02-15 14:11:41 -0700128 /* Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H) */
Kevin O'Connor9f505f72014-11-12 18:00:30 -0500129 return pci_irqs[(pin - 1 + pin_addend) & 3];
Alex Williamsonb9490402013-02-15 14:11:41 -0700130}
131
Kevin O'Connor6e4583c2011-06-19 10:09:26 -0400132/* PIIX3/PIIX4 PCI to ISA bridge */
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500133static void piix_isa_bridge_setup(struct pci_device *pci, void *arg)
Kevin O'Connor6e4583c2011-06-19 10:09:26 -0400134{
135 int i, irq;
136 u8 elcr[2];
137
138 elcr[0] = 0x00;
139 elcr[1] = 0x00;
140 for (i = 0; i < 4; i++) {
141 irq = pci_irqs[i];
142 /* set to trigger level */
143 elcr[irq >> 3] |= (1 << (irq & 7));
144 /* activate irq remapping in PIIX */
Kevin O'Connor278b19f2011-06-21 22:41:15 -0400145 pci_config_writeb(pci->bdf, 0x60 + i, irq);
Kevin O'Connor6e4583c2011-06-19 10:09:26 -0400146 }
Paolo Bonzini40d03122014-05-15 13:22:26 +0200147 outb(elcr[0], PIIX_PORT_ELCR1);
148 outb(elcr[1], PIIX_PORT_ELCR2);
Kevin O'Connor6e4583c2011-06-19 10:09:26 -0400149 dprintf(1, "PIIX3/PIIX4 init: elcr=%02x %02x\n", elcr[0], elcr[1]);
150}
151
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100152/* ICH9 LPC PCI to ISA bridge */
153/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */
Kevin O'Connor9a79b912014-01-15 11:08:22 -0500154static void mch_isa_bridge_setup(struct pci_device *dev, void *arg)
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100155{
156 u16 bdf = dev->bdf;
157 int i, irq;
158 u8 elcr[2];
159
160 elcr[0] = 0x00;
161 elcr[1] = 0x00;
162
163 for (i = 0; i < 4; i++) {
164 irq = pci_irqs[i];
165 /* set to trigger level */
166 elcr[irq >> 3] |= (1 << (irq & 7));
167
168 /* activate irq remapping in LPC */
169
170 /* PIRQ[A-D] routing */
Alex Williamson555a2132013-02-15 14:11:35 -0700171 pci_config_writeb(bdf, ICH9_LPC_PIRQA_ROUT + i, irq);
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100172 /* PIRQ[E-H] routing */
Alex Williamson555a2132013-02-15 14:11:35 -0700173 pci_config_writeb(bdf, ICH9_LPC_PIRQE_ROUT + i, irq);
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100174 }
175 outb(elcr[0], ICH9_LPC_PORT_ELCR1);
176 outb(elcr[1], ICH9_LPC_PORT_ELCR2);
177 dprintf(1, "Q35 LPC init: elcr=%02x %02x\n", elcr[0], elcr[1]);
178
179 /* pm io base */
180 pci_config_writel(bdf, ICH9_LPC_PMBASE,
Gerd Hoffmanna217de92014-05-13 14:01:22 +0200181 acpi_pm_base | ICH9_LPC_PMBASE_RTE);
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100182
183 /* acpi enable, SCI: IRQ9 000b = irq9*/
184 pci_config_writeb(bdf, ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_ACPI_EN);
185
Paulo Alcantara7f50afc2015-07-09 21:04:01 -0300186 /* set root complex register block BAR */
187 pci_config_writel(bdf, ICH9_LPC_RCBA,
188 ICH9_LPC_RCBA_ADDR | ICH9_LPC_RCBA_EN);
Kevin O'Connorc167e542015-09-29 09:40:46 -0400189 e820_add(ICH9_LPC_RCBA_ADDR, 16*1024, E820_RESERVED);
Paulo Alcantara7f50afc2015-07-09 21:04:01 -0300190
Gerd Hoffmanna217de92014-05-13 14:01:22 +0200191 acpi_pm1a_cnt = acpi_pm_base + 0x04;
192 pmtimer_setup(acpi_pm_base + 0x08);
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100193}
194
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500195static void storage_ide_setup(struct pci_device *pci, void *arg)
Kevin O'Connor0d6b8d52010-07-10 13:12:37 -0400196{
197 /* IDE: we map it as in ISA mode */
Alexey Korolev030288f2012-04-19 17:44:55 +1200198 pci_set_io_region_addr(pci, 0, PORT_ATA1_CMD_BASE, 0);
199 pci_set_io_region_addr(pci, 1, PORT_ATA1_CTRL_BASE, 0);
200 pci_set_io_region_addr(pci, 2, PORT_ATA2_CMD_BASE, 0);
201 pci_set_io_region_addr(pci, 3, PORT_ATA2_CTRL_BASE, 0);
Kevin O'Connor0d6b8d52010-07-10 13:12:37 -0400202}
203
Kevin O'Connor6e4583c2011-06-19 10:09:26 -0400204/* PIIX3/PIIX4 IDE */
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500205static void piix_ide_setup(struct pci_device *pci, void *arg)
Kevin O'Connor6e4583c2011-06-19 10:09:26 -0400206{
Kevin O'Connor278b19f2011-06-21 22:41:15 -0400207 u16 bdf = pci->bdf;
Kevin O'Connor6e4583c2011-06-19 10:09:26 -0400208 pci_config_writew(bdf, 0x40, 0x8000); // enable IDE0
209 pci_config_writew(bdf, 0x42, 0x8000); // enable IDE1
Kevin O'Connor6e4583c2011-06-19 10:09:26 -0400210}
211
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500212static void pic_ibm_setup(struct pci_device *pci, void *arg)
Kevin O'Connor0d6b8d52010-07-10 13:12:37 -0400213{
214 /* PIC, IBM, MPIC & MPIC2 */
Alexey Korolev030288f2012-04-19 17:44:55 +1200215 pci_set_io_region_addr(pci, 0, 0x80800000 + 0x00040000, 0);
Kevin O'Connor0d6b8d52010-07-10 13:12:37 -0400216}
217
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500218static void apple_macio_setup(struct pci_device *pci, void *arg)
Kevin O'Connor0d6b8d52010-07-10 13:12:37 -0400219{
220 /* macio bridge */
Alexey Korolev030288f2012-04-19 17:44:55 +1200221 pci_set_io_region_addr(pci, 0, 0x80800000, 0);
Kevin O'Connor0d6b8d52010-07-10 13:12:37 -0400222}
223
Marcel Apfelbaum40d020f2014-01-15 14:20:06 +0200224static void piix4_pm_config_setup(u16 bdf)
Kevin O'Connor6e4583c2011-06-19 10:09:26 -0400225{
226 // acpi sci is hardwired to 9
227 pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 9);
228
Paolo Bonzini40d03122014-05-15 13:22:26 +0200229 pci_config_writel(bdf, PIIX_PMBASE, acpi_pm_base | 1);
230 pci_config_writeb(bdf, PIIX_PMREGMISC, 0x01); /* enable PM io space */
231 pci_config_writel(bdf, PIIX_SMBHSTBASE, (acpi_pm_base + 0x100) | 1);
232 pci_config_writeb(bdf, PIIX_SMBHSTCFG, 0x09); /* enable SMBus io space */
Marcel Apfelbaum40d020f2014-01-15 14:20:06 +0200233}
234
235static int PiixPmBDF = -1;
236
237/* PIIX4 Power Management device (for ACPI) */
238static void piix4_pm_setup(struct pci_device *pci, void *arg)
239{
240 PiixPmBDF = pci->bdf;
241 piix4_pm_config_setup(pci->bdf);
Gerd Hoffmann455a7c82012-09-06 08:01:00 +0200242
Gerd Hoffmanna217de92014-05-13 14:01:22 +0200243 acpi_pm1a_cnt = acpi_pm_base + 0x04;
244 pmtimer_setup(acpi_pm_base + 0x08);
Kevin O'Connor6e4583c2011-06-19 10:09:26 -0400245}
246
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100247/* ICH9 SMBUS */
248/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_SMBUS */
Kevin O'Connor9a79b912014-01-15 11:08:22 -0500249static void ich9_smbus_setup(struct pci_device *dev, void *arg)
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100250{
251 u16 bdf = dev->bdf;
252 /* map smbus into io space */
253 pci_config_writel(bdf, ICH9_SMB_SMB_BASE,
Gerd Hoffmanna217de92014-05-13 14:01:22 +0200254 (acpi_pm_base + 0x100) | PCI_BASE_ADDRESS_SPACE_IO);
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100255
256 /* enable SMBus */
257 pci_config_writeb(bdf, ICH9_SMB_HOSTC, ICH9_SMB_HOSTC_HST_EN);
258}
259
Kevin O'Connor0d6b8d52010-07-10 13:12:37 -0400260static const struct pci_device_id pci_device_tbl[] = {
Kevin O'Connor31dcfb02012-11-20 20:29:26 -0500261 /* PIIX3/PIIX4 PCI to ISA bridge */
262 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0,
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500263 piix_isa_bridge_setup),
Kevin O'Connor31dcfb02012-11-20 20:29:26 -0500264 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500265 piix_isa_bridge_setup),
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100266 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC,
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500267 mch_isa_bridge_setup),
Kevin O'Connor31dcfb02012-11-20 20:29:26 -0500268
269 /* STORAGE IDE */
270 PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1,
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500271 PCI_CLASS_STORAGE_IDE, piix_ide_setup),
Kevin O'Connor31dcfb02012-11-20 20:29:26 -0500272 PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB,
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500273 PCI_CLASS_STORAGE_IDE, piix_ide_setup),
Kevin O'Connor31dcfb02012-11-20 20:29:26 -0500274 PCI_DEVICE_CLASS(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500275 storage_ide_setup),
Kevin O'Connor31dcfb02012-11-20 20:29:26 -0500276
277 /* PIC, IBM, MIPC & MPIC2 */
278 PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0x0046, PCI_CLASS_SYSTEM_PIC,
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500279 pic_ibm_setup),
Kevin O'Connor31dcfb02012-11-20 20:29:26 -0500280 PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0xFFFF, PCI_CLASS_SYSTEM_PIC,
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500281 pic_ibm_setup),
Kevin O'Connor31dcfb02012-11-20 20:29:26 -0500282
Kevin O'Connor0d6b8d52010-07-10 13:12:37 -0400283 /* PIIX4 Power Management device (for ACPI) */
284 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500285 piix4_pm_setup),
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100286 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_SMBUS,
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500287 ich9_smbus_setup),
Kevin O'Connor0d6b8d52010-07-10 13:12:37 -0400288
Kevin O'Connor31dcfb02012-11-20 20:29:26 -0500289 /* 0xff00 */
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500290 PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0017, 0xff00, apple_macio_setup),
291 PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0022, 0xff00, apple_macio_setup),
Kevin O'Connor31dcfb02012-11-20 20:29:26 -0500292
Kevin O'Connor0d6b8d52010-07-10 13:12:37 -0400293 PCI_DEVICE_END,
294};
295
Marcel Apfelbaum40d020f2014-01-15 14:20:06 +0200296void pci_resume(void)
297{
298 if (!CONFIG_QEMU) {
299 return;
300 }
301
302 if (PiixPmBDF >= 0) {
303 piix4_pm_config_setup(PiixPmBDF);
304 }
305}
306
Kevin O'Connor278b19f2011-06-21 22:41:15 -0400307static void pci_bios_init_device(struct pci_device *pci)
Kevin O'Connor0525d292008-07-04 06:18:30 -0400308{
Kevin O'Connor278b19f2011-06-21 22:41:15 -0400309 u16 bdf = pci->bdf;
Kevin O'Connor99e37c42011-10-01 10:47:21 -0400310 dprintf(1, "PCI: init bdf=%02x:%02x.%x id=%04x:%04x\n"
311 , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf)
Kevin O'Connor278b19f2011-06-21 22:41:15 -0400312 , pci->vendor, pci->device);
Kevin O'Connor0ce21382011-10-01 14:52:35 -0400313
Kevin O'Connor0525d292008-07-04 06:18:30 -0400314 /* map the interrupt */
Kevin O'Connor0ce21382011-10-01 14:52:35 -0400315 int pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN);
316 if (pin != 0)
Gerd Hoffmann0c8f58d2012-05-04 17:33:36 +0200317 pci_config_writeb(bdf, PCI_INTERRUPT_LINE, pci_slot_get_irq(pci, pin));
Kevin O'Connor0525d292008-07-04 06:18:30 -0400318
Kevin O'Connor278b19f2011-06-21 22:41:15 -0400319 pci_init_device(pci_device_tbl, pci, NULL);
Kevin O'Connor31dcfb02012-11-20 20:29:26 -0500320
321 /* enable memory mappings */
Isaku Yamahatad146ab82012-11-28 10:17:32 +0100322 pci_config_maskw(bdf, PCI_COMMAND, 0,
323 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SERR);
Chen Fan32ec3ee2015-01-28 16:05:13 +0800324 /* enable SERR# for forwarding */
325 if (pci->header_type & PCI_HEADER_TYPE_BRIDGE)
326 pci_config_maskw(bdf, PCI_BRIDGE_CONTROL, 0,
327 PCI_BRIDGE_CTL_SERR);
Kevin O'Connor0525d292008-07-04 06:18:30 -0400328}
329
Kevin O'Connor3f2288f2011-10-15 12:02:14 -0400330static void pci_bios_init_devices(void)
Isaku Yamahataaf0963d2010-06-22 17:57:53 +0900331{
Kevin O'Connor278b19f2011-06-21 22:41:15 -0400332 struct pci_device *pci;
333 foreachpci(pci) {
Kevin O'Connor278b19f2011-06-21 22:41:15 -0400334 pci_bios_init_device(pci);
Isaku Yamahataaf0963d2010-06-22 17:57:53 +0900335 }
336}
337
Alex Williamson7adfd712013-03-20 10:58:47 -0600338static void pci_enable_default_vga(void)
339{
340 struct pci_device *pci;
341
342 foreachpci(pci) {
343 if (is_pci_vga(pci)) {
344 dprintf(1, "PCI: Using %02x:%02x.%x for primary VGA\n",
345 pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
346 pci_bdf_to_fn(pci->bdf));
347 return;
348 }
349 }
350
351 pci = pci_find_class(PCI_CLASS_DISPLAY_VGA);
352 if (!pci) {
353 dprintf(1, "PCI: No VGA devices found\n");
354 return;
355 }
356
357 dprintf(1, "PCI: Enabling %02x:%02x.%x for primary VGA\n",
358 pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
359 pci_bdf_to_fn(pci->bdf));
360
361 pci_config_maskw(pci->bdf, PCI_COMMAND, 0,
362 PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
363
364 while (pci->parent) {
365 pci = pci->parent;
366
367 dprintf(1, "PCI: Setting VGA enable on bridge %02x:%02x.%x\n",
368 pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
369 pci_bdf_to_fn(pci->bdf));
370
371 pci_config_maskw(pci->bdf, PCI_BRIDGE_CONTROL, 0, PCI_BRIDGE_CTL_VGA);
372 pci_config_maskw(pci->bdf, PCI_COMMAND, 0,
373 PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
374 }
375}
Kevin O'Connor5bab7e62011-10-01 11:33:31 -0400376
377/****************************************************************
Kevin O'Connorb1c35f22012-11-26 11:05:32 -0500378 * Platform device initialization
379 ****************************************************************/
380
Kevin O'Connor9a79b912014-01-15 11:08:22 -0500381static void i440fx_mem_addr_setup(struct pci_device *dev, void *arg)
Kevin O'Connorb1c35f22012-11-26 11:05:32 -0500382{
383 if (RamSize <= 0x80000000)
384 pcimem_start = 0x80000000;
385 else if (RamSize <= 0xc0000000)
386 pcimem_start = 0xc0000000;
Alex Williamsonb9490402013-02-15 14:11:41 -0700387
388 pci_slot_get_irq = piix_pci_slot_get_irq;
Kevin O'Connorb1c35f22012-11-26 11:05:32 -0500389}
390
Kevin O'Connor9a79b912014-01-15 11:08:22 -0500391static void mch_mem_addr_setup(struct pci_device *dev, void *arg)
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100392{
393 u64 addr = Q35_HOST_BRIDGE_PCIEXBAR_ADDR;
394 u32 size = Q35_HOST_BRIDGE_PCIEXBAR_SIZE;
395
396 /* setup mmconfig */
397 u16 bdf = dev->bdf;
398 u32 upper = addr >> 32;
399 u32 lower = (addr & 0xffffffff) | Q35_HOST_BRIDGE_PCIEXBAREN;
400 pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, 0);
401 pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR + 4, upper);
402 pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, lower);
Kevin O'Connorc167e542015-09-29 09:40:46 -0400403 e820_add(addr, size, E820_RESERVED);
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100404
405 /* setup pci i/o window (above mmconfig) */
406 pcimem_start = addr + size;
Alex Williamsonb9490402013-02-15 14:11:41 -0700407
408 pci_slot_get_irq = mch_pci_slot_get_irq;
Gerd Hoffmann7eac0c42014-05-13 14:09:00 +0200409
410 /* setup io address space */
411 if (acpi_pm_base < 0x1000)
412 pci_io_low_end = 0x10000;
413 else
414 pci_io_low_end = acpi_pm_base;
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100415}
416
Kevin O'Connorb1c35f22012-11-26 11:05:32 -0500417static const struct pci_device_id pci_platform_tbl[] = {
418 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500419 i440fx_mem_addr_setup),
Isaku Yamahata72a590e2012-11-28 10:17:33 +0100420 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Q35_MCH,
Kevin O'Connord83c87b2013-01-21 01:14:12 -0500421 mch_mem_addr_setup),
Kevin O'Connorb1c35f22012-11-26 11:05:32 -0500422 PCI_DEVICE_END
423};
424
425static void pci_bios_init_platform(void)
426{
427 struct pci_device *pci;
428 foreachpci(pci) {
429 pci_init_device(pci_platform_tbl, pci, NULL);
430 }
431}
432
433
434/****************************************************************
Kevin O'Connor5bab7e62011-10-01 11:33:31 -0400435 * Bus initialization
436 ****************************************************************/
437
Isaku Yamahataf4416662010-06-22 17:57:52 +0900438static void
439pci_bios_init_bus_rec(int bus, u8 *pci_bus)
440{
Kevin O'Connor2b333e42011-07-02 14:49:41 -0400441 int bdf;
Isaku Yamahataf4416662010-06-22 17:57:52 +0900442 u16 class;
443
444 dprintf(1, "PCI: %s bus = 0x%x\n", __func__, bus);
445
446 /* prevent accidental access to unintended devices */
Kevin O'Connor2b333e42011-07-02 14:49:41 -0400447 foreachbdf(bdf, bus) {
Isaku Yamahataf4416662010-06-22 17:57:52 +0900448 class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
449 if (class == PCI_CLASS_BRIDGE_PCI) {
450 pci_config_writeb(bdf, PCI_SECONDARY_BUS, 255);
451 pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 0);
452 }
453 }
454
Kevin O'Connor2b333e42011-07-02 14:49:41 -0400455 foreachbdf(bdf, bus) {
Isaku Yamahataf4416662010-06-22 17:57:52 +0900456 class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
457 if (class != PCI_CLASS_BRIDGE_PCI) {
458 continue;
459 }
460 dprintf(1, "PCI: %s bdf = 0x%x\n", __func__, bdf);
461
462 u8 pribus = pci_config_readb(bdf, PCI_PRIMARY_BUS);
463 if (pribus != bus) {
464 dprintf(1, "PCI: primary bus = 0x%x -> 0x%x\n", pribus, bus);
465 pci_config_writeb(bdf, PCI_PRIMARY_BUS, bus);
466 } else {
467 dprintf(1, "PCI: primary bus = 0x%x\n", pribus);
468 }
469
470 u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS);
471 (*pci_bus)++;
472 if (*pci_bus != secbus) {
473 dprintf(1, "PCI: secondary bus = 0x%x -> 0x%x\n",
474 secbus, *pci_bus);
475 secbus = *pci_bus;
476 pci_config_writeb(bdf, PCI_SECONDARY_BUS, secbus);
477 } else {
478 dprintf(1, "PCI: secondary bus = 0x%x\n", secbus);
479 }
480
481 /* set to max for access to all subordinate buses.
482 later set it to accurate value */
483 u8 subbus = pci_config_readb(bdf, PCI_SUBORDINATE_BUS);
484 pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 255);
485
486 pci_bios_init_bus_rec(secbus, pci_bus);
487
488 if (subbus != *pci_bus) {
489 dprintf(1, "PCI: subordinate bus = 0x%x -> 0x%x\n",
490 subbus, *pci_bus);
491 subbus = *pci_bus;
492 } else {
493 dprintf(1, "PCI: subordinate bus = 0x%x\n", subbus);
494 }
495 pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, subbus);
496 }
497}
498
499static void
500pci_bios_init_bus(void)
501{
Marcel Apfelbaum5cc7eec2015-02-16 19:29:19 +0200502 u8 extraroots = romfile_loadint("etc/extra-pci-roots", 0);
Isaku Yamahataf4416662010-06-22 17:57:52 +0900503 u8 pci_bus = 0;
Marcel Apfelbaum5cc7eec2015-02-16 19:29:19 +0200504
Isaku Yamahataf4416662010-06-22 17:57:52 +0900505 pci_bios_init_bus_rec(0 /* host bus */, &pci_bus);
Marcel Apfelbaum5cc7eec2015-02-16 19:29:19 +0200506
507 if (extraroots) {
508 while (pci_bus < 0xff) {
509 pci_bus++;
510 pci_bios_init_bus_rec(pci_bus, &pci_bus);
511 }
512 }
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200513}
514
Kevin O'Connor5bab7e62011-10-01 11:33:31 -0400515
516/****************************************************************
517 * Bus sizing
518 ****************************************************************/
519
Kevin O'Connorcbbdcf22011-10-01 13:13:29 -0400520static void
Alexey Korolev030288f2012-04-19 17:44:55 +1200521pci_bios_get_bar(struct pci_device *pci, int bar,
522 int *ptype, u64 *psize, int *pis64)
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200523{
Kevin O'Connorcbbdcf22011-10-01 13:13:29 -0400524 u32 ofs = pci_bar(pci, bar);
525 u16 bdf = pci->bdf;
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200526 u32 old = pci_config_readl(bdf, ofs);
Alexey Korolev030288f2012-04-19 17:44:55 +1200527 int is64 = 0, type = PCI_REGION_TYPE_MEM;
528 u64 mask;
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200529
530 if (bar == PCI_ROM_SLOT) {
531 mask = PCI_ROM_ADDRESS_MASK;
532 pci_config_writel(bdf, ofs, mask);
533 } else {
Alexey Korolev030288f2012-04-19 17:44:55 +1200534 if (old & PCI_BASE_ADDRESS_SPACE_IO) {
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200535 mask = PCI_BASE_ADDRESS_IO_MASK;
Alexey Korolev030288f2012-04-19 17:44:55 +1200536 type = PCI_REGION_TYPE_IO;
537 } else {
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200538 mask = PCI_BASE_ADDRESS_MEM_MASK;
Alexey Korolev030288f2012-04-19 17:44:55 +1200539 if (old & PCI_BASE_ADDRESS_MEM_PREFETCH)
540 type = PCI_REGION_TYPE_PREFMEM;
541 is64 = ((old & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
542 == PCI_BASE_ADDRESS_MEM_TYPE_64);
543 }
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200544 pci_config_writel(bdf, ofs, ~0);
545 }
Alexey Korolev030288f2012-04-19 17:44:55 +1200546 u64 val = pci_config_readl(bdf, ofs);
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200547 pci_config_writel(bdf, ofs, old);
Alexey Korolev030288f2012-04-19 17:44:55 +1200548 if (is64) {
549 u32 hold = pci_config_readl(bdf, ofs + 4);
550 pci_config_writel(bdf, ofs + 4, ~0);
551 u32 high = pci_config_readl(bdf, ofs + 4);
552 pci_config_writel(bdf, ofs + 4, hold);
553 val |= ((u64)high << 32);
554 mask |= ((u64)0xffffffff << 32);
555 *psize = (~(val & mask)) + 1;
556 } else {
557 *psize = ((~(val & mask)) + 1) & 0xffffffff;
558 }
559 *ptype = type;
560 *pis64 = is64;
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200561}
562
Alexey Korolevac0cd582012-04-19 17:48:54 +1200563static int pci_bios_bridge_region_is64(struct pci_region *r,
564 struct pci_device *pci, int type)
565{
566 if (type != PCI_REGION_TYPE_PREFMEM)
567 return 0;
568 u32 pmem = pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE);
569 if (!pmem) {
570 pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0xfff0fff0);
571 pmem = pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE);
572 pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0x0);
573 }
574 if ((pmem & PCI_PREF_RANGE_TYPE_MASK) != PCI_PREF_RANGE_TYPE_64)
575 return 0;
Kevin O'Connora88c1972013-06-08 21:51:46 -0400576 struct pci_region_entry *entry;
577 hlist_for_each_entry(entry, &r->list, node) {
Alexey Korolevac0cd582012-04-19 17:48:54 +1200578 if (!entry->is64)
579 return 0;
Alexey Korolevac0cd582012-04-19 17:48:54 +1200580 }
581 return 1;
582}
583
Alexey Korolev37c111f2012-04-26 16:51:05 +1200584static u64 pci_region_align(struct pci_region *r)
585{
Kevin O'Connora88c1972013-06-08 21:51:46 -0400586 struct pci_region_entry *entry;
587 hlist_for_each_entry(entry, &r->list, node) {
588 // The first entry in the sorted list has the largest alignment
589 return entry->align;
590 }
591 return 1;
Alexey Korolev37c111f2012-04-26 16:51:05 +1200592}
593
594static u64 pci_region_sum(struct pci_region *r)
595{
Alexey Korolev37c111f2012-04-26 16:51:05 +1200596 u64 sum = 0;
Kevin O'Connora88c1972013-06-08 21:51:46 -0400597 struct pci_region_entry *entry;
598 hlist_for_each_entry(entry, &r->list, node) {
Alexey Korolev37c111f2012-04-26 16:51:05 +1200599 sum += entry->size;
Kevin O'Connore5d71ca2012-04-26 22:04:34 -0400600 }
601 return sum;
Alexey Korolev37c111f2012-04-26 16:51:05 +1200602}
603
Alexey Koroleve5e5f962012-04-26 17:01:59 +1200604static void pci_region_migrate_64bit_entries(struct pci_region *from,
605 struct pci_region *to)
606{
Kevin O'Connor030a58a2013-06-13 21:24:14 -0400607 struct hlist_node *n, **last = &to->list.first;
Kevin O'Connora88c1972013-06-08 21:51:46 -0400608 struct pci_region_entry *entry;
Kevin O'Connor030a58a2013-06-13 21:24:14 -0400609 hlist_for_each_entry_safe(entry, n, &from->list, node) {
Kevin O'Connora88c1972013-06-08 21:51:46 -0400610 if (!entry->is64)
Kevin O'Connord630d142012-04-26 22:20:56 -0400611 continue;
Gerd Hoffmanna247e672013-11-26 12:57:19 +0100612 if (entry->dev->class == PCI_CLASS_SERIAL_USB)
613 continue;
Kevin O'Connord630d142012-04-26 22:20:56 -0400614 // Move from source list to destination list.
Kevin O'Connora88c1972013-06-08 21:51:46 -0400615 hlist_del(&entry->node);
616 hlist_add(&entry->node, last);
Gerd Hoffmann95c5afc2013-11-26 11:21:23 +0100617 last = &entry->node.next;
Alexey Koroleve5e5f962012-04-26 17:01:59 +1200618 }
619}
620
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200621static struct pci_region_entry *
622pci_region_create_entry(struct pci_bus *bus, struct pci_device *dev,
Alexey Korolev030288f2012-04-19 17:44:55 +1200623 int bar, u64 size, u64 align, int type, int is64)
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200624{
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200625 struct pci_region_entry *entry = malloc_tmp(sizeof(*entry));
626 if (!entry) {
627 warn_noalloc();
628 return NULL;
629 }
630 memset(entry, 0, sizeof(*entry));
631 entry->dev = dev;
632 entry->bar = bar;
633 entry->size = size;
Kevin O'Connor3d1bc9d2012-04-01 12:30:32 -0400634 entry->align = align;
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200635 entry->is64 = is64;
636 entry->type = type;
637 // Insert into list in sorted order.
Kevin O'Connora88c1972013-06-08 21:51:46 -0400638 struct hlist_node **pprev;
639 struct pci_region_entry *pos;
Kevin O'Connor030a58a2013-06-13 21:24:14 -0400640 hlist_for_each_entry_pprev(pos, pprev, &bus->r[type].list, node) {
Kevin O'Connor3d1bc9d2012-04-01 12:30:32 -0400641 if (pos->align < align || (pos->align == align && pos->size < size))
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200642 break;
643 }
Kevin O'Connora88c1972013-06-08 21:51:46 -0400644 hlist_add(&entry->node, pprev);
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200645 return entry;
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200646}
647
Marcel Apfelbaum76327b92015-12-07 14:05:14 +0200648static int pci_bus_hotplug_support(struct pci_bus *bus, u8 pcie_cap)
Marcel Apfelbaum3aa31d72014-06-23 18:29:51 +0300649{
Marcel Apfelbaum3aa31d72014-06-23 18:29:51 +0300650 u8 shpc_cap;
651
652 if (pcie_cap) {
653 u16 pcie_flags = pci_config_readw(bus->bus_dev->bdf,
654 pcie_cap + PCI_EXP_FLAGS);
655 u8 port_type = ((pcie_flags & PCI_EXP_FLAGS_TYPE) >>
656 (__builtin_ffs(PCI_EXP_FLAGS_TYPE) - 1));
657 u8 downstream_port = (port_type == PCI_EXP_TYPE_DOWNSTREAM) ||
658 (port_type == PCI_EXP_TYPE_ROOT_PORT);
659 /*
660 * PCI Express SPEC, 7.8.2:
661 * Slot Implemented – When Set, this bit indicates that the Link
662 * HwInit associated with this Port is connected to a slot (as
663 * compared to being connected to a system-integrated device or
664 * being disabled).
665 * This bit is valid for Downstream Ports. This bit is undefined
666 * for Upstream Ports.
667 */
668 u16 slot_implemented = pcie_flags & PCI_EXP_FLAGS_SLOT;
669
670 return downstream_port && slot_implemented;
671 }
672
Gerd Hoffmanne38be2d2015-06-25 10:49:10 +0200673 shpc_cap = pci_find_capability(bus->bus_dev, PCI_CAP_ID_SHPC, 0);
Marcel Apfelbaum3aa31d72014-06-23 18:29:51 +0300674 return !!shpc_cap;
675}
676
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200677static int pci_bios_check_devices(struct pci_bus *busses)
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200678{
Kevin O'Connor2c4c2112011-10-15 11:42:48 -0400679 dprintf(1, "PCI: check devices\n");
680
681 // Calculate resources needed for regular (non-bus) devices.
682 struct pci_device *pci;
683 foreachpci(pci) {
Alexey Korolev1a9f47f2012-04-19 17:40:13 +1200684 if (pci->class == PCI_CLASS_BRIDGE_PCI)
Kevin O'Connor2c4c2112011-10-15 11:42:48 -0400685 busses[pci->secondary_bus].bus_dev = pci;
Alexey Korolev1a9f47f2012-04-19 17:40:13 +1200686
Kevin O'Connor2c4c2112011-10-15 11:42:48 -0400687 struct pci_bus *bus = &busses[pci_bdf_to_bus(pci->bdf)];
Marcel Apfelbaum0fe4c9e2015-02-16 19:29:20 +0200688 if (!bus->bus_dev)
689 /*
690 * Resources for all root busses go in busses[0]
691 */
692 bus = &busses[0];
Kevin O'Connor2c4c2112011-10-15 11:42:48 -0400693 int i;
694 for (i = 0; i < PCI_NUM_REGIONS; i++) {
Alexey Korolev1a9f47f2012-04-19 17:40:13 +1200695 if ((pci->class == PCI_CLASS_BRIDGE_PCI) &&
696 (i >= PCI_BRIDGE_NUM_REGIONS && i < PCI_ROM_SLOT))
697 continue;
Alexey Korolev030288f2012-04-19 17:44:55 +1200698 int type, is64;
699 u64 size;
700 pci_bios_get_bar(pci, i, &type, &size, &is64);
701 if (size == 0)
Kevin O'Connor2c4c2112011-10-15 11:42:48 -0400702 continue;
703
Alexey Korolev5fa24b52012-04-18 17:31:58 +1200704 if (type != PCI_REGION_TYPE_IO && size < PCI_DEVICE_MEM_MIN)
705 size = PCI_DEVICE_MEM_MIN;
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200706 struct pci_region_entry *entry = pci_region_create_entry(
Kevin O'Connor3d1bc9d2012-04-01 12:30:32 -0400707 bus, pci, i, size, size, type, is64);
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200708 if (!entry)
709 return -1;
Kevin O'Connor2c4c2112011-10-15 11:42:48 -0400710
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200711 if (is64)
Kevin O'Connor2c4c2112011-10-15 11:42:48 -0400712 i++;
713 }
714 }
715
716 // Propagate required bus resources to parent busses.
717 int secondary_bus;
718 for (secondary_bus=MaxPCIBus; secondary_bus>0; secondary_bus--) {
719 struct pci_bus *s = &busses[secondary_bus];
720 if (!s->bus_dev)
721 continue;
722 struct pci_bus *parent = &busses[pci_bdf_to_bus(s->bus_dev->bdf)];
Marcel Apfelbaum0fe4c9e2015-02-16 19:29:20 +0200723 if (!parent->bus_dev)
724 /*
725 * Resources for all root busses go in busses[0]
726 */
727 parent = &busses[0];
Kevin O'Connorcbbdcf22011-10-01 13:13:29 -0400728 int type;
Marcel Apfelbaum76327b92015-12-07 14:05:14 +0200729 u8 pcie_cap = pci_find_capability(s->bus_dev, PCI_CAP_ID_EXP, 0);
730 int hotplug_support = pci_bus_hotplug_support(s, pcie_cap);
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200731 for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
Alexey Korolev030288f2012-04-19 17:44:55 +1200732 u64 align = (type == PCI_REGION_TYPE_IO) ?
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200733 PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
Marcel Apfelbaum0784d042014-04-10 21:55:22 +0300734 if (!pci_bridge_has_region(s->bus_dev, type))
735 continue;
Alexey Korolev37c111f2012-04-26 16:51:05 +1200736 if (pci_region_align(&s->r[type]) > align)
737 align = pci_region_align(&s->r[type]);
738 u64 sum = pci_region_sum(&s->r[type]);
Marcel Apfelbaum76327b92015-12-07 14:05:14 +0200739 int resource_optional = pcie_cap && (type == PCI_REGION_TYPE_IO);
740 if (!sum && hotplug_support && !resource_optional)
Marcel Apfelbaumc6e298e2014-04-10 21:55:21 +0300741 sum = align; /* reserve min size for hot-plug */
Alexey Korolev37c111f2012-04-26 16:51:05 +1200742 u64 size = ALIGN(sum, align);
Alexey Korolevac0cd582012-04-19 17:48:54 +1200743 int is64 = pci_bios_bridge_region_is64(&s->r[type],
744 s->bus_dev, type);
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200745 // entry->bar is -1 if the entry represents a bridge region
746 struct pci_region_entry *entry = pci_region_create_entry(
Alexey Korolevac0cd582012-04-19 17:48:54 +1200747 parent, s->bus_dev, -1, size, align, type, is64);
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200748 if (!entry)
749 return -1;
Alexey Korolev030288f2012-04-19 17:44:55 +1200750 dprintf(1, "PCI: secondary bus %d size %08llx type %s\n",
Alexey Korolevf3c2b062012-04-18 17:26:43 +1200751 entry->dev->secondary_bus, size,
752 region_type_name[entry->type]);
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200753 }
Kevin O'Connor5bab7e62011-10-01 11:33:31 -0400754 }
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200755 return 0;
Kevin O'Connor5bab7e62011-10-01 11:33:31 -0400756}
757
Kevin O'Connore5d71ca2012-04-26 22:04:34 -0400758
759/****************************************************************
760 * BAR assignment
761 ****************************************************************/
762
Kevin O'Connora8dcc5b2011-10-01 12:08:57 -0400763// Setup region bases (given the regions' size and alignment)
Gerd Hoffmannfc3cd002014-01-23 15:48:19 +0100764static int pci_bios_init_root_regions_io(struct pci_bus *bus)
Kevin O'Connor5bab7e62011-10-01 11:33:31 -0400765{
Gerd Hoffmannfc3cd002014-01-23 15:48:19 +0100766 /*
767 * QEMU I/O address space usage:
768 * 0000 - 0fff legacy isa, pci config, pci root bus, ...
769 * 1000 - 9fff free
770 * a000 - afff hotplug (cpu, pci via acpi, i440fx/piix only)
771 * b000 - bfff power management (PORT_ACPI_PM_BASE)
772 * [ qemu 1.4+ implements pci config registers
773 * properly so guests can place the registers
774 * where they want, on older versions its fixed ]
775 * c000 - ffff free, traditionally used for pci io
776 */
777 struct pci_region *r_io = &bus->r[PCI_REGION_TYPE_IO];
778 u64 sum = pci_region_sum(r_io);
779 if (sum < 0x4000) {
780 /* traditional region is big enougth, use it */
781 r_io->base = 0xc000;
Gerd Hoffmann7eac0c42014-05-13 14:09:00 +0200782 } else if (sum < pci_io_low_end - 0x1000) {
Gerd Hoffmannfc3cd002014-01-23 15:48:19 +0100783 /* use the larger region at 0x1000 */
784 r_io->base = 0x1000;
785 } else {
Gerd Hoffmann7eac0c42014-05-13 14:09:00 +0200786 /* not enouth io address space -> error out */
Gerd Hoffmannfc3cd002014-01-23 15:48:19 +0100787 return -1;
788 }
789 dprintf(1, "PCI: IO: %4llx - %4llx\n", r_io->base, r_io->base + sum - 1);
790 return 0;
791}
Kevin O'Connor5bab7e62011-10-01 11:33:31 -0400792
Gerd Hoffmannfc3cd002014-01-23 15:48:19 +0100793static int pci_bios_init_root_regions_mem(struct pci_bus *bus)
794{
Alexey Korolev37c111f2012-04-26 16:51:05 +1200795 struct pci_region *r_end = &bus->r[PCI_REGION_TYPE_PREFMEM];
796 struct pci_region *r_start = &bus->r[PCI_REGION_TYPE_MEM];
797
798 if (pci_region_align(r_start) < pci_region_align(r_end)) {
Kevin O'Connor3d1bc9d2012-04-01 12:30:32 -0400799 // Swap regions to improve alignment.
Alexey Korolev37c111f2012-04-26 16:51:05 +1200800 r_end = r_start;
801 r_start = &bus->r[PCI_REGION_TYPE_PREFMEM];
Kevin O'Connor5bab7e62011-10-01 11:33:31 -0400802 }
Alexey Korolev37c111f2012-04-26 16:51:05 +1200803 u64 sum = pci_region_sum(r_end);
804 u64 align = pci_region_align(r_end);
Gerd Hoffmanne55c4e82012-06-07 10:34:32 +0200805 r_end->base = ALIGN_DOWN((pcimem_end - sum), align);
Alexey Korolev37c111f2012-04-26 16:51:05 +1200806 sum = pci_region_sum(r_start);
807 align = pci_region_align(r_start);
808 r_start->base = ALIGN_DOWN((r_end->base - sum), align);
809
Gerd Hoffmanne55c4e82012-06-07 10:34:32 +0200810 if ((r_start->base < pcimem_start) ||
811 (r_start->base > pcimem_end))
Kevin O'Connora8dcc5b2011-10-01 12:08:57 -0400812 // Memory range requested is larger than available.
Alexey Koroleve5e5f962012-04-26 17:01:59 +1200813 return -1;
814 return 0;
Kevin O'Connor5bab7e62011-10-01 11:33:31 -0400815}
816
Kevin O'Connor5bab7e62011-10-01 11:33:31 -0400817#define PCI_IO_SHIFT 8
818#define PCI_MEMORY_SHIFT 16
819#define PCI_PREF_MEMORY_SHIFT 16
820
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200821static void
Alexey Korolev35a770f2012-04-19 17:47:19 +1200822pci_region_map_one_entry(struct pci_region_entry *entry, u64 addr)
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200823{
824 u16 bdf = entry->dev->bdf;
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200825 if (entry->bar >= 0) {
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200826 dprintf(1, "PCI: map device bdf=%02x:%02x.%x"
Alexey Korolev030288f2012-04-19 17:44:55 +1200827 " bar %d, addr %08llx, size %08llx [%s]\n",
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200828 pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf),
829 entry->bar, addr, entry->size, region_type_name[entry->type]);
830
Alexey Korolev030288f2012-04-19 17:44:55 +1200831 pci_set_io_region_addr(entry->dev, entry->bar, addr, entry->is64);
Alexey Korolev3a297162012-04-18 17:22:29 +1200832 return;
833 }
834
Alexey Korolev030288f2012-04-19 17:44:55 +1200835 u64 limit = addr + entry->size - 1;
Alexey Korolev3a297162012-04-18 17:22:29 +1200836 if (entry->type == PCI_REGION_TYPE_IO) {
837 pci_config_writeb(bdf, PCI_IO_BASE, addr >> PCI_IO_SHIFT);
838 pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0);
839 pci_config_writeb(bdf, PCI_IO_LIMIT, limit >> PCI_IO_SHIFT);
840 pci_config_writew(bdf, PCI_IO_LIMIT_UPPER16, 0);
841 }
842 if (entry->type == PCI_REGION_TYPE_MEM) {
843 pci_config_writew(bdf, PCI_MEMORY_BASE, addr >> PCI_MEMORY_SHIFT);
844 pci_config_writew(bdf, PCI_MEMORY_LIMIT, limit >> PCI_MEMORY_SHIFT);
845 }
846 if (entry->type == PCI_REGION_TYPE_PREFMEM) {
847 pci_config_writew(bdf, PCI_PREF_MEMORY_BASE, addr >> PCI_PREF_MEMORY_SHIFT);
848 pci_config_writew(bdf, PCI_PREF_MEMORY_LIMIT, limit >> PCI_PREF_MEMORY_SHIFT);
Alexey Korolev030288f2012-04-19 17:44:55 +1200849 pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, addr >> 32);
850 pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, limit >> 32);
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200851 }
852}
853
Alexey Korolev35a770f2012-04-19 17:47:19 +1200854static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r)
855{
Kevin O'Connor030a58a2013-06-13 21:24:14 -0400856 struct hlist_node *n;
Kevin O'Connora88c1972013-06-08 21:51:46 -0400857 struct pci_region_entry *entry;
Kevin O'Connor030a58a2013-06-13 21:24:14 -0400858 hlist_for_each_entry_safe(entry, n, &r->list, node) {
Alexey Korolev35a770f2012-04-19 17:47:19 +1200859 u64 addr = r->base;
860 r->base += entry->size;
861 if (entry->bar == -1)
862 // Update bus base address if entry is a bridge region
863 busses[entry->dev->secondary_bus].r[entry->type].base = addr;
864 pci_region_map_one_entry(entry, addr);
Kevin O'Connora88c1972013-06-08 21:51:46 -0400865 hlist_del(&entry->node);
Alexey Korolev35a770f2012-04-19 17:47:19 +1200866 free(entry);
Alexey Korolev35a770f2012-04-19 17:47:19 +1200867 }
868}
869
Kevin O'Connorb725dcb2011-10-15 11:53:38 -0400870static void pci_bios_map_devices(struct pci_bus *busses)
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200871{
Gerd Hoffmannfc3cd002014-01-23 15:48:19 +0100872 if (pci_bios_init_root_regions_io(busses))
873 panic("PCI: out of I/O address space\n");
874
Gerd Hoffmannc72370e2013-11-26 12:51:30 +0100875 dprintf(1, "PCI: 32: %016llx - %016llx\n", pcimem_start, pcimem_end);
Gerd Hoffmannfc3cd002014-01-23 15:48:19 +0100876 if (pci_bios_init_root_regions_mem(busses)) {
Alexey Koroleve5e5f962012-04-26 17:01:59 +1200877 struct pci_region r64_mem, r64_pref;
Kevin O'Connora88c1972013-06-08 21:51:46 -0400878 r64_mem.list.first = NULL;
879 r64_pref.list.first = NULL;
Alexey Koroleve5e5f962012-04-26 17:01:59 +1200880 pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_MEM],
881 &r64_mem);
882 pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_PREFMEM],
883 &r64_pref);
884
Gerd Hoffmannfc3cd002014-01-23 15:48:19 +0100885 if (pci_bios_init_root_regions_mem(busses))
Alexey Koroleve5e5f962012-04-26 17:01:59 +1200886 panic("PCI: out of 32bit address space\n");
887
Gerd Hoffmann5283b2e2012-06-12 09:27:15 +0200888 u64 sum_mem = pci_region_sum(&r64_mem);
889 u64 sum_pref = pci_region_sum(&r64_pref);
890 u64 align_mem = pci_region_align(&r64_mem);
891 u64 align_pref = pci_region_align(&r64_pref);
892
Gerd Hoffmann0f474d02013-11-26 12:48:20 +0100893 r64_mem.base = le64_to_cpu(romfile_loadint("etc/reserved-memory-end", 0));
894 if (r64_mem.base < 0x100000000LL + RamSizeOver4G)
895 r64_mem.base = 0x100000000LL + RamSizeOver4G;
Gerd Hoffmannf21c0062013-11-26 11:08:17 +0100896 r64_mem.base = ALIGN(r64_mem.base, align_mem);
897 r64_mem.base = ALIGN(r64_mem.base, (1LL<<30)); // 1G hugepage
898 r64_pref.base = r64_mem.base + sum_mem;
899 r64_pref.base = ALIGN(r64_pref.base, align_pref);
900 r64_pref.base = ALIGN(r64_pref.base, (1LL<<30)); // 1G hugepage
Gerd Hoffmann5283b2e2012-06-12 09:27:15 +0200901 pcimem64_start = r64_mem.base;
902 pcimem64_end = r64_pref.base + sum_pref;
Gerd Hoffmannf21c0062013-11-26 11:08:17 +0100903 pcimem64_end = ALIGN(pcimem64_end, (1LL<<30)); // 1G hugepage
Gerd Hoffmannc72370e2013-11-26 12:51:30 +0100904 dprintf(1, "PCI: 64: %016llx - %016llx\n", pcimem64_start, pcimem64_end);
Gerd Hoffmann5283b2e2012-06-12 09:27:15 +0200905
Alexey Koroleve5e5f962012-04-26 17:01:59 +1200906 pci_region_map_entries(busses, &r64_mem);
907 pci_region_map_entries(busses, &r64_pref);
Gerd Hoffmann5283b2e2012-06-12 09:27:15 +0200908 } else {
909 // no bars mapped high -> drop 64bit window (see dsdt)
910 pcimem64_start = 0;
Alexey Koroleve5e5f962012-04-26 17:01:59 +1200911 }
Kevin O'Connor2c4c2112011-10-15 11:42:48 -0400912 // Map regions on each device.
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200913 int bus;
914 for (bus = 0; bus<=MaxPCIBus; bus++) {
915 int type;
Alexey Korolev35a770f2012-04-19 17:47:19 +1200916 for (type = 0; type < PCI_REGION_TYPE_COUNT; type++)
917 pci_region_map_entries(busses, &busses[bus].r[type]);
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200918 }
919}
920
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200921
Kevin O'Connor5bab7e62011-10-01 11:33:31 -0400922/****************************************************************
923 * Main setup code
924 ****************************************************************/
Isaku Yamahataf4416662010-06-22 17:57:52 +0900925
Kevin O'Connor0525d292008-07-04 06:18:30 -0400926void
Kevin O'Connor40f5b5a2009-09-13 10:46:57 -0400927pci_setup(void)
Kevin O'Connor0525d292008-07-04 06:18:30 -0400928{
Kevin O'Connora2a86e22013-02-13 19:35:12 -0500929 if (!CONFIG_QEMU)
Kevin O'Connor0525d292008-07-04 06:18:30 -0400930 return;
931
Kevin O'Connor40f5b5a2009-09-13 10:46:57 -0400932 dprintf(3, "pci setup\n");
933
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200934 dprintf(1, "=== PCI bus & bridge init ===\n");
Jan Kiszka58e6b3f2011-09-21 08:16:21 +0200935 if (pci_probe_host() != 0) {
936 return;
937 }
Isaku Yamahataf4416662010-06-22 17:57:52 +0900938 pci_bios_init_bus();
939
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200940 dprintf(1, "=== PCI device probing ===\n");
Jan Kiszka58e6b3f2011-09-21 08:16:21 +0200941 pci_probe_devices();
Kevin O'Connor37956dd2011-06-21 22:22:58 -0400942
Kevin O'Connorb1c35f22012-11-26 11:05:32 -0500943 pcimem_start = RamSize;
944 pci_bios_init_platform();
945
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200946 dprintf(1, "=== PCI new allocation pass #1 ===\n");
Kevin O'Connorb725dcb2011-10-15 11:53:38 -0400947 struct pci_bus *busses = malloc_tmp(sizeof(*busses) * (MaxPCIBus + 1));
Kevin O'Connor28a20e12011-10-15 11:07:30 -0400948 if (!busses) {
949 warn_noalloc();
950 return;
951 }
952 memset(busses, 0, sizeof(*busses) * (MaxPCIBus + 1));
Alexey Korolevfa51bcd2012-04-18 17:21:19 +1200953 if (pci_bios_check_devices(busses))
954 return;
955
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200956 dprintf(1, "=== PCI new allocation pass #2 ===\n");
Kevin O'Connorb725dcb2011-10-15 11:53:38 -0400957 pci_bios_map_devices(busses);
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200958
Kevin O'Connor3f2288f2011-10-15 12:02:14 -0400959 pci_bios_init_devices();
Gerd Hoffmann8e301472011-08-09 17:22:42 +0200960
Gerd Hoffmann82b39b22011-07-11 09:20:28 +0200961 free(busses);
Alex Williamson7adfd712013-03-20 10:58:47 -0600962
963 pci_enable_default_vga();
Kevin O'Connor0525d292008-07-04 06:18:30 -0400964}