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 2 of 2] Add configuration options to selectively disa

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 2 of 2] Add configuration options to selectively disable S3 and S4 ACPI power states
From: Paul Durrant <paul.durrant@xxxxxxxxxx>
Date: Thu, 17 Nov 2011 16:43:56 +0000
Cc: paul.durrant@xxxxxxxxxx
Delivery-date: Thu, 17 Nov 2011 08:49:13 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1321548234@xxxxxxxxxxxxxxxxxxxxxxxxx>
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/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1321548234@xxxxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.6.4
# HG changeset patch
# User Paul Durrant <paul.durrant@xxxxxxxxxx>
# Date 1321548043 0
# Node ID c25af1f86de1699ee36684e740a323adbcffdfb5
# Parent  447738ef67ea2690c8ea6684f2e0e0b3528ad446
Add configuration options to selectively disable S3 and S4 ACPI power states.

Introduce acpi_s3 and acpi_s4 configuration options (default=1). When one of 
these
parameters is 0 it causes removal of the respective package (_S3 or _S4) from 
the
DSDT thereby disabling that power state in the guest.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>

diff -r 447738ef67ea -r c25af1f86de1 tools/firmware/hvmloader/acpi/acpi2_0.h
--- a/tools/firmware/hvmloader/acpi/acpi2_0.h   Thu Nov 17 16:21:21 2011 +0000
+++ b/tools/firmware/hvmloader/acpi/acpi2_0.h   Thu Nov 17 16:40:43 2011 +0000
@@ -396,6 +396,8 @@ struct acpi_config {
     int dsdt_anycpu_len;
     unsigned char *dsdt_15cpu;
     int dsdt_15cpu_len;
+    int dsdt_s3_enabled;
+    int dsdt_s4_enabled;
 };
 
 void acpi_build_tables(struct acpi_config *config, unsigned int physical);
diff -r 447738ef67ea -r c25af1f86de1 tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c     Thu Nov 17 16:21:21 2011 +0000
+++ b/tools/firmware/hvmloader/acpi/build.c     Thu Nov 17 16:40:43 2011 +0000
@@ -274,6 +274,54 @@ static int construct_secondary_tables(un
     return nr_tables;
 }
 
+static uint8_t *find_name(uint8_t *dsdt, const char *prefix)
+{
+    int len = strlen(prefix);
+    int i;
+
+    for ( i = 0; i < ((struct acpi_header *)dsdt)->length - len; i++, dsdt++ )
+    {
+        if ( memcmp(dsdt, prefix, len) == 0 && *(dsdt - 1) == 0x08 )
+            return dsdt - 1;
+    }
+
+    return NULL;
+}
+
+static void remove_package(uint8_t *dsdt, const char *prefix)
+{
+    struct acpi_header *header = (struct acpi_header *)dsdt;
+    uint8_t *start = find_name(dsdt, prefix);
+    uint8_t *end = dsdt + header->length - 1;
+    uint8_t *package;
+    uint8_t *len;
+    uint8_t *next;
+
+    if ( start == NULL )
+        return;
+
+    package = start + 5; /* 1 byte op, 4 bytes payload */
+    if ( package > end )
+        return;
+    if ( *package != 0x12 )
+        return;
+
+    len = package + 1;
+    if ( package > end )
+        return;
+
+    next = package + 1 + *len; /* 1 byte op, len bytes payload */
+    if ( next > end + 1 )
+        return;
+
+    printf("DSDT: removing '%c%c%c%c' (%d bytes)\n",
+           *(start + 1), *(start + 2), *(start + 3), *(start + 4),
+           next - start);
+
+    memcpy(start, next, header->length - (next - dsdt));
+    header->length -= next - start;
+}
+
 void acpi_build_tables(struct acpi_config *config, unsigned int physical)
 {
     struct acpi_info *acpi_info;
@@ -310,19 +358,29 @@ void acpi_build_tables(struct acpi_confi
      */
     if ( hvm_info->nr_vcpus <= 15 && config->dsdt_15cpu)
     {
-        dsdt = mem_alloc(config->dsdt_15cpu_len, 16);
+        dsdt = mem_probe(config->dsdt_15cpu_len, 16);
         if (!dsdt) goto oom;
         memcpy(dsdt, config->dsdt_15cpu, config->dsdt_15cpu_len);
         nr_processor_objects = 15;
     }
     else
     {
-        dsdt = mem_alloc(config->dsdt_anycpu_len, 16);
+        dsdt = mem_probe(config->dsdt_anycpu_len, 16);
         if (!dsdt) goto oom;
         memcpy(dsdt, config->dsdt_anycpu, config->dsdt_anycpu_len);
         nr_processor_objects = HVM_MAX_VCPUS;
     }
 
+    if ( !config->dsdt_s3_enabled)
+        remove_package(dsdt, "_S3");
+    if ( !config->dsdt_s4_enabled)
+        remove_package(dsdt, "_S4");
+
+    set_checksum(dsdt,
+                 offsetof(struct acpi_header, checksum),
+                 ((struct acpi_header*)dsdt)->length);
+    mem_commit(dsdt, ((struct acpi_header*)dsdt)->length);
+
     /*
      * N.B. ACPI 1.0 operating systems may not handle FADT with revision 2
      * or above properly, notably Windows 2000, which tries to copy FADT
diff -r 447738ef67ea -r c25af1f86de1 tools/firmware/hvmloader/config.h
--- a/tools/firmware/hvmloader/config.h Thu Nov 17 16:21:21 2011 +0000
+++ b/tools/firmware/hvmloader/config.h Thu Nov 17 16:40:43 2011 +0000
@@ -27,7 +27,7 @@ struct bios_config {
 
     void (*e820_setup)(void);
 
-    void (*acpi_build_tables)(void);
+    void (*acpi_build_tables)(int, int);
     void (*create_mp_tables)(void);
     void (*create_smbios_tables)(void);
     void (*create_pir_tables)(void);
diff -r 447738ef67ea -r c25af1f86de1 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Thu Nov 17 16:21:21 2011 +0000
+++ b/tools/firmware/hvmloader/hvmloader.c      Thu Nov 17 16:40:43 2011 +0000
@@ -516,11 +516,17 @@ int main(void)
             .index = HVM_PARAM_ACPI_IOPORTS_LOCATION,
             .value = 1,
         };
+        int s3_enabled, s4_enabled;
+
+        s3_enabled = !strncmp(xenstore_read("platform/acpi_s3", "1"), "1", 1);
+        s4_enabled = !strncmp(xenstore_read("platform/acpi_s4", "1"), "1", 1);
 
         if ( bios->acpi_build_tables )
         {
-            printf("Loading ACPI ...\n");
-            bios->acpi_build_tables();
+            printf("Loading ACPI (S3=%s S4=%s) ...\n",
+                   (s3_enabled) ? "ON" : "OFF",
+                   (s4_enabled) ? "ON" : "OFF");
+            bios->acpi_build_tables(s3_enabled, s4_enabled);
         }
 
         acpi_enable_sci();
diff -r 447738ef67ea -r c25af1f86de1 tools/firmware/hvmloader/rombios.c
--- a/tools/firmware/hvmloader/rombios.c        Thu Nov 17 16:21:21 2011 +0000
+++ b/tools/firmware/hvmloader/rombios.c        Thu Nov 17 16:40:43 2011 +0000
@@ -112,13 +112,15 @@ static void reset_bios_checksum(void)
     *((uint8_t *)(ROMBIOS_BEGIN + ROMBIOS_MAXOFFSET)) = -checksum;
 }
 
-static void rombios_acpi_build_tables(void)
+static void rombios_acpi_build_tables(int s3_enabled, int s4_enabled)
 {
     struct acpi_config config = {
         .dsdt_anycpu = dsdt_anycpu,
         .dsdt_anycpu_len = dsdt_anycpu_len,
         .dsdt_15cpu = dsdt_15cpu,
         .dsdt_15cpu_len = dsdt_15cpu_len,
+        .dsdt_s3_enabled = s3_enabled,
+        .dsdt_s4_enabled = s4_enabled,
     };
 
     acpi_build_tables(&config, ACPI_PHYSICAL_ADDRESS);
diff -r 447738ef67ea -r c25af1f86de1 tools/firmware/hvmloader/seabios.c
--- a/tools/firmware/hvmloader/seabios.c        Thu Nov 17 16:21:21 2011 +0000
+++ b/tools/firmware/hvmloader/seabios.c        Thu Nov 17 16:40:43 2011 +0000
@@ -91,7 +91,7 @@ static void add_table(uint32_t t)
     info->tables_nr++;
 }
 
-static void seabios_acpi_build_tables(void)
+static void seabios_acpi_build_tables(int s3_enabled, int s4_enabled)
 {
     uint32_t rsdp = (uint32_t)scratch_alloc(sizeof(struct acpi_20_rsdp), 0);
     struct acpi_config config = {
@@ -99,6 +99,8 @@ static void seabios_acpi_build_tables(vo
         .dsdt_anycpu_len = dsdt_anycpu_qemu_xen_len,
         .dsdt_15cpu = NULL,
         .dsdt_15cpu_len = 0,
+        .dsdt_s3_enabled = s3_enabled,
+        .dsdt_s4_enabled = s4_enabled,
     };
 
     acpi_build_tables(&config, rsdp);
diff -r 447738ef67ea -r c25af1f86de1 tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c   Thu Nov 17 16:21:21 2011 +0000
+++ b/tools/firmware/hvmloader/util.c   Thu Nov 17 16:40:43 2011 +0000
@@ -352,28 +352,35 @@ xen_pfn_t mem_hole_alloc(uint32_t nr_mfn
     return hvm_info->reserved_mem_pgstart;
 }
 
-void *mem_alloc(uint32_t size, uint32_t align)
+void *mem_probe(uint32_t size, uint32_t align)
 {
-    uint32_t s, e;
+    uint32_t r, s, e;
+    void *base;
 
     /* Align to at least 16 bytes. */
     if ( align < 16 )
         align = 16;
 
-    s = (reserve + align) & ~(align - 1);
+    r = reserve;
+    s = (r + align) & ~(align - 1);
     e = s + size - 1;
 
+    base = (void *)s;
+
     BUG_ON((e < s) || (e >> PAGE_SHIFT) >= hvm_info->reserved_mem_pgstart);
 
-    while ( (reserve >> PAGE_SHIFT) != (e >> PAGE_SHIFT) )
+    while ( (r >> PAGE_SHIFT) != (e >> PAGE_SHIFT) )
     {
-        reserve += PAGE_SIZE;
-        mem_hole_populate_ram(reserve >> PAGE_SHIFT, 1);
+        r += PAGE_SIZE;
+        mem_hole_populate_ram(r >> PAGE_SHIFT, 1);
     }
 
-    reserve = e;
+    return (void *)(unsigned long)s;
+}
 
-    return (void *)(unsigned long)s;
+void mem_commit(void *base, uint32_t size)
+{
+    reserve = (uint32_t)base + size;
 }
 
 void *scratch_alloc(uint32_t size, uint32_t align)
diff -r 447738ef67ea -r c25af1f86de1 tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h   Thu Nov 17 16:21:21 2011 +0000
+++ b/tools/firmware/hvmloader/util.h   Thu Nov 17 16:40:43 2011 +0000
@@ -172,7 +172,16 @@ void mem_hole_populate_ram(xen_pfn_t mfn
 xen_pfn_t mem_hole_alloc(uint32_t nr_mfns);
 
 /* Allocate memory in a reserved region below 4GB. */
-void *mem_alloc(uint32_t size, uint32_t align);
+void *mem_probe(uint32_t size, uint32_t align);
+void mem_commit(void *base, uint32_t size);
+
+static inline void *mem_alloc(uint32_t size, uint32_t align)
+{
+    void *base = mem_probe(size, align);
+    mem_commit(base, size);
+    return base;
+}
+
 #define virt_to_phys(v) ((unsigned long)(v))
 
 /* Allocate memory in a scratch region */
diff -r 447738ef67ea -r c25af1f86de1 tools/libxl/libxl_create.c
--- a/tools/libxl/libxl_create.c        Thu Nov 17 16:21:21 2011 +0000
+++ b/tools/libxl/libxl_create.c        Thu Nov 17 16:40:43 2011 +0000
@@ -93,6 +93,8 @@ int libxl_init_build_info(libxl_ctx *ctx
         b_info->u.hvm.pae = 1;
         b_info->u.hvm.apic = 1;
         b_info->u.hvm.acpi = 1;
+        b_info->u.hvm.acpi_s3 = 1;
+        b_info->u.hvm.acpi_s4 = 1;
         b_info->u.hvm.nx = 1;
         b_info->u.hvm.viridian = 0;
         b_info->u.hvm.hpet = 1;
@@ -189,9 +191,13 @@ int libxl__domain_build(libxl__gc *gc,
         vments[4] = "start_time";
         vments[5] = libxl__sprintf(gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
 
-        localents = libxl__calloc(gc, 3, sizeof(char *));
+        localents = libxl__calloc(gc, 7, sizeof(char *));
         localents[0] = "platform/acpi";
         localents[1] = (info->u.hvm.acpi) ? "1" : "0";
+        localents[2] = "platform/acpi_s3";
+        localents[3] = (info->u.hvm.acpi_s3) ? "1" : "0";
+        localents[4] = "platform/acpi_s4";
+        localents[5] = (info->u.hvm.acpi_s4) ? "1" : "0";
 
         break;
     case LIBXL_DOMAIN_TYPE_PV:
diff -r 447738ef67ea -r c25af1f86de1 tools/libxl/libxl_types.idl
--- a/tools/libxl/libxl_types.idl       Thu Nov 17 16:21:21 2011 +0000
+++ b/tools/libxl/libxl_types.idl       Thu Nov 17 16:40:43 2011 +0000
@@ -167,6 +167,8 @@ libxl_domain_build_info = Struct("domain
                                        ("pae", bool),
                                        ("apic", bool),
                                        ("acpi", bool),
+                                       ("acpi_s3", bool),
+                                       ("acpi_s4", bool),
                                        ("nx", bool),
                                        ("viridian", bool),
                                        ("timeoffset", string),
diff -r 447738ef67ea -r c25af1f86de1 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c  Thu Nov 17 16:21:21 2011 +0000
+++ b/tools/libxl/xl_cmdimpl.c  Thu Nov 17 16:40:43 2011 +0000
@@ -683,6 +683,10 @@ static void parse_config_data(const char
             b_info->u.hvm.apic = l;
         if (!xlu_cfg_get_long (config, "acpi", &l))
             b_info->u.hvm.acpi = l;
+        if (!xlu_cfg_get_long (config, "acpi_s3", &l))
+            b_info->u.hvm.acpi_s3 = l;
+        if (!xlu_cfg_get_long (config, "acpi_s4", &l))
+            b_info->u.hvm.acpi_s4 = l;
         if (!xlu_cfg_get_long (config, "nx", &l))
             b_info->u.hvm.nx = l;
         if (!xlu_cfg_get_long (config, "viridian", &l))

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