ia64/xen-unstable

changeset 6974:739154e26fb7

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@intel.com>
Signed-off-by: Xin Li <xin.b.li@intel.com>
Signed-off-by: Asit Mallick <asit.k.mallick@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Sep 20 09:02:43 2005 +0000 (2005-09-20)
parents d1cbfaf804d9
children 3ef86b208f9b
files tools/firmware/acpi/acpi_madt.c tools/firmware/acpi/acpi_madt.h tools/firmware/vmxassist/Makefile tools/firmware/vmxassist/acpi_madt.c tools/firmware/vmxassist/vmxloader.c tools/libxc/xc_vmx_build.c
line diff
     1.1 --- a/tools/firmware/acpi/acpi_madt.c	Mon Sep 19 17:10:20 2005 +0000
     1.2 +++ b/tools/firmware/acpi/acpi_madt.c	Tue Sep 20 09:02:43 2005 +0000
     1.3 @@ -37,44 +37,7 @@ ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE Mad
     1.4  				ACPI_LOCAL_APIC_ADDRESS,
     1.5  				ACPI_MULTIPLE_APIC_FLAGS,
     1.6  		},
     1.7 -		//
     1.8 -		// LOCAL APIC Entries for 4 processors.
     1.9 -		//
    1.10 -		{
    1.11 -				{
    1.12 -						ACPI_PROCESSOR_LOCAL_APIC,                          
    1.13 -						sizeof (ACPI_LOCAL_APIC_STRUCTURE),     
    1.14 -						0x00,                                                     
    1.15 -						0x00,                                                     
    1.16 -						0x00000001,                                               
    1.17 -				},
    1.18 -
    1.19 -				{
    1.20 -						ACPI_PROCESSOR_LOCAL_APIC,                          
    1.21 -						sizeof (ACPI_LOCAL_APIC_STRUCTURE),     
    1.22 -						0x01,                                                     
    1.23 -						0x00,                                                     
    1.24 -						0x00000000
    1.25 -				},                                               
    1.26 -
    1.27 -				{
    1.28 -						ACPI_PROCESSOR_LOCAL_APIC,                          
    1.29 -						sizeof (ACPI_LOCAL_APIC_STRUCTURE),     
    1.30 -						0x02,                                                     
    1.31 -						0x00,                                                     
    1.32 -						0x00000000
    1.33 -				},                                               
    1.34 -
    1.35 -				{
    1.36 -						ACPI_PROCESSOR_LOCAL_APIC,                          
    1.37 -						sizeof (ACPI_LOCAL_APIC_STRUCTURE),     
    1.38 -						0x03,                                                     
    1.39 -						0x00,                                                     
    1.40 -						0x00000000
    1.41 -				}
    1.42 -		}
    1.43 -		,
    1.44 -
    1.45 +	
    1.46  		//
    1.47  		// IO APIC
    1.48  		// 
    1.49 @@ -87,5 +50,19 @@ ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE Mad
    1.50  						ACPI_IO_APIC_ADDRESS_1,
    1.51  						0x0000
    1.52  				}
    1.53 +		},
    1.54 +
    1.55 +		//
    1.56 +		// LOCAL APIC Entries for up to 32 processors.
    1.57 +		//
    1.58 +		{
    1.59 +				{
    1.60 +						ACPI_PROCESSOR_LOCAL_APIC,
    1.61 +						sizeof (ACPI_LOCAL_APIC_STRUCTURE),
    1.62 +						0x00,
    1.63 +						0x00,
    1.64 +						0x00000001,
    1.65 +				}
    1.66 +
    1.67  		}
    1.68  };
     2.1 --- a/tools/firmware/acpi/acpi_madt.h	Mon Sep 19 17:10:20 2005 +0000
     2.2 +++ b/tools/firmware/acpi/acpi_madt.h	Tue Sep 20 09:02:43 2005 +0000
     2.3 @@ -35,9 +35,9 @@
     2.4  //
     2.5  #pragma pack (1)
     2.6  typedef struct {
     2.7 -  ACPI_2_0_MADT   				Header;
     2.8 -  ACPI_LOCAL_APIC_STRUCTURE     LocalApic[4];
     2.9 -  ACPI_IO_APIC_STRUCTURE        IoApic[1];
    2.10 +	ACPI_2_0_MADT			Header;
    2.11 +	ACPI_IO_APIC_STRUCTURE		IoApic[1];
    2.12 +	ACPI_LOCAL_APIC_STRUCTURE	LocalApic[32];
    2.13  } ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE;
    2.14  #pragma pack ()
    2.15  
     3.1 --- a/tools/firmware/vmxassist/Makefile	Mon Sep 19 17:10:20 2005 +0000
     3.2 +++ b/tools/firmware/vmxassist/Makefile	Tue Sep 20 09:02:43 2005 +0000
     3.3 @@ -41,9 +41,9 @@ OBJECTS = head.o trap.o vm86.o setup.o u
     3.4  
     3.5  all: vmxloader
     3.6  
     3.7 -vmxloader: roms.h vmxloader.c acpi.h
     3.8 -	${CC} ${CFLAGS} ${DEFINES} -c vmxloader.c
     3.9 -	$(CC) -o vmxloader.tmp -m32 -nostdlib -Wl,-N -Wl,-Ttext -Wl,0x100000 vmxloader.o
    3.10 +vmxloader: roms.h vmxloader.c acpi.h acpi_madt.c
    3.11 +	${CC} ${CFLAGS} ${DEFINES} -c vmxloader.c -c acpi_madt.c
    3.12 +	$(CC) -o vmxloader.tmp -m32 -nostdlib -Wl,-N -Wl,-Ttext -Wl,0x100000 vmxloader.o acpi_madt.o
    3.13  	objcopy --change-addresses=0xC0000000 vmxloader.tmp vmxloader
    3.14  	rm -f vmxloader.tmp
    3.15  
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/firmware/vmxassist/acpi_madt.c	Tue Sep 20 09:02:43 2005 +0000
     4.3 @@ -0,0 +1,145 @@
     4.4 +/*
     4.5 + * acpi_madt.c: Update ACPI MADT table for multiple processor guest.
     4.6 + *
     4.7 + * Yu Ke, ke.yu@intel.com
     4.8 + * Copyright (c) 2005, Intel Corporation.
     4.9 + *
    4.10 + * This program is free software; you can redistribute it and/or modify it
    4.11 + * under the terms and conditions of the GNU General Public License,
    4.12 + * version 2, as published by the Free Software Foundation.
    4.13 + *
    4.14 + * This program is distributed in the hope it will be useful, but WITHOUT
    4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    4.17 + * more details.
    4.18 + *
    4.19 + * You should have received a copy of the GNU General Public License along with
    4.20 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    4.21 + * Place - Suite 330, Boston, MA 02111-1307 USA.
    4.22 + */
    4.23 +#include "../acpi/acpi2_0.h"
    4.24 +#include "../acpi/acpi_madt.h"
    4.25 +
    4.26 +#define NULL ((void*)0)
    4.27 +
    4.28 +extern int puts(const char *s);
    4.29 +
    4.30 +#define VCPU_MAGIC 0x76637075 /* "vcpu" */
    4.31 +
    4.32 +/* xc_vmx_builder wrote vcpu block at 0x9F800. Return it. */
    4.33 +static int 
    4.34 +get_vcpus(void)
    4.35 +{
    4.36 +	unsigned long *vcpus;
    4.37 +
    4.38 +	vcpus = (unsigned long *)0x9F800;
    4.39 +	if (vcpus[0] != VCPU_MAGIC) {
    4.40 +		puts("Bad vcpus magic, set vcpu number=1\n");
    4.41 +		return 1;
    4.42 +	}
    4.43 +
    4.44 +	return vcpus[1];
    4.45 +}
    4.46 +
    4.47 +static void *
    4.48 +acpi_madt_get_madt(unsigned char *acpi_start)
    4.49 +{
    4.50 +	ACPI_2_0_RSDP *rsdp=NULL;
    4.51 +	ACPI_2_0_RSDT *rsdt=NULL;
    4.52 +	ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
    4.53 +
    4.54 +	rsdp = (ACPI_2_0_RSDP *)(acpi_start + sizeof(ACPI_2_0_FACS));
    4.55 +	if (rsdp->Signature != ACPI_2_0_RSDP_SIGNATURE) {
    4.56 +		puts("Bad RSDP signature\n");
    4.57 +		return NULL;
    4.58 +	}
    4.59 +
    4.60 +	rsdt= (ACPI_2_0_RSDT *)
    4.61 +		(acpi_start + rsdp->RsdtAddress - ACPI_PHYSICAL_ADDRESS);
    4.62 +	if (rsdt->Header.Signature != ACPI_2_0_RSDT_SIGNATURE) {
    4.63 +		puts("Bad RSDT signature\n");
    4.64 +		return NULL;
    4.65 +	}
    4.66 +
    4.67 +	madt = (ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *)
    4.68 +		( acpi_start+ rsdt->Entry[1] - ACPI_PHYSICAL_ADDRESS);
    4.69 +	if (madt->Header.Header.Signature !=
    4.70 +	    ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
    4.71 +		puts("Bad MADT signature \n");
    4.72 +		return NULL;
    4.73 +	}
    4.74 +
    4.75 +	return madt;
    4.76 +}
    4.77 +
    4.78 +static void 
    4.79 +set_checksum(void *start, int checksum_offset, int len)
    4.80 +{
    4.81 +	unsigned char sum = 0;  
    4.82 +	unsigned char *ptr;
    4.83 +
    4.84 +	ptr = start;
    4.85 +	ptr[checksum_offset] = 0;
    4.86 +	while (len--)
    4.87 +		sum += *ptr++;
    4.88 +
    4.89 +	ptr = start;
    4.90 +	ptr[checksum_offset] = -sum;
    4.91 +}
    4.92 +
    4.93 +static int 
    4.94 +acpi_madt_set_local_apics(
    4.95 +	int nr_vcpu, 
    4.96 +	ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt)
    4.97 +{
    4.98 +	int i;
    4.99 +
   4.100 +	if ((nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt)
   4.101 +		return -1;
   4.102 +
   4.103 +	for (i = 0; i < nr_vcpu; i++) {
   4.104 +		madt->LocalApic[i].Type            = ACPI_PROCESSOR_LOCAL_APIC;
   4.105 +		madt->LocalApic[i].Length          = sizeof (ACPI_LOCAL_APIC_STRUCTURE);
   4.106 +		madt->LocalApic[i].AcpiProcessorId = i;
   4.107 +		madt->LocalApic[i].ApicId          = i;
   4.108 +		madt->LocalApic[i].Flags           = 1; 
   4.109 +	}
   4.110 +
   4.111 +	madt->Header.Header.Length =
   4.112 +		sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) - 
   4.113 +		(MAX_VIRT_CPUS - nr_vcpu)* sizeof(ACPI_LOCAL_APIC_STRUCTURE);
   4.114 +
   4.115 +	return 0;                            
   4.116 +}
   4.117 +
   4.118 +#define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field)))
   4.119 +
   4.120 +int acpi_madt_update(unsigned char *acpi_start)
   4.121 +{
   4.122 +	int rc;
   4.123 +	ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
   4.124 +
   4.125 +	madt = acpi_madt_get_madt(acpi_start);
   4.126 +	if (!madt)
   4.127 +		return -1;
   4.128 +
   4.129 +	rc = acpi_madt_set_local_apics(get_vcpus(), madt);
   4.130 +	if (rc != 0)
   4.131 +		return rc;
   4.132 +
   4.133 +	set_checksum(
   4.134 +		madt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
   4.135 +		madt->Header.Header.Length);
   4.136 +
   4.137 +	return 0;              
   4.138 +}
   4.139 +
   4.140 +/*
   4.141 + * Local variables:
   4.142 + *  c-file-style: "linux"
   4.143 + *  indent-tabs-mode: t
   4.144 + *  c-indent-level: 8
   4.145 + *  c-basic-offset: 8
   4.146 + *  tab-width: 8
   4.147 + * End:
   4.148 + */
     5.1 --- a/tools/firmware/vmxassist/vmxloader.c	Mon Sep 19 17:10:20 2005 +0000
     5.2 +++ b/tools/firmware/vmxassist/vmxloader.c	Tue Sep 20 09:02:43 2005 +0000
     5.3 @@ -27,6 +27,7 @@
     5.4  #ifdef _ACPI_
     5.5  #include "acpi.h"
     5.6  #include "../acpi/acpi2_0.h"  // for ACPI_PHYSICAL_ADDRESS
     5.7 +int acpi_madt_update(unsigned char* acpi_start);
     5.8  #endif
     5.9  
    5.10  
    5.11 @@ -110,7 +111,10 @@ main()
    5.12  	}
    5.13  #ifdef _ACPI_
    5.14  	puts("Loading ACPI ...\n");
    5.15 -	if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000 ){
    5.16 +
    5.17 +	acpi_madt_update(acpi);
    5.18 +
    5.19 +	if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
    5.20  		/* make sure acpi table does not overlap rombios
    5.21   		 * currently acpi less than 8K will be OK.
    5.22  		 */
     6.1 --- a/tools/libxc/xc_vmx_build.c	Mon Sep 19 17:10:20 2005 +0000
     6.2 +++ b/tools/libxc/xc_vmx_build.c	Tue Sep 20 09:02:43 2005 +0000
     6.3 @@ -107,6 +107,33 @@ static void build_e820map(struct mem_map
     6.4      mem_mapp->nr_map = nr_map;
     6.5  }
     6.6  
     6.7 +/*
     6.8 + * Use E820 reserved memory 0x9F800 to pass number of vcpus to vmxloader
     6.9 + * vmxloader will use it to config ACPI MADT table
    6.10 + */
    6.11 +#define VCPU_MAGIC 0x76637075 /* "vcpu" */
    6.12 +static int 
    6.13 +set_nr_vcpus(int xc_handle, u32 dom, unsigned long *pfn_list, 
    6.14 +             struct domain_setup_info *dsi, unsigned long vcpus)
    6.15 +{
    6.16 +    char          *va_map;
    6.17 +    unsigned long *va_vcpus;
    6.18 +    
    6.19 +    va_map = xc_map_foreign_range(
    6.20 +        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
    6.21 +        pfn_list[(0x9F000 - dsi->v_start) >> PAGE_SHIFT]);    
    6.22 +    if ( va_map == NULL )
    6.23 +        return -1;
    6.24 +    
    6.25 +    va_vcpus = (unsigned long *)(va_map + 0x800);
    6.26 +    *va_vcpus++ = VCPU_MAGIC;
    6.27 +    *va_vcpus++ = vcpus;
    6.28 +
    6.29 +    munmap(va_map, PAGE_SIZE);
    6.30 +
    6.31 +    return 0;
    6.32 +}
    6.33 +
    6.34  #ifdef __i386__
    6.35  static int zap_mmio_range(int xc_handle, u32 dom,
    6.36                            l2_pgentry_32_t *vl2tab,
    6.37 @@ -496,7 +523,8 @@ static int setup_guest(int xc_handle,
    6.38                                 MMU_MACHPHYS_UPDATE, count) )
    6.39              goto error_out;
    6.40      }
    6.41 -    
    6.42 +
    6.43 +    set_nr_vcpus(xc_handle, dom, page_array, &dsi, vcpus);
    6.44  
    6.45      if ((boot_paramsp = xc_map_foreign_range(
    6.46          xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,