This patch dynamically sets the local apic entrys in ACPI MADT table.
The number of local apic entry is decided by the vcpu numbers passed
from config file (eg./etc/xen/xmexample.vmx).
This feature is required by the SMP VMX domain.
Signed-off-by: Ke Yu <ke.yu@xxxxxxxxx>
Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx>
Signed-off-by: Asit Mallick <asit.k.mallick@xxxxxxxxx>
diff -r d1cbfaf804d9 -r ba4dee5863c6 tools/firmware/acpi/acpi_madt.c
--- a/tools/firmware/acpi/acpi_madt.c Mon Sep 19 17:10:20 2005
+++ b/tools/firmware/acpi/acpi_madt.c Tue Sep 20 07:29:35 2005
@@ -37,44 +37,7 @@
ACPI_LOCAL_APIC_ADDRESS,
ACPI_MULTIPLE_APIC_FLAGS,
},
- //
- // LOCAL APIC Entries for 4 processors.
- //
- {
- {
-
ACPI_PROCESSOR_LOCAL_APIC,
- sizeof
(ACPI_LOCAL_APIC_STRUCTURE),
- 0x00,
- 0x00,
- 0x00000001,
- },
-
- {
-
ACPI_PROCESSOR_LOCAL_APIC,
- sizeof
(ACPI_LOCAL_APIC_STRUCTURE),
- 0x01,
- 0x00,
- 0x00000000
- },
-
- {
-
ACPI_PROCESSOR_LOCAL_APIC,
- sizeof
(ACPI_LOCAL_APIC_STRUCTURE),
- 0x02,
- 0x00,
- 0x00000000
- },
-
- {
-
ACPI_PROCESSOR_LOCAL_APIC,
- sizeof
(ACPI_LOCAL_APIC_STRUCTURE),
- 0x03,
- 0x00,
- 0x00000000
- }
- }
- ,
-
+
//
// IO APIC
//
@@ -87,5 +50,19 @@
ACPI_IO_APIC_ADDRESS_1,
0x0000
}
- }
+ },
+ //
+ // LOCAL APIC Entries for up to 32 processors.
+ //
+ {
+ {
+ ACPI_PROCESSOR_LOCAL_APIC,
+ sizeof (ACPI_LOCAL_APIC_STRUCTURE),
+ 0x00,
+ 0x00,
+ 0x00000001,
+ }
+
+ }
+
};
diff -r d1cbfaf804d9 -r ba4dee5863c6 tools/firmware/acpi/acpi_madt.h
--- a/tools/firmware/acpi/acpi_madt.h Mon Sep 19 17:10:20 2005
+++ b/tools/firmware/acpi/acpi_madt.h Tue Sep 20 07:29:35 2005
@@ -36,8 +36,8 @@
#pragma pack (1)
typedef struct {
ACPI_2_0_MADT Header;
- ACPI_LOCAL_APIC_STRUCTURE LocalApic[4];
ACPI_IO_APIC_STRUCTURE IoApic[1];
+ ACPI_LOCAL_APIC_STRUCTURE LocalApic[32];
} ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE;
#pragma pack ()
diff -r d1cbfaf804d9 -r ba4dee5863c6 tools/firmware/vmxassist/Makefile
--- a/tools/firmware/vmxassist/Makefile Mon Sep 19 17:10:20 2005
+++ b/tools/firmware/vmxassist/Makefile Tue Sep 20 07:29:35 2005
@@ -41,9 +41,9 @@
all: vmxloader
-vmxloader: roms.h vmxloader.c acpi.h
- ${CC} ${CFLAGS} ${DEFINES} -c vmxloader.c
- $(CC) -o vmxloader.tmp -m32 -nostdlib -Wl,-N -Wl,-Ttext
-Wl,0x100000 vmxloader.o
+vmxloader: roms.h vmxloader.c acpi.h acpi_madt.c
+ ${CC} ${CFLAGS} ${DEFINES} -c vmxloader.c -c acpi_madt.c
+ $(CC) -o vmxloader.tmp -m32 -nostdlib -Wl,-N -Wl,-Ttext
-Wl,0x100000 vmxloader.o acpi_madt.o
objcopy --change-addresses=0xC0000000 vmxloader.tmp vmxloader
rm -f vmxloader.tmp
diff -r d1cbfaf804d9 -r ba4dee5863c6
tools/firmware/vmxassist/vmxloader.c
--- a/tools/firmware/vmxassist/vmxloader.c Mon Sep 19 17:10:20 2005
+++ b/tools/firmware/vmxassist/vmxloader.c Tue Sep 20 07:29:35 2005
@@ -27,6 +27,9 @@
#ifdef _ACPI_
#include "acpi.h"
#include "../acpi/acpi2_0.h" // for ACPI_PHYSICAL_ADDRESS
+
+int acpi_madt_update(unsigned char* acpi_start);
+
#endif
@@ -110,6 +113,9 @@
}
#ifdef _ACPI_
puts("Loading ACPI ...\n");
+
+ acpi_madt_update(acpi);
+
if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000 ){
/* make sure acpi table does not overlap rombios
* currently acpi less than 8K will be OK.
diff -r d1cbfaf804d9 -r ba4dee5863c6 tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c Mon Sep 19 17:10:20 2005
+++ b/tools/libxc/xc_vmx_build.c Tue Sep 20 07:29:35 2005
@@ -105,6 +105,33 @@
nr_map++;
mem_mapp->nr_map = nr_map;
+}
+
+#define VCPU_MAGIC 0x76637075 // "vcpu"
+static int
+set_nr_vcpus(int xc_handle, u32 dom, unsigned long *pfn_list,
+ struct domain_setup_info *dsi, unsigned long vcpus)
+/*
+ * Use E820 reserved memeory 0x9F800 to pass number of vcpus to
vmxloader
+ * vmxloader will use it to config ACPI Madt table
+ *
+ */
+{
+ u8* va_map;
+ unsigned long* va_vcpus;
+
+ va_map = (u8*)xc_map_foreign_range(
+ xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
+ pfn_list[(0x9F000-dsi->v_start)>>PAGE_SHIFT]);
+
+ if (!va_map) return -1;
+
+ va_vcpus = (unsigned long*)(va_map+0x800);
+ *va_vcpus = VCPU_MAGIC;
+ va_vcpus++;
+ *va_vcpus = vcpus;
+ munmap(va_map, PAGE_SIZE);
+ return 0;
}
#ifdef __i386__
@@ -496,7 +523,8 @@
MMU_MACHPHYS_UPDATE, count) )
goto error_out;
}
-
+
+ set_nr_vcpus(xc_handle, dom, page_array, &dsi, vcpus);
if ((boot_paramsp = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
diff -r d1cbfaf804d9 -r ba4dee5863c6
tools/firmware/vmxassist/acpi_madt.c
--- /dev/null Mon Sep 19 17:10:20 2005
+++ b/tools/firmware/vmxassist/acpi_madt.c Tue Sep 20 07:29:35 2005
@@ -0,0 +1,142 @@
+/*
+ * 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 "../acpi/acpi_madt.h"
+
+#define NULL ((void*)0)
+
+extern int puts(const char *s);
+
+#define VCPU_MAGIC 0x76637075 // "vcpu"
+
+static int
+get_vcpus()
+/*
+ * xc_vmx_buider set vcpus in 0x9F800, get it
+ *
+ */
+{
+ unsigned long* vcpus;
+
+ vcpus=(unsigned long*)(0x9F800);
+ if (*vcpus!=VCPU_MAGIC) {
+ puts("Bad vcpus magic, set vcpu number=1\n");
+ return 1;
+ }
+ vcpus++;
+ return *vcpus;
+}
+
+ static void*
+acpi_madt_get_madt(unsigned char* acpi_start)
+/* ACPI table-> RSDP
+ RSDP -> RSDT
+ RSDT-> MADT
+ */
+{
+ ACPI_2_0_RSDP *rsdp=NULL;
+ ACPI_2_0_RSDT *rsdt=NULL;
+ ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
+
+ rsdp = (ACPI_2_0_RSDP*)(acpi_start + sizeof(ACPI_2_0_FACS));
+ if (rsdp->Signature != ACPI_2_0_RSDP_SIGNATURE){
+ puts("Bad RSDP signature\n");
+ return NULL;
+ }
+
+ rsdt= (ACPI_2_0_RSDT*) (acpi_start + rsdp->RsdtAddress -
ACPI_PHYSICAL_ADDRESS);
+ if (rsdt->Header.Signature != ACPI_2_0_RSDT_SIGNATURE) {
+ puts("Bad RSDT signature\n");
+ return NULL;
+ }
+
+ madt = (ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE*) ( acpi_start+
rsdt->Entry[1]
+ - ACPI_PHYSICAL_ADDRESS);
+ if (madt->Header.Header.Signature !=
ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE){
+ puts("Bad MADT signature \n");
+ return NULL;
+ }
+
+ return madt;
+}
+
+ static void
+set_checksum(void* start, int checksum_offset, int len)
+{
+ unsigned char sum = 0;
+ unsigned char *ptr;
+
+ ptr=start;
+ ptr[checksum_offset]=0;
+ while (len--) {
+ sum = (unsigned char)(sum + (*ptr++));
+ }
+
+ ptr = start;
+ ptr[checksum_offset] = (unsigned char) (0xff - sum + 1);
+}
+
+static int
+acpi_madt_set_local_apics(int nr_vcpu,
+ ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE* madt)
+{
+ int i;
+
+ if ( nr_vcpu>MAX_VIRT_CPUS || nr_vcpu<0 || !madt) {
+ return -1;
+ }
+
+ for (i=0; i<nr_vcpu; i++){
+ madt->LocalApic[i].Type = ACPI_PROCESSOR_LOCAL_APIC;
+ madt->LocalApic[i].Length = sizeof
(ACPI_LOCAL_APIC_STRUCTURE);
+ madt->LocalApic[i].AcpiProcessorId = i;
+ madt->LocalApic[i].ApicId = i;
+ madt->LocalApic[i].Flags = 1;
+ }
+
+ madt->Header.Header.Length =
sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) -
+ (MAX_VIRT_CPUS - nr_vcpu)* sizeof(ACPI_LOCAL_APIC_STRUCTURE);
+
+ return 0;
+}
+
+#define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *)
0)->Field)))
+
+int acpi_madt_update(unsigned char* acpi_start){
+
+ int rc;
+
+ ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE* madt;
+
+ madt = acpi_madt_get_madt(acpi_start);
+ if (!madt) {
+ return -1;
+ }
+
+ rc = acpi_madt_set_local_apics (get_vcpus(), madt);
+ if (rc!=0) {
+ return rc;
+ }
+
+ set_checksum (madt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
+ madt->Header.Header.Length);
+
+ return 0;
+}
dynamic_madt.patch
Description: dynamic_madt.patch
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|