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

[Xen-changelog] Dynamically generate the local apic entries in ACPI MADT table.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 739154e26fb752caf6496620644e01318b64540a
# Parent  d1cbfaf804d98aec913ad57e3531d45c6459b366
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@xxxxxxxxx>
Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx>
Signed-off-by: Asit Mallick <asit.k.mallick@xxxxxxxxx>

diff -r d1cbfaf804d9 -r 739154e26fb7 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 09:02:43 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 739154e26fb7 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 09:02:43 2005
@@ -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 ()
 
diff -r d1cbfaf804d9 -r 739154e26fb7 tools/firmware/vmxassist/Makefile
--- a/tools/firmware/vmxassist/Makefile Mon Sep 19 17:10:20 2005
+++ b/tools/firmware/vmxassist/Makefile Tue Sep 20 09:02:43 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 739154e26fb7 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 09:02:43 2005
@@ -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 @@
        }
 #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.
                 */
diff -r d1cbfaf804d9 -r 739154e26fb7 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 09:02:43 2005
@@ -105,6 +105,33 @@
     nr_map++;
 
     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__
@@ -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 739154e26fb7 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 09:02:43 2005
@@ -0,0 +1,145 @@
+/*
+ * 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" */
+
+/* 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:
+ */

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


 


Rackspace

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