[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.