Paul Durrant
2011-Nov-17 16:43 UTC
[Xen-devel] [PATCH 0 of 2] New ACPI configuration options
_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Paul Durrant
2011-Nov-17 16:43 UTC
[Xen-devel] [PATCH 1 of 2] Move acpi_enabled out of hvm_info_table into xenstore
# HG changeset patch # User Paul Durrant <paul.durrant@citrix.com> # Date 1321546881 0 # Node ID 447738ef67ea2690c8ea6684f2e0e0b3528ad446 # Parent dbdc840f8f62db58321b5009e5e0f7833066386f Move acpi_enabled out of hvm_info_table into xenstore Since hvmloader has a xentore client, use a platform key in xenstore to indicate whether ACPI is enabled or not rather than the shared hvm_info_table structure. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> diff -r dbdc840f8f62 -r 447738ef67ea tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Nov 16 18:21:14 2011 +0000 +++ b/tools/firmware/hvmloader/hvmloader.c Thu Nov 17 16:21:21 2011 +0000 @@ -423,6 +423,7 @@ int main(void) const struct bios_config *bios; int option_rom_sz = 0, vgabios_sz = 0, etherboot_sz = 0; uint32_t etherboot_phys_addr = 0, option_rom_phys_addr = 0; + int acpi_enabled; /* Initialise hypercall stubs with RET, rendering them no-ops. */ memset((void *)HYPERCALL_PHYSICAL_ADDRESS, 0xc3 /* RET */, PAGE_SIZE); @@ -506,7 +507,9 @@ int main(void) option_rom_phys_addr); } - if ( hvm_info->acpi_enabled ) + acpi_enabled = !strncmp(xenstore_read("platform/acpi", "1"), "1", 1); + + if ( acpi_enabled ) { struct xen_hvm_param p = { .domid = DOMID_SELF, diff -r dbdc840f8f62 -r 447738ef67ea tools/libxc/xc_hvm_build.c --- a/tools/libxc/xc_hvm_build.c Wed Nov 16 18:21:14 2011 +0000 +++ b/tools/libxc/xc_hvm_build.c Thu Nov 17 16:21:21 2011 +0000 @@ -67,7 +67,6 @@ static void build_hvm_info(void *hvm_inf hvm_info->length = sizeof(struct hvm_info_table); /* Sensible defaults: these can be overridden by the caller. */ - hvm_info->acpi_enabled = 1; hvm_info->apic_mode = 1; hvm_info->nr_vcpus = 1; memset(hvm_info->vcpu_online, 0xff, sizeof(hvm_info->vcpu_online)); diff -r dbdc840f8f62 -r 447738ef67ea tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c Wed Nov 16 18:21:14 2011 +0000 +++ b/tools/libxl/libxl_create.c Thu Nov 17 16:21:21 2011 +0000 @@ -188,6 +188,11 @@ int libxl__domain_build(libxl__gc *gc, vments[3] = "hvm"; 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[0] = "platform/acpi"; + localents[1] = (info->u.hvm.acpi) ? "1" : "0"; + break; case LIBXL_DOMAIN_TYPE_PV: ret = libxl__build_pv(gc, domid, info, state); diff -r dbdc840f8f62 -r 447738ef67ea tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c Wed Nov 16 18:21:14 2011 +0000 +++ b/tools/libxl/libxl_dom.c Thu Nov 17 16:21:21 2011 +0000 @@ -248,7 +248,6 @@ static int hvm_build_set_params(xc_inter return -1; va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET); - va_hvm->acpi_enabled = info->u.hvm.acpi; va_hvm->apic_mode = info->u.hvm.apic; va_hvm->nr_vcpus = info->max_vcpus; memcpy(va_hvm->vcpu_online, &info->cur_vcpus, sizeof(info->cur_vcpus)); diff -r dbdc840f8f62 -r 447738ef67ea tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Wed Nov 16 18:21:14 2011 +0000 +++ b/tools/python/xen/lowlevel/xc/xc.c Thu Nov 17 16:21:21 2011 +0000 @@ -996,7 +996,6 @@ static PyObject *pyxc_hvm_build(XcObject if ( va_map == NULL ) return PyErr_SetFromErrno(xc_error_obj); va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET); - va_hvm->acpi_enabled = acpi; va_hvm->apic_mode = apic; va_hvm->nr_vcpus = vcpus; memcpy(va_hvm->vcpu_online, vcpu_avail, sizeof(vcpu_avail)); diff -r dbdc840f8f62 -r 447738ef67ea xen/include/public/hvm/hvm_info_table.h --- a/xen/include/public/hvm/hvm_info_table.h Wed Nov 16 18:21:14 2011 +0000 +++ b/xen/include/public/hvm/hvm_info_table.h Thu Nov 17 16:21:21 2011 +0000 @@ -37,9 +37,6 @@ struct hvm_info_table { uint32_t length; uint8_t checksum; - /* Should firmware build ACPI tables? */ - uint8_t acpi_enabled; - /* Should firmware build APIC descriptors (APIC MADT / MP BIOS)? */ uint8_t apic_mode; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Paul Durrant
2011-Nov-17 16:43 UTC
[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@citrix.com> # 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@citrix.com> 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@lists.xensource.com http://lists.xensource.com/xen-devel
Paul Durrant
2011-Nov-17 16:47 UTC
[Xen-devel] RE: [PATCH 0 of 2] New ACPI configuration options
For some reason this email seems to have been sent empty. The test should be: This patch series adds the ability to selectively disable the S3 and S4 ACPI power states for HVM guests. Since there is a general move towards retiring the hvm_info_table structure, the first patch moves the acpi_enabled flag out of the hvm_info_table and into a xenstore key (platform/acpi). The second patch then introduces the acpi_s3 and acpi_s4 configuration parameters to the xl config file (default=1). These result in population of new platform/acpi_s3 and platform/acpi_s4 xenstore keys. hvmloader then reads these keys and will remove the respective package(s) from the DSDT if either/both of them are zero. Apologies for that. Paul> -----Original Message----- > From: Paul Durrant [mailto:paul.durrant@citrix.com] > Sent: 17 November 2011 16:44 > To: xen-devel@lists.xensource.com > Cc: Paul Durrant > Subject: [PATCH 0 of 2] New ACPI configuration options >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Nov-17 17:21 UTC
Re: [Xen-devel] [PATCH 2 of 2] Add configuration options to selectively disable S3 and S4 ACPI power states
On 17/11/2011 16:43, "Paul Durrant" <paul.durrant@citrix.com> wrote:> # HG changeset patch > # User Paul Durrant <paul.durrant@citrix.com> > # 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.Yeeees. Brave as binary patching the DSDT is, how about sticking _S3 and _S4 in optional SSDTs? -- Keir> Signed-off-by: Paul Durrant <paul.durrant@citrix.com> > > 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@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Paul Durrant
2011-Nov-18 08:56 UTC
RE: [Xen-devel] [PATCH 2 of 2] Add configuration options to selectively disable S3 and S4 ACPI power states
Not sure whether that will work, but I can give it a try. Windows quite often has very particular ideas about where things should be. Paul> -----Original Message----- > From: Keir Fraser [mailto:keir.xen@gmail.com] On Behalf Of Keir > Fraser > Sent: 17 November 2011 17:21 > To: Paul Durrant; xen-devel@lists.xensource.com > Subject: Re: [Xen-devel] [PATCH 2 of 2] Add configuration options to > selectively disable S3 and S4 ACPI power states > > On 17/11/2011 16:43, "Paul Durrant" <paul.durrant@citrix.com> wrote: > > > # HG changeset patch > > # User Paul Durrant <paul.durrant@citrix.com> # 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. > > Yeeees. Brave as binary patching the DSDT is, how about sticking _S3 > and _S4 in optional SSDTs? > > -- Keir > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com> > > > > 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@lists.xensource.com > > http://lists.xensource.com/xen-devel >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Nov-18 09:35 UTC
Re: [Xen-devel] [PATCH 2 of 2] Add configuration options to selectively disable S3 and S4 ACPI power states
The OSPM shouldn''t care. It parses all tables at start of day into one big homogeneous namespace. On 18/11/2011 08:56, "Paul Durrant" <Paul.Durrant@citrix.com> wrote:> Not sure whether that will work, but I can give it a try. Windows quite often > has very particular ideas about where things should be. > > Paul > >> -----Original Message----- >> From: Keir Fraser [mailto:keir.xen@gmail.com] On Behalf Of Keir >> Fraser >> Sent: 17 November 2011 17:21 >> To: Paul Durrant; xen-devel@lists.xensource.com >> Subject: Re: [Xen-devel] [PATCH 2 of 2] Add configuration options to >> selectively disable S3 and S4 ACPI power states >> >> On 17/11/2011 16:43, "Paul Durrant" <paul.durrant@citrix.com> wrote: >> >>> # HG changeset patch >>> # User Paul Durrant <paul.durrant@citrix.com> # 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. >> >> Yeeees. Brave as binary patching the DSDT is, how about sticking _S3 >> and _S4 in optional SSDTs? >> >> -- Keir >> >>> Signed-off-by: Paul Durrant <paul.durrant@citrix.com> >>> >>> 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@lists.xensource.com >>> http://lists.xensource.com/xen-devel >> >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel