WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [HVM] Dynamically build ACPI-table data b

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVM] Dynamically build ACPI-table data block.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 27 Nov 2006 11:40:14 +0000
Delivery-date: Mon, 27 Nov 2006 03:39:49 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [HVM] Dynamically build ACPI-table data block., Xen patchbot-unstable <=