[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Dynamically generate the local apic entries in ACPI MADT table.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 739154e26fb752caf6496620644e01318b64540a # Parent d1cbfaf804d98aec913ad57e3531d45c6459b366 Dynamically generate the local apic entries in ACPI MADT table. The number of local apic entries is decided by the #vcpus passed from the 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 739154e26fb7 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 09:02:43 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 739154e26fb7 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 09:02:43 2005 @@ -35,9 +35,9 @@ // #pragma pack (1) typedef struct { - ACPI_2_0_MADT Header; - ACPI_LOCAL_APIC_STRUCTURE LocalApic[4]; - ACPI_IO_APIC_STRUCTURE IoApic[1]; + ACPI_2_0_MADT Header; + ACPI_IO_APIC_STRUCTURE IoApic[1]; + ACPI_LOCAL_APIC_STRUCTURE LocalApic[32]; } ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE; #pragma pack () diff -r d1cbfaf804d9 -r 739154e26fb7 tools/firmware/vmxassist/Makefile --- a/tools/firmware/vmxassist/Makefile Mon Sep 19 17:10:20 2005 +++ b/tools/firmware/vmxassist/Makefile Tue Sep 20 09:02:43 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 739154e26fb7 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 09:02:43 2005 @@ -27,6 +27,7 @@ #ifdef _ACPI_ #include "acpi.h" #include "../acpi/acpi2_0.h" // for ACPI_PHYSICAL_ADDRESS +int acpi_madt_update(unsigned char* acpi_start); #endif @@ -110,7 +111,10 @@ } #ifdef _ACPI_ puts("Loading ACPI ...\n"); - if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000 ){ + + 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 739154e26fb7 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 09:02:43 2005 @@ -105,6 +105,33 @@ nr_map++; mem_mapp->nr_map = nr_map; +} + +/* + * Use E820 reserved memory 0x9F800 to pass number of vcpus to vmxloader + * vmxloader will use it to config ACPI MADT table + */ +#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) +{ + char *va_map; + unsigned long *va_vcpus; + + va_map = xc_map_foreign_range( + xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, + pfn_list[(0x9F000 - dsi->v_start) >> PAGE_SHIFT]); + if ( va_map == NULL ) + return -1; + + va_vcpus = (unsigned long *)(va_map + 0x800); + *va_vcpus++ = VCPU_MAGIC; + *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 739154e26fb7 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 09:02:43 2005 @@ -0,0 +1,145 @@ +/* + * 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" */ + +/* xc_vmx_builder wrote vcpu block at 0x9F800. Return it. */ +static int +get_vcpus(void) +{ + unsigned long *vcpus; + + vcpus = (unsigned long *)0x9F800; + if (vcpus[0] != VCPU_MAGIC) { + puts("Bad vcpus magic, set vcpu number=1\n"); + return 1; + } + + return vcpus[1]; +} + +static void * +acpi_madt_get_madt(unsigned char *acpi_start) +{ + 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 += *ptr++; + + ptr = start; + ptr[checksum_offset] = -sum; +} + +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; +} + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |