# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 40a61d01e9dc8281fbef205d19bf7306714cc3c1
# Parent 18cd7d8869490c5662056c9c52d617c02d7c2003
[HVM] Set VIOAPIC ID to a value that does not conflict with LAPIC IDs.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
tools/firmware/hvmloader/acpi/static_tables.c | 8
tools/firmware/hvmloader/config.h | 10
tools/firmware/hvmloader/hvmloader.c | 346 ++++++++++++++------------
tools/firmware/hvmloader/mp_tables.c | 36 --
4 files changed, 214 insertions(+), 186 deletions(-)
diff -r 18cd7d886949 -r 40a61d01e9dc
tools/firmware/hvmloader/acpi/static_tables.c
--- a/tools/firmware/hvmloader/acpi/static_tables.c Wed Nov 22 10:31:50
2006 +0000
+++ b/tools/firmware/hvmloader/acpi/static_tables.c Wed Nov 22 11:52:46
2006 +0000
@@ -17,6 +17,7 @@
*/
#include "acpi2_0.h"
+#include "../config.h"
#include <xen/hvm/ioreq.h>
/*
@@ -35,16 +36,17 @@ struct acpi_20_madt Madt = {
.creator_id = ACPI_CREATOR_ID,
.creator_revision = ACPI_CREATOR_REVISION
},
- .lapic_addr = 0xFEE00000,
+ .lapic_addr = LAPIC_BASE_ADDRESS,
.flags = ACPI_PCAT_COMPAT
},
/* IO APIC */
.io_apic = {
[0] = {
- .type = ACPI_IO_APIC,
+ .type = ACPI_IO_APIC,
.length = sizeof(struct acpi_20_madt_ioapic),
- .ioapic_addr = 0xFEC00000
+ .ioapic_id = IOAPIC_ID,
+ .ioapic_addr = IOAPIC_BASE_ADDRESS
}
},
diff -r 18cd7d886949 -r 40a61d01e9dc tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c Wed Nov 22 10:31:50 2006 +0000
+++ b/tools/firmware/hvmloader/hvmloader.c Wed Nov 22 11:52:46 2006 +0000
@@ -27,54 +27,51 @@
#include "util.h"
#include "acpi_utils.h"
#include "smbios.h"
+#include "config.h"
#include <xen/version.h>
#include <xen/hvm/params.h>
/* memory map */
-#define HYPERCALL_PHYSICAL_ADDRESS 0x00080000
-#define VGABIOS_PHYSICAL_ADDRESS 0x000C0000
-#define VMXASSIST_PHYSICAL_ADDRESS 0x000D0000
-#define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000
+#define HYPERCALL_PHYSICAL_ADDRESS 0x00080000
+#define VGABIOS_PHYSICAL_ADDRESS 0x000C0000
+#define VMXASSIST_PHYSICAL_ADDRESS 0x000D0000
+#define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000
/* invoke SVM's paged realmode support */
-#define SVM_VMMCALL_RESET_TO_REALMODE 0x80000001
+#define SVM_VMMCALL_RESET_TO_REALMODE 0x80000001
/*
* C runtime start off
*/
asm(
-" .text \n"
-" .globl _start \n"
-"_start: \n"
-" cld \n"
-" cli \n"
-" lgdt gdt_desr \n"
-" movl $stack_top, %esp \n"
-" movl %esp, %ebp \n"
-" call main \n"
-" jmp halt \n"
-" \n"
-"gdt_desr: \n"
-" .word gdt_end - gdt - 1 \n"
-" .long gdt \n"
-" \n"
-" .align 8 \n"
-"gdt: \n"
-" .quad 0x0000000000000000 \n"
-" .quad 0x00CF92000000FFFF \n"
-" .quad 0x00CF9A000000FFFF \n"
-"gdt_end: \n"
-" \n"
-"halt: \n"
-" sti \n"
-" jmp . \n"
-" \n"
-" .bss \n"
-" .align 8 \n"
-"stack: \n"
-" .skip 0x4000 \n"
-"stack_top: \n"
-);
+ " .text \n"
+ " .globl _start \n"
+ "_start: \n"
+ " cld \n"
+ " cli \n"
+ " lgdt gdt_desr \n"
+ " movl $stack_top, %esp \n"
+ " movl %esp, %ebp \n"
+ " call main \n"
+ " ud2 \n"
+ " \n"
+ "gdt_desr: \n"
+ " .word gdt_end - gdt - 1 \n"
+ " .long gdt \n"
+ " \n"
+ " .align 8 \n"
+ "gdt: \n"
+ " .quad 0x0000000000000000 \n"
+ " .quad 0x00CF92000000FFFF \n"
+ " .quad 0x00CF9A000000FFFF \n"
+ "gdt_end: \n"
+ " \n"
+ " .bss \n"
+ " .align 8 \n"
+ "stack: \n"
+ " .skip 0x4000 \n"
+ "stack_top: \n"
+ );
extern int get_acpi_enabled(void);
extern int acpi_madt_update(unsigned char* acpi_start);
@@ -84,145 +81,176 @@ static int
static int
cirrus_check(void)
{
- outw(0x3C4, 0x9206);
- return inb(0x3C5) == 0x12;
+ outw(0x3C4, 0x9206);
+ return inb(0x3C5) == 0x12;
}
static int
vmmcall(int function, int edi, int esi, int edx, int ecx, int ebx)
{
- int eax;
-
- __asm__ __volatile__(
- ".byte 0x0F,0x01,0xD9"
- : "=a" (eax)
- : "a"(function),
- "b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi)
- );
- return eax;
+ int eax;
+
+ __asm__ __volatile__ (
+ ".byte 0x0F,0x01,0xD9"
+ : "=a" (eax)
+ : "a"(function),
+ "b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi) );
+ return eax;
}
static int
check_amd(void)
{
- char id[12];
-
- __asm__ __volatile__(
- "cpuid"
- : "=b" (*(int *)(&id[0])),
- "=c" (*(int *)(&id[8])),
- "=d" (*(int *)(&id[4]))
- : "a" (0)
- );
- return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
+ char id[12];
+
+ __asm__ __volatile__ (
+ "cpuid"
+ : "=b" (*(int *)(&id[0])),
+ "=c" (*(int *)(&id[8])),
+ "=d" (*(int *)(&id[4]))
+ : "a" (0) );
+ return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
}
static void
wrmsr(uint32_t idx, uint64_t v)
{
- __asm__ __volatile__(
- "wrmsr"
- : : "c" (idx), "a" ((uint32_t)v), "d" ((uint32_t)(v>>32)) );
+ __asm__ __volatile__ (
+ "wrmsr"
+ : : "c" (idx), "a" ((uint32_t)v), "d" ((uint32_t)(v>>32)) );
}
static void
init_hypercalls(void)
{
- uint32_t eax, ebx, ecx, edx;
- unsigned long i;
- char signature[13], number[13];
- xen_extraversion_t extraversion;
-
- cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
-
- *(uint32_t *)(signature + 0) = ebx;
- *(uint32_t *)(signature + 4) = ecx;
- *(uint32_t *)(signature + 8) = edx;
- signature[12] = '\0';
-
- if (strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002)) {
- puts("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));
-
- cpuid(0x40000002, &eax, &ebx, &ecx, &edx);
-
- for (i = 0; i < eax; i++)
- wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i);
-
- hypercall_xen_version(XENVER_extraversion, extraversion);
- puts(extraversion);
- puts("\n");
-}
-
-int
-main(void)
-{
- puts("HVM Loader\n");
-
- init_hypercalls();
-
- puts("Writing SMBIOS tables ...\n");
- hvm_write_smbios_tables();
-
- puts("Loading ROMBIOS ...\n");
- memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
-
- create_mp_tables();
-
- if (cirrus_check()) {
- puts("Loading Cirrus VGABIOS ...\n");
- memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
- vgabios_cirrusvga, sizeof(vgabios_cirrusvga));
- } else {
- puts("Loading Standard VGABIOS ...\n");
- memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
- vgabios_stdvga, sizeof(vgabios_stdvga));
- }
-
- if (get_acpi_enabled() != 0) {
- puts("Loading ACPI ...\n");
- acpi_madt_update((unsigned char *) acpi);
- if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
- unsigned char *freemem = (unsigned char *)
- (ACPI_PHYSICAL_ADDRESS + sizeof(acpi));
- /*
- * Make sure acpi table does not overlap rombios
- * currently acpi less than 8K will be OK.
- */
- memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi,
- sizeof(acpi));
- acpi_update((unsigned char *)ACPI_PHYSICAL_ADDRESS,
- sizeof(acpi),
- (unsigned char *)0xF0000,
- &freemem);
- }
- }
-
- if (check_amd()) {
- /* AMD implies this is SVM */
- puts("SVM go ...\n");
- vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0);
- } else {
- puts("Loading VMXAssist ...\n");
- memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
- vmxassist, sizeof(vmxassist));
-
- puts("VMX go ...\n");
- __asm__ __volatile__(
- "jmp *%%eax"
- : : "a" (VMXASSIST_PHYSICAL_ADDRESS), "d" (0)
- );
- }
-
- puts("Failed to invoke ROMBIOS\n");
- return 0;
-}
-
+ uint32_t eax, ebx, ecx, edx;
+ unsigned long i;
+ char signature[13], number[13];
+ xen_extraversion_t extraversion;
+
+ cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
+
+ *(uint32_t *)(signature + 0) = ebx;
+ *(uint32_t *)(signature + 4) = ecx;
+ *(uint32_t *)(signature + 8) = edx;
+ signature[12] = '\0';
+
+ if ( strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002) )
+ {
+ puts("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));
+
+ cpuid(0x40000002, &eax, &ebx, &ecx, &edx);
+
+ for ( i = 0; i < eax; i++ )
+ wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i);
+
+ hypercall_xen_version(XENVER_extraversion, extraversion);
+ puts(extraversion);
+ puts("\n");
+}
+
+static void apic_setup(void)
+{
+ volatile uint32_t *ioregsel;
+ volatile uint32_t *iowin;
+
+ /* IOAPIC memory-mapped access window registers. */
+ ioregsel = (volatile uint32_t *)(IOAPIC_BASE_ADDRESS + 0x00);
+ iowin = (volatile uint32_t *)(IOAPIC_BASE_ADDRESS + 0x10);
+
+ /* Set the IOAPIC ID to tha static value used in the MP/ACPI tables. */
+ *ioregsel = 0;
+ *iowin = IOAPIC_ID;
+}
+
+int main(void)
+{
+ puts("HVM Loader\n");
+
+ init_hypercalls();
+
+ puts("Writing SMBIOS tables ...\n");
+ hvm_write_smbios_tables();
+
+ puts("Loading ROMBIOS ...\n");
+ memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
+
+ apic_setup();
+
+ create_mp_tables();
+
+ if ( cirrus_check() )
+ {
+ puts("Loading Cirrus VGABIOS ...\n");
+ memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
+ vgabios_cirrusvga, sizeof(vgabios_cirrusvga));
+ }
+ else
+ {
+ puts("Loading Standard VGABIOS ...\n");
+ memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
+ vgabios_stdvga, sizeof(vgabios_stdvga));
+ }
+
+ if ( get_acpi_enabled() != 0 )
+ {
+ puts("Loading ACPI ...\n");
+ acpi_madt_update((unsigned char *) acpi);
+ if ( (ACPI_PHYSICAL_ADDRESS + sizeof(acpi)) <= 0xF0000 )
+ {
+ unsigned char *freemem = (unsigned char *)
+ (ACPI_PHYSICAL_ADDRESS + sizeof(acpi));
+ /*
+ * Make sure acpi table does not overlap rombios
+ * currently acpi less than 8K will be OK.
+ */
+ memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi,
+ sizeof(acpi));
+ acpi_update((unsigned char *)ACPI_PHYSICAL_ADDRESS,
+ sizeof(acpi),
+ (unsigned char *)0xF0000,
+ &freemem);
+ }
+ }
+
+ if ( check_amd() )
+ {
+ /* AMD implies this is SVM */
+ puts("SVM go ...\n");
+ vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0);
+ }
+ else
+ {
+ puts("Loading VMXAssist ...\n");
+ memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
+ vmxassist, sizeof(vmxassist));
+
+ puts("VMX go ...\n");
+ __asm__ __volatile__(
+ "jmp *%%eax"
+ : : "a" (VMXASSIST_PHYSICAL_ADDRESS), "d" (0)
+ );
+ }
+
+ puts("Failed to invoke ROMBIOS\n");
+ return 0;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 18cd7d886949 -r 40a61d01e9dc tools/firmware/hvmloader/mp_tables.c
--- a/tools/firmware/hvmloader/mp_tables.c Wed Nov 22 10:31:50 2006 +0000
+++ b/tools/firmware/hvmloader/mp_tables.c Wed Nov 22 11:52:46 2006 +0000
@@ -29,6 +29,7 @@
*/
#include <acpi_utils.h>
+#include "config.h"
/* FIXME find a header that already has types defined!!! */
typedef unsigned char uint8_t;
@@ -45,11 +46,11 @@ typedef signed long int64_t;
typedef signed long int64_t;
#endif
-#define ROMBIOS_SEG 0xF000
-#define ROMBIOS_BEGIN 0x000F0000
-#define ROMBIOS_SIZE 0x00010000
-#define ROMBIOS_MAXOFFSET 0x0000FFFF
-#define ROMBIOS_END (ROMBIOS_BEGIN + ROMBIOS_SIZE)
+#define ROMBIOS_SEG 0xF000
+#define ROMBIOS_BEGIN 0x000F0000
+#define ROMBIOS_SIZE 0x00010000
+#define ROMBIOS_MAXOFFSET 0x0000FFFF
+#define ROMBIOS_END (ROMBIOS_BEGIN + ROMBIOS_SIZE)
/* number of non-processor MP table entries */
#define NR_NONPROC_ENTRIES 18
@@ -78,17 +79,7 @@ typedef signed long int64_t;
#define BUS_TYPE_LENGTH 6
#define BUS_TYPE_STR_ISA "ISA "
-#define BUS_TYPE_STR_PCI "PCI "
-
#define BUS_ID_ISA 0
-#define BUS_ID_PCI 1
-
-#define LAPIC_BASE_ADDR 0xFEE00000
-
-#define IOAPIC_ID 0
-#define IOAPIC_VERSION 0x11
-#define IOAPIC_BASE_ADDR 0xFEC00000
-#define IOAPIC_FLAG_ENABLED (1U << 0)
#define INTR_TYPE_INT 0
#define INTR_TYPE_NMI 1
@@ -217,7 +208,7 @@ void fill_mp_config_table(struct mp_conf
mpct->nr_entries = vcpu_nr + NR_NONPROC_ENTRIES;
- mpct->lapic = LAPIC_BASE_ADDR;
+ mpct->lapic = LAPIC_BASE_ADDRESS;
mpct->extended_length = 0;
mpct->extended_checksum = 0;
@@ -255,13 +246,13 @@ void fill_mp_bus_entry(struct mp_bus_ent
/* fills in an MP IOAPIC entry for IOAPIC 'ioapic_id' */
-void fill_mp_ioapic_entry(struct mp_ioapic_entry *mpie, int ioapic_id)
+void fill_mp_ioapic_entry(struct mp_ioapic_entry *mpie)
{
mpie->type = ENTRY_TYPE_IOAPIC;
- mpie->ioapic_id = ioapic_id;
+ mpie->ioapic_id = IOAPIC_ID;
mpie->ioapic_version = IOAPIC_VERSION;
- mpie->ioapic_flags = IOAPIC_FLAG_ENABLED;
- mpie->ioapic_addr = IOAPIC_BASE_ADDR;
+ mpie->ioapic_flags = 1; /* enabled */
+ mpie->ioapic_addr = IOAPIC_BASE_ADDRESS;
}
@@ -379,10 +370,7 @@ void create_mp_tables(void)
fill_mp_bus_entry((struct mp_bus_entry *)p, BUS_ID_ISA, BUS_TYPE_STR_ISA);
p += sizeof(struct mp_bus_entry);
- fill_mp_bus_entry((struct mp_bus_entry *)p, BUS_ID_PCI, BUS_TYPE_STR_PCI);
- p += sizeof(struct mp_bus_entry);
-
- fill_mp_ioapic_entry((struct mp_ioapic_entry *)p, IOAPIC_ID);
+ fill_mp_ioapic_entry((struct mp_ioapic_entry *)p);
p += sizeof(struct mp_ioapic_entry);
for ( i = 0; i < 16; i++ )
diff -r 18cd7d886949 -r 40a61d01e9dc tools/firmware/hvmloader/config.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/firmware/hvmloader/config.h Wed Nov 22 11:52:46 2006 +0000
@@ -0,0 +1,10 @@
+#ifndef __HVMLOADER_CONFIG_H__
+#define __HVMLOADER_CONFIG_H__
+
+#define IOAPIC_BASE_ADDRESS 0xfec00000
+#define IOAPIC_ID 0xfe
+#define IOAPIC_VERSION 0x11
+
+#define LAPIC_BASE_ADDRESS 0xfee00000
+
+#endif /* __HVMLOADER_CONFIG_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|