The following series further updates hvmloader to support SeaBIOS. It undoes a bunch of premature-refactoring from my previous series and adds generation of BIOS tables, plus a mechanism for passing those through to SeaBIOS. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:39 UTC
[Xen-devel] [PATCH 01 of 15] hvmloader: allow per-BIOS decision on loading option ROMS
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306916275 -3600 # Node ID 253a38db096bdc72b4e266ed103643210a739d93 # Parent cdc873250db270f1d7593eb7381cc308aa5c517f hvmloader: allow per-BIOS decision on loading option ROMS SeaBIOS has functionality to load ROMs from the PCI device directly, it makes sense to use this when it is available. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r cdc873250db2 -r 253a38db096b tools/firmware/hvmloader/config-seabios.h --- a/tools/firmware/hvmloader/config-seabios.h Tue May 31 17:31:28 2011 +0100 +++ b/tools/firmware/hvmloader/config-seabios.h Wed Jun 01 09:17:55 2011 +0100 @@ -1,9 +1,6 @@ #ifndef __HVMLOADER_CONFIG_SEABIOS_H__ #define __HVMLOADER_CONFIG_SEABIOS_H__ -#define OPTIONROM_PHYSICAL_ADDRESS 0x000C8000 -#define OPTIONROM_PHYSICAL_END 0x000E0000 - #define SEABIOS_PHYSICAL_ADDRESS 0x000E0000 #endif /* __HVMLOADER_CONFIG_SEABIOS_H__ */ diff -r cdc873250db2 -r 253a38db096b tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Tue May 31 17:31:28 2011 +0100 +++ b/tools/firmware/hvmloader/config.h Wed Jun 01 09:17:55 2011 +0100 @@ -19,7 +19,8 @@ struct bios_config { /* SMBIOS */ unsigned int smbios_start, smbios_end; - /* Option ROMs */ + /* ROMS */ + int load_roms; unsigned int optionrom_start, optionrom_end; /* ACPI tables */ diff -r cdc873250db2 -r 253a38db096b tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Tue May 31 17:31:28 2011 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:17:55 2011 +0100 @@ -373,7 +373,7 @@ int main(void) uint32_t highbios = 0; const struct bios_config *bios; int option_rom_sz = 0, vgabios_sz = 0, etherboot_sz = 0, smbios_sz = 0; - uint32_t etherboot_phys_addr, option_rom_phys_addr; + uint32_t etherboot_phys_addr = 0, option_rom_phys_addr = 0; /* Initialise hypercall stubs with RET, rendering them no-ops. */ memset((void *)HYPERCALL_PHYSICAL_ADDRESS, 0xc3 /* RET */, PAGE_SIZE); @@ -417,40 +417,43 @@ int main(void) ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode ) ) bios->create_mp_tables(); - switch ( virtual_vga ) + if ( bios->load_roms ) { - case VGA_cirrus: - printf("Loading Cirrus VGABIOS ...\n"); - memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, - vgabios_cirrusvga, sizeof(vgabios_cirrusvga)); - vgabios_sz = round_option_rom(sizeof(vgabios_cirrusvga)); - break; - case VGA_std: - printf("Loading Standard VGABIOS ...\n"); - memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, - vgabios_stdvga, sizeof(vgabios_stdvga)); - vgabios_sz = round_option_rom(sizeof(vgabios_stdvga)); - break; - case VGA_pt: - printf("Loading VGABIOS of passthroughed gfx ...\n"); - vgabios_sz - round_option_rom((*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); - break; - default: - printf("No emulated VGA adaptor ...\n"); - break; + switch ( virtual_vga ) + { + case VGA_cirrus: + printf("Loading Cirrus VGABIOS ...\n"); + memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, + vgabios_cirrusvga, sizeof(vgabios_cirrusvga)); + vgabios_sz = round_option_rom(sizeof(vgabios_cirrusvga)); + break; + case VGA_std: + printf("Loading Standard VGABIOS ...\n"); + memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, + vgabios_stdvga, sizeof(vgabios_stdvga)); + vgabios_sz = round_option_rom(sizeof(vgabios_stdvga)); + break; + case VGA_pt: + printf("Loading VGABIOS of passthroughed gfx ...\n"); + vgabios_sz + round_option_rom((*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); + break; + default: + printf("No emulated VGA adaptor ...\n"); + break; + } + + etherboot_phys_addr = VGABIOS_PHYSICAL_ADDRESS + vgabios_sz; + if ( etherboot_phys_addr < bios->optionrom_start ) + etherboot_phys_addr = bios->optionrom_start; + etherboot_sz = scan_etherboot_nic(bios->optionrom_end, + etherboot_phys_addr); + + option_rom_phys_addr = etherboot_phys_addr + etherboot_sz; + option_rom_sz = pci_load_option_roms(bios->optionrom_end, + option_rom_phys_addr); } - etherboot_phys_addr = VGABIOS_PHYSICAL_ADDRESS + vgabios_sz; - if ( etherboot_phys_addr < bios->optionrom_start ) - etherboot_phys_addr = bios->optionrom_start; - etherboot_sz = scan_etherboot_nic(bios->optionrom_end, - etherboot_phys_addr); - - option_rom_phys_addr = etherboot_phys_addr + etherboot_sz; - option_rom_sz = pci_load_option_roms(bios->optionrom_end, - option_rom_phys_addr); - if ( hvm_info->acpi_enabled ) { struct xen_hvm_param p = { diff -r cdc873250db2 -r 253a38db096b tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Tue May 31 17:31:28 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:17:55 2011 +0100 @@ -372,6 +372,8 @@ struct bios_config rombios_config = { .smbios_start = SMBIOS_PHYSICAL_ADDRESS, .smbios_end = SMBIOS_PHYSICAL_END, + .load_roms = 1, + .optionrom_start = OPTIONROM_PHYSICAL_ADDRESS, .optionrom_end = OPTIONROM_PHYSICAL_END, diff -r cdc873250db2 -r 253a38db096b tools/firmware/hvmloader/seabios.c --- a/tools/firmware/hvmloader/seabios.c Tue May 31 17:31:28 2011 +0100 +++ b/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:17:55 2011 +0100 @@ -46,8 +46,10 @@ struct bios_config seabios_config = { .smbios_start = 0, .smbios_end = 0, - .optionrom_start = OPTIONROM_PHYSICAL_ADDRESS, - .optionrom_end = OPTIONROM_PHYSICAL_END, + .load_roms = 0, + + .optionrom_start = 0, + .optionrom_end = 0, .acpi_start = 0, _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:39 UTC
[Xen-devel] [PATCH 02 of 15] hvmloader: enable PCI_COMMAND_IO on primary VGA device
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306916791 -3600 # Node ID 062bc0a35d9933cc64c11f861609559e11994778 # Parent 253a38db096bdc72b4e266ed103643210a739d93 hvmloader: enable PCI_COMMAND_IO on primary VGA device There is an implicit assumption in the PCI spec that the primary VGA device (e.g. something with class==VGA) will have I/O enabled in order to make the standard VGA I/O registers (e.g. at 0x3xx) available, even though the device has no explicit I/O BARS. The qemu device model for the Cirrus VGA card does not actually enforce this but SeaBIOS looks for a VGA device with I/O enabled before running the VGA ROM. Coreboot has similar behaviour and I verified on a physical Cirrus GD 5446 that the BIOS had enable I/O cycles. The thread at http://www.seabios.org/pipermail/seabios/2011-May/001804.html contains more info. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 253a38db096b -r 062bc0a35d99 tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:17:55 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:26:31 2011 +0100 @@ -102,6 +102,7 @@ static void rombios_apic_setup(void) static void rombios_pci_setup(void) { uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0; + uint32_t vga_devfn = 256; uint16_t class, vendor_id, device_id; unsigned int bar, pin, link, isa_irq; @@ -146,6 +147,8 @@ static void rombios_pci_setup(void) { case 0x0300: /* If emulated VGA is found, preserve it as primary VGA. */ + if ( virtual_vga == VGA_none ) + vga_devfn = devfn; if ( (vendor_id == 0x1234) && (device_id == 0x1111) ) virtual_vga = VGA_std; else if ( (vendor_id == 0x1013) && (device_id == 0xb8) ) @@ -307,6 +310,18 @@ static void rombios_pci_setup(void) cmd |= PCI_COMMAND_IO; pci_writew(devfn, PCI_COMMAND, cmd); } + + if ( vga_devfn != 256 ) + { + /* + * VGA registers live in I/O space so ensure that primary VGA + * has IO enabled, even if there is no I/O BAR on that + * particular device. + */ + cmd = pci_readw(vga_devfn, PCI_COMMAND); + cmd |= PCI_COMMAND_IO; + pci_writew(vga_devfn, PCI_COMMAND, cmd); + } } /* _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:39 UTC
[Xen-devel] [PATCH 03 of 15] hvmloader: setup PCI bus in a common function again
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306916881 -3600 # Node ID 8a7fb25fff1980aa4fcf963da1aa82d4dfd34bda # Parent 062bc0a35d9933cc64c11f861609559e11994778 hvmloader: setup PCI bus in a common function again. Previous refactoring was premature. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 062bc0a35d99 -r 8a7fb25fff19 tools/firmware/hvmloader/Makefile --- a/tools/firmware/hvmloader/Makefile Wed Jun 01 09:26:31 2011 +0100 +++ b/tools/firmware/hvmloader/Makefile Wed Jun 01 09:28:01 2011 +0100 @@ -30,7 +30,7 @@ CFLAGS += $(CFLAGS_xeninclude) OBJS = hvmloader.o mp_tables.o util.o smbios.o OBJS += 32bitbios_support.o smp.o cacheattr.o xenbus.o -OBJS += e820.o +OBJS += e820.o pci.o ifeq ($(debug),y) OBJS += tests.o endif diff -r 062bc0a35d99 -r 8a7fb25fff19 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Jun 01 09:26:31 2011 +0100 +++ b/tools/firmware/hvmloader/config.h Wed Jun 01 09:28:01 2011 +0100 @@ -3,7 +3,7 @@ #include <stdint.h> -enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt } virtual_vga; +enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt }; extern enum virtual_vga virtual_vga; struct bios_config { @@ -27,7 +27,6 @@ struct bios_config { unsigned int acpi_start; void (*apic_setup)(void); - void (*pci_setup)(void); void (*smp_setup)(void); uint32_t (*bios_high_setup)(void); diff -r 062bc0a35d99 -r 8a7fb25fff19 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:26:31 2011 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:28:01 2011 +0100 @@ -109,11 +109,6 @@ asm ( " .text \n" ); -unsigned long pci_mem_start = PCI_MEM_START; -unsigned long pci_mem_end = PCI_MEM_END; - -enum virtual_vga virtual_vga = VGA_none; - static void init_hypercalls(void) { uint32_t eax, ebx, ecx, edx; @@ -391,8 +386,7 @@ int main(void) if (bios->apic_setup) bios->apic_setup(); - if (bios->pci_setup) - bios->pci_setup(); + pci_setup(); if (bios->smp_setup) bios->smp_setup(); diff -r 062bc0a35d99 -r 8a7fb25fff19 tools/firmware/hvmloader/pci.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/firmware/hvmloader/pci.c Wed Jun 01 09:28:01 2011 +0100 @@ -0,0 +1,260 @@ +/* + * pci.c: HVM PCI setup. + * + * Leendert van Doorn, leendert@watson.ibm.com + * Copyright (c) 2005, International Business Machines Corporation. + * + * Copyright (c) 2006, Keir Fraser, XenSource Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "util.h" +#include "hypercall.h" +#include "config.h" +#include "pci_regs.h" + +#include <xen/memory.h> +#include <xen/hvm/ioreq.h> + +unsigned long pci_mem_start = PCI_MEM_START; +unsigned long pci_mem_end = PCI_MEM_END; + +enum virtual_vga virtual_vga = VGA_none; + +void pci_setup(void) +{ + uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0; + uint32_t vga_devfn = 256; + 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 ( virtual_vga == VGA_none ) + vga_devfn = devfn; + 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); + } + + if ( vga_devfn != 256 ) + { + /* + * VGA registers live in I/O space so ensure that primary VGA + * has IO enabled, even if there is no I/O BAR on that + * particular device. + */ + cmd = pci_readw(vga_devfn, PCI_COMMAND); + cmd |= PCI_COMMAND_IO; + pci_writew(vga_devfn, PCI_COMMAND, cmd); + } +} + diff -r 062bc0a35d99 -r 8a7fb25fff19 tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:26:31 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:28:01 2011 +0100 @@ -31,8 +31,6 @@ #include "hypercall.h" #include <xen/hvm/params.h> -#include <xen/hvm/ioreq.h> -#include <xen/memory.h> #define ROM_INCLUDE_ROMBIOS #include "roms.inc" @@ -99,231 +97,6 @@ static void rombios_apic_setup(void) 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; - uint32_t vga_devfn = 256; - 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 ( virtual_vga == VGA_none ) - vga_devfn = devfn; - 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); - } - - if ( vga_devfn != 256 ) - { - /* - * VGA registers live in I/O space so ensure that primary VGA - * has IO enabled, even if there is no I/O BAR on that - * particular device. - */ - cmd = pci_readw(vga_devfn, PCI_COMMAND); - cmd |= PCI_COMMAND_IO; - pci_writew(vga_devfn, PCI_COMMAND, cmd); - } -} - /* * find_mp_table_start - searchs through BIOS memory for ''___HVMMP'' signature * @@ -395,7 +168,6 @@ struct bios_config rombios_config = { .acpi_start = ACPI_PHYSICAL_ADDRESS, .apic_setup = rombios_apic_setup, - .pci_setup = rombios_pci_setup, .smp_setup = smp_initialise, .bios_high_setup = rombios_highbios_setup, diff -r 062bc0a35d99 -r 8a7fb25fff19 tools/firmware/hvmloader/seabios.c --- a/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:26:31 2011 +0100 +++ b/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:28:01 2011 +0100 @@ -28,11 +28,6 @@ #define ROM_INCLUDE_SEABIOS #include "roms.inc" -static void seabios_pci_setup(void) -{ - virtual_vga = VGA_cirrus; -} - //BUILD_BUG_ON(sizeof(seabios) > (0x00100000U - SEABIOS_PHYSICAL_ADDRESS)); struct bios_config seabios_config = { @@ -56,7 +51,6 @@ struct bios_config seabios_config = { .bios_info_setup = NULL, .apic_setup = NULL, - .pci_setup = seabios_pci_setup, .smp_setup = NULL, .vm86_setup = NULL, diff -r 062bc0a35d99 -r 8a7fb25fff19 tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Wed Jun 01 09:26:31 2011 +0100 +++ b/tools/firmware/hvmloader/util.h Wed Jun 01 09:28:01 2011 +0100 @@ -180,6 +180,9 @@ void xenbus_shutdown(void); * static buffer, so only valid until the next xenstore/xenbus operation. */ char *xenstore_read(char *path); +/* Setup PCI bus */ +void pci_setup(void); + /* Prepare the 32bit BIOS */ uint32_t rombios_highbios_setup(void); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:39 UTC
[Xen-devel] [PATCH 04 of 15] hvmloader: setup APICs in a common function again
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306916889 -3600 # Node ID b76a45b26b062be8f376271b039698ef566ffab2 # Parent 8a7fb25fff1980aa4fcf963da1aa82d4dfd34bda hvmloader: setup APICs in a common function again. Previous refactoring was premature. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 8a7fb25fff19 -r b76a45b26b06 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Jun 01 09:28:01 2011 +0100 +++ b/tools/firmware/hvmloader/config.h Wed Jun 01 09:28:09 2011 +0100 @@ -26,7 +26,6 @@ struct bios_config { /* ACPI tables */ unsigned int acpi_start; - void (*apic_setup)(void); void (*smp_setup)(void); uint32_t (*bios_high_setup)(void); diff -r 8a7fb25fff19 -r b76a45b26b06 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:28:01 2011 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:28:09 2011 +0100 @@ -25,6 +25,7 @@ #include "config.h" #include "pci_regs.h" #include "option_rom.h" +#include "apic_regs.h" #include <xen/version.h> #include <xen/hvm/params.h> @@ -332,6 +333,21 @@ static void cmos_write_memory_size(void) cmos_outb(0x35, (uint8_t)( alt_mem >> 8)); } +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))); +} + struct bios_info { const char *key; const struct bios_config *bios; @@ -384,8 +400,7 @@ int main(void) printf("CPU speed is %u MHz\n", get_cpu_mhz()); - if (bios->apic_setup) - bios->apic_setup(); + apic_setup(); pci_setup(); if (bios->smp_setup) diff -r 8a7fb25fff19 -r b76a45b26b06 tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:28:01 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:28:09 2011 +0100 @@ -25,7 +25,6 @@ #include "../rombios/config.h" #include "acpi/acpi2_0.h" -#include "apic_regs.h" #include "pci_regs.h" #include "util.h" #include "hypercall.h" @@ -82,21 +81,6 @@ static void rombios_setup_bios_info(uint bios_info->bios32_entry = bioshigh; } -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))); -} - /* * find_mp_table_start - searchs through BIOS memory for ''___HVMMP'' signature * @@ -167,7 +151,6 @@ struct bios_config rombios_config = { .acpi_start = ACPI_PHYSICAL_ADDRESS, - .apic_setup = rombios_apic_setup, .smp_setup = smp_initialise, .bios_high_setup = rombios_highbios_setup, diff -r 8a7fb25fff19 -r b76a45b26b06 tools/firmware/hvmloader/seabios.c --- a/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:28:01 2011 +0100 +++ b/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:28:09 2011 +0100 @@ -50,7 +50,6 @@ struct bios_config seabios_config = { .bios_info_setup = NULL, - .apic_setup = NULL, .smp_setup = NULL, .vm86_setup = NULL, _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:40 UTC
[Xen-devel] [PATCH 05 of 15] hvmloader: call SMP setup from common code again
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306916902 -3600 # Node ID ecc58aeac569ad6defd47cc068eb93df143a0b5c # Parent b76a45b26b062be8f376271b039698ef566ffab2 hvmloader: call SMP setup from common code again. Previous refactoring was premature. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r b76a45b26b06 -r ecc58aeac569 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Jun 01 09:28:09 2011 +0100 +++ b/tools/firmware/hvmloader/config.h Wed Jun 01 09:28:22 2011 +0100 @@ -26,8 +26,6 @@ struct bios_config { /* ACPI tables */ unsigned int acpi_start; - void (*smp_setup)(void); - uint32_t (*bios_high_setup)(void); void (*bios_info_setup)(uint32_t); diff -r b76a45b26b06 -r ecc58aeac569 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:28:09 2011 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:28:22 2011 +0100 @@ -403,8 +403,7 @@ int main(void) apic_setup(); pci_setup(); - if (bios->smp_setup) - bios->smp_setup(); + smp_initialise(); perform_tests(); diff -r b76a45b26b06 -r ecc58aeac569 tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:28:09 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:28:22 2011 +0100 @@ -151,8 +151,6 @@ struct bios_config rombios_config = { .acpi_start = ACPI_PHYSICAL_ADDRESS, - .smp_setup = smp_initialise, - .bios_high_setup = rombios_highbios_setup, .bios_info_setup = rombios_setup_bios_info, diff -r b76a45b26b06 -r ecc58aeac569 tools/firmware/hvmloader/seabios.c --- a/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:28:09 2011 +0100 +++ b/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:28:22 2011 +0100 @@ -50,8 +50,6 @@ struct bios_config seabios_config = { .bios_info_setup = NULL, - .smp_setup = NULL, - .vm86_setup = NULL, .e820_setup = NULL, _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:40 UTC
[Xen-devel] [PATCH 06 of 15] hvmloader: make ACPI initialisation hook more general
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306916909 -3600 # Node ID 4d9116ca460ed18d23f2c04c28ea2b5a67586830 # Parent ecc58aeac569ad6defd47cc068eb93df143a0b5c hvmloader: make ACPI initialisation hook more general. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r ecc58aeac569 -r 4d9116ca460e tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Jun 01 09:28:22 2011 +0100 +++ b/tools/firmware/hvmloader/config.h Wed Jun 01 09:28:29 2011 +0100 @@ -23,16 +23,13 @@ struct bios_config { int load_roms; unsigned int optionrom_start, optionrom_end; - /* ACPI tables */ - unsigned int acpi_start; - uint32_t (*bios_high_setup)(void); void (*bios_info_setup)(uint32_t); void (*vm86_setup)(void); void (*e820_setup)(void); - void (*acpi_build_tables)(unsigned int physical); + void (*acpi_build_tables)(void); void (*create_mp_tables)(void); }; diff -r ecc58aeac569 -r 4d9116ca460e tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:28:22 2011 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:28:29 2011 +0100 @@ -472,7 +472,7 @@ int main(void) if ( bios->acpi_build_tables ) { printf("Loading ACPI ...\n"); - bios->acpi_build_tables(bios->acpi_start); + bios->acpi_build_tables(); } hypercall_hvm_op(HVMOP_set_param, &p); } diff -r ecc58aeac569 -r 4d9116ca460e tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:28:22 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:28:29 2011 +0100 @@ -115,6 +115,11 @@ static void reset_bios_checksum(void) *((uint8_t *)(ROMBIOS_BEGIN + ROMBIOS_MAXOFFSET)) = -checksum; } +static void rombios_acpi_build_tables(void) +{ + acpi_build_tables(ACPI_PHYSICAL_ADDRESS); +} + static void rombios_create_mp_tables(void) { /* Find the ''safe'' place in ROMBIOS for the MP tables. */ @@ -149,15 +154,13 @@ struct bios_config rombios_config = { .optionrom_start = OPTIONROM_PHYSICAL_ADDRESS, .optionrom_end = OPTIONROM_PHYSICAL_END, - .acpi_start = ACPI_PHYSICAL_ADDRESS, - .bios_high_setup = rombios_highbios_setup, .bios_info_setup = rombios_setup_bios_info, .vm86_setup = rombios_init_vm86_tss, .e820_setup = rombios_setup_e820, - .acpi_build_tables = acpi_build_tables, + .acpi_build_tables = rombios_acpi_build_tables, .create_mp_tables = rombios_create_mp_tables, }; diff -r ecc58aeac569 -r 4d9116ca460e tools/firmware/hvmloader/seabios.c --- a/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:28:22 2011 +0100 +++ b/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:28:29 2011 +0100 @@ -46,8 +46,6 @@ struct bios_config seabios_config = { .optionrom_start = 0, .optionrom_end = 0, - .acpi_start = 0, - .bios_info_setup = NULL, .vm86_setup = NULL, _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:40 UTC
[Xen-devel] [PATCH 07 of 15] hvmloader: make SMBIOS initialisation more general
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306917341 -3600 # Node ID 673d9039cd5972d496fa1dbdb2b783a6696c3fbb # Parent 4d9116ca460ed18d23f2c04c28ea2b5a67586830 hvmloader: make SMBIOS initialisation more general. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 4d9116ca460e -r 673d9039cd59 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Jun 01 09:28:29 2011 +0100 +++ b/tools/firmware/hvmloader/config.h Wed Jun 01 09:35:41 2011 +0100 @@ -16,9 +16,6 @@ struct bios_config { /* Physical address to load at */ unsigned int bios_address; - /* SMBIOS */ - unsigned int smbios_start, smbios_end; - /* ROMS */ int load_roms; unsigned int optionrom_start, optionrom_end; @@ -31,6 +28,7 @@ struct bios_config { void (*acpi_build_tables)(void); void (*create_mp_tables)(void); + void (*create_smbios_tables)(void); }; extern struct bios_config rombios_config; diff -r 4d9116ca460e -r 673d9039cd59 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:28:29 2011 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:35:41 2011 +0100 @@ -383,7 +383,7 @@ int main(void) { uint32_t highbios = 0; const struct bios_config *bios; - int option_rom_sz = 0, vgabios_sz = 0, etherboot_sz = 0, smbios_sz = 0; + int option_rom_sz = 0, vgabios_sz = 0, etherboot_sz = 0; uint32_t etherboot_phys_addr = 0, option_rom_phys_addr = 0; /* Initialise hypercall stubs with RET, rendering them no-ops. */ @@ -407,11 +407,9 @@ int main(void) perform_tests(); - if (bios->smbios_start) { + if (bios->create_smbios_tables) { printf("Writing SMBIOS tables ...\n"); - smbios_sz = hvm_write_smbios_tables(SCRATCH_PHYSICAL_ADDRESS, - bios->smbios_start, - bios->smbios_end); + bios->create_smbios_tables(); } printf("Loading %s ...\n", bios->name); @@ -495,10 +493,6 @@ int main(void) printf(" %05x-%05x: PCI Option ROMs\n", option_rom_phys_addr, option_rom_phys_addr + option_rom_sz - 1); - if ( smbios_sz ) - printf(" %05x-%05x: SMBIOS tables\n", - bios->smbios_start, - bios->smbios_start + smbios_sz - 1); printf(" %05x-%05x: Main BIOS\n", bios->bios_address, bios->bios_address + bios->image_size - 1); diff -r 4d9116ca460e -r 673d9039cd59 tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:28:29 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:35:41 2011 +0100 @@ -136,6 +136,13 @@ static void rombios_create_mp_tables(voi reset_bios_checksum(); } +static void rombios_create_smbios_tables(void) +{ + hvm_write_smbios_tables(SCRATCH_PHYSICAL_ADDRESS, + SMBIOS_PHYSICAL_ADDRESS, + SMBIOS_PHYSICAL_END); +} + //BUILD_BUG_ON(sizeof(rombios) > (0x00100000U - ROMBIOS_PHYSICAL_ADDRESS)); struct bios_config rombios_config = { @@ -146,9 +153,6 @@ struct bios_config rombios_config = { .bios_address = ROMBIOS_PHYSICAL_ADDRESS, - .smbios_start = SMBIOS_PHYSICAL_ADDRESS, - .smbios_end = SMBIOS_PHYSICAL_END, - .load_roms = 1, .optionrom_start = OPTIONROM_PHYSICAL_ADDRESS, @@ -162,6 +166,7 @@ struct bios_config rombios_config = { .acpi_build_tables = rombios_acpi_build_tables, .create_mp_tables = rombios_create_mp_tables, + .create_smbios_tables = rombios_create_smbios_tables, }; /* diff -r 4d9116ca460e -r 673d9039cd59 tools/firmware/hvmloader/seabios.c --- a/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:28:29 2011 +0100 +++ b/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:35:41 2011 +0100 @@ -38,9 +38,6 @@ struct bios_config seabios_config = { .bios_address = SEABIOS_PHYSICAL_ADDRESS, - .smbios_start = 0, - .smbios_end = 0, - .load_roms = 0, .optionrom_start = 0, @@ -53,6 +50,7 @@ struct bios_config seabios_config = { .acpi_build_tables = NULL, .create_mp_tables = NULL, + .create_smbios_tables = NULL, }; /* _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:40 UTC
[Xen-devel] [PATCH 08 of 15] hvmloader: Add a simple "scratch allocator"
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306917394 -3600 # Node ID 3c920f4ec4f24e1c134749972d5762aa009ee3dc # Parent 673d9039cd5972d496fa1dbdb2b783a6696c3fbb hvmloader: Add a simple "scratch allocator" Returns memory which is passed to the subsequent BIOS but can be reused once the contents is consumed. An example of this would be a BIOS table which the BIOS consumes by copying rather than simply referencing. Users which need a temporary scratch buffer for internal use scratch_start which follows these allocations. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 673d9039cd59 -r 3c920f4ec4f2 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Jun 01 09:35:41 2011 +0100 +++ b/tools/firmware/hvmloader/config.h Wed Jun 01 09:36:34 2011 +0100 @@ -62,6 +62,8 @@ extern unsigned long pci_mem_start, pci_ #define VGABIOS_PHYSICAL_ADDRESS 0x000C0000 #define HVMLOADER_PHYSICAL_ADDRESS 0x00100000 +extern unsigned long scratch_start; + #endif /* __HVMLOADER_CONFIG_H__ */ /* diff -r 673d9039cd59 -r 3c920f4ec4f2 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:35:41 2011 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:36:34 2011 +0100 @@ -110,6 +110,8 @@ asm ( " .text \n" ); +unsigned long scratch_start = SCRATCH_PHYSICAL_ADDRESS; + static void init_hypercalls(void) { uint32_t eax, ebx, ecx, edx; @@ -481,6 +483,9 @@ int main(void) cmos_write_memory_size(); printf("BIOS map:\n"); + if ( SCRATCH_PHYSICAL_ADDRESS != scratch_start ) + printf(" %05x-%05lx: Scratch space\n", + SCRATCH_PHYSICAL_ADDRESS, scratch_start); if ( vgabios_sz ) printf(" %05x-%05x: VGA BIOS\n", VGABIOS_PHYSICAL_ADDRESS, diff -r 673d9039cd59 -r 3c920f4ec4f2 tools/firmware/hvmloader/pci.c --- a/tools/firmware/hvmloader/pci.c Wed Jun 01 09:35:41 2011 +0100 +++ b/tools/firmware/hvmloader/pci.c Wed Jun 01 09:36:34 2011 +0100 @@ -48,7 +48,7 @@ void pci_setup(void) /* 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; + } *bars = (struct bars *)scratch_start; unsigned int i, nr_bars = 0; /* Program PCI-ISA bridge with appropriate link routes. */ diff -r 673d9039cd59 -r 3c920f4ec4f2 tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:35:41 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:36:34 2011 +0100 @@ -138,7 +138,7 @@ static void rombios_create_mp_tables(voi static void rombios_create_smbios_tables(void) { - hvm_write_smbios_tables(SCRATCH_PHYSICAL_ADDRESS, + hvm_write_smbios_tables(scratch_start, SMBIOS_PHYSICAL_ADDRESS, SMBIOS_PHYSICAL_END); } diff -r 673d9039cd59 -r 3c920f4ec4f2 tools/firmware/hvmloader/util.c --- a/tools/firmware/hvmloader/util.c Wed Jun 01 09:35:41 2011 +0100 +++ b/tools/firmware/hvmloader/util.c Wed Jun 01 09:36:34 2011 +0100 @@ -362,6 +362,24 @@ void *mem_alloc(uint32_t size, uint32_t return (void *)(unsigned long)s; } +void *scratch_alloc(uint32_t size, uint32_t align) +{ + uint32_t s, e; + + /* Align to at least one kilobyte. */ + if ( align < 1024 ) + align = 1024; + + s = (scratch_start + align - 1) & ~(align - 1); + e = s + size - 1; + + BUG_ON(e < s); + + scratch_start = e; + + return (void *)(unsigned long)s; +} + uint32_t ioapic_read(uint32_t reg) { *(volatile uint32_t *)(IOAPIC_BASE_ADDRESS + 0x00) = reg; diff -r 673d9039cd59 -r 3c920f4ec4f2 tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Wed Jun 01 09:35:41 2011 +0100 +++ b/tools/firmware/hvmloader/util.h Wed Jun 01 09:36:34 2011 +0100 @@ -168,6 +168,9 @@ int vprintf(const char *fmt, va_list ap) void *mem_alloc(uint32_t size, uint32_t align); #define virt_to_phys(v) ((unsigned long)(v)) +/* Allocate memory in a scratch region */ +void *scratch_alloc(uint32_t size, uint32_t align); + /* Connect our xenbus client to the backend. * Call once, before any other xenbus actions. */ void xenbus_setup(void); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:40 UTC
[Xen-devel] [PATCH 09 of 15] hvmloader: refactor BIOS info setup
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306917395 -3600 # Node ID 99820702549e428fd961b160afa1dae75bc7010d # Parent 3c920f4ec4f24e1c134749972d5762aa009ee3dc hvmloader: refactor BIOS info setup Currently we have ->bios_high_setup, which is called relatively early and returns a cookie which is passed to ->bios_info_setup which runs towards the end and creates the BIOS info, incorporating the cookie which (in the case of ROMBIOS) happens to be the BIOS''s high load address . This is rather ROMBIOS specific. Refactor to have ->bios_info_setup which is called early and prepares the bios_info, ->bios_relocate which does any necessary relocation (updating the BIOS info as necessary) and ->bios_info_finish which finalises the info (e.g. by calculating the checksum). Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 3c920f4ec4f2 -r 99820702549e tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Jun 01 09:36:34 2011 +0100 +++ b/tools/firmware/hvmloader/config.h Wed Jun 01 09:36:35 2011 +0100 @@ -20,8 +20,10 @@ struct bios_config { int load_roms; unsigned int optionrom_start, optionrom_end; - uint32_t (*bios_high_setup)(void); - void (*bios_info_setup)(uint32_t); + void (*bios_info_setup)(void); + void (*bios_info_finish)(void); + + void (*bios_relocate)(void); void (*vm86_setup)(void); void (*e820_setup)(void); diff -r 3c920f4ec4f2 -r 99820702549e tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:36:34 2011 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:36:35 2011 +0100 @@ -383,7 +383,6 @@ static const struct bios_config *detect_ int main(void) { - uint32_t highbios = 0; const struct bios_config *bios; int option_rom_sz = 0, vgabios_sz = 0, etherboot_sz = 0; uint32_t etherboot_phys_addr = 0, option_rom_phys_addr = 0; @@ -409,6 +408,9 @@ int main(void) perform_tests(); + if (bios->bios_info_setup) + bios->bios_info_setup(); + if (bios->create_smbios_tables) { printf("Writing SMBIOS tables ...\n"); bios->create_smbios_tables(); @@ -418,8 +420,8 @@ int main(void) memcpy((void *)bios->bios_address, bios->image, bios->image_size); - if (bios->bios_high_setup) - highbios = bios->bios_high_setup(); + if (bios->bios_relocate) + bios->bios_relocate(); if ( bios->create_mp_tables && ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode ) ) @@ -505,8 +507,8 @@ int main(void) if (bios->e820_setup) bios->e820_setup(); - if (bios->bios_info_setup) - bios->bios_info_setup(highbios); + if (bios->bios_info_finish) + bios->bios_info_finish(); xenbus_shutdown(); diff -r 3c920f4ec4f2 -r 99820702549e tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:36:34 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:36:35 2011 +0100 @@ -64,7 +64,7 @@ static void rombios_setup_e820(void) dump_e820_table(E820, *E820_NR); } -static void rombios_setup_bios_info(uint32_t bioshigh) +static void rombios_setup_bios_info(void) { struct bios_info *bios_info; @@ -74,11 +74,28 @@ static void rombios_setup_bios_info(uint bios_info->com2_present = uart_exists(0x2f8); bios_info->lpt1_present = lpt_exists(0x378); bios_info->hpet_present = hpet_exists(ACPI_HPET_ADDRESS); + bios_info->madt_csum_addr = madt_csum_addr; + bios_info->madt_lapic0_addr = madt_lapic0_addr; +} + +static void rombios_relocate(void) +{ + uint32_t bioshigh; + struct bios_info *bios_info; + + bioshigh = rombios_highbios_setup(); + + bios_info = (struct bios_info *)BIOS_INFO_PHYSICAL_ADDRESS; + bios_info->bios32_entry = bioshigh; +} + +static void rombios_finish_bios_info(void) +{ + struct bios_info *bios_info; + + bios_info = (struct bios_info *)BIOS_INFO_PHYSICAL_ADDRESS; bios_info->pci_min = pci_mem_start; bios_info->pci_len = pci_mem_end - pci_mem_start; - bios_info->madt_csum_addr = madt_csum_addr; - bios_info->madt_lapic0_addr = madt_lapic0_addr; - bios_info->bios32_entry = bioshigh; } /* @@ -158,8 +175,10 @@ struct bios_config rombios_config = { .optionrom_start = OPTIONROM_PHYSICAL_ADDRESS, .optionrom_end = OPTIONROM_PHYSICAL_END, - .bios_high_setup = rombios_highbios_setup, .bios_info_setup = rombios_setup_bios_info, + .bios_info_finish = rombios_finish_bios_info, + + .bios_relocate = rombios_relocate, .vm86_setup = rombios_init_vm86_tss, .e820_setup = rombios_setup_e820, diff -r 3c920f4ec4f2 -r 99820702549e tools/firmware/hvmloader/seabios.c --- a/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:36:34 2011 +0100 +++ b/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:36:35 2011 +0100 @@ -44,6 +44,9 @@ struct bios_config seabios_config = { .optionrom_end = 0, .bios_info_setup = NULL, + .bios_info_finish = NULL, + + .bios_relocate = NULL, .vm86_setup = NULL, .e820_setup = NULL, _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:40 UTC
[Xen-devel] [PATCH 10 of 15] hvmloader: return MPFPS from create_mp_tables()
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306917433 -3600 # Node ID 361304106d85f61cdeffd5805c46520feac19e89 # Parent 99820702549e428fd961b160afa1dae75bc7010d hvmloader: return MPFPS from create_mp_tables() This is the hook which the mptables hang off, so it is useful to know. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 99820702549e -r 361304106d85 tools/firmware/hvmloader/mp_tables.c --- a/tools/firmware/hvmloader/mp_tables.c Wed Jun 01 09:36:35 2011 +0100 +++ b/tools/firmware/hvmloader/mp_tables.c Wed Jun 01 09:37:13 2011 +0100 @@ -260,17 +260,21 @@ static void fill_mpfps(struct mp_floatin } /* create_mp_tables - creates MP tables for the guest based upon config data */ -void create_mp_tables(void *mp_table_base) +unsigned long create_mp_tables(void *_mpfps) { char *p; int vcpu_nr, i, length; + void *base; struct mp_io_intr_entry *mpiie; + struct mp_floating_pointer_struct *mpfps = _mpfps; vcpu_nr = hvm_info->nr_vcpus; printf("Creating MP tables ...\n"); - p = mp_table_base + sizeof(struct mp_config_table); + base = &mpfps[1]; + + p = base + sizeof(struct mp_config_table); for ( i = 0; i < vcpu_nr; i++ ) { @@ -308,14 +312,11 @@ void create_mp_tables(void *mp_table_bas p += sizeof(*mpiie); } - length = p - (char *)mp_table_base; + length = p - (char *)base; - /* find the next 16-byte boundary to place the mp floating pointer */ - while ( (unsigned long)p & 0xF ) - p++; + fill_mp_config_table((struct mp_config_table *)base, length); - fill_mpfps((struct mp_floating_pointer_struct *)p, - (uint32_t)mp_table_base); + fill_mpfps(mpfps, (uint32_t)base); - fill_mp_config_table((struct mp_config_table *)mp_table_base, length); + return (unsigned long)mpfps; } diff -r 99820702549e -r 361304106d85 tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Wed Jun 01 09:36:35 2011 +0100 +++ b/tools/firmware/hvmloader/util.h Wed Jun 01 09:37:13 2011 +0100 @@ -191,7 +191,7 @@ uint32_t rombios_highbios_setup(void); /* Miscellaneous. */ void cacheattr_init(void); -void create_mp_tables(void *table); +unsigned long create_mp_tables(void *table); int hvm_write_smbios_tables(unsigned long scratch, unsigned long smbios_start, unsigned long smbios_end); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:40 UTC
[Xen-devel] [PATCH 11 of 15] hvmloader: allow create_mp_tables() to allocate the table
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306917709 -3600 # Node ID 5357077295f21154b076925d1d4687b076de6bfc # Parent 361304106d85f61cdeffd5805c46520feac19e89 hvmloader: allow create_mp_tables() to allocate the table Will be used by SeaBIOS. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 361304106d85 -r 5357077295f2 tools/firmware/hvmloader/mp_tables.c --- a/tools/firmware/hvmloader/mp_tables.c Wed Jun 01 09:37:13 2011 +0100 +++ b/tools/firmware/hvmloader/mp_tables.c Wed Jun 01 09:41:49 2011 +0100 @@ -266,12 +266,27 @@ unsigned long create_mp_tables(void *_mp int vcpu_nr, i, length; void *base; struct mp_io_intr_entry *mpiie; - struct mp_floating_pointer_struct *mpfps = _mpfps; + struct mp_floating_pointer_struct *mpfps; vcpu_nr = hvm_info->nr_vcpus; printf("Creating MP tables ...\n"); + if (!_mpfps) { + int sz; + + sz = sizeof(struct mp_floating_pointer_struct); + sz += sizeof(struct mp_config_table); + sz += sizeof(struct mp_proc_entry) * vcpu_nr; + sz += sizeof(struct mp_bus_entry); + sz += sizeof(struct mp_ioapic_entry); + sz += sizeof(struct mp_io_intr_entry) * 16; + + base = mem_alloc(sz, 0); + } + + mpfps = _mpfps; + base = &mpfps[1]; p = base + sizeof(struct mp_config_table); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:40 UTC
[Xen-devel] [PATCH 12 of 15] hvmloader: smbios: allow the entry point data structure to be located separately
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306917734 -3600 # Node ID 644a9208e3bb34e533ffeaf7001c48355e05a084 # Parent 5357077295f21154b076925d1d4687b076de6bfc hvmloader: smbios: allow the entry point data structure to be located separately. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 5357077295f2 -r 644a9208e3bb tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:41:49 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:42:14 2011 +0100 @@ -24,6 +24,7 @@ #include "../rombios/config.h" +#include "smbios_types.h" #include "acpi/acpi2_0.h" #include "pci_regs.h" #include "util.h" @@ -155,8 +156,8 @@ static void rombios_create_mp_tables(voi static void rombios_create_smbios_tables(void) { - hvm_write_smbios_tables(scratch_start, - SMBIOS_PHYSICAL_ADDRESS, + hvm_write_smbios_tables(SMBIOS_PHYSICAL_ADDRESS, + SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point), SMBIOS_PHYSICAL_END); } diff -r 5357077295f2 -r 644a9208e3bb tools/firmware/hvmloader/smbios.c --- a/tools/firmware/hvmloader/smbios.c Wed Jun 01 09:41:49 2011 +0100 +++ b/tools/firmware/hvmloader/smbios.c Wed Jun 01 09:42:14 2011 +0100 @@ -28,7 +28,7 @@ #include "hypercall.h" static int -write_smbios_tables(void *start, unsigned long phys, +write_smbios_tables(void *ep, void *start, unsigned long phys, uint32_t vcpus, uint64_t memsize, uint8_t uuid[16], char *xen_version, uint32_t xen_major_version, uint32_t xen_minor_version); @@ -85,7 +85,7 @@ get_cpu_manufacturer(char *buf, int len) } static int -write_smbios_tables(void *start, unsigned long phys, +write_smbios_tables(void *ep, void *start, unsigned long phys, uint32_t vcpus, uint64_t memsize, uint8_t uuid[16], char *xen_version, uint32_t xen_major_version, uint32_t xen_minor_version) @@ -97,7 +97,7 @@ write_smbios_tables(void *start, unsigne get_cpu_manufacturer(cpu_manufacturer, 15); - p = (char *)start + sizeof(struct smbios_entry_point); + p = (char *)start; #define do_struct(fn) do { \ q = (fn); \ @@ -133,11 +133,9 @@ write_smbios_tables(void *start, unsigne #undef do_struct - smbios_entry_point_init( - start, max_struct_size, - (p - (char *)start) - sizeof(struct smbios_entry_point), - phys + sizeof(struct smbios_entry_point), - nr_structs); + smbios_entry_point_init(ep, max_struct_size, + (p - (char *)start), phys, + nr_structs); return ((char *)p - (char *)start); } @@ -162,7 +160,7 @@ get_memsize(void) } int -hvm_write_smbios_tables(unsigned long scratch, unsigned long smbios_start, unsigned long smbios_end) +hvm_write_smbios_tables(unsigned long ep, unsigned long smbios_start, unsigned long smbios_end) { xen_domain_handle_t uuid; uint16_t xen_major_version, xen_minor_version; @@ -221,15 +219,15 @@ hvm_write_smbios_tables(unsigned long sc xen_version_str[sizeof(xen_version_str)-1] = ''\0''; - /* SCRATCH_PHYSICAL_ADDRESS is a safe large memory area for scratch. */ - len = write_smbios_tables((void *)scratch, smbios_start, + /* scratch_start is a safe large memory area for scratch. */ + len = write_smbios_tables((void *)ep, (void *)scratch_start, smbios_start, hvm_info->nr_vcpus, get_memsize(), uuid, xen_version_str, xen_major_version, xen_minor_version); if ( smbios_start + len > smbios_end ) goto error_out; /* Okay, not too large: copy out of scratch to final location. */ - memcpy((void *)smbios_start, (void *)scratch, len); + memcpy((void *)smbios_start, (void *)scratch_start, len); return len; diff -r 5357077295f2 -r 644a9208e3bb tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Wed Jun 01 09:41:49 2011 +0100 +++ b/tools/firmware/hvmloader/util.h Wed Jun 01 09:42:14 2011 +0100 @@ -192,7 +192,7 @@ uint32_t rombios_highbios_setup(void); /* Miscellaneous. */ void cacheattr_init(void); unsigned long create_mp_tables(void *table); -int hvm_write_smbios_tables(unsigned long scratch, +int hvm_write_smbios_tables(unsigned long ep, unsigned long smbios_start, unsigned long smbios_end); void smp_initialise(void); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:40 UTC
[Xen-devel] [PATCH 13 of 15] hvmloader: further support for SeaBIOS
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306917958 -3600 # Node ID 5d695cfaded597bb9e70818a9225bde3a91d3355 # Parent 644a9208e3bb34e533ffeaf7001c48355e05a084 hvmloader: further support for SeaBIOS Build the various BIOS tables and arrange for them to be passed to SeaBIOS. We define a simple data structure structure at a known physical address for this purpose. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 644a9208e3bb -r 5d695cfaded5 tools/firmware/hvmloader/config-seabios.h --- a/tools/firmware/hvmloader/config-seabios.h Wed Jun 01 09:42:14 2011 +0100 +++ b/tools/firmware/hvmloader/config-seabios.h Wed Jun 01 09:45:58 2011 +0100 @@ -1,6 +1,8 @@ #ifndef __HVMLOADER_CONFIG_SEABIOS_H__ #define __HVMLOADER_CONFIG_SEABIOS_H__ +#define BIOS_INFO_PHYSICAL_ADDRESS 0x00001000 + #define SEABIOS_PHYSICAL_ADDRESS 0x000E0000 #endif /* __HVMLOADER_CONFIG_SEABIOS_H__ */ diff -r 644a9208e3bb -r 5d695cfaded5 tools/firmware/hvmloader/seabios.c --- a/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:42:14 2011 +0100 +++ b/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:45:58 2011 +0100 @@ -25,9 +25,98 @@ #include "util.h" +#include "smbios_types.h" +#include "acpi/acpi2_0.h" + #define ROM_INCLUDE_SEABIOS #include "roms.inc" +struct seabios_info { + char signature[14]; /* XenHVMSeaBIOS\0 */ + uint8_t length; /* Length of this struct */ + uint8_t checksum; /* Set such that the sum over bytes 0..length == 0 */ + /* + * Physical address of an array of tables_nr elements. + * + * Each element is a 32 bit value contianing the physical address + * of a BIOS table. + */ + uint32_t tables; + uint32_t tables_nr; + /* + * Physical address of the e820 table, contains e820_nr entries. + */ + uint32_t e820; + uint32_t e820_nr; +} __attribute__ ((packed)); + +#define MAX_TABLES 4 + +static void seabios_setup_bios_info(void) +{ + struct seabios_info *info = (void *)BIOS_INFO_PHYSICAL_ADDRESS; + + memset(info, 0, sizeof(*info)); + + memcpy(info->signature, "XenHVMSeaBIOS", sizeof(info->signature)); + info->length = sizeof(*info); + + info->tables = (uint32_t)scratch_alloc(MAX_TABLES*sizeof(uint32_t), 0); +} + +static void seabios_finish_bios_info(void) +{ + struct seabios_info *info = (void *)BIOS_INFO_PHYSICAL_ADDRESS; + uint32_t i; + uint8_t checksum; + + checksum = 0; + for (i = 0; i < info->length; ++i) + checksum += ((uint8_t *)(info))[i]; + + info->checksum = -checksum; +} + +static void add_table(uint32_t t) +{ + struct seabios_info *info = (void *)BIOS_INFO_PHYSICAL_ADDRESS; + uint32_t *ts = (uint32_t *)info->tables; + + ASSERT(info->tables_nr < MAX_TABLES); + + ts[info->tables_nr] = t; + info->tables_nr++; +} + +static void seabios_acpi_build_tables(void) +{ + uint32_t rsdp = (uint32_t)scratch_alloc(sizeof(struct acpi_20_rsdp), 0); + acpi_build_tables(rsdp); + add_table(rsdp); +} + +static void seabios_create_mp_tables(void) +{ + add_table(create_mp_tables(NULL)); +} + +static void seabios_create_smbios_tables(void) +{ + uint32_t ep = (uint32_t)scratch_alloc(sizeof(struct smbios_entry_point), 0); + uint32_t t = (uint32_t)mem_alloc(32*1024, 0); + hvm_write_smbios_tables(ep, t, 32*1024); + add_table(ep); +} + +static void seabios_setup_e820(void) +{ + struct seabios_info *info = (void *)BIOS_INFO_PHYSICAL_ADDRESS; + struct e820entry *e820 = scratch_alloc(sizeof(struct e820entry)*16, 0); + info->e820 = (uint32_t)e820; + info->e820_nr = build_e820_table(e820); + dump_e820_table(e820, info->e820_nr); +} + //BUILD_BUG_ON(sizeof(seabios) > (0x00100000U - SEABIOS_PHYSICAL_ADDRESS)); struct bios_config seabios_config = { @@ -43,17 +132,17 @@ struct bios_config seabios_config = { .optionrom_start = 0, .optionrom_end = 0, - .bios_info_setup = NULL, - .bios_info_finish = NULL, + .bios_info_setup = seabios_setup_bios_info, + .bios_info_finish = seabios_finish_bios_info, .bios_relocate = NULL, .vm86_setup = NULL, - .e820_setup = NULL, + .e820_setup = seabios_setup_e820, - .acpi_build_tables = NULL, - .create_mp_tables = NULL, - .create_smbios_tables = NULL, + .acpi_build_tables = seabios_acpi_build_tables, + .create_mp_tables = seabios_create_mp_tables, + .create_smbios_tables = seabios_create_smbios_tables, }; /* _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:40 UTC
[Xen-devel] [PATCH 14 of 15] hvmloader: allow the possibility to allocate the size of smbios table we actually need
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306917980 -3600 # Node ID 7e6e8594316a62193f9ab629ee2b8848224cce22 # Parent 5d695cfaded597bb9e70818a9225bde3a91d3355 hvmloader: allow the possibility to allocate the size of smbios table we actually need. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 5d695cfaded5 -r 7e6e8594316a tools/firmware/hvmloader/seabios.c --- a/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:45:58 2011 +0100 +++ b/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:46:20 2011 +0100 @@ -103,8 +103,7 @@ static void seabios_create_mp_tables(voi static void seabios_create_smbios_tables(void) { uint32_t ep = (uint32_t)scratch_alloc(sizeof(struct smbios_entry_point), 0); - uint32_t t = (uint32_t)mem_alloc(32*1024, 0); - hvm_write_smbios_tables(ep, t, 32*1024); + hvm_write_smbios_tables(ep, 0UL, 0UL); add_table(ep); } diff -r 5d695cfaded5 -r 7e6e8594316a tools/firmware/hvmloader/smbios.c --- a/tools/firmware/hvmloader/smbios.c Wed Jun 01 09:45:58 2011 +0100 +++ b/tools/firmware/hvmloader/smbios.c Wed Jun 01 09:46:20 2011 +0100 @@ -28,10 +28,11 @@ #include "hypercall.h" static int -write_smbios_tables(void *ep, void *start, unsigned long phys, +write_smbios_tables(void *ep, void *start, uint32_t vcpus, uint64_t memsize, uint8_t uuid[16], char *xen_version, - uint32_t xen_major_version, uint32_t xen_minor_version); + uint32_t xen_major_version, uint32_t xen_minor_version, + unsigned *nr_structs, unsigned *max_struct_size); static void get_cpu_manufacturer(char *buf, int len); @@ -85,12 +86,13 @@ get_cpu_manufacturer(char *buf, int len) } static int -write_smbios_tables(void *ep, void *start, unsigned long phys, +write_smbios_tables(void *ep, void *start, uint32_t vcpus, uint64_t memsize, uint8_t uuid[16], char *xen_version, - uint32_t xen_major_version, uint32_t xen_minor_version) + uint32_t xen_major_version, uint32_t xen_minor_version, + unsigned *nr_structs, unsigned *max_struct_size) { - unsigned cpu_num, nr_structs = 0, max_struct_size = 0; + unsigned cpu_num; char *p, *q; char cpu_manufacturer[15]; int i, nr_mem_devs; @@ -101,9 +103,9 @@ write_smbios_tables(void *ep, void *star #define do_struct(fn) do { \ q = (fn); \ - nr_structs++; \ - if ( (q - p) > max_struct_size ) \ - max_struct_size = q - p; \ + (*nr_structs)++; \ + if ( (q - p) > *max_struct_size ) \ + *max_struct_size = q - p; \ p = q; \ } while (0) @@ -133,10 +135,6 @@ write_smbios_tables(void *ep, void *star #undef do_struct - smbios_entry_point_init(ep, max_struct_size, - (p - (char *)start), phys, - nr_structs); - return ((char *)p - (char *)start); } @@ -159,7 +157,7 @@ get_memsize(void) return (sz + (1ul << 20) - 1) >> 20; } -int +void hvm_write_smbios_tables(unsigned long ep, unsigned long smbios_start, unsigned long smbios_end) { xen_domain_handle_t uuid; @@ -173,6 +171,7 @@ hvm_write_smbios_tables(unsigned long ep unsigned len = 0; /* length of string already composed */ char tmp[16]; /* holds result of itoa() */ unsigned tmp_len; /* length of next string to add */ + unsigned nr_structs = 0, max_struct_size = 0; hypercall_xen_version(XENVER_guest_handle, uuid); BUILD_BUG_ON(sizeof(xen_domain_handle_t) != 16); @@ -220,21 +219,26 @@ hvm_write_smbios_tables(unsigned long ep xen_version_str[sizeof(xen_version_str)-1] = ''\0''; /* scratch_start is a safe large memory area for scratch. */ - len = write_smbios_tables((void *)ep, (void *)scratch_start, smbios_start, + len = write_smbios_tables((void *)ep, (void *)scratch_start, hvm_info->nr_vcpus, get_memsize(), uuid, xen_version_str, - xen_major_version, xen_minor_version); - if ( smbios_start + len > smbios_end ) + xen_major_version, xen_minor_version, + &nr_structs, &max_struct_size); + if ( smbios_start && smbios_start + len > smbios_end ) goto error_out; - /* Okay, not too large: copy out of scratch to final location. */ + + if ( !smbios_start ) + smbios_start = (unsigned long)mem_alloc(len, 0); + memcpy((void *)smbios_start, (void *)scratch_start, len); - return len; + smbios_entry_point_init((void *)ep, max_struct_size, len, smbios_start, nr_structs); + + return; error_out: printf("Could not write SMBIOS tables, error in hvmloader.c:" "hvm_write_smbios_tables()\n"); - return 0; } diff -r 5d695cfaded5 -r 7e6e8594316a tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Wed Jun 01 09:45:58 2011 +0100 +++ b/tools/firmware/hvmloader/util.h Wed Jun 01 09:46:20 2011 +0100 @@ -192,7 +192,7 @@ uint32_t rombios_highbios_setup(void); /* Miscellaneous. */ void cacheattr_init(void); unsigned long create_mp_tables(void *table); -int hvm_write_smbios_tables(unsigned long ep, +void hvm_write_smbios_tables(unsigned long ep, unsigned long smbios_start, unsigned long smbios_end); void smp_initialise(void); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 09:40 UTC
[Xen-devel] [PATCH 15 of 15] hvmloader: add code to generate a $PIR table
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306918266 -3600 # Node ID b47bc708c79191ee7ca15d4e642a4609fe26d88b # Parent 7e6e8594316a62193f9ab629ee2b8848224cce22 hvmloader: add code to generate a $PIR table. Does not replace the table hardcoded in ROMBIOS (it ain''t broke) but is used for SeaBIOS. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 7e6e8594316a -r b47bc708c791 tools/firmware/hvmloader/Makefile --- a/tools/firmware/hvmloader/Makefile Wed Jun 01 09:46:20 2011 +0100 +++ b/tools/firmware/hvmloader/Makefile Wed Jun 01 09:51:06 2011 +0100 @@ -30,7 +30,7 @@ CFLAGS += $(CFLAGS_xeninclude) OBJS = hvmloader.o mp_tables.o util.o smbios.o OBJS += 32bitbios_support.o smp.o cacheattr.o xenbus.o -OBJS += e820.o pci.o +OBJS += e820.o pci.o pir.o ifeq ($(debug),y) OBJS += tests.o endif diff -r 7e6e8594316a -r b47bc708c791 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Jun 01 09:46:20 2011 +0100 +++ b/tools/firmware/hvmloader/config.h Wed Jun 01 09:51:06 2011 +0100 @@ -31,6 +31,7 @@ struct bios_config { void (*acpi_build_tables)(void); void (*create_mp_tables)(void); void (*create_smbios_tables)(void); + void (*create_pir_tables)(void); }; extern struct bios_config rombios_config; diff -r 7e6e8594316a -r b47bc708c791 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:46:20 2011 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 09:51:06 2011 +0100 @@ -423,9 +423,12 @@ int main(void) if (bios->bios_relocate) bios->bios_relocate(); - if ( bios->create_mp_tables && - ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode ) ) - bios->create_mp_tables(); + if ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode ) { + if ( bios->create_mp_tables ) + bios->create_mp_tables(); + if ( bios->create_pir_tables ) + bios->create_pir_tables(); + } if ( bios->load_roms ) { diff -r 7e6e8594316a -r b47bc708c791 tools/firmware/hvmloader/pir.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/firmware/hvmloader/pir.c Wed Jun 01 09:51:06 2011 +0100 @@ -0,0 +1,67 @@ +/* + * pir.c: Support for genrating $PIR tables. + * + * Copyright (c) 2011 Citrix Systems Inc + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "config.h" +#include "pir_types.h" +#include "util.h" + +/* + * The structure of these tables is described in + * http://www.microsoft.com/taiwan/whdc/archive/pciirq.mspx + */ +unsigned long create_pir_tables(void) +{ + int length = sizeof(struct pir_table) + sizeof(struct pir_slot)*NR_PIR_SLOTS; + struct pir_table *pir = scratch_alloc(length, 0); + int i, checksum; + + memset(pir, 0, length); + + memcpy(pir->signature, "$PIR", 4); + pir->version = 0x0100; + pir->length = length; + + pir->router_bus = 0; + pir->router_devfn = PCI_ISA_DEVFN; + pir->router_vid = 0x8086; + pir->router_did = 0x122e; + + pir->pci_irqs = 0x0000; + + for ( i = 0 ; i < NR_PIR_SLOTS; i++ ) + { + struct pir_slot *slot = &pir->slots[i]; + slot->slot = i; + slot->bus = 0; + slot->dev = i<<3; + slot->link_a = 0x60 + (i+1)%4; + slot->bitmap_a = PCI_ISA_IRQ_MASK; + slot->link_b = 0x60 + (i+2)%4; + slot->bitmap_b = PCI_ISA_IRQ_MASK; + slot->link_c = 0x60 + (i+3)%4; + slot->bitmap_c = PCI_ISA_IRQ_MASK; + slot->link_d = 0x60 + (i+4)%4; + slot->bitmap_d = PCI_ISA_IRQ_MASK; + } + + checksum = 0; + for ( i = 0; i < length; i++) + { + checksum += ((int8_t *)pir)[i]; + } + pir->checksum = -checksum; + + return (unsigned long)pir; +} diff -r 7e6e8594316a -r b47bc708c791 tools/firmware/hvmloader/pir_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/firmware/hvmloader/pir_types.h Wed Jun 01 09:51:06 2011 +0100 @@ -0,0 +1,61 @@ +/* + * pir_types.h - data structure definitions for Xen HVM $PIR support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) Citrix Systems, 2011 + * + * See the PCI Interrupt Routing spec for more detail: + * http://www.microsoft.com/taiwan/whdc/archive/pciirq.mspx + */ + +#ifndef PIR_TYPES_H +#define PIR_TYPES_H + +#include <stdint.h> + +#define NR_PIR_SLOTS 6 + +struct pir_slot { + uint8_t bus; + uint8_t dev; + uint8_t link_a; + uint16_t bitmap_a; + uint8_t link_b; + uint16_t bitmap_b; + uint8_t link_c; + uint16_t bitmap_c; + uint8_t link_d; + uint16_t bitmap_d; + uint8_t slot; + uint8_t reserved; +} __attribute__ ((packed)); + +struct pir_table { + char signature[4]; + uint16_t version; + uint16_t length; + uint8_t router_bus; + uint8_t router_devfn; + uint16_t pci_irqs; + uint16_t router_vid; + uint16_t router_did; + uint32_t miniport_data; + uint8_t reserved[11]; + uint8_t checksum; + struct pir_slot slots[0]; +} __attribute__ ((packed)); + +#endif diff -r 7e6e8594316a -r b47bc708c791 tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:46:20 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:51:06 2011 +0100 @@ -187,6 +187,7 @@ struct bios_config rombios_config = { .acpi_build_tables = rombios_acpi_build_tables, .create_mp_tables = rombios_create_mp_tables, .create_smbios_tables = rombios_create_smbios_tables, + .create_pir_tables = NULL, /* embedded in ROMBIOS */ }; /* diff -r 7e6e8594316a -r b47bc708c791 tools/firmware/hvmloader/seabios.c --- a/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:46:20 2011 +0100 +++ b/tools/firmware/hvmloader/seabios.c Wed Jun 01 09:51:06 2011 +0100 @@ -107,6 +107,11 @@ static void seabios_create_smbios_tables add_table(ep); } +static void seabios_create_pir_tables(void) +{ + add_table(create_pir_tables()); +} + static void seabios_setup_e820(void) { struct seabios_info *info = (void *)BIOS_INFO_PHYSICAL_ADDRESS; @@ -142,6 +147,7 @@ struct bios_config seabios_config = { .acpi_build_tables = seabios_acpi_build_tables, .create_mp_tables = seabios_create_mp_tables, .create_smbios_tables = seabios_create_smbios_tables, + .create_pir_tables = seabios_create_pir_tables, }; /* diff -r 7e6e8594316a -r b47bc708c791 tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Wed Jun 01 09:46:20 2011 +0100 +++ b/tools/firmware/hvmloader/util.h Wed Jun 01 09:51:06 2011 +0100 @@ -195,6 +195,8 @@ unsigned long create_mp_tables(void *tab void hvm_write_smbios_tables(unsigned long ep, unsigned long smbios_start, unsigned long smbios_end); +unsigned long create_pir_tables(void); + void smp_initialise(void); #include "e820.h" _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 10:04 UTC
[Xen-devel] Re: [PATCH 02 of 15] hvmloader: enable PCI_COMMAND_IO on primary VGA device
On Wed, 2011-06-01 at 10:39 +0100, Ian Campbell wrote:> # HG changeset patch > # User Ian Campbell <ian.campbell@citrix.com> > # Date 1306916791 -3600 > # Node ID 062bc0a35d9933cc64c11f861609559e11994778 > # Parent 253a38db096bdc72b4e266ed103643210a739d93 > hvmloader: enable PCI_COMMAND_IO on primary VGA device > > There is an implicit assumption in the PCI spec that the primary VGA > device (e.g. something with class==VGA) will have I/O enabled in order > to make the standard VGA I/O registers (e.g. at 0x3xx) available, even > though the device has no explicit I/O BARS. > > The qemu device model for the Cirrus VGA card does not actually > enforce this but SeaBIOS looks for a VGA device with I/O enabled > before running the VGA ROM. Coreboot has similar behaviour and I > verified on a physical Cirrus GD 5446 that the BIOS had enable I/O > cycles. > > The thread at http://www.seabios.org/pipermail/seabios/2011-May/001804.html > contains more info. > > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>Actually, this doesn''t do quite what I expected. The value of virtual_vga can change multiple times if an PT device is found before one of the emulated devices. Since we want this devfn to match the device we have chosen as primary we should always update both together. The following does that. This change conflicts with 3/15 so I will repost that too shortly. 8<------------------------------------------------- # HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306922623 -3600 # Node ID e28514b40c909f882e7075d05e614a8814786ad2 # Parent 253a38db096bdc72b4e266ed103643210a739d93 hvmloader: enable PCI_COMMAND_IO on primary VGA device There is an implicit assumption in the PCI spec that the primary VGA device (e.g. something with class==VGA) will have I/O enabled in order to make the standard VGA I/O registers (e.g. at 0x3xx) available, even though the device has no explicit I/O BARS. The qemu device model for the Cirrus VGA card does not actually enforce this but SeaBIOS looks for a VGA device with I/O enabled before running the VGA ROM. Coreboot has similar behaviour and I verified on a physical Cirrus GD 5446 that the BIOS had enable I/O cycles. The thread at http://www.seabios.org/pipermail/seabios/2011-May/001804.html contains more info. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 253a38db096b -r e28514b40c90 tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Wed Jun 01 09:17:55 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 11:03:43 2011 +0100 @@ -102,6 +102,7 @@ static void rombios_apic_setup(void) static void rombios_pci_setup(void) { uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0; + uint32_t vga_devfn = 256; uint16_t class, vendor_id, device_id; unsigned int bar, pin, link, isa_irq; @@ -146,12 +147,22 @@ static void rombios_pci_setup(void) { case 0x0300: /* If emulated VGA is found, preserve it as primary VGA. */ + if ( virtual_vga == VGA_none ) if ( (vendor_id == 0x1234) && (device_id == 0x1111) ) + { + vga_devfn = devfn; virtual_vga = VGA_std; + } else if ( (vendor_id == 0x1013) && (device_id == 0xb8) ) + { + vga_devfn = devfn; virtual_vga = VGA_cirrus; + } else if ( virtual_vga == VGA_none ) + { + vga_devfn = devfn; virtual_vga = VGA_pt; + } break; case 0x0680: /* PIIX4 ACPI PM. Special device with special PCI config space. */ @@ -307,6 +318,18 @@ static void rombios_pci_setup(void) cmd |= PCI_COMMAND_IO; pci_writew(devfn, PCI_COMMAND, cmd); } + + if ( vga_devfn != 256 ) + { + /* + * VGA registers live in I/O space so ensure that primary VGA + * has IO enabled, even if there is no I/O BAR on that + * particular device. + */ + cmd = pci_readw(vga_devfn, PCI_COMMAND); + cmd |= PCI_COMMAND_IO; + pci_writew(vga_devfn, PCI_COMMAND, cmd); + } } /* _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 10:05 UTC
[Xen-devel] Re: [PATCH 03 of 15] hvmloader: setup PCI bus in a common function again
On Wed, 2011-06-01 at 10:39 +0100, Ian Campbell wrote:> # HG changeset patch > # User Ian Campbell <ian.campbell@citrix.com> > # Date 1306916881 -3600 > # Node ID 8a7fb25fff1980aa4fcf963da1aa82d4dfd34bda > # Parent 062bc0a35d9933cc64c11f861609559e11994778 > hvmloader: setup PCI bus in a common function again.Reposting, updated for changed patch 2/15. 8<---------------------------------------------------- # HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1306922653 -3600 # Node ID 3a17969b49e2d07ebf5cd302250bfcd31c88a758 # Parent e28514b40c909f882e7075d05e614a8814786ad2 hvmloader: setup PCI bus in a common function again. Previous refactoring was premature. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r e28514b40c90 -r 3a17969b49e2 tools/firmware/hvmloader/Makefile --- a/tools/firmware/hvmloader/Makefile Wed Jun 01 11:03:43 2011 +0100 +++ b/tools/firmware/hvmloader/Makefile Wed Jun 01 11:04:13 2011 +0100 @@ -30,7 +30,7 @@ CFLAGS += $(CFLAGS_xeninclude) OBJS = hvmloader.o mp_tables.o util.o smbios.o OBJS += 32bitbios_support.o smp.o cacheattr.o xenbus.o -OBJS += e820.o +OBJS += e820.o pci.o ifeq ($(debug),y) OBJS += tests.o endif diff -r e28514b40c90 -r 3a17969b49e2 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Jun 01 11:03:43 2011 +0100 +++ b/tools/firmware/hvmloader/config.h Wed Jun 01 11:04:13 2011 +0100 @@ -3,7 +3,7 @@ #include <stdint.h> -enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt } virtual_vga; +enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt }; extern enum virtual_vga virtual_vga; struct bios_config { @@ -27,7 +27,6 @@ struct bios_config { unsigned int acpi_start; void (*apic_setup)(void); - void (*pci_setup)(void); void (*smp_setup)(void); uint32_t (*bios_high_setup)(void); diff -r e28514b40c90 -r 3a17969b49e2 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 11:03:43 2011 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Jun 01 11:04:13 2011 +0100 @@ -109,11 +109,6 @@ asm ( " .text \n" ); -unsigned long pci_mem_start = PCI_MEM_START; -unsigned long pci_mem_end = PCI_MEM_END; - -enum virtual_vga virtual_vga = VGA_none; - static void init_hypercalls(void) { uint32_t eax, ebx, ecx, edx; @@ -391,8 +386,7 @@ int main(void) if (bios->apic_setup) bios->apic_setup(); - if (bios->pci_setup) - bios->pci_setup(); + pci_setup(); if (bios->smp_setup) bios->smp_setup(); diff -r e28514b40c90 -r 3a17969b49e2 tools/firmware/hvmloader/pci.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/firmware/hvmloader/pci.c Wed Jun 01 11:04:13 2011 +0100 @@ -0,0 +1,267 @@ +/* + * pci.c: HVM PCI setup. + * + * Leendert van Doorn, leendert@watson.ibm.com + * Copyright (c) 2005, International Business Machines Corporation. + * + * Copyright (c) 2006, Keir Fraser, XenSource Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "util.h" +#include "hypercall.h" +#include "config.h" +#include "pci_regs.h" + +#include <xen/memory.h> +#include <xen/hvm/ioreq.h> + +unsigned long pci_mem_start = PCI_MEM_START; +unsigned long pci_mem_end = PCI_MEM_END; + +enum virtual_vga virtual_vga = VGA_none; + +void pci_setup(void) +{ + uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0; + uint32_t vga_devfn = 256; + 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 ( virtual_vga == VGA_none ) + if ( (vendor_id == 0x1234) && (device_id == 0x1111) ) + { + vga_devfn = devfn; + virtual_vga = VGA_std; + } + else if ( (vendor_id == 0x1013) && (device_id == 0xb8) ) + { + vga_devfn = devfn; + virtual_vga = VGA_cirrus; + } + else if ( virtual_vga == VGA_none ) + { + vga_devfn = devfn; + 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); + } + + if ( vga_devfn != 256 ) + { + /* + * VGA registers live in I/O space so ensure that primary VGA + * has IO enabled, even if there is no I/O BAR on that + * particular device. + */ + cmd = pci_readw(vga_devfn, PCI_COMMAND); + cmd |= PCI_COMMAND_IO; + pci_writew(vga_devfn, PCI_COMMAND, cmd); + } +} diff -r e28514b40c90 -r 3a17969b49e2 tools/firmware/hvmloader/rombios.c --- a/tools/firmware/hvmloader/rombios.c Wed Jun 01 11:03:43 2011 +0100 +++ b/tools/firmware/hvmloader/rombios.c Wed Jun 01 11:04:13 2011 +0100 @@ -31,8 +31,6 @@ #include "hypercall.h" #include <xen/hvm/params.h> -#include <xen/hvm/ioreq.h> -#include <xen/memory.h> #define ROM_INCLUDE_ROMBIOS #include "roms.inc" @@ -99,239 +97,6 @@ static void rombios_apic_setup(void) 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; - uint32_t vga_devfn = 256; - 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 ( virtual_vga == VGA_none ) - if ( (vendor_id == 0x1234) && (device_id == 0x1111) ) - { - vga_devfn = devfn; - virtual_vga = VGA_std; - } - else if ( (vendor_id == 0x1013) && (device_id == 0xb8) ) - { - vga_devfn = devfn; - virtual_vga = VGA_cirrus; - } - else if ( virtual_vga == VGA_none ) - { - vga_devfn = devfn; - 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); - } - - if ( vga_devfn != 256 ) - { - /* - * VGA registers live in I/O space so ensure that primary VGA - * has IO enabled, even if there is no I/O BAR on that - * particular device. - */ - cmd = pci_readw(vga_devfn, PCI_COMMAND); - cmd |= PCI_COMMAND_IO; - pci_writew(vga_devfn, PCI_COMMAND, cmd); - } -} - /* * find_mp_table_start - searchs through BIOS memory for ''___HVMMP'' signature * @@ -403,7 +168,6 @@ struct bios_config rombios_config = { .acpi_start = ACPI_PHYSICAL_ADDRESS, .apic_setup = rombios_apic_setup, - .pci_setup = rombios_pci_setup, .smp_setup = smp_initialise, .bios_high_setup = rombios_highbios_setup, diff -r e28514b40c90 -r 3a17969b49e2 tools/firmware/hvmloader/seabios.c --- a/tools/firmware/hvmloader/seabios.c Wed Jun 01 11:03:43 2011 +0100 +++ b/tools/firmware/hvmloader/seabios.c Wed Jun 01 11:04:13 2011 +0100 @@ -28,11 +28,6 @@ #define ROM_INCLUDE_SEABIOS #include "roms.inc" -static void seabios_pci_setup(void) -{ - virtual_vga = VGA_cirrus; -} - //BUILD_BUG_ON(sizeof(seabios) > (0x00100000U - SEABIOS_PHYSICAL_ADDRESS)); struct bios_config seabios_config = { @@ -56,7 +51,6 @@ struct bios_config seabios_config = { .bios_info_setup = NULL, .apic_setup = NULL, - .pci_setup = seabios_pci_setup, .smp_setup = NULL, .vm86_setup = NULL, diff -r e28514b40c90 -r 3a17969b49e2 tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Wed Jun 01 11:03:43 2011 +0100 +++ b/tools/firmware/hvmloader/util.h Wed Jun 01 11:04:13 2011 +0100 @@ -180,6 +180,9 @@ void xenbus_shutdown(void); * static buffer, so only valid until the next xenstore/xenbus operation. */ char *xenstore_read(char *path); +/* Setup PCI bus */ +void pci_setup(void); + /* Prepare the 32bit BIOS */ uint32_t rombios_highbios_setup(void); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Jun-01 10:44 UTC
Re: [Xen-devel] Re: [PATCH 03 of 15] hvmloader: setup PCI bus in a common function again
On Wed, 2011-06-01 at 11:05 +0100, Ian Campbell wrote:> On Wed, 2011-06-01 at 10:39 +0100, Ian Campbell wrote: > > # HG changeset patch > > # User Ian Campbell <ian.campbell@citrix.com> > > # Date 1306916881 -3600 > > # Node ID 8a7fb25fff1980aa4fcf963da1aa82d4dfd34bda > > # Parent 062bc0a35d9933cc64c11f861609559e11994778 > > hvmloader: setup PCI bus in a common function again. > > Reposting, updated for changed patch 2/15.Gah, not sure what I build tested, but it obviously wasn''t this code... Incremental fix (to avoid reposting both 2/15 and 3/15) below. diff -r 439f07b2d43e tools/firmware/hvmloader/pci.c --- a/tools/firmware/hvmloader/pci.c Wed Jun 01 11:04:18 2011 +0100 +++ b/tools/firmware/hvmloader/pci.c Wed Jun 01 11:43:30 2011 +0100 @@ -81,7 +81,6 @@ void pci_setup(void) { case 0x0300: /* If emulated VGA is found, preserve it as primary VGA. */ - if ( virtual_vga == VGA_none ) if ( (vendor_id == 0x1234) && (device_id == 0x1111) ) { vga_devfn = devfn; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Konrad Rzeszutek Wilk
2011-Jun-02 19:43 UTC
Re: [Xen-devel] [PATCH 08 of 15] hvmloader: Add a simple "scratch allocator"
> +void *scratch_alloc(uint32_t size, uint32_t align) > +{ > + uint32_t s, e; > + > + /* Align to at least one kilobyte. */ > + if ( align < 1024 ) > + align = 1024; > + > + s = (scratch_start + align - 1) & ~(align - 1); > + e = s + size - 1; > + > + BUG_ON(e < s); > + > + scratch_start = e; > + > + return (void *)(unsigned long)s;Why the double cast? _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Jun-02 20:00 UTC
Re: [Xen-devel] [PATCH 08 of 15] hvmloader: Add a simple "scratch allocator"
On 02/06/2011 20:43, "Konrad Rzeszutek Wilk" <konrad.wilk@oracle.com> wrote:>> + return (void *)(unsigned long)s; > > Why the double cast?gcc complains if you cast between a pointer and an integer of a different size. We assume in many places that a pointer is same size as a long, so we cast through a long when the original integer type may be different size. In this case, in hvmloader, we know that pointers/longs/uint32_t are all 32-bit, but still I quite like the principle of always casting through a long when the integer is not explicitly that type already. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel