# 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
|