WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH][VT] Dynamic ACPI MADT Table Support
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
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
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
<Prev in Thread] Current Thread [Next in Thread>