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>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2005-09-20 09:02:43 +00:00
1 parent e02527cc82
commit 8ad67b4949
6 files changed
+200 -46

No files matched your search

+15 -38
View File
@@ -37,44 +37,7 @@ ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE Madt = {
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_MULTIPLE_APIC_DESCRIPTION_TABLE Madt = {
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,
}
}
};
+3 -3
View File
@@ -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 ()
+3 -3
View File
@@ -41,9 +41,9 @@ OBJECTS = head.o trap.o vm86.o setup.o util.o
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
+145
View File
@@ -0,0 +1,145 @@
/*
* 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" */
/* 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:
*/
+5 -1
View File
@@ -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 @@ main()
}
#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.
*/
+29 -1
View File
@@ -107,6 +107,33 @@ static void build_e820map(struct mem_map *mem_mapp, unsigned long mem_size)
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__
static int zap_mmio_range(int xc_handle, u32 dom,
l2_pgentry_32_t *vl2tab,
@@ -496,7 +523,8 @@ static int setup_guest(int xc_handle,
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,
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.