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@intel.com> Signed-off-by: Xin Li <xin.b.li@intel.com> Signed-off-by: Asit Mallick <asit.k.mallick@intel.com> 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@intel.com + * 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; +} _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2005-Sep-20 09:16 UTC
Re: [Xen-devel] [PATCH][VT] Dynamic ACPI MADT Table Support
On 20 Sep 2005, at 08:54, Yu, Ke wrote:> 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).Applied, but please take care to format code according to the style in that file and directory. I had to go through your patch adding hard tabs as necessary, and generally cleaning things up. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Thanks for the patient going through and cleaning up. Previously I was confused if I should stick to the code format under tools/firmware/acpi, since it is a bit different from xen code style. Now I know sometimes "local style" also needs to be obeyed :). Regards Ke> >Applied, but please take care to format code according to the style in >that file and directory. I had to go through your patch adding hard >tabs as necessary, and generally cleaning things up. > > -- Keir_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel