~ubuntu-branches/ubuntu/trusty/seabios/trusty-proposed

« back to all changes in this revision

Viewing changes to .pc/1.7.2.2.diff/src/pciinit.c

  • Committer: Package Import Robot
  • Author(s): Michael Tokarev
  • Date: 2013-07-08 21:34:44 UTC
  • mfrom: (1.1.7)
  • Revision ID: package-import@ubuntu.com-20130708213444-6ed9q23j39x143lu
Tags: 1.7.3-1
Multi-Arch: allowed

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Initialize PCI devices (on emulators)
2
 
//
3
 
// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
4
 
// Copyright (C) 2006 Fabrice Bellard
5
 
//
6
 
// This file may be distributed under the terms of the GNU LGPLv3 license.
7
 
 
8
 
#include "util.h" // dprintf
9
 
#include "pci.h" // pci_config_readl
10
 
#include "pci_ids.h" // PCI_VENDOR_ID_INTEL
11
 
#include "pci_regs.h" // PCI_COMMAND
12
 
#include "ioport.h" // PORT_ATA1_CMD_BASE
13
 
#include "config.h" // CONFIG_*
14
 
#include "xen.h" // usingXen
15
 
#include "memmap.h" // add_e820
16
 
#include "dev-q35.h"
17
 
 
18
 
/* PM Timer ticks per second (HZ) */
19
 
#define PM_TIMER_FREQUENCY  3579545
20
 
 
21
 
#define PCI_DEVICE_MEM_MIN     0x1000
22
 
#define PCI_BRIDGE_IO_MIN      0x1000
23
 
#define PCI_BRIDGE_MEM_MIN   0x100000
24
 
 
25
 
enum pci_region_type {
26
 
    PCI_REGION_TYPE_IO,
27
 
    PCI_REGION_TYPE_MEM,
28
 
    PCI_REGION_TYPE_PREFMEM,
29
 
    PCI_REGION_TYPE_COUNT,
30
 
};
31
 
 
32
 
static const char *region_type_name[] = {
33
 
    [ PCI_REGION_TYPE_IO ]      = "io",
34
 
    [ PCI_REGION_TYPE_MEM ]     = "mem",
35
 
    [ PCI_REGION_TYPE_PREFMEM ] = "prefmem",
36
 
};
37
 
 
38
 
u64 pcimem_start   = BUILD_PCIMEM_START;
39
 
u64 pcimem_end     = BUILD_PCIMEM_END;
40
 
u64 pcimem64_start = BUILD_PCIMEM64_START;
41
 
u64 pcimem64_end   = BUILD_PCIMEM64_END;
42
 
 
43
 
struct pci_region_entry {
44
 
    struct pci_device *dev;
45
 
    int bar;
46
 
    u64 size;
47
 
    u64 align;
48
 
    int is64;
49
 
    enum pci_region_type type;
50
 
    struct pci_region_entry *next;
51
 
};
52
 
 
53
 
struct pci_region {
54
 
    /* pci region assignments */
55
 
    u64 base;
56
 
    struct pci_region_entry *list;
57
 
};
58
 
 
59
 
struct pci_bus {
60
 
    struct pci_region r[PCI_REGION_TYPE_COUNT];
61
 
    struct pci_device *bus_dev;
62
 
};
63
 
 
64
 
static u32 pci_bar(struct pci_device *pci, int region_num)
65
 
{
66
 
    if (region_num != PCI_ROM_SLOT) {
67
 
        return PCI_BASE_ADDRESS_0 + region_num * 4;
68
 
    }
69
 
 
70
 
#define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80
71
 
    u8 type = pci->header_type & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
72
 
    return type == PCI_HEADER_TYPE_BRIDGE ? PCI_ROM_ADDRESS1 : PCI_ROM_ADDRESS;
73
 
}
74
 
 
75
 
static void
76
 
pci_set_io_region_addr(struct pci_device *pci, int bar, u64 addr, int is64)
77
 
{
78
 
    u32 ofs = pci_bar(pci, bar);
79
 
    pci_config_writel(pci->bdf, ofs, addr);
80
 
    if (is64)
81
 
        pci_config_writel(pci->bdf, ofs + 4, addr >> 32);
82
 
}
83
 
 
84
 
 
85
 
/****************************************************************
86
 
 * Misc. device init
87
 
 ****************************************************************/
88
 
 
89
 
/* host irqs corresponding to PCI irqs A-D */
90
 
const u8 pci_irqs[4] = {
91
 
    10, 10, 11, 11
92
 
};
93
 
 
94
 
// Return the global irq number corresponding to a host bus device irq pin.
95
 
static int pci_slot_get_irq(struct pci_device *pci, int pin)
96
 
{
97
 
    int slot_addend = 0;
98
 
 
99
 
    while (pci->parent != NULL) {
100
 
        slot_addend += pci_bdf_to_dev(pci->bdf);
101
 
        pci = pci->parent;
102
 
    }
103
 
    slot_addend += pci_bdf_to_dev(pci->bdf) - 1;
104
 
    return pci_irqs[(pin - 1 + slot_addend) & 3];
105
 
}
106
 
 
107
 
/* PIIX3/PIIX4 PCI to ISA bridge */
108
 
static void piix_isa_bridge_init(struct pci_device *pci, void *arg)
109
 
{
110
 
    int i, irq;
111
 
    u8 elcr[2];
112
 
 
113
 
    elcr[0] = 0x00;
114
 
    elcr[1] = 0x00;
115
 
    for (i = 0; i < 4; i++) {
116
 
        irq = pci_irqs[i];
117
 
        /* set to trigger level */
118
 
        elcr[irq >> 3] |= (1 << (irq & 7));
119
 
        /* activate irq remapping in PIIX */
120
 
        pci_config_writeb(pci->bdf, 0x60 + i, irq);
121
 
    }
122
 
    outb(elcr[0], 0x4d0);
123
 
    outb(elcr[1], 0x4d1);
124
 
    dprintf(1, "PIIX3/PIIX4 init: elcr=%02x %02x\n", elcr[0], elcr[1]);
125
 
}
126
 
 
127
 
/* ICH9 LPC PCI to ISA bridge */
128
 
/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */
129
 
void mch_isa_bridge_init(struct pci_device *dev, void *arg)
130
 
{
131
 
    u16 bdf = dev->bdf;
132
 
    int i, irq;
133
 
    u8 elcr[2];
134
 
 
135
 
    elcr[0] = 0x00;
136
 
    elcr[1] = 0x00;
137
 
 
138
 
    for (i = 0; i < 4; i++) {
139
 
        irq = pci_irqs[i];
140
 
        /* set to trigger level */
141
 
        elcr[irq >> 3] |= (1 << (irq & 7));
142
 
 
143
 
        /* activate irq remapping in LPC */
144
 
 
145
 
        /* PIRQ[A-D] routing */
146
 
        pci_config_writeb(bdf, ICH9_LPC_PIRQA_ROUT + i,
147
 
                          irq | ICH9_LPC_PIRQ_ROUT_IRQEN);
148
 
        /* PIRQ[E-H] routing */
149
 
        pci_config_writeb(bdf, ICH9_LPC_PIRQE_ROUT + i,
150
 
                          irq | ICH9_LPC_PIRQ_ROUT_IRQEN);
151
 
    }
152
 
    outb(elcr[0], ICH9_LPC_PORT_ELCR1);
153
 
    outb(elcr[1], ICH9_LPC_PORT_ELCR2);
154
 
    dprintf(1, "Q35 LPC init: elcr=%02x %02x\n", elcr[0], elcr[1]);
155
 
 
156
 
    /* pm io base */
157
 
    pci_config_writel(bdf, ICH9_LPC_PMBASE,
158
 
                      PORT_ACPI_PM_BASE | ICH9_LPC_PMBASE_RTE);
159
 
 
160
 
    /* acpi enable, SCI: IRQ9 000b = irq9*/
161
 
    pci_config_writeb(bdf, ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_ACPI_EN);
162
 
 
163
 
    pmtimer_init(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000);
164
 
}
165
 
 
166
 
static void storage_ide_init(struct pci_device *pci, void *arg)
167
 
{
168
 
    /* IDE: we map it as in ISA mode */
169
 
    pci_set_io_region_addr(pci, 0, PORT_ATA1_CMD_BASE, 0);
170
 
    pci_set_io_region_addr(pci, 1, PORT_ATA1_CTRL_BASE, 0);
171
 
    pci_set_io_region_addr(pci, 2, PORT_ATA2_CMD_BASE, 0);
172
 
    pci_set_io_region_addr(pci, 3, PORT_ATA2_CTRL_BASE, 0);
173
 
}
174
 
 
175
 
/* PIIX3/PIIX4 IDE */
176
 
static void piix_ide_init(struct pci_device *pci, void *arg)
177
 
{
178
 
    u16 bdf = pci->bdf;
179
 
    pci_config_writew(bdf, 0x40, 0x8000); // enable IDE0
180
 
    pci_config_writew(bdf, 0x42, 0x8000); // enable IDE1
181
 
}
182
 
 
183
 
static void pic_ibm_init(struct pci_device *pci, void *arg)
184
 
{
185
 
    /* PIC, IBM, MPIC & MPIC2 */
186
 
    pci_set_io_region_addr(pci, 0, 0x80800000 + 0x00040000, 0);
187
 
}
188
 
 
189
 
static void apple_macio_init(struct pci_device *pci, void *arg)
190
 
{
191
 
    /* macio bridge */
192
 
    pci_set_io_region_addr(pci, 0, 0x80800000, 0);
193
 
}
194
 
 
195
 
/* PIIX4 Power Management device (for ACPI) */
196
 
static void piix4_pm_init(struct pci_device *pci, void *arg)
197
 
{
198
 
    u16 bdf = pci->bdf;
199
 
    // acpi sci is hardwired to 9
200
 
    pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 9);
201
 
 
202
 
    pci_config_writel(bdf, 0x40, PORT_ACPI_PM_BASE | 1);
203
 
    pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */
204
 
    pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1);
205
 
    pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */
206
 
 
207
 
    pmtimer_init(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000);
208
 
}
209
 
 
210
 
/* ICH9 SMBUS */
211
 
/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_SMBUS */
212
 
void ich9_smbus_init(struct pci_device *dev, void *arg)
213
 
{
214
 
    u16 bdf = dev->bdf;
215
 
    /* map smbus into io space */
216
 
    pci_config_writel(bdf, ICH9_SMB_SMB_BASE,
217
 
                      PORT_SMB_BASE | PCI_BASE_ADDRESS_SPACE_IO);
218
 
 
219
 
    /* enable SMBus */
220
 
    pci_config_writeb(bdf, ICH9_SMB_HOSTC, ICH9_SMB_HOSTC_HST_EN);
221
 
}
222
 
 
223
 
static const struct pci_device_id pci_device_tbl[] = {
224
 
    /* PIIX3/PIIX4 PCI to ISA bridge */
225
 
    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0,
226
 
               piix_isa_bridge_init),
227
 
    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
228
 
               piix_isa_bridge_init),
229
 
    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC,
230
 
               mch_isa_bridge_init),
231
 
 
232
 
    /* STORAGE IDE */
233
 
    PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1,
234
 
                     PCI_CLASS_STORAGE_IDE, piix_ide_init),
235
 
    PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB,
236
 
                     PCI_CLASS_STORAGE_IDE, piix_ide_init),
237
 
    PCI_DEVICE_CLASS(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
238
 
                     storage_ide_init),
239
 
 
240
 
    /* PIC, IBM, MIPC & MPIC2 */
241
 
    PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0x0046, PCI_CLASS_SYSTEM_PIC,
242
 
                     pic_ibm_init),
243
 
    PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0xFFFF, PCI_CLASS_SYSTEM_PIC,
244
 
                     pic_ibm_init),
245
 
 
246
 
    /* PIIX4 Power Management device (for ACPI) */
247
 
    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
248
 
               piix4_pm_init),
249
 
    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_SMBUS,
250
 
               ich9_smbus_init),
251
 
 
252
 
    /* 0xff00 */
253
 
    PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0017, 0xff00, apple_macio_init),
254
 
    PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0022, 0xff00, apple_macio_init),
255
 
 
256
 
    PCI_DEVICE_END,
257
 
};
258
 
 
259
 
static void pci_bios_init_device(struct pci_device *pci)
260
 
{
261
 
    u16 bdf = pci->bdf;
262
 
    dprintf(1, "PCI: init bdf=%02x:%02x.%x id=%04x:%04x\n"
263
 
            , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf)
264
 
            , pci->vendor, pci->device);
265
 
 
266
 
    /* map the interrupt */
267
 
    int pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN);
268
 
    if (pin != 0)
269
 
        pci_config_writeb(bdf, PCI_INTERRUPT_LINE, pci_slot_get_irq(pci, pin));
270
 
 
271
 
    pci_init_device(pci_device_tbl, pci, NULL);
272
 
 
273
 
    /* enable memory mappings */
274
 
    pci_config_maskw(bdf, PCI_COMMAND, 0,
275
 
                     PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SERR);
276
 
}
277
 
 
278
 
static void pci_bios_init_devices(void)
279
 
{
280
 
    struct pci_device *pci;
281
 
    foreachpci(pci) {
282
 
        pci_bios_init_device(pci);
283
 
    }
284
 
}
285
 
 
286
 
 
287
 
/****************************************************************
288
 
 * Platform device initialization
289
 
 ****************************************************************/
290
 
 
291
 
void i440fx_mem_addr_init(struct pci_device *dev, void *arg)
292
 
{
293
 
    if (RamSize <= 0x80000000)
294
 
        pcimem_start = 0x80000000;
295
 
    else if (RamSize <= 0xc0000000)
296
 
        pcimem_start = 0xc0000000;
297
 
}
298
 
 
299
 
void mch_mem_addr_init(struct pci_device *dev, void *arg)
300
 
{
301
 
    u64 addr = Q35_HOST_BRIDGE_PCIEXBAR_ADDR;
302
 
    u32 size = Q35_HOST_BRIDGE_PCIEXBAR_SIZE;
303
 
 
304
 
    /* setup mmconfig */
305
 
    u16 bdf = dev->bdf;
306
 
    u32 upper = addr >> 32;
307
 
    u32 lower = (addr & 0xffffffff) | Q35_HOST_BRIDGE_PCIEXBAREN;
308
 
    pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, 0);
309
 
    pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR + 4, upper);
310
 
    pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, lower);
311
 
    add_e820(addr, size, E820_RESERVED);
312
 
 
313
 
    /* setup pci i/o window (above mmconfig) */
314
 
    pcimem_start = addr + size;
315
 
}
316
 
 
317
 
static const struct pci_device_id pci_platform_tbl[] = {
318
 
    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,
319
 
               i440fx_mem_addr_init),
320
 
    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Q35_MCH,
321
 
               mch_mem_addr_init),
322
 
    PCI_DEVICE_END
323
 
};
324
 
 
325
 
static void pci_bios_init_platform(void)
326
 
{
327
 
    struct pci_device *pci;
328
 
    foreachpci(pci) {
329
 
        pci_init_device(pci_platform_tbl, pci, NULL);
330
 
    }
331
 
}
332
 
 
333
 
 
334
 
/****************************************************************
335
 
 * Bus initialization
336
 
 ****************************************************************/
337
 
 
338
 
static void
339
 
pci_bios_init_bus_rec(int bus, u8 *pci_bus)
340
 
{
341
 
    int bdf;
342
 
    u16 class;
343
 
 
344
 
    dprintf(1, "PCI: %s bus = 0x%x\n", __func__, bus);
345
 
 
346
 
    /* prevent accidental access to unintended devices */
347
 
    foreachbdf(bdf, bus) {
348
 
        class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
349
 
        if (class == PCI_CLASS_BRIDGE_PCI) {
350
 
            pci_config_writeb(bdf, PCI_SECONDARY_BUS, 255);
351
 
            pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 0);
352
 
        }
353
 
    }
354
 
 
355
 
    foreachbdf(bdf, bus) {
356
 
        class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
357
 
        if (class != PCI_CLASS_BRIDGE_PCI) {
358
 
            continue;
359
 
        }
360
 
        dprintf(1, "PCI: %s bdf = 0x%x\n", __func__, bdf);
361
 
 
362
 
        u8 pribus = pci_config_readb(bdf, PCI_PRIMARY_BUS);
363
 
        if (pribus != bus) {
364
 
            dprintf(1, "PCI: primary bus = 0x%x -> 0x%x\n", pribus, bus);
365
 
            pci_config_writeb(bdf, PCI_PRIMARY_BUS, bus);
366
 
        } else {
367
 
            dprintf(1, "PCI: primary bus = 0x%x\n", pribus);
368
 
        }
369
 
 
370
 
        u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS);
371
 
        (*pci_bus)++;
372
 
        if (*pci_bus != secbus) {
373
 
            dprintf(1, "PCI: secondary bus = 0x%x -> 0x%x\n",
374
 
                    secbus, *pci_bus);
375
 
            secbus = *pci_bus;
376
 
            pci_config_writeb(bdf, PCI_SECONDARY_BUS, secbus);
377
 
        } else {
378
 
            dprintf(1, "PCI: secondary bus = 0x%x\n", secbus);
379
 
        }
380
 
 
381
 
        /* set to max for access to all subordinate buses.
382
 
           later set it to accurate value */
383
 
        u8 subbus = pci_config_readb(bdf, PCI_SUBORDINATE_BUS);
384
 
        pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 255);
385
 
 
386
 
        pci_bios_init_bus_rec(secbus, pci_bus);
387
 
 
388
 
        if (subbus != *pci_bus) {
389
 
            dprintf(1, "PCI: subordinate bus = 0x%x -> 0x%x\n",
390
 
                    subbus, *pci_bus);
391
 
            subbus = *pci_bus;
392
 
        } else {
393
 
            dprintf(1, "PCI: subordinate bus = 0x%x\n", subbus);
394
 
        }
395
 
        pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, subbus);
396
 
    }
397
 
}
398
 
 
399
 
static void
400
 
pci_bios_init_bus(void)
401
 
{
402
 
    u8 pci_bus = 0;
403
 
    pci_bios_init_bus_rec(0 /* host bus */, &pci_bus);
404
 
}
405
 
 
406
 
 
407
 
/****************************************************************
408
 
 * Bus sizing
409
 
 ****************************************************************/
410
 
 
411
 
static void
412
 
pci_bios_get_bar(struct pci_device *pci, int bar,
413
 
                 int *ptype, u64 *psize, int *pis64)
414
 
{
415
 
    u32 ofs = pci_bar(pci, bar);
416
 
    u16 bdf = pci->bdf;
417
 
    u32 old = pci_config_readl(bdf, ofs);
418
 
    int is64 = 0, type = PCI_REGION_TYPE_MEM;
419
 
    u64 mask;
420
 
 
421
 
    if (bar == PCI_ROM_SLOT) {
422
 
        mask = PCI_ROM_ADDRESS_MASK;
423
 
        pci_config_writel(bdf, ofs, mask);
424
 
    } else {
425
 
        if (old & PCI_BASE_ADDRESS_SPACE_IO) {
426
 
            mask = PCI_BASE_ADDRESS_IO_MASK;
427
 
            type = PCI_REGION_TYPE_IO;
428
 
        } else {
429
 
            mask = PCI_BASE_ADDRESS_MEM_MASK;
430
 
            if (old & PCI_BASE_ADDRESS_MEM_PREFETCH)
431
 
                type = PCI_REGION_TYPE_PREFMEM;
432
 
            is64 = ((old & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
433
 
                    == PCI_BASE_ADDRESS_MEM_TYPE_64);
434
 
        }
435
 
        pci_config_writel(bdf, ofs, ~0);
436
 
    }
437
 
    u64 val = pci_config_readl(bdf, ofs);
438
 
    pci_config_writel(bdf, ofs, old);
439
 
    if (is64) {
440
 
        u32 hold = pci_config_readl(bdf, ofs + 4);
441
 
        pci_config_writel(bdf, ofs + 4, ~0);
442
 
        u32 high = pci_config_readl(bdf, ofs + 4);
443
 
        pci_config_writel(bdf, ofs + 4, hold);
444
 
        val |= ((u64)high << 32);
445
 
        mask |= ((u64)0xffffffff << 32);
446
 
        *psize = (~(val & mask)) + 1;
447
 
    } else {
448
 
        *psize = ((~(val & mask)) + 1) & 0xffffffff;
449
 
    }
450
 
    *ptype = type;
451
 
    *pis64 = is64;
452
 
}
453
 
 
454
 
static int pci_bios_bridge_region_is64(struct pci_region *r,
455
 
                                 struct pci_device *pci, int type)
456
 
{
457
 
    if (type != PCI_REGION_TYPE_PREFMEM)
458
 
        return 0;
459
 
    u32 pmem = pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE);
460
 
    if (!pmem) {
461
 
        pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0xfff0fff0);
462
 
        pmem = pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE);
463
 
        pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0x0);
464
 
    }
465
 
    if ((pmem & PCI_PREF_RANGE_TYPE_MASK) != PCI_PREF_RANGE_TYPE_64)
466
 
       return 0;
467
 
    struct pci_region_entry *entry = r->list;
468
 
    while (entry) {
469
 
        if (!entry->is64)
470
 
            return 0;
471
 
        entry = entry->next;
472
 
    }
473
 
    return 1;
474
 
}
475
 
 
476
 
static u64 pci_region_align(struct pci_region *r)
477
 
{
478
 
    if (!r->list)
479
 
        return 1;
480
 
    // The first entry in the sorted list has the largest alignment
481
 
    return r->list->align;
482
 
}
483
 
 
484
 
static u64 pci_region_sum(struct pci_region *r)
485
 
{
486
 
    struct pci_region_entry *entry = r->list;
487
 
    u64 sum = 0;
488
 
    while (entry) {
489
 
        sum += entry->size;
490
 
        entry = entry->next;
491
 
    }
492
 
    return sum;
493
 
}
494
 
 
495
 
static void pci_region_migrate_64bit_entries(struct pci_region *from,
496
 
                                             struct pci_region *to)
497
 
{
498
 
    struct pci_region_entry **pprev = &from->list, **last = &to->list;
499
 
    while (*pprev) {
500
 
        struct pci_region_entry *entry = *pprev;
501
 
        if (!entry->is64) {
502
 
            pprev = &entry->next;
503
 
            continue;
504
 
        }
505
 
        // Move from source list to destination list.
506
 
        *pprev = entry->next;
507
 
        entry->next = NULL;
508
 
        *last = entry;
509
 
        last = &entry->next;
510
 
    }
511
 
}
512
 
 
513
 
static struct pci_region_entry *
514
 
pci_region_create_entry(struct pci_bus *bus, struct pci_device *dev,
515
 
                        int bar, u64 size, u64 align, int type, int is64)
516
 
{
517
 
    struct pci_region_entry *entry = malloc_tmp(sizeof(*entry));
518
 
    if (!entry) {
519
 
        warn_noalloc();
520
 
        return NULL;
521
 
    }
522
 
    memset(entry, 0, sizeof(*entry));
523
 
    entry->dev = dev;
524
 
    entry->bar = bar;
525
 
    entry->size = size;
526
 
    entry->align = align;
527
 
    entry->is64 = is64;
528
 
    entry->type = type;
529
 
    // Insert into list in sorted order.
530
 
    struct pci_region_entry **pprev;
531
 
    for (pprev = &bus->r[type].list; *pprev; pprev = &(*pprev)->next) {
532
 
        struct pci_region_entry *pos = *pprev;
533
 
        if (pos->align < align || (pos->align == align && pos->size < size))
534
 
            break;
535
 
    }
536
 
    entry->next = *pprev;
537
 
    *pprev = entry;
538
 
    return entry;
539
 
}
540
 
 
541
 
static int pci_bios_check_devices(struct pci_bus *busses)
542
 
{
543
 
    dprintf(1, "PCI: check devices\n");
544
 
 
545
 
    // Calculate resources needed for regular (non-bus) devices.
546
 
    struct pci_device *pci;
547
 
    foreachpci(pci) {
548
 
        if (pci->class == PCI_CLASS_BRIDGE_PCI)
549
 
            busses[pci->secondary_bus].bus_dev = pci;
550
 
 
551
 
        struct pci_bus *bus = &busses[pci_bdf_to_bus(pci->bdf)];
552
 
        int i;
553
 
        for (i = 0; i < PCI_NUM_REGIONS; i++) {
554
 
            if ((pci->class == PCI_CLASS_BRIDGE_PCI) &&
555
 
                (i >= PCI_BRIDGE_NUM_REGIONS && i < PCI_ROM_SLOT))
556
 
                continue;
557
 
            int type, is64;
558
 
            u64 size;
559
 
            pci_bios_get_bar(pci, i, &type, &size, &is64);
560
 
            if (size == 0)
561
 
                continue;
562
 
 
563
 
            if (type != PCI_REGION_TYPE_IO && size < PCI_DEVICE_MEM_MIN)
564
 
                size = PCI_DEVICE_MEM_MIN;
565
 
            struct pci_region_entry *entry = pci_region_create_entry(
566
 
                bus, pci, i, size, size, type, is64);
567
 
            if (!entry)
568
 
                return -1;
569
 
 
570
 
            if (is64)
571
 
                i++;
572
 
        }
573
 
    }
574
 
 
575
 
    // Propagate required bus resources to parent busses.
576
 
    int secondary_bus;
577
 
    for (secondary_bus=MaxPCIBus; secondary_bus>0; secondary_bus--) {
578
 
        struct pci_bus *s = &busses[secondary_bus];
579
 
        if (!s->bus_dev)
580
 
            continue;
581
 
        struct pci_bus *parent = &busses[pci_bdf_to_bus(s->bus_dev->bdf)];
582
 
        int type;
583
 
        for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
584
 
            u64 align = (type == PCI_REGION_TYPE_IO) ?
585
 
                PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
586
 
            if (pci_region_align(&s->r[type]) > align)
587
 
                 align = pci_region_align(&s->r[type]);
588
 
            u64 sum = pci_region_sum(&s->r[type]);
589
 
            u64 size = ALIGN(sum, align);
590
 
            int is64 = pci_bios_bridge_region_is64(&s->r[type],
591
 
                                            s->bus_dev, type);
592
 
            // entry->bar is -1 if the entry represents a bridge region
593
 
            struct pci_region_entry *entry = pci_region_create_entry(
594
 
                parent, s->bus_dev, -1, size, align, type, is64);
595
 
            if (!entry)
596
 
                return -1;
597
 
            dprintf(1, "PCI: secondary bus %d size %08llx type %s\n",
598
 
                      entry->dev->secondary_bus, size,
599
 
                      region_type_name[entry->type]);
600
 
        }
601
 
    }
602
 
    return 0;
603
 
}
604
 
 
605
 
 
606
 
/****************************************************************
607
 
 * BAR assignment
608
 
 ****************************************************************/
609
 
 
610
 
// Setup region bases (given the regions' size and alignment)
611
 
static int pci_bios_init_root_regions(struct pci_bus *bus)
612
 
{
613
 
    bus->r[PCI_REGION_TYPE_IO].base = 0xc000;
614
 
 
615
 
    struct pci_region *r_end = &bus->r[PCI_REGION_TYPE_PREFMEM];
616
 
    struct pci_region *r_start = &bus->r[PCI_REGION_TYPE_MEM];
617
 
 
618
 
    if (pci_region_align(r_start) < pci_region_align(r_end)) {
619
 
        // Swap regions to improve alignment.
620
 
        r_end = r_start;
621
 
        r_start = &bus->r[PCI_REGION_TYPE_PREFMEM];
622
 
    }
623
 
    u64 sum = pci_region_sum(r_end);
624
 
    u64 align = pci_region_align(r_end);
625
 
    r_end->base = ALIGN_DOWN((pcimem_end - sum), align);
626
 
    sum = pci_region_sum(r_start);
627
 
    align = pci_region_align(r_start);
628
 
    r_start->base = ALIGN_DOWN((r_end->base - sum), align);
629
 
 
630
 
    if ((r_start->base < pcimem_start) ||
631
 
         (r_start->base > pcimem_end))
632
 
        // Memory range requested is larger than available.
633
 
        return -1;
634
 
    return 0;
635
 
}
636
 
 
637
 
#define PCI_IO_SHIFT            8
638
 
#define PCI_MEMORY_SHIFT        16
639
 
#define PCI_PREF_MEMORY_SHIFT   16
640
 
 
641
 
static void
642
 
pci_region_map_one_entry(struct pci_region_entry *entry, u64 addr)
643
 
{
644
 
    u16 bdf = entry->dev->bdf;
645
 
    if (entry->bar >= 0) {
646
 
        dprintf(1, "PCI: map device bdf=%02x:%02x.%x"
647
 
                "  bar %d, addr %08llx, size %08llx [%s]\n",
648
 
                pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf),
649
 
                entry->bar, addr, entry->size, region_type_name[entry->type]);
650
 
 
651
 
        pci_set_io_region_addr(entry->dev, entry->bar, addr, entry->is64);
652
 
        return;
653
 
    }
654
 
 
655
 
    u64 limit = addr + entry->size - 1;
656
 
    if (entry->type == PCI_REGION_TYPE_IO) {
657
 
        pci_config_writeb(bdf, PCI_IO_BASE, addr >> PCI_IO_SHIFT);
658
 
        pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0);
659
 
        pci_config_writeb(bdf, PCI_IO_LIMIT, limit >> PCI_IO_SHIFT);
660
 
        pci_config_writew(bdf, PCI_IO_LIMIT_UPPER16, 0);
661
 
    }
662
 
    if (entry->type == PCI_REGION_TYPE_MEM) {
663
 
        pci_config_writew(bdf, PCI_MEMORY_BASE, addr >> PCI_MEMORY_SHIFT);
664
 
        pci_config_writew(bdf, PCI_MEMORY_LIMIT, limit >> PCI_MEMORY_SHIFT);
665
 
    }
666
 
    if (entry->type == PCI_REGION_TYPE_PREFMEM) {
667
 
        pci_config_writew(bdf, PCI_PREF_MEMORY_BASE, addr >> PCI_PREF_MEMORY_SHIFT);
668
 
        pci_config_writew(bdf, PCI_PREF_MEMORY_LIMIT, limit >> PCI_PREF_MEMORY_SHIFT);
669
 
        pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, addr >> 32);
670
 
        pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, limit >> 32);
671
 
    }
672
 
}
673
 
 
674
 
static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r)
675
 
{
676
 
    struct pci_region_entry *entry = r->list;
677
 
    while (entry) {
678
 
        u64 addr = r->base;
679
 
        r->base += entry->size;
680
 
        if (entry->bar == -1)
681
 
            // Update bus base address if entry is a bridge region
682
 
            busses[entry->dev->secondary_bus].r[entry->type].base = addr;
683
 
        pci_region_map_one_entry(entry, addr);
684
 
        struct pci_region_entry *next = entry->next;
685
 
        free(entry);
686
 
        entry = next;
687
 
    }
688
 
}
689
 
 
690
 
static void pci_bios_map_devices(struct pci_bus *busses)
691
 
{
692
 
    if (pci_bios_init_root_regions(busses)) {
693
 
        struct pci_region r64_mem, r64_pref;
694
 
        r64_mem.list = NULL;
695
 
        r64_pref.list = NULL;
696
 
        pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_MEM],
697
 
                                         &r64_mem);
698
 
        pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_PREFMEM],
699
 
                                         &r64_pref);
700
 
 
701
 
        if (pci_bios_init_root_regions(busses))
702
 
            panic("PCI: out of 32bit address space\n");
703
 
 
704
 
        u64 sum_mem = pci_region_sum(&r64_mem);
705
 
        u64 sum_pref = pci_region_sum(&r64_pref);
706
 
        u64 align_mem = pci_region_align(&r64_mem);
707
 
        u64 align_pref = pci_region_align(&r64_pref);
708
 
 
709
 
        r64_mem.base = ALIGN(0x100000000LL + RamSizeOver4G, align_mem);
710
 
        r64_pref.base = ALIGN(r64_mem.base + sum_mem, align_pref);
711
 
        pcimem64_start = r64_mem.base;
712
 
        pcimem64_end = r64_pref.base + sum_pref;
713
 
 
714
 
        pci_region_map_entries(busses, &r64_mem);
715
 
        pci_region_map_entries(busses, &r64_pref);
716
 
    } else {
717
 
        // no bars mapped high -> drop 64bit window (see dsdt)
718
 
        pcimem64_start = 0;
719
 
    }
720
 
    // Map regions on each device.
721
 
    int bus;
722
 
    for (bus = 0; bus<=MaxPCIBus; bus++) {
723
 
        int type;
724
 
        for (type = 0; type < PCI_REGION_TYPE_COUNT; type++)
725
 
            pci_region_map_entries(busses, &busses[bus].r[type]);
726
 
    }
727
 
}
728
 
 
729
 
 
730
 
/****************************************************************
731
 
 * Main setup code
732
 
 ****************************************************************/
733
 
 
734
 
void
735
 
pci_setup(void)
736
 
{
737
 
    if (CONFIG_COREBOOT || usingXen()) {
738
 
        // PCI setup already done by coreboot or Xen - just do probe.
739
 
        pci_probe_devices();
740
 
        return;
741
 
    }
742
 
 
743
 
    dprintf(3, "pci setup\n");
744
 
 
745
 
    dprintf(1, "=== PCI bus & bridge init ===\n");
746
 
    if (pci_probe_host() != 0) {
747
 
        return;
748
 
    }
749
 
    pci_bios_init_bus();
750
 
 
751
 
    dprintf(1, "=== PCI device probing ===\n");
752
 
    pci_probe_devices();
753
 
 
754
 
    pcimem_start = RamSize;
755
 
    pci_bios_init_platform();
756
 
 
757
 
    dprintf(1, "=== PCI new allocation pass #1 ===\n");
758
 
    struct pci_bus *busses = malloc_tmp(sizeof(*busses) * (MaxPCIBus + 1));
759
 
    if (!busses) {
760
 
        warn_noalloc();
761
 
        return;
762
 
    }
763
 
    memset(busses, 0, sizeof(*busses) * (MaxPCIBus + 1));
764
 
    if (pci_bios_check_devices(busses))
765
 
        return;
766
 
 
767
 
    dprintf(1, "=== PCI new allocation pass #2 ===\n");
768
 
    pci_bios_map_devices(busses);
769
 
 
770
 
    pci_bios_init_devices();
771
 
 
772
 
    free(busses);
773
 
}