[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH][VT] Dynamic ACPI MADT Table Support
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; +} Attachment:
dynamic_madt.patch _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |