# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxxx
# Node ID 4d07411c517adf3b24e03e71f7d8049e7754fb1c
# Parent 91951de7592c0a553dd5bacef6b481cab2e9fac5
[HVM] Dynamically build ACPI-table data block.
Only emit MP tables and MADT for multi-processor guests.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
tools/firmware/hvmloader/acpi/gen.c | 55 ---
tools/firmware/hvmloader/acpi_madt.c | 164 -----------
tools/firmware/hvmloader/Makefile | 12
tools/firmware/hvmloader/acpi/Makefile | 22 -
tools/firmware/hvmloader/acpi/acpi2_0.h | 11
tools/firmware/hvmloader/acpi/build.c | 385 +++++++++++---------------
tools/firmware/hvmloader/acpi/static_tables.c | 72 ----
tools/firmware/hvmloader/hvmloader.c | 33 --
tools/firmware/hvmloader/util.c | 57 +++
tools/firmware/hvmloader/util.h | 6
10 files changed, 268 insertions(+), 549 deletions(-)
diff -r 91951de7592c -r 4d07411c517a tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Sun Nov 26 17:35:00 2006 +0000
+++ b/tools/firmware/hvmloader/Makefile Sun Nov 26 17:37:28 2006 +0000
@@ -40,25 +40,27 @@ CFLAGS += $(DEFINES) -I. $(XENINC) -fno
CFLAGS += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float
LDFLAGS = -nostdlib -Wl,-N -Wl,-Ttext -Wl,$(LOADADDR)
-SRCS = hvmloader.c acpi_madt.c mp_tables.c util.c smbios.c acpi_utils.c
+SRCS = hvmloader.c mp_tables.c util.c smbios.c acpi_utils.c
OBJS = $(patsubst %.c,%.o,$(SRCS))
.PHONY: all
all: hvmloader
-hvmloader: roms.h $(SRCS)
+hvmloader: roms.h acpi/acpi.a $(SRCS)
$(CC) $(CFLAGS) -c $(SRCS)
- $(CC) $(CFLAGS) $(LDFLAGS) -o hvmloader.tmp $(OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o hvmloader.tmp $(OBJS) acpi/acpi.a
$(OBJCOPY) hvmloader.tmp hvmloader
rm -f hvmloader.tmp
+.PHONY: acpi/acpi.a
+acpi/acpi.a:
+ $(MAKE) -C acpi
+
roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin
../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin
- $(MAKE) -C acpi
sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin
>> roms.h
sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
- sh ./mkhex acpi acpi/acpi.bin >> roms.h
.PHONY: clean
clean:
diff -r 91951de7592c -r 4d07411c517a tools/firmware/hvmloader/acpi/Makefile
--- a/tools/firmware/hvmloader/acpi/Makefile Sun Nov 26 17:35:00 2006 +0000
+++ b/tools/firmware/hvmloader/acpi/Makefile Sun Nov 26 17:37:28 2006 +0000
@@ -15,21 +15,20 @@
# Place - Suite 330, Boston, MA 02111-1307 USA.
#
+override XEN_TARGET_ARCH = x86_32
XEN_ROOT = ../../../..
+CFLAGS := -I. -I.. -I$(XEN_ROOT)/tools/libxc
include $(XEN_ROOT)/tools/Rules.mk
-HOSTCFLAGS += -I. -I.. -I$(XEN_ROOT)/tools/libxc
-
-C_SRC = build.c dsdt.c gen.c static_tables.c
+C_SRC = build.c dsdt.c static_tables.c
H_SRC = $(wildcard *.h)
-ACPI_GEN = acpigen
-ACPI_BIN = acpi.bin
+OBJS = $(patsubst %.c,%.o,$(C_SRC))
IASL_VER = acpica-unix-20050513
IASL_URL =
http://developer.intel.com/technology/iapc/acpi/downloads/$(IASL_VER).tar.gz
vpath iasl $(PATH)
-all:$(ACPI_BIN)
+all: acpi.a
dsdt.c: dsdt.asl
$(MAKE) iasl
@@ -50,14 +49,13 @@ iasl:
make -C $(IASL_VER)/compiler
$(INSTALL_PROG) $(IASL_VER)/compiler/iasl /usr/bin/iasl
-$(ACPI_GEN): $(C_SRC) $(H_SRC)
- $(HOSTCC) -o $(ACPI_GEN) $(HOSTCFLAGS) $(C_SRC)
+acpi.a: $(OBJS)
+ $(AR) rc $@ $(OBJS)
-$(ACPI_BIN): $(ACPI_GEN)
- ./$(ACPI_GEN) $(ACPI_BIN)
+%.o: %.c $(H_SRC)
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
clean:
- rm -rf *.o $(ACPI_GEN) $(ACPI_BIN) $(IASL_VER)
- rm -rf $(IASL_VER).tar.gz
+ rm -rf *.a *.o $(IASL_VER) $(IASL_VER).tar.gz
install: all
diff -r 91951de7592c -r 4d07411c517a tools/firmware/hvmloader/acpi/acpi2_0.h
--- a/tools/firmware/hvmloader/acpi/acpi2_0.h Sun Nov 26 17:35:00 2006 +0000
+++ b/tools/firmware/hvmloader/acpi/acpi2_0.h Sun Nov 26 17:37:28 2006 +0000
@@ -249,7 +249,7 @@ struct acpi_20_facs {
/*
* Multiple APIC Description Table header definition (MADT).
*/
-struct acpi_20_madt_header {
+struct acpi_20_madt {
struct acpi_header header;
uint32_t lapic_addr;
uint32_t flags;
@@ -316,13 +316,6 @@ struct acpi_20_madt_intsrcovr {
uint16_t flags;
};
-struct acpi_20_madt {
- struct acpi_20_madt_header header;
- struct acpi_20_madt_intsrcovr intsrcovr[4];
- struct acpi_20_madt_ioapic io_apic[1];
- struct acpi_20_madt_lapic lapic[32];
-};
-
/*
* Table Signatures.
*/
@@ -338,7 +331,7 @@ struct acpi_20_madt {
#define ACPI_PHYSICAL_ADDRESS 0xEA000
-void AcpiBuildTable(uint8_t *buf);
+int acpi_build_tables(uint8_t *);
#endif /* _ACPI_2_0_H_ */
diff -r 91951de7592c -r 4d07411c517a tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c Sun Nov 26 17:35:00 2006 +0000
+++ b/tools/firmware/hvmloader/acpi/build.c Sun Nov 26 17:37:28 2006 +0000
@@ -1,233 +1,196 @@
/*
* Copyright (c) 2004, Intel Corporation.
+ * Copyright (c) 2006, Keir Fraser, XenSource Inc.
*
* This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
+ * under the terms and conditions of the GNU General Public License, version
+ * 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
- *
*/
#include "acpi2_0.h"
+#include "../config.h"
+#include "../util.h"
extern struct acpi_20_rsdp Rsdp;
extern struct acpi_20_rsdt Rsdt;
extern struct acpi_20_xsdt Xsdt;
extern struct acpi_20_fadt Fadt;
-extern struct acpi_20_madt Madt;
extern struct acpi_20_facs Facs;
-extern unsigned char *AmlCode;
+extern unsigned char AmlCode[];
extern int DsdtLen;
-
-typedef struct _ACPI_TABLE_ALL{
- struct acpi_20_rsdp *Rsdp;
- struct acpi_20_rsdt *Rsdt;
- struct acpi_20_xsdt *Xsdt;
- struct acpi_20_fadt *Fadt;
- struct acpi_20_madt *Madt;
- struct acpi_20_facs *Facs;
- unsigned char *Dsdt;
- uint32_t RsdpOffset;
- uint32_t RsdtOffset;
- uint32_t XsdtOffset;
- uint32_t FadtOffset;
- uint32_t MadtOffset;
- uint32_t FacsOffset;
- uint32_t DsdtOffset;
-}ACPI_TABLE_ALL;
-
-static
-void
-MemCopy(void* src, void* dst, int len){
-
- uint8_t* src0=src;
- uint8_t* dst0=dst;
-
- while(len--){
- *(dst0++)=*(src0++);
- }
-}
-
-static
-void
-SetCheckSum(
- void* Table,
- uint32_t ChecksumOffset,
- uint32_t Length
- )
-/*
- * Routine Description:
- * Calculate Checksum and store the result in the checksum
- * filed of the table
- *
- * INPUT:
- * Table: Start pointer of table
- * ChecksumOffset: Offset of checksum field in the table
- * Length: Length of Table
- */
-{
- uint8_t Sum = 0;
- uint8_t *Ptr;
-
- Ptr=Table;
- Ptr[ChecksumOffset]=0;
- while (Length--) {
- Sum = (uint8_t)(Sum + (*Ptr++));
- }
-
- Ptr = Table;
- Ptr[ChecksumOffset] = (uint8_t) (0xff - Sum + 1);
-}
-
-//
-// FIELD_OFFSET - returns the byte offset to a field within a structure
-//
-#define FIELD_OFFSET(TYPE,Field) ((uint32_t)(&(((TYPE *) 0)->Field)))
-
-static
-void
-UpdateTable(
- ACPI_TABLE_ALL *table
- )
-/*
- * Update the ACPI table:
- * fill in the actuall physical address of RSDT, XSDT, FADT, MADT,
FACS
- * Caculate the checksum
- */
-{
- // RSDP Update
- table->Rsdp->rsdt_address = (uint32_t)(ACPI_PHYSICAL_ADDRESS+
- table->RsdtOffset);
- table->Rsdp->xsdt_address = (uint64_t)(ACPI_PHYSICAL_ADDRESS+
- table->XsdtOffset);
- SetCheckSum(table->Rsdp,
- FIELD_OFFSET(struct acpi_10_rsdp, checksum),
- sizeof(struct acpi_10_rsdp)
- );
- SetCheckSum(table->Rsdp,
- FIELD_OFFSET(struct acpi_20_rsdp,
- extended_checksum),
- sizeof(struct acpi_20_rsdp)
- );
-
-
- //RSDT Update
- table->Rsdt->entry[0] = (uint32_t)(ACPI_PHYSICAL_ADDRESS +
- table->FadtOffset);
- table->Rsdt->entry[1] = (uint32_t)(ACPI_PHYSICAL_ADDRESS +
- table->MadtOffset);
- table->Rsdt->header.length = sizeof (struct acpi_header) +
- 2*sizeof(uint32_t);
- SetCheckSum(table->Rsdt,
- FIELD_OFFSET(struct acpi_header, checksum),
- table->Rsdt->header.length
- );
-
- //XSDT Update
- table->Xsdt->entry[0] = (uint64_t)(ACPI_PHYSICAL_ADDRESS +
- table->FadtOffset);
- table->Xsdt->entry[1] = (uint64_t)(ACPI_PHYSICAL_ADDRESS +
- table->MadtOffset);
- table->Xsdt->header.length = sizeof (struct acpi_header) +
- 2*sizeof(uint64_t);
- SetCheckSum(table->Xsdt,
- FIELD_OFFSET(struct acpi_header, checksum),
- table->Xsdt->header.length
- );
-
- // FADT Update
- table->Fadt->dsdt = (uint32_t)(ACPI_PHYSICAL_ADDRESS +
- table->DsdtOffset);
- table->Fadt->x_dsdt = (uint64_t)(ACPI_PHYSICAL_ADDRESS +
- table->DsdtOffset);
- table->Fadt->firmware_ctrl = (uint32_t)(ACPI_PHYSICAL_ADDRESS +
- table->FacsOffset);
- table->Fadt->x_firmware_ctrl = (uint64_t)(ACPI_PHYSICAL_ADDRESS +
- table->FacsOffset);
- SetCheckSum(table->Fadt,
- FIELD_OFFSET(struct acpi_header, checksum),
- sizeof(struct acpi_20_fadt)
- );
-
- // MADT update
- SetCheckSum(table->Madt,
- FIELD_OFFSET(struct acpi_header, checksum),
- sizeof(struct acpi_20_madt)
- );
-}
-
-void
-AcpiBuildTable(uint8_t* buf)
-/*
- * Copy all the ACPI table to buffer
- * Buffer Layout:
- * FACS
- * RSDP
- * RSDT
- * XSDT
- * FADT
- * MADT
- * DSDT
- *
- */
-{
- ACPI_TABLE_ALL table;
- int offset=0;
-
- // FACS: should be 64-bit alignment
- // so it is put at the start of buffer
- // as the buffer is 64 bit alignment
- table.FacsOffset = offset;
- table.Facs = (struct acpi_20_facs *)(&buf[offset]);
- MemCopy(&Facs, table.Facs, sizeof(struct acpi_20_facs));
- offset += sizeof(struct acpi_20_facs);
-
- // RSDP
- table.RsdpOffset = offset;
- table.Rsdp = (struct acpi_20_rsdp *)(&buf[offset]);
- MemCopy(&Rsdp, table.Rsdp, sizeof(struct acpi_20_rsdp));
- offset += sizeof(struct acpi_20_rsdp);
-
- // RSDT
- table.RsdtOffset = offset;
- table.Rsdt = (struct acpi_20_rsdt *)(&buf[offset]);
- MemCopy(&Rsdt, table.Rsdt, sizeof(struct acpi_20_rsdt));
- offset += sizeof(struct acpi_20_rsdt);
-
- // XSDT
- table.XsdtOffset = offset;
- table.Xsdt = (struct acpi_20_xsdt *)(&buf[offset]);
- MemCopy(&Xsdt, table.Xsdt, sizeof(struct acpi_20_xsdt));
- offset += sizeof(struct acpi_20_xsdt);
-
- // FADT
- table.FadtOffset = offset;
- table.Fadt = (struct acpi_20_fadt *)(&buf[offset]);
- MemCopy(&Fadt, table.Fadt, sizeof(struct acpi_20_fadt));
- offset += sizeof(struct acpi_20_fadt);
-
- // MADT
- table.MadtOffset = offset;
- table.Madt = (struct acpi_20_madt*)(&buf[offset]);
- MemCopy(&Madt, table.Madt, sizeof(struct acpi_20_madt));
- offset += sizeof(struct acpi_20_madt);
-
- // DSDT
- table.DsdtOffset = offset;
- table.Dsdt = (unsigned char *)(&buf[offset]);
- MemCopy(&AmlCode, table.Dsdt, DsdtLen);
- offset += DsdtLen;
-
- UpdateTable(&table);
+static void set_checksum(
+ void *table, uint32_t checksum_offset, uint32_t length)
+{
+ uint8_t *p, sum = 0;
+
+ p = table;
+ p[checksum_offset] = 0;
+
+ while ( length-- )
+ sum = sum + *p++;
+
+ p = table;
+ p[checksum_offset] = -sum;
+}
+
+int construct_madt(struct acpi_20_madt *madt)
+{
+ struct acpi_20_madt_intsrcovr *intsrcovr;
+ struct acpi_20_madt_ioapic *io_apic;
+ struct acpi_20_madt_lapic *lapic;
+ int i, offset = 0;
+
+ memset(madt, 0, sizeof(*madt));
+ madt->header.signature = ACPI_2_0_MADT_SIGNATURE;
+ madt->header.revision = ACPI_2_0_MADT_REVISION;
+ strncpy(madt->header.oem_id, "INTEL ", 6);
+ madt->header.oem_table_id = ACPI_OEM_TABLE_ID;
+ madt->header.oem_revision = ACPI_OEM_REVISION;
+ madt->header.creator_id = ACPI_CREATOR_ID;
+ madt->header.creator_revision = ACPI_CREATOR_REVISION;
+ madt->lapic_addr = LAPIC_BASE_ADDRESS;
+ madt->flags = ACPI_PCAT_COMPAT;
+ offset += sizeof(*madt);
+
+ intsrcovr = (struct acpi_20_madt_intsrcovr *)(madt + 1);
+ for ( i = 0; i < 16; i++ )
+ {
+ if ( !(PCI_ISA_IRQ_MASK & (1U << i)) )
+ continue;
+
+ /* PCI: active-low level-triggered */
+ memset(intsrcovr, 0, sizeof(*intsrcovr));
+ intsrcovr->type = ACPI_INTERRUPT_SOURCE_OVERRIDE;
+ intsrcovr->length = sizeof(*intsrcovr);
+ intsrcovr->source = i;
+ intsrcovr->gsi = i;
+ intsrcovr->flags = 0xf;
+
+ offset += sizeof(*intsrcovr);
+ intsrcovr++;
+ }
+
+ io_apic = (struct acpi_20_madt_ioapic *)intsrcovr;
+ memset(io_apic, 0, sizeof(*io_apic));
+ io_apic->type = ACPI_IO_APIC;
+ io_apic->length = sizeof(*io_apic);
+ io_apic->ioapic_id = IOAPIC_ID;
+ io_apic->ioapic_addr = IOAPIC_BASE_ADDRESS;
+ offset += sizeof(*io_apic);
+
+ lapic = (struct acpi_20_madt_lapic *)io_apic;
+ for ( i = 0; i < get_vcpu_nr(); i++ )
+ {
+ memset(lapic, 0, sizeof(*lapic));
+ lapic->type = ACPI_PROCESSOR_LOCAL_APIC;
+ lapic->length = sizeof(*lapic);
+ lapic->acpi_processor_id = i;
+ lapic->apic_id = i;
+ lapic->flags = ACPI_LOCAL_APIC_ENABLED;
+ offset += sizeof(*lapic);
+ lapic++;
+ }
+
+ madt->header.length = offset;
+ set_checksum(madt, offsetof(struct acpi_header, checksum), offset);
+
+ return offset;
+}
+
+/*
+ * Copy all the ACPI table to buffer.
+ * Buffer layout: FACS, DSDT, FADT, MADT, XSDT, RSDT, RSDP.
+ */
+int acpi_build_tables(uint8_t *buf)
+{
+ struct acpi_20_rsdp *rsdp;
+ struct acpi_20_rsdt *rsdt;
+ struct acpi_20_xsdt *xsdt;
+ struct acpi_20_fadt *fadt;
+ struct acpi_20_madt *madt = 0;
+ struct acpi_20_facs *facs;
+ unsigned char *dsdt;
+ int offset = 0, nr_vcpus = get_vcpu_nr();
+
+#define inc_offset(sz) (offset = (offset + (sz) + 15) & ~15)
+#define requires_madt() (nr_vcpus > 1)
+
+ facs = (struct acpi_20_facs *)&buf[offset];
+ memcpy(facs, &Facs, sizeof(struct acpi_20_facs));
+ inc_offset(sizeof(struct acpi_20_facs));
+
+ dsdt = (unsigned char *)&buf[offset];
+ memcpy(dsdt, &AmlCode, DsdtLen);
+ inc_offset(DsdtLen);
+
+ fadt = (struct acpi_20_fadt *)&buf[offset];
+ memcpy(fadt, &Fadt, sizeof(struct acpi_20_fadt));
+ inc_offset(sizeof(struct acpi_20_fadt));
+ fadt->dsdt = (unsigned long)dsdt;
+ fadt->x_dsdt = (unsigned long)dsdt;
+ fadt->firmware_ctrl = (unsigned long)facs;
+ fadt->x_firmware_ctrl = (unsigned long)facs;
+ set_checksum(fadt,
+ offsetof(struct acpi_header, checksum),
+ sizeof(struct acpi_20_fadt));
+
+ if ( requires_madt() )
+ {
+ madt = (struct acpi_20_madt *)&buf[offset];
+ inc_offset(construct_madt(madt));
+ }
+
+ xsdt = (struct acpi_20_xsdt *)&buf[offset];
+ memcpy(xsdt, &Xsdt, sizeof(struct acpi_20_xsdt));
+ inc_offset(sizeof(struct acpi_20_xsdt));
+ xsdt->entry[0] = (unsigned long)fadt;
+ xsdt->header.length = sizeof(struct acpi_header) + sizeof(uint64_t);
+ if ( requires_madt() )
+ {
+ xsdt->entry[1] = (unsigned long)madt;
+ xsdt->header.length += sizeof(uint64_t);
+ }
+ set_checksum(xsdt,
+ offsetof(struct acpi_header, checksum),
+ xsdt->header.length);
+
+ rsdt = (struct acpi_20_rsdt *)&buf[offset];
+ memcpy(rsdt, &Rsdt, sizeof(struct acpi_20_rsdt));
+ inc_offset(sizeof(struct acpi_20_rsdt));
+ rsdt->entry[0] = (unsigned long)fadt;
+ rsdt->header.length = sizeof(struct acpi_header) + sizeof(uint32_t);
+ if ( requires_madt() )
+ {
+ rsdt->entry[1] = (unsigned long)madt;
+ rsdt->header.length += sizeof(uint32_t);
+ }
+ set_checksum(rsdt,
+ offsetof(struct acpi_header, checksum),
+ rsdt->header.length);
+
+ rsdp = (struct acpi_20_rsdp *)&buf[offset];
+ memcpy(rsdp, &Rsdp, sizeof(struct acpi_20_rsdp));
+ inc_offset(sizeof(struct acpi_20_rsdp));
+ rsdp->rsdt_address = (unsigned long)rsdt;
+ rsdp->xsdt_address = (unsigned long)xsdt;
+ set_checksum(rsdp,
+ offsetof(struct acpi_10_rsdp, checksum),
+ sizeof(struct acpi_10_rsdp));
+ set_checksum(rsdp,
+ offsetof(struct acpi_20_rsdp, extended_checksum),
+ sizeof(struct acpi_20_rsdp));
+
+ return offset;
}
/*
diff -r 91951de7592c -r 4d07411c517a
tools/firmware/hvmloader/acpi/static_tables.c
--- a/tools/firmware/hvmloader/acpi/static_tables.c Sun Nov 26 17:35:00
2006 +0000
+++ b/tools/firmware/hvmloader/acpi/static_tables.c Sun Nov 26 17:37:28
2006 +0000
@@ -19,78 +19,6 @@
#include "acpi2_0.h"
#include "../config.h"
#include <xen/hvm/ioreq.h>
-
-/*
- * Multiple APIC Description Table (MADT).
- */
-
-struct acpi_20_madt Madt = {
- .header = {
- .header = {
- .signature = ACPI_2_0_MADT_SIGNATURE,
- .length = sizeof(struct acpi_20_madt),
- .revision = ACPI_2_0_MADT_REVISION,
- .oem_id = ACPI_OEM_ID,
- .oem_table_id = ACPI_OEM_TABLE_ID,
- .oem_revision = ACPI_OEM_REVISION,
- .creator_id = ACPI_CREATOR_ID,
- .creator_revision = ACPI_CREATOR_REVISION
- },
- .lapic_addr = LAPIC_BASE_ADDRESS,
- .flags = ACPI_PCAT_COMPAT
- },
-
- .intsrcovr = {
- [0] = {
- .type = ACPI_INTERRUPT_SOURCE_OVERRIDE,
- .length = sizeof(struct acpi_20_madt_intsrcovr),
- .source = 5,
- .gsi = 5,
- .flags = 0xf /* PCI: active-low level-triggered */
- },
- [1] = {
- .type = ACPI_INTERRUPT_SOURCE_OVERRIDE,
- .length = sizeof(struct acpi_20_madt_intsrcovr),
- .source = 6,
- .gsi = 6,
- .flags = 0xf /* PCI: active-low level-triggered */
- },
- [2] = {
- .type = ACPI_INTERRUPT_SOURCE_OVERRIDE,
- .length = sizeof(struct acpi_20_madt_intsrcovr),
- .source = 10,
- .gsi = 10,
- .flags = 0xf /* PCI: active-low level-triggered */
- },
- [3] = {
- .type = ACPI_INTERRUPT_SOURCE_OVERRIDE,
- .length = sizeof(struct acpi_20_madt_intsrcovr),
- .source = 11,
- .gsi = 11,
- .flags = 0xf /* PCI: active-low level-triggered */
- }
- },
-
- /* IO APIC */
- .io_apic = {
- [0] = {
- .type = ACPI_IO_APIC,
- .length = sizeof(struct acpi_20_madt_ioapic),
- .ioapic_id = IOAPIC_ID,
- .ioapic_addr = IOAPIC_BASE_ADDRESS
- }
- },
-
- /* Local APIC entries for up to 32 processors. */
- .lapic = {
- [0] = {
- .type = ACPI_PROCESSOR_LOCAL_APIC,
- .length = sizeof(struct acpi_20_madt_lapic),
- .flags = ACPI_LOCAL_APIC_ENABLED
- }
- }
-};
-
/*
* Firmware ACPI Control Structure (FACS).
diff -r 91951de7592c -r 4d07411c517a tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c Sun Nov 26 17:35:00 2006 +0000
+++ b/tools/firmware/hvmloader/hvmloader.c Sun Nov 26 17:37:28 2006 +0000
@@ -74,10 +74,7 @@ asm(
"stack_top: \n"
);
-extern int get_acpi_enabled(void);
-extern int acpi_madt_update(unsigned char* acpi_start);
extern void create_mp_tables(void);
-struct hvm_info_table *get_hvm_info_table(void);
static int
cirrus_check(void)
@@ -285,6 +282,9 @@ static void pci_setup(void)
int main(void)
{
+ int acpi_sz;
+ uint8_t *freemem;
+
printf("HVM Loader\n");
init_hypercalls();
@@ -297,7 +297,9 @@ int main(void)
apic_setup();
pci_setup();
- create_mp_tables();
+
+ if ( get_vcpu_nr() > 1 )
+ create_mp_tables();
if ( cirrus_check() )
{
@@ -315,22 +317,13 @@ int main(void)
if ( get_acpi_enabled() != 0 )
{
printf("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);
- }
+ acpi_sz = acpi_build_tables((uint8_t *)ACPI_PHYSICAL_ADDRESS);
+ freemem = (uint8_t *)ACPI_PHYSICAL_ADDRESS + acpi_sz;
+ ASSERT(freemem <= (uint8_t *)0xF0000);
+ acpi_update((unsigned char *)ACPI_PHYSICAL_ADDRESS,
+ freemem - (uint8_t *)ACPI_PHYSICAL_ADDRESS,
+ (unsigned char *)0xF0000,
+ &freemem);
}
if ( check_amd() )
diff -r 91951de7592c -r 4d07411c517a tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c Sun Nov 26 17:35:00 2006 +0000
+++ b/tools/firmware/hvmloader/util.c Sun Nov 26 17:37:28 2006 +0000
@@ -23,6 +23,7 @@
#include "config.h"
#include <stdint.h>
#include <xenctrl.h>
+#include <xen/hvm/hvm_info_table.h>
void outb(uint16_t addr, uint8_t val)
{
@@ -487,6 +488,62 @@ void __bug(char *file, int line)
__asm__ __volatile__ ( "ud2" );
}
+static int validate_hvm_info(struct hvm_info_table *t)
+{
+ char signature[] = "HVM INFO";
+ uint8_t *ptr = (uint8_t *)t;
+ uint8_t sum = 0;
+ int i;
+
+ /* strncmp(t->signature, "HVM INFO", 8) */
+ 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++ )
+ sum += ptr[i];
+
+ return (sum == 0);
+}
+
+static struct hvm_info_table *get_hvm_info_table(void)
+{
+ static struct hvm_info_table *table;
+ struct hvm_info_table *t;
+
+ if ( table != NULL )
+ return table;
+
+ t = (struct hvm_info_table *)HVM_INFO_PADDR;
+
+ if ( !validate_hvm_info(t) )
+ {
+ printf("Bad hvm info table\n");
+ return NULL;
+ }
+
+ table = t;
+
+ return table;
+}
+
+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)
+{
+ struct hvm_info_table *t = get_hvm_info_table();
+ return (t ? t->acpi_enabled : 0); /* default no acpi */
+}
+
/*
* Local variables:
* mode: C
diff -r 91951de7592c -r 4d07411c517a tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h Sun Nov 26 17:35:00 2006 +0000
+++ b/tools/firmware/hvmloader/util.h Sun Nov 26 17:37:28 2006 +0000
@@ -2,6 +2,9 @@
#define __HVMLOADER_UTIL_H__
#include <stdarg.h>
+
+#undef offsetof
+#define offsetof(t, m) ((unsigned long)&((t *)0)->m)
extern void __assert_failed(char *assertion, char *file, int line)
__attribute__((noreturn));
@@ -40,8 +43,9 @@ void cpuid(uint32_t idx, uint32_t *eax,
void cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx);
-/* Return number of vcpus. */
+/* HVM-builder info. */
int get_vcpu_nr(void);
+int get_acpi_enabled(void);
/* String and memory functions */
int strcmp(const char *cs, const char *ct);
diff -r 91951de7592c -r 4d07411c517a tools/firmware/hvmloader/acpi/gen.c
--- a/tools/firmware/hvmloader/acpi/gen.c Sun Nov 26 17:35:00 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2004, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- */
-#include "acpi2_0.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#define USAGE "Usage: acpi_gen filename \n" \
- " generage acpitable and write to the binary \n" \
- " filename - the binary name\n"
-
-#define ACPI_TABLE_SIZE (8*1024)
-
-int main(int argc, char **argv)
-{
- char *filename;
- char buf[ACPI_TABLE_SIZE] = { 0 };
- FILE *f;
-
- if (argc < 2) {
- fprintf(stderr,"%s",USAGE);
- exit(1);
- }
-
- filename = argv[1];
-
- if ((f = fopen(filename, "w+")) == NULL) {
- fprintf(stderr,"Can not open %s", filename);
- exit(1);
- }
-
- AcpiBuildTable((uint8_t *)buf);
-
- if (fwrite(buf, ACPI_TABLE_SIZE, 1, f) < 1) {
- fprintf(stderr,"Can not write to %s\n", filename);
- exit(1);
- }
-
- return 0;
-}
diff -r 91951de7592c -r 4d07411c517a tools/firmware/hvmloader/acpi_madt.c
--- a/tools/firmware/hvmloader/acpi_madt.c Sun Nov 26 17:35:00 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * acpi_madt.c: Update ACPI MADT table for multiple processor guest.
- *
- * Yu Ke, ke.yu@xxxxxxxxx
- * Copyright (c) 2005, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "acpi/acpi2_0.h"
-#include "util.h"
-#include "acpi_utils.h"
-#include <xen/hvm/hvm_info_table.h>
-
-#define NULL ((void*)0)
-
-static struct hvm_info_table *table = NULL;
-
-static int validate_hvm_info(struct hvm_info_table *t)
-{
- char signature[] = "HVM INFO";
- uint8_t *ptr = (uint8_t *)t;
- uint8_t sum = 0;
- int i;
-
- /* strncmp(t->signature, "HVM INFO", 8) */
- 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++ )
- 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 *t;
-
- if ( table != NULL )
- return table;
-
- t = (struct hvm_info_table *)HVM_INFO_PADDR;
-
- if ( !validate_hvm_info(t) )
- {
- printf("Bad hvm info table\n");
- return NULL;
- }
-
- table = t;
-
- return table;
-}
-
-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)
-{
- struct hvm_info_table *t = get_hvm_info_table();
- return (t ? t->acpi_enabled : 0); /* default no acpi */
-}
-
-
-static void *
-acpi_madt_get_madt(unsigned char *acpi_start)
-{
- struct acpi_20_rsdt *rsdt;
- struct acpi_20_madt *madt;
-
- rsdt = acpi_rsdt_get(acpi_start);
- 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 )
- {
- printf("Bad MADT signature \n");
- return NULL;
- }
-
- return madt;
-}
-
-static int
-acpi_madt_set_local_apics(
- int nr_vcpu,
- struct acpi_20_madt *madt)
-{
- int i;
-
- if ( (nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt )
- return -1;
-
- 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;
- madt->lapic[i].apic_id = i;
- madt->lapic[i].flags = 1;
- }
-
- madt->header.header.length =
- sizeof(struct acpi_20_madt) -
- (MAX_VIRT_CPUS - nr_vcpu) * sizeof(struct acpi_20_madt_lapic);
-
- return 0;
-}
-
-#define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field)))
-
-int acpi_madt_update(unsigned char *acpi_start)
-{
- int rc;
- struct acpi_20_madt *madt;
-
- madt = acpi_madt_get_madt(acpi_start);
- if ( !madt )
- return -1;
-
- rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt);
- if ( rc != 0 )
- return rc;
-
- set_checksum(
- madt, FIELD_OFFSET(struct acpi_header, checksum),
- madt->header.header.length);
-
- return 0;
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|