[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] Dynamically build ACPI-table data block.
# 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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |