mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
tools: hvmloader: Refactor APIC, PCI and SMP setup into struct bios_config
Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Acked-by: Keir Fraser <keir@xen.org>
This commit is contained in:
1 parent
548977fea1
commit
7128e9e70e
3 files changed
+249
-232
No files matched your search
@@ -3,6 +3,9 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt } virtual_vga;
|
||||
extern enum virtual_vga virtual_vga;
|
||||
|
||||
struct bios_config {
|
||||
const char *name;
|
||||
|
||||
@@ -21,6 +24,10 @@ struct bios_config {
|
||||
|
||||
/* ACPI tables */
|
||||
unsigned int acpi_start;
|
||||
|
||||
void (*apic_setup)(void);
|
||||
void (*pci_setup)(void);
|
||||
void (*smp_setup)(void);
|
||||
};
|
||||
|
||||
extern struct bios_config rombios_config;
|
||||
|
||||
@@ -24,13 +24,10 @@
|
||||
#include "util.h"
|
||||
#include "hypercall.h"
|
||||
#include "config.h"
|
||||
#include "apic_regs.h"
|
||||
#include "pci_regs.h"
|
||||
#include "option_rom.h"
|
||||
#include <xen/version.h>
|
||||
#include <xen/hvm/params.h>
|
||||
#include <xen/hvm/ioreq.h>
|
||||
#include <xen/memory.h>
|
||||
|
||||
#define ROM_INCLUDE_VGABIOS
|
||||
#define ROM_INCLUDE_ETHERBOOT
|
||||
@@ -116,7 +113,7 @@ asm (
|
||||
unsigned long pci_mem_start = PCI_MEM_START;
|
||||
unsigned long pci_mem_end = PCI_MEM_END;
|
||||
|
||||
static enum { VGA_none, VGA_std, VGA_cirrus, VGA_pt } virtual_vga = VGA_none;
|
||||
enum virtual_vga virtual_vga = VGA_none;
|
||||
|
||||
static void init_hypercalls(void)
|
||||
{
|
||||
@@ -152,231 +149,6 @@ static void init_hypercalls(void)
|
||||
printf("Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion);
|
||||
}
|
||||
|
||||
static void apic_setup(void)
|
||||
{
|
||||
/* Set the IOAPIC ID to the static value used in the MP/ACPI tables. */
|
||||
ioapic_write(0x00, IOAPIC_ID);
|
||||
|
||||
/* NMIs are delivered direct to the BSP. */
|
||||
lapic_write(APIC_SPIV, APIC_SPIV_APIC_ENABLED | 0xFF);
|
||||
lapic_write(APIC_LVT0, (APIC_MODE_EXTINT << 8) | APIC_LVT_MASKED);
|
||||
lapic_write(APIC_LVT1, APIC_MODE_NMI << 8);
|
||||
|
||||
/* 8259A ExtInts are delivered through IOAPIC pin 0 (Virtual Wire Mode). */
|
||||
ioapic_write(0x10, APIC_DM_EXTINT);
|
||||
ioapic_write(0x11, SET_APIC_ID(LAPIC_ID(0)));
|
||||
}
|
||||
|
||||
static void pci_setup(void)
|
||||
{
|
||||
uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0;
|
||||
uint16_t class, vendor_id, device_id;
|
||||
unsigned int bar, pin, link, isa_irq;
|
||||
|
||||
/* Resources assignable to PCI devices via BARs. */
|
||||
struct resource {
|
||||
uint32_t base, max;
|
||||
} *resource, mem_resource, io_resource;
|
||||
|
||||
/* Create a list of device BARs in descending order of size. */
|
||||
struct bars {
|
||||
uint32_t devfn, bar_reg, bar_sz;
|
||||
} *bars = (struct bars *)SCRATCH_PHYSICAL_ADDRESS;
|
||||
unsigned int i, nr_bars = 0;
|
||||
|
||||
/* Program PCI-ISA bridge with appropriate link routes. */
|
||||
isa_irq = 0;
|
||||
for ( link = 0; link < 4; link++ )
|
||||
{
|
||||
do { isa_irq = (isa_irq + 1) & 15;
|
||||
} while ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) );
|
||||
pci_writeb(PCI_ISA_DEVFN, 0x60 + link, isa_irq);
|
||||
printf("PCI-ISA link %u routed to IRQ%u\n", link, isa_irq);
|
||||
}
|
||||
|
||||
/* Program ELCR to match PCI-wired IRQs. */
|
||||
outb(0x4d0, (uint8_t)(PCI_ISA_IRQ_MASK >> 0));
|
||||
outb(0x4d1, (uint8_t)(PCI_ISA_IRQ_MASK >> 8));
|
||||
|
||||
/* Scan the PCI bus and map resources. */
|
||||
for ( devfn = 0; devfn < 256; devfn++ )
|
||||
{
|
||||
class = pci_readw(devfn, PCI_CLASS_DEVICE);
|
||||
vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
|
||||
device_id = pci_readw(devfn, PCI_DEVICE_ID);
|
||||
if ( (vendor_id == 0xffff) && (device_id == 0xffff) )
|
||||
continue;
|
||||
|
||||
ASSERT((devfn != PCI_ISA_DEVFN) ||
|
||||
((vendor_id == 0x8086) && (device_id == 0x7000)));
|
||||
|
||||
switch ( class )
|
||||
{
|
||||
case 0x0300:
|
||||
/* If emulated VGA is found, preserve it as primary VGA. */
|
||||
if ( (vendor_id == 0x1234) && (device_id == 0x1111) )
|
||||
virtual_vga = VGA_std;
|
||||
else if ( (vendor_id == 0x1013) && (device_id == 0xb8) )
|
||||
virtual_vga = VGA_cirrus;
|
||||
else if ( virtual_vga == VGA_none )
|
||||
virtual_vga = VGA_pt;
|
||||
break;
|
||||
case 0x0680:
|
||||
/* PIIX4 ACPI PM. Special device with special PCI config space. */
|
||||
ASSERT((vendor_id == 0x8086) && (device_id == 0x7113));
|
||||
pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */
|
||||
pci_writew(devfn, 0xd2, 0x0000); /* No smb bus IO enable */
|
||||
pci_writew(devfn, 0x22, 0x0000);
|
||||
pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */
|
||||
pci_writew(devfn, 0x3d, 0x0001);
|
||||
pci_writel(devfn, 0x40, ACPI_PM1A_EVT_BLK_ADDRESS_V1 | 1);
|
||||
pci_writeb(devfn, 0x80, 0x01); /* enable PM io space */
|
||||
break;
|
||||
case 0x0101:
|
||||
if ( vendor_id == 0x8086 )
|
||||
{
|
||||
/* Intel ICHs since PIIX3: enable IDE legacy mode. */
|
||||
pci_writew(devfn, 0x40, 0x8000); /* enable IDE0 */
|
||||
pci_writew(devfn, 0x42, 0x8000); /* enable IDE1 */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Map the I/O memory and port resources. */
|
||||
for ( bar = 0; bar < 7; bar++ )
|
||||
{
|
||||
bar_reg = PCI_BASE_ADDRESS_0 + 4*bar;
|
||||
if ( bar == 6 )
|
||||
bar_reg = PCI_ROM_ADDRESS;
|
||||
|
||||
bar_data = pci_readl(devfn, bar_reg);
|
||||
pci_writel(devfn, bar_reg, ~0);
|
||||
bar_sz = pci_readl(devfn, bar_reg);
|
||||
pci_writel(devfn, bar_reg, bar_data);
|
||||
if ( bar_sz == 0 )
|
||||
continue;
|
||||
|
||||
bar_sz &= (((bar_data & PCI_BASE_ADDRESS_SPACE) ==
|
||||
PCI_BASE_ADDRESS_SPACE_MEMORY) ?
|
||||
PCI_BASE_ADDRESS_MEM_MASK :
|
||||
(PCI_BASE_ADDRESS_IO_MASK & 0xffff));
|
||||
bar_sz &= ~(bar_sz - 1);
|
||||
|
||||
for ( i = 0; i < nr_bars; i++ )
|
||||
if ( bars[i].bar_sz < bar_sz )
|
||||
break;
|
||||
|
||||
if ( i != nr_bars )
|
||||
memmove(&bars[i+1], &bars[i], (nr_bars-i) * sizeof(*bars));
|
||||
|
||||
bars[i].devfn = devfn;
|
||||
bars[i].bar_reg = bar_reg;
|
||||
bars[i].bar_sz = bar_sz;
|
||||
|
||||
if ( (bar_data & PCI_BASE_ADDRESS_SPACE) ==
|
||||
PCI_BASE_ADDRESS_SPACE_MEMORY )
|
||||
mmio_total += bar_sz;
|
||||
|
||||
nr_bars++;
|
||||
|
||||
/* Skip the upper-half of the address for a 64-bit BAR. */
|
||||
if ( (bar_data & (PCI_BASE_ADDRESS_SPACE |
|
||||
PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
|
||||
(PCI_BASE_ADDRESS_SPACE_MEMORY |
|
||||
PCI_BASE_ADDRESS_MEM_TYPE_64) )
|
||||
bar++;
|
||||
}
|
||||
|
||||
/* Map the interrupt. */
|
||||
pin = pci_readb(devfn, PCI_INTERRUPT_PIN);
|
||||
if ( pin != 0 )
|
||||
{
|
||||
/* This is the barber's pole mapping used by Xen. */
|
||||
link = ((pin - 1) + (devfn >> 3)) & 3;
|
||||
isa_irq = pci_readb(PCI_ISA_DEVFN, 0x60 + link);
|
||||
pci_writeb(devfn, PCI_INTERRUPT_LINE, isa_irq);
|
||||
printf("pci dev %02x:%x INT%c->IRQ%u\n",
|
||||
devfn>>3, devfn&7, 'A'+pin-1, isa_irq);
|
||||
}
|
||||
|
||||
/* Enable bus mastering. */
|
||||
cmd = pci_readw(devfn, PCI_COMMAND);
|
||||
cmd |= PCI_COMMAND_MASTER;
|
||||
pci_writew(devfn, PCI_COMMAND, cmd);
|
||||
}
|
||||
|
||||
while ( (mmio_total > (pci_mem_end - pci_mem_start)) &&
|
||||
((pci_mem_start << 1) != 0) )
|
||||
pci_mem_start <<= 1;
|
||||
|
||||
while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend )
|
||||
{
|
||||
struct xen_add_to_physmap xatp;
|
||||
if ( hvm_info->high_mem_pgend == 0 )
|
||||
hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT);
|
||||
xatp.domid = DOMID_SELF;
|
||||
xatp.space = XENMAPSPACE_gmfn;
|
||||
xatp.idx = --hvm_info->low_mem_pgend;
|
||||
xatp.gpfn = hvm_info->high_mem_pgend++;
|
||||
if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
|
||||
BUG();
|
||||
}
|
||||
|
||||
mem_resource.base = pci_mem_start;
|
||||
mem_resource.max = pci_mem_end;
|
||||
io_resource.base = 0xc000;
|
||||
io_resource.max = 0x10000;
|
||||
|
||||
/* Assign iomem and ioport resources in descending order of size. */
|
||||
for ( i = 0; i < nr_bars; i++ )
|
||||
{
|
||||
devfn = bars[i].devfn;
|
||||
bar_reg = bars[i].bar_reg;
|
||||
bar_sz = bars[i].bar_sz;
|
||||
|
||||
bar_data = pci_readl(devfn, bar_reg);
|
||||
|
||||
if ( (bar_data & PCI_BASE_ADDRESS_SPACE) ==
|
||||
PCI_BASE_ADDRESS_SPACE_MEMORY )
|
||||
{
|
||||
resource = &mem_resource;
|
||||
bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
resource = &io_resource;
|
||||
bar_data &= ~PCI_BASE_ADDRESS_IO_MASK;
|
||||
}
|
||||
|
||||
base = (resource->base + bar_sz - 1) & ~(bar_sz - 1);
|
||||
bar_data |= base;
|
||||
base += bar_sz;
|
||||
|
||||
if ( (base < resource->base) || (base > resource->max) )
|
||||
{
|
||||
printf("pci dev %02x:%x bar %02x size %08x: no space for "
|
||||
"resource!\n", devfn>>3, devfn&7, bar_reg, bar_sz);
|
||||
continue;
|
||||
}
|
||||
|
||||
resource->base = base;
|
||||
|
||||
pci_writel(devfn, bar_reg, bar_data);
|
||||
printf("pci dev %02x:%x bar %02x size %08x: %08x\n",
|
||||
devfn>>3, devfn&7, bar_reg, bar_sz, bar_data);
|
||||
|
||||
/* Now enable the memory or I/O mapping. */
|
||||
cmd = pci_readw(devfn, PCI_COMMAND);
|
||||
if ( (bar_reg == PCI_ROM_ADDRESS) ||
|
||||
((bar_data & PCI_BASE_ADDRESS_SPACE) ==
|
||||
PCI_BASE_ADDRESS_SPACE_MEMORY) )
|
||||
cmd |= PCI_COMMAND_MEMORY;
|
||||
else
|
||||
cmd |= PCI_COMMAND_IO;
|
||||
pci_writew(devfn, PCI_COMMAND, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan the list of Option ROMs at @roms for one which supports
|
||||
* PCI (@vendor_id, @device_id) found at slot @devfn. If one is found,
|
||||
@@ -608,10 +380,13 @@ int main(void)
|
||||
|
||||
printf("CPU speed is %u MHz\n", get_cpu_mhz());
|
||||
|
||||
apic_setup();
|
||||
pci_setup();
|
||||
if (bios->apic_setup)
|
||||
bios->apic_setup();
|
||||
if (bios->pci_setup)
|
||||
bios->pci_setup();
|
||||
|
||||
smp_initialise();
|
||||
if (bios->smp_setup)
|
||||
bios->smp_setup();
|
||||
|
||||
perform_tests();
|
||||
|
||||
|
||||
@@ -24,9 +24,241 @@
|
||||
|
||||
#include "../rombios/config.h"
|
||||
|
||||
#include "apic_regs.h"
|
||||
#include "pci_regs.h"
|
||||
#include "util.h"
|
||||
#include "hypercall.h"
|
||||
|
||||
#include <xen/hvm/ioreq.h>
|
||||
#include <xen/memory.h>
|
||||
|
||||
#define ROM_INCLUDE_ROMBIOS
|
||||
#include "roms.inc"
|
||||
|
||||
static void rombios_apic_setup(void)
|
||||
{
|
||||
/* Set the IOAPIC ID to the static value used in the MP/ACPI tables. */
|
||||
ioapic_write(0x00, IOAPIC_ID);
|
||||
|
||||
/* NMIs are delivered direct to the BSP. */
|
||||
lapic_write(APIC_SPIV, APIC_SPIV_APIC_ENABLED | 0xFF);
|
||||
lapic_write(APIC_LVT0, (APIC_MODE_EXTINT << 8) | APIC_LVT_MASKED);
|
||||
lapic_write(APIC_LVT1, APIC_MODE_NMI << 8);
|
||||
|
||||
/* 8259A ExtInts are delivered through IOAPIC pin 0 (Virtual Wire Mode). */
|
||||
ioapic_write(0x10, APIC_DM_EXTINT);
|
||||
ioapic_write(0x11, SET_APIC_ID(LAPIC_ID(0)));
|
||||
}
|
||||
|
||||
static void rombios_pci_setup(void)
|
||||
{
|
||||
uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0;
|
||||
uint16_t class, vendor_id, device_id;
|
||||
unsigned int bar, pin, link, isa_irq;
|
||||
|
||||
/* Resources assignable to PCI devices via BARs. */
|
||||
struct resource {
|
||||
uint32_t base, max;
|
||||
} *resource, mem_resource, io_resource;
|
||||
|
||||
/* Create a list of device BARs in descending order of size. */
|
||||
struct bars {
|
||||
uint32_t devfn, bar_reg, bar_sz;
|
||||
} *bars = (struct bars *)SCRATCH_PHYSICAL_ADDRESS;
|
||||
unsigned int i, nr_bars = 0;
|
||||
|
||||
/* Program PCI-ISA bridge with appropriate link routes. */
|
||||
isa_irq = 0;
|
||||
for ( link = 0; link < 4; link++ )
|
||||
{
|
||||
do { isa_irq = (isa_irq + 1) & 15;
|
||||
} while ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) );
|
||||
pci_writeb(PCI_ISA_DEVFN, 0x60 + link, isa_irq);
|
||||
printf("PCI-ISA link %u routed to IRQ%u\n", link, isa_irq);
|
||||
}
|
||||
|
||||
/* Program ELCR to match PCI-wired IRQs. */
|
||||
outb(0x4d0, (uint8_t)(PCI_ISA_IRQ_MASK >> 0));
|
||||
outb(0x4d1, (uint8_t)(PCI_ISA_IRQ_MASK >> 8));
|
||||
|
||||
/* Scan the PCI bus and map resources. */
|
||||
for ( devfn = 0; devfn < 256; devfn++ )
|
||||
{
|
||||
class = pci_readw(devfn, PCI_CLASS_DEVICE);
|
||||
vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
|
||||
device_id = pci_readw(devfn, PCI_DEVICE_ID);
|
||||
if ( (vendor_id == 0xffff) && (device_id == 0xffff) )
|
||||
continue;
|
||||
|
||||
ASSERT((devfn != PCI_ISA_DEVFN) ||
|
||||
((vendor_id == 0x8086) && (device_id == 0x7000)));
|
||||
|
||||
switch ( class )
|
||||
{
|
||||
case 0x0300:
|
||||
/* If emulated VGA is found, preserve it as primary VGA. */
|
||||
if ( (vendor_id == 0x1234) && (device_id == 0x1111) )
|
||||
virtual_vga = VGA_std;
|
||||
else if ( (vendor_id == 0x1013) && (device_id == 0xb8) )
|
||||
virtual_vga = VGA_cirrus;
|
||||
else if ( virtual_vga == VGA_none )
|
||||
virtual_vga = VGA_pt;
|
||||
break;
|
||||
case 0x0680:
|
||||
/* PIIX4 ACPI PM. Special device with special PCI config space. */
|
||||
ASSERT((vendor_id == 0x8086) && (device_id == 0x7113));
|
||||
pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */
|
||||
pci_writew(devfn, 0xd2, 0x0000); /* No smb bus IO enable */
|
||||
pci_writew(devfn, 0x22, 0x0000);
|
||||
pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */
|
||||
pci_writew(devfn, 0x3d, 0x0001);
|
||||
pci_writel(devfn, 0x40, ACPI_PM1A_EVT_BLK_ADDRESS_V1 | 1);
|
||||
pci_writeb(devfn, 0x80, 0x01); /* enable PM io space */
|
||||
break;
|
||||
case 0x0101:
|
||||
if ( vendor_id == 0x8086 )
|
||||
{
|
||||
/* Intel ICHs since PIIX3: enable IDE legacy mode. */
|
||||
pci_writew(devfn, 0x40, 0x8000); /* enable IDE0 */
|
||||
pci_writew(devfn, 0x42, 0x8000); /* enable IDE1 */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Map the I/O memory and port resources. */
|
||||
for ( bar = 0; bar < 7; bar++ )
|
||||
{
|
||||
bar_reg = PCI_BASE_ADDRESS_0 + 4*bar;
|
||||
if ( bar == 6 )
|
||||
bar_reg = PCI_ROM_ADDRESS;
|
||||
|
||||
bar_data = pci_readl(devfn, bar_reg);
|
||||
pci_writel(devfn, bar_reg, ~0);
|
||||
bar_sz = pci_readl(devfn, bar_reg);
|
||||
pci_writel(devfn, bar_reg, bar_data);
|
||||
if ( bar_sz == 0 )
|
||||
continue;
|
||||
|
||||
bar_sz &= (((bar_data & PCI_BASE_ADDRESS_SPACE) ==
|
||||
PCI_BASE_ADDRESS_SPACE_MEMORY) ?
|
||||
PCI_BASE_ADDRESS_MEM_MASK :
|
||||
(PCI_BASE_ADDRESS_IO_MASK & 0xffff));
|
||||
bar_sz &= ~(bar_sz - 1);
|
||||
|
||||
for ( i = 0; i < nr_bars; i++ )
|
||||
if ( bars[i].bar_sz < bar_sz )
|
||||
break;
|
||||
|
||||
if ( i != nr_bars )
|
||||
memmove(&bars[i+1], &bars[i], (nr_bars-i) * sizeof(*bars));
|
||||
|
||||
bars[i].devfn = devfn;
|
||||
bars[i].bar_reg = bar_reg;
|
||||
bars[i].bar_sz = bar_sz;
|
||||
|
||||
if ( (bar_data & PCI_BASE_ADDRESS_SPACE) ==
|
||||
PCI_BASE_ADDRESS_SPACE_MEMORY )
|
||||
mmio_total += bar_sz;
|
||||
|
||||
nr_bars++;
|
||||
|
||||
/* Skip the upper-half of the address for a 64-bit BAR. */
|
||||
if ( (bar_data & (PCI_BASE_ADDRESS_SPACE |
|
||||
PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
|
||||
(PCI_BASE_ADDRESS_SPACE_MEMORY |
|
||||
PCI_BASE_ADDRESS_MEM_TYPE_64) )
|
||||
bar++;
|
||||
}
|
||||
|
||||
/* Map the interrupt. */
|
||||
pin = pci_readb(devfn, PCI_INTERRUPT_PIN);
|
||||
if ( pin != 0 )
|
||||
{
|
||||
/* This is the barber's pole mapping used by Xen. */
|
||||
link = ((pin - 1) + (devfn >> 3)) & 3;
|
||||
isa_irq = pci_readb(PCI_ISA_DEVFN, 0x60 + link);
|
||||
pci_writeb(devfn, PCI_INTERRUPT_LINE, isa_irq);
|
||||
printf("pci dev %02x:%x INT%c->IRQ%u\n",
|
||||
devfn>>3, devfn&7, 'A'+pin-1, isa_irq);
|
||||
}
|
||||
|
||||
/* Enable bus mastering. */
|
||||
cmd = pci_readw(devfn, PCI_COMMAND);
|
||||
cmd |= PCI_COMMAND_MASTER;
|
||||
pci_writew(devfn, PCI_COMMAND, cmd);
|
||||
}
|
||||
|
||||
while ( (mmio_total > (pci_mem_end - pci_mem_start)) &&
|
||||
((pci_mem_start << 1) != 0) )
|
||||
pci_mem_start <<= 1;
|
||||
|
||||
while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend )
|
||||
{
|
||||
struct xen_add_to_physmap xatp;
|
||||
if ( hvm_info->high_mem_pgend == 0 )
|
||||
hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT);
|
||||
xatp.domid = DOMID_SELF;
|
||||
xatp.space = XENMAPSPACE_gmfn;
|
||||
xatp.idx = --hvm_info->low_mem_pgend;
|
||||
xatp.gpfn = hvm_info->high_mem_pgend++;
|
||||
if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
|
||||
BUG();
|
||||
}
|
||||
|
||||
mem_resource.base = pci_mem_start;
|
||||
mem_resource.max = pci_mem_end;
|
||||
io_resource.base = 0xc000;
|
||||
io_resource.max = 0x10000;
|
||||
|
||||
/* Assign iomem and ioport resources in descending order of size. */
|
||||
for ( i = 0; i < nr_bars; i++ )
|
||||
{
|
||||
devfn = bars[i].devfn;
|
||||
bar_reg = bars[i].bar_reg;
|
||||
bar_sz = bars[i].bar_sz;
|
||||
|
||||
bar_data = pci_readl(devfn, bar_reg);
|
||||
|
||||
if ( (bar_data & PCI_BASE_ADDRESS_SPACE) ==
|
||||
PCI_BASE_ADDRESS_SPACE_MEMORY )
|
||||
{
|
||||
resource = &mem_resource;
|
||||
bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
resource = &io_resource;
|
||||
bar_data &= ~PCI_BASE_ADDRESS_IO_MASK;
|
||||
}
|
||||
|
||||
base = (resource->base + bar_sz - 1) & ~(bar_sz - 1);
|
||||
bar_data |= base;
|
||||
base += bar_sz;
|
||||
|
||||
if ( (base < resource->base) || (base > resource->max) )
|
||||
{
|
||||
printf("pci dev %02x:%x bar %02x size %08x: no space for "
|
||||
"resource!\n", devfn>>3, devfn&7, bar_reg, bar_sz);
|
||||
continue;
|
||||
}
|
||||
|
||||
resource->base = base;
|
||||
|
||||
pci_writel(devfn, bar_reg, bar_data);
|
||||
printf("pci dev %02x:%x bar %02x size %08x: %08x\n",
|
||||
devfn>>3, devfn&7, bar_reg, bar_sz, bar_data);
|
||||
|
||||
/* Now enable the memory or I/O mapping. */
|
||||
cmd = pci_readw(devfn, PCI_COMMAND);
|
||||
if ( (bar_reg == PCI_ROM_ADDRESS) ||
|
||||
((bar_data & PCI_BASE_ADDRESS_SPACE) ==
|
||||
PCI_BASE_ADDRESS_SPACE_MEMORY) )
|
||||
cmd |= PCI_COMMAND_MEMORY;
|
||||
else
|
||||
cmd |= PCI_COMMAND_IO;
|
||||
pci_writew(devfn, PCI_COMMAND, cmd);
|
||||
}
|
||||
}
|
||||
//BUILD_BUG_ON(sizeof(rombios) > (0x00100000U - ROMBIOS_PHYSICAL_ADDRESS));
|
||||
|
||||
struct bios_config rombios_config = {
|
||||
@@ -45,6 +277,9 @@ struct bios_config rombios_config = {
|
||||
|
||||
.acpi_start = ACPI_PHYSICAL_ADDRESS,
|
||||
|
||||
.apic_setup = rombios_apic_setup,
|
||||
.pci_setup = rombios_pci_setup,
|
||||
.smp_setup = smp_initialise,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||