[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH][VT] Dynamic ACPI MADT Table Support


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: "Yu, Ke" <ke.yu@xxxxxxxxx>
  • Date: Tue, 20 Sep 2005 15:54:11 +0800
  • Delivery-date: Tue, 20 Sep 2005 07:53:18 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>
  • Thread-index: AcW9uHybyZ6VpdXoTZG3lro3GfBzDA==
  • Thread-topic: [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
Description: dynamic_madt.patch

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.