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

[Xen-devel] [PATCH 2 of 2] Add configuration options to selectively disable S3 and S4 ACPI power states



# 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


 


Rackspace

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