[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] Move PCI and PCI-ISA bridge setup to hvmloader.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID a8d31d5ce2589762c3226185deeca3afca47a698 # Parent b8cc9ffda0a3dc449b026c72c97f78dea2e6f114 [HVM] Move PCI and PCI-ISA bridge setup to hvmloader. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- tools/firmware/hvmloader/acpi_madt.c | 42 - tools/firmware/hvmloader/acpi_utils.c | 15 tools/firmware/hvmloader/config.h | 3 tools/firmware/hvmloader/hvmloader.c | 167 +++++- tools/firmware/hvmloader/mp_tables.c | 9 tools/firmware/hvmloader/pci_regs.h | 108 +++ tools/firmware/hvmloader/smbios.c | 839 +++++++++++++++---------------- tools/firmware/hvmloader/util.c | 580 ++++++++++++++------- tools/firmware/hvmloader/util.h | 35 + tools/firmware/rombios/rombios.c | 48 - tools/ioemu/target-i386-dm/piix_pci-dm.c | 247 --------- 11 files changed, 1160 insertions(+), 933 deletions(-) diff -r b8cc9ffda0a3 -r a8d31d5ce258 tools/firmware/hvmloader/acpi_madt.c --- a/tools/firmware/hvmloader/acpi_madt.c Wed Nov 22 09:52:48 2006 -0700 +++ b/tools/firmware/hvmloader/acpi_madt.c Wed Nov 22 17:50:20 2006 +0000 @@ -35,32 +35,34 @@ static int validate_hvm_info(struct hvm_ int i; /* strncmp(t->signature, "HVM INFO", 8) */ - for (i = 0; i < 8; i++) { - if (signature[i] != t->signature[i]) { - puts("Bad hvm info signature\n"); + for ( i = 0; i < 8; i++ ) + { + if ( signature[i] != t->signature[i] ) + { + printf("Bad hvm info signature\n"); return 0; } } - for (i = 0; i < t->length; i++) + for ( i = 0; i < t->length; i++ ) sum += ptr[i]; return (sum == 0); } /* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */ -struct hvm_info_table * -get_hvm_info_table(void) +struct hvm_info_table *get_hvm_info_table(void) { struct hvm_info_table *t; - if (table != NULL) + if ( table != NULL ) return table; t = (struct hvm_info_table *)HVM_INFO_PADDR; - if (!validate_hvm_info(t)) { - puts("Bad hvm info table\n"); + if ( !validate_hvm_info(t) ) + { + printf("Bad hvm info table\n"); return NULL; } @@ -69,15 +71,13 @@ get_hvm_info_table(void) return table; } -int -get_vcpu_nr(void) +int get_vcpu_nr(void) { struct hvm_info_table *t = get_hvm_info_table(); return (t ? t->nr_vcpus : 1); /* default 1 vcpu */ } -int -get_acpi_enabled(void) +int get_acpi_enabled(void) { struct hvm_info_table *t = get_hvm_info_table(); return (t ? t->acpi_enabled : 0); /* default no acpi */ @@ -91,13 +91,14 @@ acpi_madt_get_madt(unsigned char *acpi_s struct acpi_20_madt *madt; rsdt = acpi_rsdt_get(acpi_start); - if (rsdt == NULL) + if ( rsdt == NULL ) return NULL; madt = (struct acpi_20_madt *)(acpi_start + rsdt->entry[1] - ACPI_PHYSICAL_ADDRESS); - if (madt->header.header.signature != ACPI_2_0_MADT_SIGNATURE) { - puts("Bad MADT signature \n"); + if ( madt->header.header.signature != ACPI_2_0_MADT_SIGNATURE ) + { + printf("Bad MADT signature \n"); return NULL; } @@ -111,10 +112,11 @@ acpi_madt_set_local_apics( { int i; - if ((nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt) + if ( (nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt ) return -1; - for (i = 0; i < nr_vcpu; i++) { + for ( i = 0; i < nr_vcpu; i++ ) + { madt->lapic[i].type = ACPI_PROCESSOR_LOCAL_APIC; madt->lapic[i].length = sizeof(struct acpi_20_madt_lapic); madt->lapic[i].acpi_processor_id = i; @@ -137,11 +139,11 @@ int acpi_madt_update(unsigned char *acpi struct acpi_20_madt *madt; madt = acpi_madt_get_madt(acpi_start); - if (!madt) + if ( !madt ) return -1; rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt); - if (rc != 0) + if ( rc != 0 ) return rc; set_checksum( diff -r b8cc9ffda0a3 -r a8d31d5ce258 tools/firmware/hvmloader/acpi_utils.c --- a/tools/firmware/hvmloader/acpi_utils.c Wed Nov 22 09:52:48 2006 -0700 +++ b/tools/firmware/hvmloader/acpi_utils.c Wed Nov 22 17:50:20 2006 +0000 @@ -78,7 +78,7 @@ static void acpi_tpm_tis_probe(unsigned sizeof(tis_did_vid_rid)) != 0 ) return; - puts("TIS is available\n"); + printf("TIS is available\n"); addr = acpi_xsdt_add_entry(acpi_start, freemem, limit, AmlCode_TPM, sizeof(AmlCode_TPM)); if ( addr == NULL ) @@ -133,7 +133,7 @@ struct acpi_20_rsdt *acpi_rsdt_get(unsig rsdp = (struct acpi_20_rsdp *)(acpi_start + sizeof(struct acpi_20_facs)); if ( rsdp->signature != ACPI_2_0_RSDP_SIGNATURE ) { - puts("Bad RSDP signature\n"); + printf("Bad RSDP signature\n"); return NULL; } @@ -141,7 +141,7 @@ struct acpi_20_rsdt *acpi_rsdt_get(unsig (acpi_start + rsdp->rsdt_address - ACPI_PHYSICAL_ADDRESS); if ( rsdt->header.signature != ACPI_2_0_RSDT_SIGNATURE ) { - puts("Bad RSDT signature\n"); + printf("Bad RSDT signature\n"); return NULL; } @@ -192,7 +192,7 @@ struct acpi_20_xsdt *acpi_xsdt_get(unsig rsdp = (struct acpi_20_rsdp *)(acpi_start + sizeof(struct acpi_20_facs)); if ( rsdp->signature != ACPI_2_0_RSDP_SIGNATURE ) { - puts("Bad RSDP signature\n"); + printf("Bad RSDP signature\n"); return NULL; } @@ -200,7 +200,7 @@ struct acpi_20_xsdt *acpi_xsdt_get(unsig (acpi_start + rsdp->xsdt_address - ACPI_PHYSICAL_ADDRESS); if ( xsdt->header.signature != ACPI_2_0_XSDT_SIGNATURE ) { - puts("Bad XSDT signature\n"); + printf("Bad XSDT signature\n"); return NULL; } return xsdt; @@ -270,8 +270,9 @@ static unsigned char *acpi_xsdt_add_entr if ( found ) { /* memory below hard limit ? */ - if (*freemem + table_size <= limit) { - puts("Copying SSDT entry!\n"); + if ( (*freemem + table_size) <= limit ) + { + printf("Copying SSDT entry\n"); addr = *freemem; memcpy(addr, table, table_size); *freemem += table_size; diff -r b8cc9ffda0a3 -r a8d31d5ce258 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Nov 22 09:52:48 2006 -0700 +++ b/tools/firmware/hvmloader/config.h Wed Nov 22 17:50:20 2006 +0000 @@ -7,4 +7,7 @@ #define LAPIC_BASE_ADDRESS 0xfee00000 +#define PCI_ISA_DEVFN 0x08 /* dev 1, fn 0 */ +#define PCI_ISA_IRQ_MASK 0x0c60U /* ISA IRQs 5,6,10,11 are PCI connected */ + #endif /* __HVMLOADER_CONFIG_H__ */ diff -r b8cc9ffda0a3 -r a8d31d5ce258 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Nov 22 09:52:48 2006 -0700 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Nov 22 17:50:20 2006 +0000 @@ -1,12 +1,10 @@ /* * hvmloader.c: HVM ROMBIOS/VGABIOS/ACPI/VMXAssist image loader. * - * A quicky so that we can boot rom images as if they were a Linux kernel. - * This code will copy the rom images (ROMBIOS/VGABIOS/VM86) into their - * respective spaces and transfer control to VM86 to execute the BIOSes. - * * Leendert van Doorn, leendert@xxxxxxxxxxxxxx * 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, @@ -28,8 +26,10 @@ #include "acpi_utils.h" #include "smbios.h" #include "config.h" +#include "pci_regs.h" #include <xen/version.h> #include <xen/hvm/params.h> +#include <xen/hvm/e820.h> /* memory map */ #define HYPERCALL_PHYSICAL_ADDRESS 0x00080000 @@ -125,7 +125,7 @@ init_hypercalls(void) { uint32_t eax, ebx, ecx, edx; unsigned long i; - char signature[13], number[13]; + char signature[13]; xen_extraversion_t extraversion; cpuid(0x40000000, &eax, &ebx, &ecx, &edx); @@ -137,25 +137,19 @@ init_hypercalls(void) if ( strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002) ) { - puts("FATAL: Xen hypervisor not detected\n"); + printf("FATAL: Xen hypervisor not detected\n"); __asm__ __volatile__( "ud2" ); } - cpuid(0x40000001, &eax, &ebx, &ecx, &edx); - - puts("Detected Xen v"); - puts(itoa(number, eax >> 16)); - puts("."); - puts(itoa(number, eax & 0xffff)); - + /* Fill in hypercall transfer pages. */ cpuid(0x40000002, &eax, &ebx, &ecx, &edx); - for ( i = 0; i < eax; i++ ) wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i); + /* Print version information. */ + cpuid(0x40000001, &eax, &ebx, &ecx, &edx); hypercall_xen_version(XENVER_extraversion, extraversion); - puts(extraversion); - puts("\n"); + printf("Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion); } static void apic_setup(void) @@ -172,38 +166,157 @@ static void apic_setup(void) *iowin = IOAPIC_ID; } +static void pci_setup(void) +{ + uint32_t devfn, bar_reg, bar_data, bar_sz, cmd; + uint32_t *base, io_base = 0xc000, mem_base = HVM_BELOW_4G_MMIO_START; + uint16_t class, vendor_id, device_id; + unsigned int bar, pin, link, isa_irq; + + /* Program PCI-ISA bridge with appropriate link routes. */ + link = 0; + for ( isa_irq = 0; isa_irq < 15; isa_irq++ ) + { + if ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) ) + continue; + pci_writeb(PCI_ISA_DEVFN, 0x60 + link, isa_irq); + printf("PCI-ISA link %u routed to IRQ%u\n", link, isa_irq); + if ( link++ == 4 ) + break; + } + + /* 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 < 128; 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 0x0680: + ASSERT((vendor_id == 0x8086) && (device_id == 0x7113)); + /* + * PIIX4 ACPI PM. Special device with special PCI config space. + * No ordinary BARs. + */ + pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */ + pci_writew(devfn, 0x22, 0x0000); + pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */ + pci_writew(devfn, 0x3d, 0x0001); + break; + case 0x0101: + /* PIIX3 IDE */ + ASSERT((vendor_id == 0x8086) && (device_id == 0x7010)); + pci_writew(devfn, 0x40, 0x8000); /* enable IDE0 */ + pci_writew(devfn, 0x42, 0x8000); /* enable IDE1 */ + /* fall through */ + default: + /* Default memory mappings. */ + 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); + if ( bar_sz == 0 ) + continue; + + if ( (bar_data & PCI_BASE_ADDRESS_SPACE) == + PCI_BASE_ADDRESS_SPACE_MEMORY ) + { + base = &mem_base; + bar_sz &= PCI_BASE_ADDRESS_MEM_MASK; + bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK; + } + else + { + base = &io_base; + bar_sz &= PCI_BASE_ADDRESS_IO_MASK & 0xffff; + bar_data &= ~PCI_BASE_ADDRESS_IO_MASK; + } + bar_sz &= ~(bar_sz - 1); + + *base = (*base + bar_sz - 1) & ~(bar_sz - 1); + bar_data |= *base; + *base += bar_sz; + + 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); + } + break; + } + + /* 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); + } + } +} + int main(void) { - puts("HVM Loader\n"); + printf("HVM Loader\n"); init_hypercalls(); - puts("Writing SMBIOS tables ...\n"); + printf("Writing SMBIOS tables ...\n"); hvm_write_smbios_tables(); - puts("Loading ROMBIOS ...\n"); + printf("Loading ROMBIOS ...\n"); memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios)); apic_setup(); - + pci_setup(); create_mp_tables(); if ( cirrus_check() ) { - puts("Loading Cirrus VGABIOS ...\n"); + printf("Loading Cirrus VGABIOS ...\n"); memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, vgabios_cirrusvga, sizeof(vgabios_cirrusvga)); } else { - puts("Loading Standard VGABIOS ...\n"); + printf("Loading Standard VGABIOS ...\n"); memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, vgabios_stdvga, sizeof(vgabios_stdvga)); } if ( get_acpi_enabled() != 0 ) { - puts("Loading ACPI ...\n"); + printf("Loading ACPI ...\n"); acpi_madt_update((unsigned char *) acpi); if ( (ACPI_PHYSICAL_ADDRESS + sizeof(acpi)) <= 0xF0000 ) { @@ -225,23 +338,23 @@ int main(void) if ( check_amd() ) { /* AMD implies this is SVM */ - puts("SVM go ...\n"); + printf("SVM go ...\n"); vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0); } else { - puts("Loading VMXAssist ...\n"); + printf("Loading VMXAssist ...\n"); memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS, vmxassist, sizeof(vmxassist)); - puts("VMX go ...\n"); + printf("VMX go ...\n"); __asm__ __volatile__( "jmp *%%eax" : : "a" (VMXASSIST_PHYSICAL_ADDRESS), "d" (0) ); } - puts("Failed to invoke ROMBIOS\n"); + printf("Failed to invoke ROMBIOS\n"); return 0; } diff -r b8cc9ffda0a3 -r a8d31d5ce258 tools/firmware/hvmloader/mp_tables.c --- a/tools/firmware/hvmloader/mp_tables.c Wed Nov 22 09:52:48 2006 -0700 +++ b/tools/firmware/hvmloader/mp_tables.c Wed Nov 22 17:50:20 2006 +0000 @@ -263,10 +263,7 @@ void fill_mp_io_intr_entry( { mpiie->type = ENTRY_TYPE_IO_INTR; mpiie->intr_type = INTR_TYPE_INT; - mpiie->io_intr_flags = 0; - /* IRQs 10 and 11 are PCI, so level triggered and active low. */ - if ( (src_bus_irq == 10) || (src_bus_irq == 11) ) - mpiie->io_intr_flags = 0xf; + mpiie->io_intr_flags = (PCI_ISA_IRQ_MASK & (1U<<src_bus_irq)) ? 0xf : 0x0; mpiie->src_bus_id = src_bus_id; mpiie->src_bus_irq = src_bus_irq; mpiie->dst_ioapic_id = ioapic_id; @@ -349,13 +346,13 @@ void create_mp_tables(void) vcpu_nr = get_vcpu_nr(); - puts("Creating MP tables ...\n"); + printf("Creating MP tables ...\n"); /* Find the 'safe' place in ROMBIOS for the MP tables. */ mp_table_base = get_mp_table_start(); if ( mp_table_base == NULL ) { - puts("Couldn't find start point for MP tables\n"); + printf("Couldn't find start point for MP tables\n"); return; } diff -r b8cc9ffda0a3 -r a8d31d5ce258 tools/firmware/hvmloader/smbios.c --- a/tools/firmware/hvmloader/smbios.c Wed Nov 22 09:52:48 2006 -0700 +++ b/tools/firmware/hvmloader/smbios.c Wed Nov 22 17:50:20 2006 +0000 @@ -30,29 +30,29 @@ static size_t write_smbios_tables(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 vcpus, uint64_t memsize, + uint8_t uuid[16], char *xen_version, + uint32_t xen_major_version, uint32_t xen_minor_version); static void get_cpu_manufacturer(char *buf, int len); static void smbios_entry_point_init(void *start, - uint16_t max_structure_size, - uint16_t structure_table_length, - uint32_t structure_table_address, - uint16_t number_of_structures); + uint16_t max_structure_size, + uint16_t structure_table_length, + uint32_t structure_table_address, + uint16_t number_of_structures); static void * smbios_type_0_init(void *start, const char *xen_version, - uint32_t xen_major_version, uint32_t xen_minor_version); + uint32_t xen_major_version, uint32_t xen_minor_version); static void * smbios_type_1_init(void *start, const char *xen_version, - uint8_t uuid[16]); + uint8_t uuid[16]); static void * smbios_type_3_init(void *start); static void * smbios_type_4_init(void *start, unsigned int cpu_number, - char *cpu_manufacturer); + char *cpu_manufacturer); static void * smbios_type_16_init(void *start, uint32_t memory_size_mb); static void * @@ -69,64 +69,64 @@ static void static void get_cpu_manufacturer(char *buf, int len) { - char id[12]; - uint32_t eax = 0; - - cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8], - (uint32_t *)&id[4]); - - if (memcmp(id, "GenuineIntel", 12) == 0) - strncpy(buf, "Intel", len); - else if (memcmp(id, "AuthenticAMD", 12) == 0) - strncpy(buf, "AMD", len); - else - strncpy(buf, "unknown", len); + char id[12]; + uint32_t eax = 0; + + cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8], + (uint32_t *)&id[4]); + + if (memcmp(id, "GenuineIntel", 12) == 0) + strncpy(buf, "Intel", len); + else if (memcmp(id, "AuthenticAMD", 12) == 0) + strncpy(buf, "AMD", len); + else + strncpy(buf, "unknown", len); } static size_t write_smbios_tables(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) -{ - unsigned cpu_num, nr_structs = 0, max_struct_size = 0; - char *p, *q; - char cpu_manufacturer[15]; - - get_cpu_manufacturer(cpu_manufacturer, 15); - - p = (char *)start + sizeof(struct smbios_entry_point); - -#define do_struct(fn) do { \ - q = (fn); \ - nr_structs++; \ - if ((q - p) > max_struct_size) \ - max_struct_size = q - p; \ - p = q; \ + uint32_t vcpus, uint64_t memsize, + uint8_t uuid[16], char *xen_version, + uint32_t xen_major_version, uint32_t xen_minor_version) +{ + unsigned cpu_num, nr_structs = 0, max_struct_size = 0; + char *p, *q; + char cpu_manufacturer[15]; + + get_cpu_manufacturer(cpu_manufacturer, 15); + + p = (char *)start + sizeof(struct smbios_entry_point); + +#define do_struct(fn) do { \ + q = (fn); \ + nr_structs++; \ + if ( (q - p) > max_struct_size ) \ + max_struct_size = q - p; \ + p = q; \ } while (0) - do_struct(smbios_type_0_init(p, xen_version, xen_major_version, - xen_minor_version)); - do_struct(smbios_type_1_init(p, xen_version, uuid)); - do_struct(smbios_type_3_init(p)); - for (cpu_num = 1; cpu_num <= vcpus; cpu_num++) - do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer)); - do_struct(smbios_type_16_init(p, memsize)); - do_struct(smbios_type_17_init(p, memsize)); - do_struct(smbios_type_19_init(p, memsize)); - do_struct(smbios_type_20_init(p, memsize)); - do_struct(smbios_type_32_init(p)); - do_struct(smbios_type_127_init(p)); + do_struct(smbios_type_0_init(p, xen_version, xen_major_version, + xen_minor_version)); + do_struct(smbios_type_1_init(p, xen_version, uuid)); + do_struct(smbios_type_3_init(p)); + for ( cpu_num = 1; cpu_num <= vcpus; cpu_num++ ) + do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer)); + do_struct(smbios_type_16_init(p, memsize)); + do_struct(smbios_type_17_init(p, memsize)); + do_struct(smbios_type_19_init(p, memsize)); + do_struct(smbios_type_20_init(p, memsize)); + do_struct(smbios_type_32_init(p)); + do_struct(smbios_type_127_init(p)); #undef do_struct - smbios_entry_point_init( - start, max_struct_size, - (p - (char *)start) - sizeof(struct smbios_entry_point), - SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point), - nr_structs); - - return (size_t)((char *)p - (char *)start); + smbios_entry_point_init( + start, max_struct_size, + (p - (char *)start) - sizeof(struct smbios_entry_point), + SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point), + nr_structs); + + return (size_t)((char *)p - (char *)start); } /* This tries to figure out how much pseudo-physical memory (in MB) @@ -142,428 +142,439 @@ static uint64_t static uint64_t get_memsize(void) { - struct e820entry *map = NULL; - uint8_t num_entries = 0; - uint64_t memsize = 0; - uint8_t i; - - map = (struct e820entry *) (E820_MAP_PAGE + E820_MAP_OFFSET); - num_entries = *((uint8_t *) (E820_MAP_PAGE + E820_MAP_NR_OFFSET)); - - /* walk through e820map, ignoring any entries that aren't marked - as usable or reserved. */ - - for (i = 0; i < num_entries; i++) { - if (map->type == E820_RAM || map->type == E820_RESERVED) - memsize += map->size; - map++; - } - - /* Round up to the nearest MB. The user specifies domU - pseudo-physical memory in megabytes, so not doing this - could easily lead to reporting one less MB than the user - specified. */ - if (memsize & ((1<<20)-1)) - memsize = (memsize >> 20) + 1; - else - memsize = (memsize >> 20); - - return memsize; + struct e820entry *map = NULL; + uint8_t num_entries = 0; + uint64_t memsize = 0; + uint8_t i; + + map = (struct e820entry *) (E820_MAP_PAGE + E820_MAP_OFFSET); + num_entries = *((uint8_t *) (E820_MAP_PAGE + E820_MAP_NR_OFFSET)); + + /* walk through e820map, ignoring any entries that aren't marked + as usable or reserved. */ + + for ( i = 0; i < num_entries; i++ ) + { + if (map->type == E820_RAM || map->type == E820_RESERVED) + memsize += map->size; + map++; + } + + /* Round up to the nearest MB. The user specifies domU + pseudo-physical memory in megabytes, so not doing this + could easily lead to reporting one less MB than the user + specified. */ + if ( memsize & ((1<<20)-1) ) + memsize = (memsize >> 20) + 1; + else + memsize = (memsize >> 20); + + return memsize; } void hvm_write_smbios_tables(void) { - uint8_t uuid[16]; /* ** This will break if xen_domain_handle_t is - not uint8_t[16]. ** */ - uint16_t xen_major_version, xen_minor_version; - uint32_t xen_version; - char xen_extra_version[XEN_EXTRAVERSION_LEN]; - /* guess conservatively on buffer length for Xen version string */ - char xen_version_str[80]; - /* temporary variables used to build up Xen version string */ - char *p = NULL; /* points to next point of insertion */ - unsigned len = 0; /* length of string already composed */ - char *tmp = NULL; /* holds result of itoa() */ - unsigned tmp_len; /* length of next string to add */ - - hypercall_xen_version(XENVER_guest_handle, uuid); - - /* xen_version major and minor */ - xen_version = hypercall_xen_version(XENVER_version, NULL); - xen_major_version = (uint16_t) (xen_version >> 16); - xen_minor_version = (uint16_t) xen_version; - - hypercall_xen_version(XENVER_extraversion, xen_extra_version); - - /* build up human-readable Xen version string */ - p = xen_version_str; - len = 0; - - itoa(tmp, xen_major_version); - tmp_len = strlen(tmp); - len += tmp_len; - if (len >= sizeof(xen_version_str)) - goto error_out; - strcpy(p, tmp); - p += tmp_len; - - len++; - if (len >= sizeof(xen_version_str)) - goto error_out; - *p = '.'; - p++; - - itoa(tmp, xen_minor_version); - tmp_len = strlen(tmp); - len += tmp_len; - if (len >= sizeof(xen_version_str)) - goto error_out; - strcpy(p, tmp); - p += tmp_len; - - tmp_len = strlen(xen_extra_version); - len += tmp_len; - if (len >= sizeof(xen_version_str)) - goto error_out; - strcpy(p, xen_extra_version); - p += tmp_len; - - xen_version_str[sizeof(xen_version_str)-1] = '\0'; - - /* NB. 0xC0000 is a safe large memory area for scratch. */ - len = write_smbios_tables((void *)0xC0000, - get_vcpu_nr(), get_memsize(), - uuid, xen_version_str, - xen_major_version, xen_minor_version); - if (len > SMBIOS_SIZE_LIMIT) - goto error_out; - /* Okay, not too large: copy out of scratch to final location. */ - memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len); - - return; + uint8_t uuid[16]; /* ** This will break if xen_domain_handle_t is + not uint8_t[16]. ** */ + uint16_t xen_major_version, xen_minor_version; + uint32_t xen_version; + char xen_extra_version[XEN_EXTRAVERSION_LEN]; + /* guess conservatively on buffer length for Xen version string */ + char xen_version_str[80]; + /* temporary variables used to build up Xen version string */ + char *p = NULL; /* points to next point of insertion */ + unsigned len = 0; /* length of string already composed */ + char *tmp = NULL; /* holds result of itoa() */ + unsigned tmp_len; /* length of next string to add */ + + hypercall_xen_version(XENVER_guest_handle, uuid); + + /* xen_version major and minor */ + xen_version = hypercall_xen_version(XENVER_version, NULL); + xen_major_version = (uint16_t) (xen_version >> 16); + xen_minor_version = (uint16_t) xen_version; + + hypercall_xen_version(XENVER_extraversion, xen_extra_version); + + /* build up human-readable Xen version string */ + p = xen_version_str; + len = 0; + + itoa(tmp, xen_major_version); + tmp_len = strlen(tmp); + len += tmp_len; + if ( len >= sizeof(xen_version_str) ) + goto error_out; + strcpy(p, tmp); + p += tmp_len; + + len++; + if ( len >= sizeof(xen_version_str) ) + goto error_out; + *p = '.'; + p++; + + itoa(tmp, xen_minor_version); + tmp_len = strlen(tmp); + len += tmp_len; + if ( len >= sizeof(xen_version_str) ) + goto error_out; + strcpy(p, tmp); + p += tmp_len; + + tmp_len = strlen(xen_extra_version); + len += tmp_len; + if ( len >= sizeof(xen_version_str) ) + goto error_out; + strcpy(p, xen_extra_version); + p += tmp_len; + + xen_version_str[sizeof(xen_version_str)-1] = '\0'; + + /* NB. 0xC0000 is a safe large memory area for scratch. */ + len = write_smbios_tables((void *)0xC0000, + get_vcpu_nr(), get_memsize(), + uuid, xen_version_str, + xen_major_version, xen_minor_version); + if ( len > SMBIOS_SIZE_LIMIT ) + goto error_out; + /* Okay, not too large: copy out of scratch to final location. */ + memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len); + + return; error_out: - puts("Could not write SMBIOS tables, error in hvmloader.c:" - "hvm_write_smbios_tables()\n"); + printf("Could not write SMBIOS tables, error in hvmloader.c:" + "hvm_write_smbios_tables()\n"); } static void smbios_entry_point_init(void *start, - uint16_t max_structure_size, - uint16_t structure_table_length, - uint32_t structure_table_address, - uint16_t number_of_structures) -{ - uint8_t sum; - int i; - struct smbios_entry_point *ep = (struct smbios_entry_point *)start; - - strncpy(ep->anchor_string, "_SM_", 4); - ep->length = 0x1f; - ep->smbios_major_version = 2; - ep->smbios_minor_version = 4; - ep->max_structure_size = max_structure_size; - ep->entry_point_revision = 0; - memset(ep->formatted_area, 0, 5); - strncpy(ep->intermediate_anchor_string, "_DMI_", 5); - - ep->structure_table_length = structure_table_length; - ep->structure_table_address = structure_table_address; - ep->number_of_structures = number_of_structures; - ep->smbios_bcd_revision = 0x24; - - ep->checksum = 0; - ep->intermediate_checksum = 0; - - sum = 0; - for (i = 0; i < 0x10; ++i) - sum += ((int8_t *)start)[i]; - ep->checksum = -sum; - - sum = 0; - for (i = 0x10; i < ep->length; ++i) - sum += ((int8_t *)start)[i]; - ep->intermediate_checksum = -sum; + uint16_t max_structure_size, + uint16_t structure_table_length, + uint32_t structure_table_address, + uint16_t number_of_structures) +{ + uint8_t sum; + int i; + struct smbios_entry_point *ep = (struct smbios_entry_point *)start; + + strncpy(ep->anchor_string, "_SM_", 4); + ep->length = 0x1f; + ep->smbios_major_version = 2; + ep->smbios_minor_version = 4; + ep->max_structure_size = max_structure_size; + ep->entry_point_revision = 0; + memset(ep->formatted_area, 0, 5); + strncpy(ep->intermediate_anchor_string, "_DMI_", 5); + + ep->structure_table_length = structure_table_length; + ep->structure_table_address = structure_table_address; + ep->number_of_structures = number_of_structures; + ep->smbios_bcd_revision = 0x24; + + ep->checksum = 0; + ep->intermediate_checksum = 0; + + sum = 0; + for ( i = 0; i < 0x10; i++ ) + sum += ((int8_t *)start)[i]; + ep->checksum = -sum; + + sum = 0; + for ( i = 0x10; i < ep->length; i++ ) + sum += ((int8_t *)start)[i]; + ep->intermediate_checksum = -sum; } /* Type 0 -- BIOS Information */ static void * smbios_type_0_init(void *start, const char *xen_version, - uint32_t xen_major_version, uint32_t xen_minor_version) -{ - struct smbios_type_0 *p = (struct smbios_type_0 *)start; - - p->header.type = 0; - p->header.length = sizeof(struct smbios_type_0); - p->header.handle = 0; - - p->vendor_str = 1; - p->version_str = 2; - p->starting_address_segment = 0xe800; - p->release_date_str = 0; - p->rom_size = 0; - - memset(p->characteristics, 0, 8); - p->characteristics[7] = 0x08; /* BIOS characteristics not supported */ - p->characteristics_extension_bytes[0] = 0; - p->characteristics_extension_bytes[1] = 0; - - p->major_release = (uint8_t) xen_major_version; - p->minor_release = (uint8_t) xen_minor_version; - p->embedded_controller_major = 0xff; - p->embedded_controller_minor = 0xff; - - start += sizeof(struct smbios_type_0); - strcpy((char *)start, "Xen"); - start += strlen("Xen") + 1; - strcpy((char *)start, xen_version); - start += strlen(xen_version) + 1; - - *((uint8_t *)start) = 0; - return start + 1; + uint32_t xen_major_version, uint32_t xen_minor_version) +{ + struct smbios_type_0 *p = (struct smbios_type_0 *)start; + + p->header.type = 0; + p->header.length = sizeof(struct smbios_type_0); + p->header.handle = 0; + + p->vendor_str = 1; + p->version_str = 2; + p->starting_address_segment = 0xe800; + p->release_date_str = 0; + p->rom_size = 0; + + memset(p->characteristics, 0, 8); + p->characteristics[7] = 0x08; /* BIOS characteristics not supported */ + p->characteristics_extension_bytes[0] = 0; + p->characteristics_extension_bytes[1] = 0; + + p->major_release = (uint8_t) xen_major_version; + p->minor_release = (uint8_t) xen_minor_version; + p->embedded_controller_major = 0xff; + p->embedded_controller_minor = 0xff; + + start += sizeof(struct smbios_type_0); + strcpy((char *)start, "Xen"); + start += strlen("Xen") + 1; + strcpy((char *)start, xen_version); + start += strlen(xen_version) + 1; + + *((uint8_t *)start) = 0; + return start + 1; } /* Type 1 -- System Information */ static void * smbios_type_1_init(void *start, const char *xen_version, - uint8_t uuid[16]) -{ - char uuid_str[37]; - struct smbios_type_1 *p = (struct smbios_type_1 *)start; - p->header.type = 1; - p->header.length = sizeof(struct smbios_type_1); - p->header.handle = 0x100; - - p->manufacturer_str = 1; - p->product_name_str = 2; - p->version_str = 3; - p->serial_number_str = 4; - - memcpy(p->uuid, uuid, 16); - - p->wake_up_type = 0x06; /* power switch */ - p->sku_str = 0; - p->family_str = 0; - - start += sizeof(struct smbios_type_1); - - strcpy((char *)start, "Xen"); - start += strlen("Xen") + 1; - strcpy((char *)start, "HVM domU"); - start += strlen("HVM domU") + 1; - strcpy((char *)start, xen_version); - start += strlen(xen_version) + 1; - uuid_to_string(uuid_str, uuid); - strcpy((char *)start, uuid_str); - start += strlen(uuid_str) + 1; - *((uint8_t *)start) = 0; - - return start+1; + uint8_t uuid[16]) +{ + char uuid_str[37]; + struct smbios_type_1 *p = (struct smbios_type_1 *)start; + p->header.type = 1; + p->header.length = sizeof(struct smbios_type_1); + p->header.handle = 0x100; + + p->manufacturer_str = 1; + p->product_name_str = 2; + p->version_str = 3; + p->serial_number_str = 4; + + memcpy(p->uuid, uuid, 16); + + p->wake_up_type = 0x06; /* power switch */ + p->sku_str = 0; + p->family_str = 0; + + start += sizeof(struct smbios_type_1); + + strcpy((char *)start, "Xen"); + start += strlen("Xen") + 1; + strcpy((char *)start, "HVM domU"); + start += strlen("HVM domU") + 1; + strcpy((char *)start, xen_version); + start += strlen(xen_version) + 1; + uuid_to_string(uuid_str, uuid); + strcpy((char *)start, uuid_str); + start += strlen(uuid_str) + 1; + *((uint8_t *)start) = 0; + + return start+1; } /* Type 3 -- System Enclosure */ static void * smbios_type_3_init(void *start) { - struct smbios_type_3 *p = (struct smbios_type_3 *)start; - - p->header.type = 3; - p->header.length = sizeof(struct smbios_type_3); - p->header.handle = 0x300; - - p->manufacturer_str = 1; - p->type = 0x01; /* other */ - p->version_str = 0; - p->serial_number_str = 0; - p->asset_tag_str = 0; - p->boot_up_state = 0x03; /* safe */ - p->power_supply_state = 0x03; /* safe */ - p->thermal_state = 0x03; /* safe */ - p->security_status = 0x02; /* unknown */ - - start += sizeof(struct smbios_type_3); - - strcpy((char *)start, "Xen"); - start += strlen("Xen") + 1; - *((uint8_t *)start) = 0; - return start+1; + struct smbios_type_3 *p = (struct smbios_type_3 *)start; + + p->header.type = 3; + p->header.length = sizeof(struct smbios_type_3); + p->header.handle = 0x300; + + p->manufacturer_str = 1; + p->type = 0x01; /* other */ + p->version_str = 0; + p->serial_number_str = 0; + p->asset_tag_str = 0; + p->boot_up_state = 0x03; /* safe */ + p->power_supply_state = 0x03; /* safe */ + p->thermal_state = 0x03; /* safe */ + p->security_status = 0x02; /* unknown */ + + start += sizeof(struct smbios_type_3); + + strcpy((char *)start, "Xen"); + start += strlen("Xen") + 1; + *((uint8_t *)start) = 0; + return start+1; } /* Type 4 -- Processor Information */ static void * smbios_type_4_init(void *start, unsigned int cpu_number, char *cpu_manufacturer) { - char buf[80]; - struct smbios_type_4 *p = (struct smbios_type_4 *)start; - uint32_t eax, ebx, ecx, edx; - - p->header.type = 4; - p->header.length = sizeof(struct smbios_type_4); - p->header.handle = 0x400 + cpu_number; - - p->socket_designation_str = 1; - p->processor_type = 0x03; /* CPU */ - p->processor_family = 0x01; /* other */ - p->manufacturer_str = 2; - - cpuid(1, &eax, &ebx, &ecx, &edx); - - p->cpuid[0] = eax; - p->cpuid[1] = edx; - - p->version_str = 0; - p->voltage = 0; - p->external_clock = 0; - - p->max_speed = 0; /* unknown */ - p->current_speed = 0; /* unknown */ - - p->status = 0x41; /* socket populated, CPU enabled */ - p->upgrade = 0x01; /* other */ - - start += sizeof(struct smbios_type_4); - - strncpy(buf, "CPU ", sizeof(buf)); - if ((sizeof(buf) - strlen("CPU ")) >= 3) - itoa(buf + strlen("CPU "), cpu_number); - - strcpy((char *)start, buf); - start += strlen(buf) + 1; - - strcpy((char *)start, cpu_manufacturer); - start += strlen(cpu_manufacturer) + 1; - - *((uint8_t *)start) = 0; - return start+1; + char buf[80]; + struct smbios_type_4 *p = (struct smbios_type_4 *)start; + uint32_t eax, ebx, ecx, edx; + + p->header.type = 4; + p->header.length = sizeof(struct smbios_type_4); + p->header.handle = 0x400 + cpu_number; + + p->socket_designation_str = 1; + p->processor_type = 0x03; /* CPU */ + p->processor_family = 0x01; /* other */ + p->manufacturer_str = 2; + + cpuid(1, &eax, &ebx, &ecx, &edx); + + p->cpuid[0] = eax; + p->cpuid[1] = edx; + + p->version_str = 0; + p->voltage = 0; + p->external_clock = 0; + + p->max_speed = 0; /* unknown */ + p->current_speed = 0; /* unknown */ + + p->status = 0x41; /* socket populated, CPU enabled */ + p->upgrade = 0x01; /* other */ + + start += sizeof(struct smbios_type_4); + + strncpy(buf, "CPU ", sizeof(buf)); + if ( (sizeof(buf) - strlen("CPU ")) >= 3 ) + itoa(buf + strlen("CPU "), cpu_number); + + strcpy((char *)start, buf); + start += strlen(buf) + 1; + + strcpy((char *)start, cpu_manufacturer); + start += strlen(cpu_manufacturer) + 1; + + *((uint8_t *)start) = 0; + return start+1; } /* Type 16 -- Physical Memory Array */ static void * smbios_type_16_init(void *start, uint32_t memsize) { - struct smbios_type_16 *p = (struct smbios_type_16*)start; - - p->header.type = 16; - p->header.handle = 0x1000; - p->header.length = sizeof(struct smbios_type_16); - - p->location = 0x01; /* other */ - p->use = 0x03; /* system memory */ - p->error_correction = 0x01; /* other */ - p->maximum_capacity = memsize * 1024; - p->memory_error_information_handle = 0xfffe; /* none provided */ - p->number_of_memory_devices = 1; - - start += sizeof(struct smbios_type_16); - *((uint16_t *)start) = 0; - return start + 2; + struct smbios_type_16 *p = (struct smbios_type_16*)start; + + p->header.type = 16; + p->header.handle = 0x1000; + p->header.length = sizeof(struct smbios_type_16); + + p->location = 0x01; /* other */ + p->use = 0x03; /* system memory */ + p->error_correction = 0x01; /* other */ + p->maximum_capacity = memsize * 1024; + p->memory_error_information_handle = 0xfffe; /* none provided */ + p->number_of_memory_devices = 1; + + start += sizeof(struct smbios_type_16); + *((uint16_t *)start) = 0; + return start + 2; } /* Type 17 -- Memory Device */ static void * smbios_type_17_init(void *start, uint32_t memory_size_mb) { - struct smbios_type_17 *p = (struct smbios_type_17 *)start; - - p->header.type = 17; - p->header.length = sizeof(struct smbios_type_17); - p->header.handle = 0x1100; - - p->physical_memory_array_handle = 0x1000; - p->total_width = 64; - p->data_width = 64; - /* truncate memory_size_mb to 16 bits and clear most significant - bit [indicates size in MB] */ - p->size = (uint16_t) memory_size_mb & 0x7fff; - p->form_factor = 0x09; /* DIMM */ - p->device_set = 0; - p->device_locator_str = 1; - p->bank_locator_str = 0; - p->memory_type = 0x07; /* RAM */ - p->type_detail = 0; - - start += sizeof(struct smbios_type_17); - strcpy((char *)start, "DIMM 1"); - start += strlen("DIMM 1") + 1; - *((uint8_t *)start) = 0; - - return start+1; + struct smbios_type_17 *p = (struct smbios_type_17 *)start; + + p->header.type = 17; + p->header.length = sizeof(struct smbios_type_17); + p->header.handle = 0x1100; + + p->physical_memory_array_handle = 0x1000; + p->total_width = 64; + p->data_width = 64; + /* truncate memory_size_mb to 16 bits and clear most significant + bit [indicates size in MB] */ + p->size = (uint16_t) memory_size_mb & 0x7fff; + p->form_factor = 0x09; /* DIMM */ + p->device_set = 0; + p->device_locator_str = 1; + p->bank_locator_str = 0; + p->memory_type = 0x07; /* RAM */ + p->type_detail = 0; + + start += sizeof(struct smbios_type_17); + strcpy((char *)start, "DIMM 1"); + start += strlen("DIMM 1") + 1; + *((uint8_t *)start) = 0; + + return start+1; } /* Type 19 -- Memory Array Mapped Address */ static void * smbios_type_19_init(void *start, uint32_t memory_size_mb) { - struct smbios_type_19 *p = (struct smbios_type_19 *)start; - - p->header.type = 19; - p->header.length = sizeof(struct smbios_type_19); - p->header.handle = 0x1300; - - p->starting_address = 0; - p->ending_address = (memory_size_mb-1) * 1024; - p->memory_array_handle = 0x1000; - p->partition_width = 1; - - start += sizeof(struct smbios_type_19); - *((uint16_t *)start) = 0; - return start + 2; + struct smbios_type_19 *p = (struct smbios_type_19 *)start; + + p->header.type = 19; + p->header.length = sizeof(struct smbios_type_19); + p->header.handle = 0x1300; + + p->starting_address = 0; + p->ending_address = (memory_size_mb-1) * 1024; + p->memory_array_handle = 0x1000; + p->partition_width = 1; + + start += sizeof(struct smbios_type_19); + *((uint16_t *)start) = 0; + return start + 2; } /* Type 20 -- Memory Device Mapped Address */ static void * smbios_type_20_init(void *start, uint32_t memory_size_mb) { - struct smbios_type_20 *p = (struct smbios_type_20 *)start; - - p->header.type = 20; - p->header.length = sizeof(struct smbios_type_20); - p->header.handle = 0x1400; - - p->starting_address = 0; - p->ending_address = (memory_size_mb-1)*1024; - p->memory_device_handle = 0x1100; - p->memory_array_mapped_address_handle = 0x1300; - p->partition_row_position = 1; - p->interleave_position = 0; - p->interleaved_data_depth = 0; - - start += sizeof(struct smbios_type_20); - - *((uint16_t *)start) = 0; - return start+2; + struct smbios_type_20 *p = (struct smbios_type_20 *)start; + + p->header.type = 20; + p->header.length = sizeof(struct smbios_type_20); + p->header.handle = 0x1400; + + p->starting_address = 0; + p->ending_address = (memory_size_mb-1)*1024; + p->memory_device_handle = 0x1100; + p->memory_array_mapped_address_handle = 0x1300; + p->partition_row_position = 1; + p->interleave_position = 0; + p->interleaved_data_depth = 0; + + start += sizeof(struct smbios_type_20); + + *((uint16_t *)start) = 0; + return start+2; } /* Type 32 -- System Boot Information */ static void * smbios_type_32_init(void *start) { - struct smbios_type_32 *p = (struct smbios_type_32 *)start; - - p->header.type = 32; - p->header.length = sizeof(struct smbios_type_32); - p->header.handle = 0x2000; - memset(p->reserved, 0, 6); - p->boot_status = 0; /* no errors detected */ - - start += sizeof(struct smbios_type_32); - *((uint16_t *)start) = 0; - return start+2; + struct smbios_type_32 *p = (struct smbios_type_32 *)start; + + p->header.type = 32; + p->header.length = sizeof(struct smbios_type_32); + p->header.handle = 0x2000; + memset(p->reserved, 0, 6); + p->boot_status = 0; /* no errors detected */ + + start += sizeof(struct smbios_type_32); + *((uint16_t *)start) = 0; + return start+2; } /* Type 127 -- End of Table */ static void * smbios_type_127_init(void *start) { - struct smbios_type_127 *p = (struct smbios_type_127 *)start; - - p->header.type = 127; - p->header.length = sizeof(struct smbios_type_127); - p->header.handle = 0x7f00; - - start += sizeof(struct smbios_type_127); - *((uint16_t *)start) = 0; - return start + 2; -} + struct smbios_type_127 *p = (struct smbios_type_127 *)start; + + p->header.type = 127; + p->header.length = sizeof(struct smbios_type_127); + p->header.handle = 0x7f00; + + start += sizeof(struct smbios_type_127); + *((uint16_t *)start) = 0; + return start + 2; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r b8cc9ffda0a3 -r a8d31d5ce258 tools/firmware/hvmloader/util.c --- a/tools/firmware/hvmloader/util.c Wed Nov 22 09:52:48 2006 -0700 +++ b/tools/firmware/hvmloader/util.c Wed Nov 22 17:50:20 2006 +0000 @@ -20,175 +20,193 @@ #include "acpi/acpi2_0.h" /* for ACPI_PHYSICAL_ADDRESS */ #include "util.h" +#include "config.h" #include <stdint.h> +#include <xenctrl.h> + +void outb(uint16_t addr, uint8_t val) +{ + __asm__ __volatile__ ( "outb %%al, %%dx" :: "d"(addr), "a"(val) ); +} void outw(uint16_t addr, uint16_t val) { - __asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val)); -} - -void outb(uint16_t addr, uint8_t val) -{ - __asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val)); + __asm__ __volatile__ ( "outw %%ax, %%dx" :: "d"(addr), "a"(val) ); +} + +void outl(uint16_t addr, uint32_t val) +{ + __asm__ __volatile__ ( "outl %%eax, %%dx" :: "d"(addr), "a"(val) ); } uint8_t inb(uint16_t addr) { - uint8_t val; - __asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr)); - return val; + uint8_t val; + __asm__ __volatile__ ( "inb %%dx,%%al" : "=a" (val) : "d" (addr) ); + return val; +} + +uint16_t inw(uint16_t addr) +{ + uint16_t val; + __asm__ __volatile__ ( "inw %%dx,%%ax" : "=a" (val) : "d" (addr) ); + return val; +} + +uint32_t inl(uint16_t addr) +{ + uint32_t val; + __asm__ __volatile__ ( "inl %%dx,%%eax" : "=a" (val) : "d" (addr) ); + return val; } char *itoa(char *a, unsigned int i) { - unsigned int _i = i, x = 0; - - do { - x++; - _i /= 10; - } while (_i != 0); - - a += x; - *a-- = '\0'; - - do { - *a-- = (i % 10) + '0'; - i /= 10; - } while (i != 0); - - return a + 1; + unsigned int _i = i, x = 0; + + do { + x++; + _i /= 10; + } while ( _i != 0 ); + + a += x; + *a-- = '\0'; + + do { + *a-- = (i % 10) + '0'; + i /= 10; + } while ( i != 0 ); + + return a + 1; } int strcmp(const char *cs, const char *ct) { - signed char res; - - while (((res = *cs - *ct++) == 0) && (*cs++ != '\0')) - continue; - - return res; + signed char res; + + while ( ((res = *cs - *ct++) == 0) && (*cs++ != '\0') ) + continue; + + return res; } void *memcpy(void *dest, const void *src, unsigned n) { - int t0, t1, t2; - - __asm__ __volatile__( - "cld\n" - "rep; movsl\n" - "testb $2,%b4\n" - "je 1f\n" - "movsw\n" - "1: testb $1,%b4\n" - "je 2f\n" - "movsb\n" - "2:" - : "=&c" (t0), "=&D" (t1), "=&S" (t2) - : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src) - : "memory" - ); - return dest; + int t0, t1, t2; + + __asm__ __volatile__ ( + "cld\n" + "rep; movsl\n" + "testb $2,%b4\n" + "je 1f\n" + "movsw\n" + "1: testb $1,%b4\n" + "je 2f\n" + "movsb\n" + "2:" + : "=&c" (t0), "=&D" (t1), "=&S" (t2) + : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src) + : "memory" ); + return dest; } void *memmove(void *dest, const void *src, unsigned n) { - if ((long)dest > (long)src) { - n--; - while (n > 0) { - ((char *)dest)[n] = ((char *)src)[n]; - n--; - } - } else { - memcpy(dest, src, n); - } - return dest; -} - - - - -void puts(const char *s) -{ - while (*s) - outb(0xE9, *s++); + if ( (long)dest > (long)src ) + { + n--; + while ( n > 0 ) + { + ((char *)dest)[n] = ((char *)src)[n]; + n--; + } + } + else + { + memcpy(dest, src, n); + } + return dest; } char * strcpy(char *dest, const char *src) { - char *p = dest; - while (*src) - *p++ = *src++; - *p = 0; - return dest; + char *p = dest; + while ( *src ) + *p++ = *src++; + *p = 0; + return dest; } char * strncpy(char *dest, const char *src, unsigned n) { - int i = 0; - char *p = dest; - - /* write non-NUL characters from src into dest until we run - out of room in dest or encounter a NUL in src */ - while (i < n && *src) { - *p++ = *src++; - ++i; - } - - /* pad remaining bytes of dest with NUL bytes */ - while (i < n) { - *p++ = 0; - ++i; - } - - return dest; + int i = 0; + char *p = dest; + + /* write non-NUL characters from src into dest until we run + out of room in dest or encounter a NUL in src */ + while ( (i < n) && *src ) + { + *p++ = *src++; + i++; + } + + /* pad remaining bytes of dest with NUL bytes */ + while ( i < n ) + { + *p++ = 0; + i++; + } + + return dest; } unsigned strlen(const char *s) { - int i = 0; - while (*s++) - ++i; - return i; + int i = 0; + while ( *s++ ) + i++; + return i; } void * memset(void *s, int c, unsigned n) { - uint8_t b = (uint8_t) c; - uint8_t *p = (uint8_t *)s; - int i; - for (i = 0; i < n; ++i) - *p++ = b; - return s; + uint8_t b = (uint8_t) c; + uint8_t *p = (uint8_t *)s; + int i; + for ( i = 0; i < n; i++ ) + *p++ = b; + return s; } int memcmp(const void *s1, const void *s2, unsigned n) { - unsigned i; - uint8_t *p1 = (uint8_t *) s1; - uint8_t *p2 = (uint8_t *) s2; - - for (i = 0; i < n; ++i) { - if (p1[i] < p2[i]) - return -1; - else if (p1[i] > p2[i]) - return 1; - } - - return 0; + unsigned i; + uint8_t *p1 = (uint8_t *) s1; + uint8_t *p2 = (uint8_t *) s2; + + for ( i = 0; i < n; i++ ) + { + if ( p1[i] < p2[i] ) + return -1; + else if ( p1[i] > p2[i] ) + return 1; + } + + return 0; } void cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { - __asm__ __volatile__( - "cpuid" - : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) - : "0" (idx) ); + __asm__ __volatile__ ( + "cpuid" + : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) + : "0" (idx) ); } /* Write a two-character hex representation of 'byte' to digits[]. @@ -196,18 +214,18 @@ void void byte_to_hex(char *digits, uint8_t byte) { - uint8_t nybbel = byte >> 4; - - if (nybbel > 9) - digits[0] = 'a' + nybbel-10; - else - digits[0] = '0' + nybbel; - - nybbel = byte & 0x0f; - if (nybbel > 9) - digits[1] = 'a' + nybbel-10; - else - digits[1] = '0' + nybbel; + uint8_t nybbel = byte >> 4; + + if ( nybbel > 9 ) + digits[0] = 'a' + nybbel-10; + else + digits[0] = '0' + nybbel; + + nybbel = byte & 0x0f; + if ( nybbel > 9 ) + digits[1] = 'a' + nybbel-10; + else + digits[1] = '0' + nybbel; } /* Convert an array of 16 unsigned bytes to a DCE/OSF formatted UUID @@ -217,34 +235,39 @@ void void uuid_to_string(char *dest, uint8_t *uuid) { - int i = 0; - char *p = dest; - - for (i = 0; i < 4; ++i) { - byte_to_hex(p, uuid[i]); - p += 2; - } - *p++ = '-'; - for (i = 4; i < 6; ++i) { - byte_to_hex(p, uuid[i]); - p += 2; - } - *p++ = '-'; - for (i = 6; i < 8; ++i) { - byte_to_hex(p, uuid[i]); - p += 2; - } - *p++ = '-'; - for (i = 8; i < 10; ++i) { - byte_to_hex(p, uuid[i]); - p += 2; - } - *p++ = '-'; - for (i = 10; i < 16; ++i) { - byte_to_hex(p, uuid[i]); - p += 2; - } - *p = 0; + int i = 0; + char *p = dest; + + for ( i = 0; i < 4; i++ ) + { + byte_to_hex(p, uuid[i]); + p += 2; + } + *p++ = '-'; + for ( i = 4; i < 6; i++ ) + { + byte_to_hex(p, uuid[i]); + p += 2; + } + *p++ = '-'; + for ( i = 6; i < 8; i++ ) + { + byte_to_hex(p, uuid[i]); + p += 2; + } + *p++ = '-'; + for ( i = 8; i < 10; i++ ) + { + byte_to_hex(p, uuid[i]); + p += 2; + } + *p++ = '-'; + for ( i = 10; i < 16; i++ ) + { + byte_to_hex(p, uuid[i]); + p += 2; + } + *p = '\0'; } #include <xen/hvm/e820.h> @@ -252,31 +275,222 @@ uuid_to_string(char *dest, uint8_t *uuid #define E820_MAP ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET)) uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask) { - uint64_t addr = 0; - int c = *E820_MAP_NR - 1; - struct e820entry *e820entry = (struct e820entry *)E820_MAP; - - while (c >= 0) { - if (e820entry[c].type == E820_RAM && - (e820entry[c].addr & (~mask)) == 0 && - e820entry[c].size >= size) { - addr = e820entry[c].addr; - if (e820entry[c].size != size) { - (*E820_MAP_NR)++; - memmove(&e820entry[c+1], - &e820entry[c], - (*E820_MAP_NR - c) * - sizeof(struct e820entry)); - e820entry[c].size -= size; - addr += e820entry[c].size; - c++; - } - e820entry[c].addr = addr; - e820entry[c].size = size; - e820entry[c].type = type; - break; - } - c--; - } - return addr; -} + uint64_t addr = 0; + int c = *E820_MAP_NR - 1; + struct e820entry *e820entry = (struct e820entry *)E820_MAP; + + while ( c >= 0 ) + { + if ( (e820entry[c].type == E820_RAM) && + ((e820entry[c].addr & (~mask)) == 0) && + (e820entry[c].size >= size) ) + { + addr = e820entry[c].addr; + if ( e820entry[c].size != size ) + { + (*E820_MAP_NR)++; + memmove(&e820entry[c+1], + &e820entry[c], + (*E820_MAP_NR - c) * + sizeof(struct e820entry)); + e820entry[c].size -= size; + addr += e820entry[c].size; + c++; + } + e820entry[c].addr = addr; + e820entry[c].size = size; + e820entry[c].type = type; + break; + } + c--; + } + return addr; +} + +uint32_t ioapic_read(uint32_t reg) +{ + uint32_t *ioregsel = (uint32_t *)(IOAPIC_BASE_ADDRESS + 0x00); + uint32_t *iowin = (uint32_t *)(IOAPIC_BASE_ADDRESS + 0x10); + + *ioregsel = reg; + mb(); + return *iowin; +} + +void ioapic_write(uint32_t reg, uint32_t val) +{ + uint32_t *ioregsel = (uint32_t *)(IOAPIC_BASE_ADDRESS + 0x00); + uint32_t *iowin = (uint32_t *)(IOAPIC_BASE_ADDRESS + 0x10); + + *ioregsel = reg; + wmb(); + *iowin = val; +} + +#define PCI_CONF1_ADDRESS(bus, devfn, reg) \ + (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) + +uint32_t pci_read(uint32_t devfn, uint32_t reg, uint32_t len) +{ + outl(0xcf8, PCI_CONF1_ADDRESS(0, devfn, reg)); + + switch ( len ) + { + case 1: return inb(0xcfc + (reg & 3)); + case 2: return inw(0xcfc + (reg & 2)); + } + + return inl(0xcfc); +} + +void pci_write(uint32_t devfn, uint32_t reg, uint32_t len, uint32_t val) +{ + outl(0xcf8, PCI_CONF1_ADDRESS(0, devfn, reg)); + + switch ( len ) + { + case 1: outb(0xcfc + (reg & 3), val); break; + case 2: outw(0xcfc + (reg & 2), val); break; + case 4: outl(0xcfc, val); break; + } +} + +static char *printnum(char *p, unsigned long num, int base) +{ + unsigned long n; + + if ( (n = num/base) > 0 ) + p = printnum(p, n, base); + *p++ = "0123456789abcdef"[(int)(num % base)]; + *p = '\0'; + return p; +} + +static void _doprint(void (*put)(char), char const *fmt, va_list ap) +{ + register char *str, c; + int lflag, zflag, nflag; + char buffer[17]; + unsigned value; + int i, slen, pad; + + for ( ; *fmt != '\0'; fmt++ ) + { + if ( *fmt != '%' ) + { + put(*fmt); + continue; + } + + pad = zflag = nflag = lflag = 0; + c = *++fmt; + if ( (c == '-') || isdigit(c) ) + { + if ( c == '-' ) + { + nflag = 1; + c = *++fmt; + } + zflag = c == '0'; + for ( pad = 0; isdigit(c); c = *++fmt ) + pad = (pad * 10) + c - '0'; + } + if ( c == 'l' ) /* long extension */ + { + lflag = 1; + c = *++fmt; + } + if ( (c == 'd') || (c == 'u') || (c == 'o') || (c == 'x') ) + { + if ( lflag ) + value = va_arg(ap, unsigned); + else + value = (unsigned) va_arg(ap, unsigned int); + str = buffer; + printnum(str, value, + c == 'o' ? 8 : (c == 'x' ? 16 : 10)); + goto printn; + } + else if ( (c == 'O') || (c == 'D') || (c == 'X') ) + { + value = va_arg(ap, unsigned); + str = buffer; + printnum(str, value, + c == 'O' ? 8 : (c == 'X' ? 16 : 10)); + printn: + slen = strlen(str); + for ( i = pad - slen; i > 0; i-- ) + put(zflag ? '0' : ' '); + while ( *str ) + put(*str++); + } + else if ( c == 's' ) + { + str = va_arg(ap, char *); + slen = strlen(str); + if ( nflag == 0 ) + for ( i = pad - slen; i > 0; i-- ) + put(' '); + while ( *str ) + put(*str++); + if ( nflag ) + for ( i = pad - slen; i > 0; i-- ) + put(' '); + } + else if ( c == 'c' ) + { + put(va_arg(ap, int)); + } + else + { + put(*fmt); + } + } +} + +static void putchar(char c) +{ + outb(0xe9, c); +} + +int printf(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + _doprint(putchar, fmt, ap); + va_end(ap); + + return 0; +} + +int vprintf(const char *fmt, va_list ap) +{ + _doprint(putchar, fmt, ap); + return 0; +} + +void __assert_failed(char *assertion, char *file, int line) +{ + printf("HVMLoader assertion '%s' failed at %s:%d\n", + assertion, file, line); + for ( ; ; ) + __asm__ __volatile__ ( "ud2" ); +} + +void __bug(char *file, int line) +{ + printf("HVMLoader bug at %s:%d\n", file, line); + for ( ; ; ) + __asm__ __volatile__ ( "ud2" ); +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r b8cc9ffda0a3 -r a8d31d5ce258 tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Wed Nov 22 09:52:48 2006 -0700 +++ b/tools/firmware/hvmloader/util.h Wed Nov 22 17:50:20 2006 +0000 @@ -1,12 +1,34 @@ #ifndef __HVMLOADER_UTIL_H__ #define __HVMLOADER_UTIL_H__ +#include <stdarg.h> + +extern void __assert_failed(char *assertion, char *file, int line) + __attribute__((noreturn)); +#define ASSERT(p) \ + do { if (!(p)) __assert_failed(#p, __FILE__, __LINE__); } while (0) +extern void __bug(char *file, int line) __attribute__((noreturn)); +#define BUG() __bug() + /* I/O output */ +void outb(uint16_t addr, uint8_t val); void outw(uint16_t addr, uint16_t val); -void outb(uint16_t addr, uint8_t val); +void outl(uint16_t addr, uint32_t val); /* I/O input */ -uint8_t inb(uint16_t addr); +uint8_t inb(uint16_t addr); +uint16_t inw(uint16_t addr); +uint32_t inl(uint16_t addr); + +/* PCI access */ +uint32_t pci_read(uint32_t devfn, uint32_t reg, uint32_t len); +#define pci_readb(devfn, reg) ((uint8_t) pci_read(devfn, reg, 1)) +#define pci_readw(devfn, reg) ((uint16_t)pci_read(devfn, reg, 2)) +#define pci_readl(devfn, reg) ((uint32_t)pci_read(devfn, reg, 4)) +void pci_write(uint32_t devfn, uint32_t reg, uint32_t len, uint32_t val); +#define pci_writeb(devfn, reg, val) (pci_write(devfn, reg, 1, (uint8_t) val)) +#define pci_writew(devfn, reg, val) (pci_write(devfn, reg, 2, (uint16_t)val)) +#define pci_writel(devfn, reg, val) (pci_write(devfn, reg, 4, (uint32_t)val)) /* Do cpuid instruction, with operation 'idx' */ void cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, @@ -31,15 +53,16 @@ void byte_to_hex(char *digits, uint8_t b void byte_to_hex(char *digits, uint8_t byte); /* Convert an array of 16 unsigned bytes to a DCE/OSF formatted UUID - string. - - Pre-condition: sizeof(dest) >= 37 */ + string. Pre-condition: sizeof(dest) >= 37 */ void uuid_to_string(char *dest, uint8_t *uuid); /* Debug output */ -void puts(const char *s); +int printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +int vprintf(const char *fmt, va_list ap); /* Allocate region of specified type in the e820 table. */ uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask); +#define isdigit(c) ((c) >= '0' && (c) <= '9') + #endif /* __HVMLOADER_UTIL_H__ */ diff -r b8cc9ffda0a3 -r a8d31d5ce258 tools/firmware/rombios/rombios.c --- a/tools/firmware/rombios/rombios.c Wed Nov 22 09:52:48 2006 -0700 +++ b/tools/firmware/rombios/rombios.c Wed Nov 22 17:50:20 2006 +0000 @@ -9104,78 +9104,78 @@ pci_routing_table_structure: db 0 ;; pci bus number db 0x08 ;; pci device number (bit 7-3) db 0x61 ;; link value INTA#: pointer into PCI2ISA config space - dw 0xdef8 ;; IRQ bitmap INTA# + dw 0x0c60 ;; IRQ bitmap INTA# db 0x62 ;; link value INTB# - dw 0xdef8 ;; IRQ bitmap INTB# + dw 0x0c60 ;; IRQ bitmap INTB# db 0x63 ;; link value INTC# - dw 0xdef8 ;; IRQ bitmap INTC# + dw 0x0c60 ;; IRQ bitmap INTC# db 0x60 ;; link value INTD# - dw 0xdef8 ;; IRQ bitmap INTD# + dw 0x0c60 ;; IRQ bitmap INTD# db 0 ;; physical slot (0 = embedded) db 0 ;; reserved ;; second slot entry: 1st PCI slot db 0 ;; pci bus number db 0x10 ;; pci device number (bit 7-3) db 0x62 ;; link value INTA# - dw 0xdef8 ;; IRQ bitmap INTA# + dw 0x0c60 ;; IRQ bitmap INTA# db 0x63 ;; link value INTB# - dw 0xdef8 ;; IRQ bitmap INTB# + dw 0x0c60 ;; IRQ bitmap INTB# db 0x60 ;; link value INTC# - dw 0xdef8 ;; IRQ bitmap INTC# + dw 0x0c60 ;; IRQ bitmap INTC# db 0x61 ;; link value INTD# - dw 0xdef8 ;; IRQ bitmap INTD# + dw 0x0c60 ;; IRQ bitmap INTD# db 1 ;; physical slot (0 = embedded) db 0 ;; reserved ;; third slot entry: 2nd PCI slot db 0 ;; pci bus number db 0x18 ;; pci device number (bit 7-3) db 0x63 ;; link value INTA# - dw 0xdef8 ;; IRQ bitmap INTA# + dw 0x0c60 ;; IRQ bitmap INTA# db 0x60 ;; link value INTB# - dw 0xdef8 ;; IRQ bitmap INTB# + dw 0x0c60 ;; IRQ bitmap INTB# db 0x61 ;; link value INTC# - dw 0xdef8 ;; IRQ bitmap INTC# + dw 0x0c60 ;; IRQ bitmap INTC# db 0x62 ;; link value INTD# - dw 0xdef8 ;; IRQ bitmap INTD# + dw 0x0c60 ;; IRQ bitmap INTD# db 2 ;; physical slot (0 = embedded) db 0 ;; reserved ;; 4th slot entry: 3rd PCI slot db 0 ;; pci bus number db 0x20 ;; pci device number (bit 7-3) db 0x60 ;; link value INTA# - dw 0xdef8 ;; IRQ bitmap INTA# + dw 0x0c60 ;; IRQ bitmap INTA# db 0x61 ;; link value INTB# - dw 0xdef8 ;; IRQ bitmap INTB# + dw 0x0c60 ;; IRQ bitmap INTB# db 0x62 ;; link value INTC# - dw 0xdef8 ;; IRQ bitmap INTC# + dw 0x0c60 ;; IRQ bitmap INTC# db 0x63 ;; link value INTD# - dw 0xdef8 ;; IRQ bitmap INTD# + dw 0x0c60 ;; IRQ bitmap INTD# db 3 ;; physical slot (0 = embedded) db 0 ;; reserved ;; 5th slot entry: 4rd PCI slot db 0 ;; pci bus number db 0x28 ;; pci device number (bit 7-3) db 0x61 ;; link value INTA# - dw 0xdef8 ;; IRQ bitmap INTA# + dw 0x0c60 ;; IRQ bitmap INTA# db 0x62 ;; link value INTB# - dw 0xdef8 ;; IRQ bitmap INTB# + dw 0x0c60 ;; IRQ bitmap INTB# db 0x63 ;; link value INTC# - dw 0xdef8 ;; IRQ bitmap INTC# + dw 0x0c60 ;; IRQ bitmap INTC# db 0x60 ;; link value INTD# - dw 0xdef8 ;; IRQ bitmap INTD# + dw 0x0c60 ;; IRQ bitmap INTD# db 4 ;; physical slot (0 = embedded) db 0 ;; reserved ;; 6th slot entry: 5rd PCI slot db 0 ;; pci bus number db 0x30 ;; pci device number (bit 7-3) db 0x62 ;; link value INTA# - dw 0xdef8 ;; IRQ bitmap INTA# + dw 0x0c60 ;; IRQ bitmap INTA# db 0x63 ;; link value INTB# - dw 0xdef8 ;; IRQ bitmap INTB# + dw 0x0c60 ;; IRQ bitmap INTB# db 0x60 ;; link value INTC# - dw 0xdef8 ;; IRQ bitmap INTC# + dw 0x0c60 ;; IRQ bitmap INTC# db 0x61 ;; link value INTD# - dw 0xdef8 ;; IRQ bitmap INTD# + dw 0x0c60 ;; IRQ bitmap INTD# db 5 ;; physical slot (0 = embedded) db 0 ;; reserved diff -r b8cc9ffda0a3 -r a8d31d5ce258 tools/ioemu/target-i386-dm/piix_pci-dm.c --- a/tools/ioemu/target-i386-dm/piix_pci-dm.c Wed Nov 22 09:52:48 2006 -0700 +++ b/tools/ioemu/target-i386-dm/piix_pci-dm.c Wed Nov 22 17:50:20 2006 +0000 @@ -84,12 +84,6 @@ PCIBus *i440fx_init(void) static PCIDevice *piix3_dev; -static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) -{ - /* This is the barber's pole mapping used by Xen. */ - return (irq_num + (pci_dev->devfn >> 3)) & 3; -} - static void piix3_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { @@ -114,12 +108,9 @@ static void piix3_reset(PCIDevice *d) uint8_t *pci_conf = d->config; pci_conf[0x04] = 0x07; // master, memory and I/O - pci_conf[0x05] = 0x00; - pci_conf[0x06] = 0x00; pci_conf[0x07] = 0x02; // PCI_status_devsel_medium pci_conf[0x4c] = 0x4d; pci_conf[0x4e] = 0x03; - pci_conf[0x4f] = 0x00; pci_conf[0x60] = 0x80; pci_conf[0x61] = 0x80; pci_conf[0x62] = 0x80; @@ -129,22 +120,9 @@ static void piix3_reset(PCIDevice *d) pci_conf[0x76] = 0x0c; pci_conf[0x77] = 0x0c; pci_conf[0x78] = 0x02; - pci_conf[0x79] = 0x00; - pci_conf[0x80] = 0x00; - pci_conf[0x82] = 0x00; pci_conf[0xa0] = 0x08; pci_conf[0xa0] = 0x08; - pci_conf[0xa2] = 0x00; - pci_conf[0xa3] = 0x00; - pci_conf[0xa4] = 0x00; - pci_conf[0xa5] = 0x00; - pci_conf[0xa6] = 0x00; - pci_conf[0xa7] = 0x00; pci_conf[0xa8] = 0x0f; - pci_conf[0xaa] = 0x00; - pci_conf[0xab] = 0x00; - pci_conf[0xac] = 0x00; - pci_conf[0xae] = 0x00; } int piix3_init(PCIBus *bus) @@ -171,227 +149,4 @@ int piix3_init(PCIBus *bus) return d->devfn; } -/***********************************************************/ -/* XXX: the following should be moved to the PC BIOS */ - -static __attribute__((unused)) uint32_t isa_inb(uint32_t addr) -{ - return cpu_inb(NULL, addr); -} - -static void isa_outb(uint32_t val, uint32_t addr) -{ - cpu_outb(NULL, addr, val); -} - -static __attribute__((unused)) uint32_t isa_inw(uint32_t addr) -{ - return cpu_inw(NULL, addr); -} - -static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr) -{ - cpu_outw(NULL, addr, val); -} - -static __attribute__((unused)) uint32_t isa_inl(uint32_t addr) -{ - return cpu_inl(NULL, addr); -} - -static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr) -{ - cpu_outl(NULL, addr, val); -} - -static uint32_t pci_bios_io_addr; -static uint32_t pci_bios_mem_addr; -/* host irqs corresponding to PCI irqs A-D */ -static uint8_t pci_irqs[4] = { 10, 11, 10, 11 }; - -static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val) -{ - PCIBus *s = d->bus; - addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); - pci_data_write(s, addr, val, 4); -} - -static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val) -{ - PCIBus *s = d->bus; - addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); - pci_data_write(s, addr, val, 2); -} - -static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val) -{ - PCIBus *s = d->bus; - addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); - pci_data_write(s, addr, val, 1); -} - -static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr) -{ - PCIBus *s = d->bus; - addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); - return pci_data_read(s, addr, 4); -} - -static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr) -{ - PCIBus *s = d->bus; - addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); - return pci_data_read(s, addr, 2); -} - -static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr) -{ - PCIBus *s = d->bus; - addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); - return pci_data_read(s, addr, 1); -} - -static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr) -{ - PCIIORegion *r; - uint16_t cmd; - uint32_t ofs; - - if ( region_num == PCI_ROM_SLOT ) { - ofs = 0x30; - }else{ - ofs = 0x10 + region_num * 4; - } - - pci_config_writel(d, ofs, addr); - r = &d->io_regions[region_num]; - - /* enable memory mappings */ - cmd = pci_config_readw(d, PCI_COMMAND); - if ( region_num == PCI_ROM_SLOT ) - cmd |= 2; - else if (r->type & PCI_ADDRESS_SPACE_IO) - cmd |= 1; - else - cmd |= 2; - pci_config_writew(d, PCI_COMMAND, cmd); -} - -static void pci_bios_init_device(PCIDevice *d) -{ - int class; - PCIIORegion *r; - uint32_t *paddr; - int i, pin, pic_irq, vendor_id, device_id; - - class = pci_config_readw(d, PCI_CLASS_DEVICE); - vendor_id = pci_config_readw(d, PCI_VENDOR_ID); - device_id = pci_config_readw(d, PCI_DEVICE_ID); - switch(class) { - case 0x0101: - if (vendor_id == 0x8086 && device_id == 0x7010) { - /* PIIX3 IDE */ - pci_config_writew(d, 0x40, 0x8000); // enable IDE0 - pci_config_writew(d, 0x42, 0x8000); // enable IDE1 - goto default_map; - } else { - /* IDE: we map it as in ISA mode */ - pci_set_io_region_addr(d, 0, 0x1f0); - pci_set_io_region_addr(d, 1, 0x3f4); - pci_set_io_region_addr(d, 2, 0x170); - pci_set_io_region_addr(d, 3, 0x374); - } - break; - case 0x0680: - if (vendor_id == 0x8086 && device_id == 0x7113) { - /* - * PIIX4 ACPI PM. - * Special device with special PCI config space. No ordinary BARs. - */ - pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable - pci_config_writew(d, 0x22, 0x0000); - pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9 - pci_config_writew(d, 0x3d, 0x0001); - } - break; - case 0x0300: - if (vendor_id != 0x1234) - goto default_map; - /* VGA: map frame buffer to default Bochs VBE address */ - pci_set_io_region_addr(d, 0, 0xE0000000); - break; - case 0x0800: - /* PIC */ - vendor_id = pci_config_readw(d, PCI_VENDOR_ID); - device_id = pci_config_readw(d, PCI_DEVICE_ID); - if (vendor_id == 0x1014) { - /* IBM */ - if (device_id == 0x0046 || device_id == 0xFFFF) { - /* MPIC & MPIC2 */ - pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000); - } - } - break; - case 0xff00: - if (vendor_id == 0x0106b && - (device_id == 0x0017 || device_id == 0x0022)) { - /* macio bridge */ - pci_set_io_region_addr(d, 0, 0x80800000); - } - break; - default: - default_map: - /* default memory mappings */ - for(i = 0; i < PCI_NUM_REGIONS; i++) { - r = &d->io_regions[i]; - if (r->size) { - if (r->type & PCI_ADDRESS_SPACE_IO) - paddr = &pci_bios_io_addr; - else - paddr = &pci_bios_mem_addr; - *paddr = (*paddr + r->size - 1) & ~(r->size - 1); - pci_set_io_region_addr(d, i, *paddr); - *paddr += r->size; - } - } - break; - } - - /* map the interrupt */ - pin = pci_config_readb(d, PCI_INTERRUPT_PIN); - if (pin != 0) { - pin = pci_slot_get_pirq(d, pin - 1); - pic_irq = pci_irqs[pin]; - pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq); - } -} - -/* - * This function initializes the PCI devices as a normal PCI BIOS - * would do. It is provided just in case the BIOS has no support for - * PCI. - */ -void pci_bios_init(void) -{ - int i, irq; - uint8_t elcr[2]; - - pci_bios_io_addr = 0xc000; - pci_bios_mem_addr = HVM_BELOW_4G_MMIO_START; - - /* activate IRQ mappings */ - elcr[0] = 0x00; - elcr[1] = 0x00; - for(i = 0; i < 4; i++) { - irq = pci_irqs[i]; - /* set to trigger level */ - elcr[irq >> 3] |= (1 << (irq & 7)); - /* activate irq remapping in PIIX */ - pci_config_writeb(piix3_dev, 0x60 + i, irq); - } - isa_outb(elcr[0], 0x4d0); - isa_outb(elcr[1], 0x4d1); - - pci_for_each_device(pci_bios_init_device); -} - +void pci_bios_init(void) {} diff -r b8cc9ffda0a3 -r a8d31d5ce258 tools/firmware/hvmloader/pci_regs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/firmware/hvmloader/pci_regs.h Wed Nov 22 17:50:20 2006 +0000 @@ -0,0 +1,108 @@ +/* + * pci_regs.h + * + * PCI standard defines + * Copyright 1994, Drew Eckhardt + * Copyright 1997--1999 Martin Mares <mj@xxxxxx> + * + * For more information, please consult the following manuals (look at + * http://www.pcisig.com/ for how to get them): + * + * PCI BIOS Specification + * PCI Local Bus Specification + * PCI to PCI Bridge Specification + * PCI System Design Guide + */ + +#ifndef __HVMLOADER_PCI_REGS_H__ +#define __HVMLOADER_PCI_REGS_H__ + +#define PCI_VENDOR_ID 0x00 /* 16 bits */ +#define PCI_DEVICE_ID 0x02 /* 16 bits */ +#define PCI_COMMAND 0x04 /* 16 bits */ +#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ +#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ +#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ +#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */ +#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */ +#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */ +#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */ +#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */ +#define PCI_COMMAND_SERR 0x100 /* Enable SERR */ +#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */ +#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */ + +#define PCI_STATUS 0x06 /* 16 bits */ +#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */ +#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */ +#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */ +#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */ +#define PCI_STATUS_PARITY 0x100 /* Detected parity error */ +#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */ +#define PCI_STATUS_DEVSEL_FAST 0x000 +#define PCI_STATUS_DEVSEL_MEDIUM 0x200 +#define PCI_STATUS_DEVSEL_SLOW 0x400 +#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */ +#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */ +#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */ +#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */ +#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */ + +#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */ +#define PCI_REVISION_ID 0x08 /* Revision ID */ +#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */ +#define PCI_CLASS_DEVICE 0x0a /* Device class */ + +#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */ +#define PCI_LATENCY_TIMER 0x0d /* 8 bits */ +#define PCI_HEADER_TYPE 0x0e /* 8 bits */ +#define PCI_HEADER_TYPE_NORMAL 0 +#define PCI_HEADER_TYPE_BRIDGE 1 +#define PCI_HEADER_TYPE_CARDBUS 2 + +#define PCI_BIST 0x0f /* 8 bits */ +#define PCI_BIST_CODE_MASK 0x0f /* Return result */ +#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */ +#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */ + +/* + * Base addresses specify locations in memory or I/O space. + * Decoded size can be determined by writing a value of + * 0xffffffff to the register, and reading it back. Only + * 1 bits are decoded. + */ +#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */ +#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */ +#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */ +#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */ +#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */ +#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */ +#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */ +#define PCI_BASE_ADDRESS_SPACE_IO 0x01 +#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00 +#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06 +#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */ +#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */ +#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */ +#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */ +#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL) +#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL) +/* bit 1 is reserved if address_space = 1 */ + +/* Header type 0 (normal devices) */ +#define PCI_CARDBUS_CIS 0x28 +#define PCI_SUBSYSTEM_VENDOR_ID 0x2c +#define PCI_SUBSYSTEM_ID 0x2e +#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */ +#define PCI_ROM_ADDRESS_ENABLE 0x01 +#define PCI_ROM_ADDRESS_MASK (~0x7ffUL) + +#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */ + +/* 0x35-0x3b are reserved */ +#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */ +#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */ +#define PCI_MIN_GNT 0x3e /* 8 bits */ +#define PCI_MAX_LAT 0x3f /* 8 bits */ + +#endif /* __HVMLOADER_PCI_REGS_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |