All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] ACPI: Add -acpifadt to allow FADT revision changes
@ 2016-08-08  7:28 Lv Zheng
  2016-08-08  7:35 ` no-reply
                   ` (5 more replies)
  0 siblings, 6 replies; 32+ messages in thread
From: Lv Zheng @ 2016-08-08  7:28 UTC (permalink / raw)
  To: Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, Lv Zheng, qemu-devel, qemu-arm

This patch allows FADT to be built with different revisions. When the revision
is greater than 1.0, 64-bit address fields may also be filled.

Note that FADT revision 2 has never been defined by the ACPI specification. So
this patch only adds an option -acpifadt to allow revision 1,3,5 to be
configured by the users.

1. Tested by booting a linux image, the 64-bit addresses are correctly filled
   in the dumped FADT.
2. Tested by booting a Windows image, no boot failure can be seen.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 hw/i386/acpi-build.c   |   62 ++++++++++++++++++++++++++++++++++++++++++------
 include/hw/acpi/acpi.h |    1 +
 qemu-options.hx        |    9 +++++++
 vl.c                   |   18 ++++++++++++++
 4 files changed, 83 insertions(+), 7 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ce7cbc5..1f664de 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker *linker)
     facs->length = cpu_to_le32(sizeof(*facs));
 }
 
+/* GAS */
+static void
+build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
+	  uint8_t bit_width, uint8_t bit_offset,
+	  uint8_t access_width, uint64_t address)
+{
+    gas->space_id = space_id;
+    gas->bit_width = bit_width;
+    gas->bit_offset = bit_offset;
+    gas->access_width= access_width;
+    gas->address = address;
+}
+
 /* Load chipset information in FADT */
-static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
+static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo *pm,
+                       uint8_t revision)
 {
     fadt->model = 1;
     fadt->reserved1 = 0;
@@ -309,6 +323,25 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
         fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
     }
     fadt->century = RTC_CENTURY;
+
+    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
+    if (revision >= 3) {
+        /* EVT, CNT, TMR register matches hw/acpi/core.c */
+        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
+                  32, 0, 0, cpu_to_le64(pm->io_base));
+        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
+                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
+        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
+                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
+        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
+                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm->gpe0_blk));
+    }
+
+    /* Build dummy ACPI 5.0 fields */
+    if (revision >= 5) {
+        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
+        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
+    }
 }
 
 
@@ -316,9 +349,9 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
 static void
 build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
            unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
-           const char *oem_id, const char *oem_table_id)
+           const char *oem_id, const char *oem_table_id, uint8_t revision)
 {
-    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
+    AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
     unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
     unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
 
@@ -328,13 +361,28 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
         ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
 
     /* DSDT address to be filled by Guest linker */
-    fadt_setup(fadt, pm);
     bios_linker_loader_add_pointer(linker,
         ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
         ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
 
-    build_header(linker, table_data,
-                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
+    if (revision > 2) {
+        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
+        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
+
+        /* FACS address to be filled by Guest linker */
+        bios_linker_loader_add_pointer(linker,
+            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
+            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
+
+        /* DSDT address to be filled by Guest linker */
+        bios_linker_loader_add_pointer(linker,
+            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->Xdsdt),
+            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
+    }
+
+    fadt_setup(fadt, pm, revision);
+    build_header(linker, table_data, (void *)fadt, "FACP", sizeof(*fadt),
+                 revision, oem_id, oem_table_id);
 }
 
 void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
@@ -2681,7 +2729,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
     fadt = tables_blob->len;
     acpi_add_table(table_offsets, tables_blob);
     build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
-               slic_oem.id, slic_oem.table_id);
+               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
     aml_len += tables_blob->len - fadt;
 
     acpi_add_table(table_offsets, tables_blob);
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 7b3d93c..63df38d 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq);
 
 /* acpi.c */
 extern int acpi_enabled;
+extern uint8_t acpi_fadt_rev;
 extern char unsigned *acpi_tables;
 extern size_t acpi_tables_len;
 
diff --git a/qemu-options.hx b/qemu-options.hx
index a71aaf8..cff34f6 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1492,6 +1492,15 @@ STEXI
 Disable HPET support.
 ETEXI
 
+DEF("acpifadt", HAS_ARG, QEMU_OPTION_acpifadt, \
+    "-acpifadt  n    configure FADT revision number (1, 3, 5)\n",
+    QEMU_ARCH_ALL)
+STEXI
+@item -acpifadt @var{n}
+@findex -acpifadt
+Configure FADT revision number, default is 1.
+ETEXI
+
 DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
     "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
     "                ACPI table description\n", QEMU_ARCH_I386)
diff --git a/vl.c b/vl.c
index e7c2c62..5fe2414 100644
--- a/vl.c
+++ b/vl.c
@@ -64,6 +64,7 @@ int main(int argc, char **argv)
 #include "hw/bt.h"
 #include "sysemu/watchdog.h"
 #include "hw/smbios/smbios.h"
+#include "hw/acpi/acpi.h"
 #include "hw/xen/xen.h"
 #include "hw/qdev.h"
 #include "hw/loader.h"
@@ -158,6 +159,7 @@ int max_cpus = 1;
 int smp_cores = 1;
 int smp_threads = 1;
 int acpi_enabled = 1;
+uint8_t acpi_fadt_rev = 1;
 int no_hpet = 0;
 int fd_bootchk = 1;
 static int no_reboot;
@@ -2301,6 +2303,19 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
     return 0;
 }
 
+static void fadt_parse(const char *arg)
+{
+    uint32_t rev;
+
+    rev = strtoul(arg, NULL, 0);
+    if (rev != 1 && rev != 3 && rev != 5) {
+        error_printf("Unsupported FADT revision %d,"
+                     "please specify 1,3,5.\n", rev);
+        exit(1);
+    }
+    acpi_fadt_rev = rev;
+}
+
 static int device_help_func(void *opaque, QemuOpts *opts, Error **errp)
 {
     return qdev_device_help(opts);
@@ -3622,6 +3637,9 @@ int main(int argc, char **argv, char **envp)
                 qdev_prop_register_global(&slew_lost_ticks);
                 break;
             }
+            case QEMU_OPTION_acpifadt:
+                fadt_parse(optarg);
+                break;
             case QEMU_OPTION_acpitable:
                 opts = qemu_opts_parse_noisily(qemu_find_opts("acpi"),
                                                optarg, true);
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH] ACPI: Add -acpifadt to allow FADT revision changes
  2016-08-08  7:28 [Qemu-devel] [PATCH] ACPI: Add -acpifadt to allow FADT revision changes Lv Zheng
@ 2016-08-08  7:35 ` no-reply
  2016-08-08  8:16 ` [Qemu-devel] [PATCH v2] " Lv Zheng
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 32+ messages in thread
From: no-reply @ 2016-08-08  7:35 UTC (permalink / raw)
  To: lv.zheng; +Cc: famz, mst, imammedo, shannon.zhao, qemu-arm, zetalog, qemu-devel

Hi,

Your series seems to have some coding style problems. See output below for
more information:

Message-id: 409b2bbd046a53987a71e64d855e5761d441bbaf.1470641265.git.lv.zheng@intel.com
Type: series
Subject: [Qemu-devel] [PATCH] ACPI: Add -acpifadt to allow FADT revision changes

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git show --no-patch --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/409b2bbd046a53987a71e64d855e5761d441bbaf.1470641265.git.lv.zheng@intel.com -> patchew/409b2bbd046a53987a71e64d855e5761d441bbaf.1470641265.git.lv.zheng@intel.com
 * [new tag]         patchew/5d4b5e6b17eadf92b61e9ef6f3118f7658bb99d0.1470641028.git.lv.zheng@intel.com -> patchew/5d4b5e6b17eadf92b61e9ef6f3118f7658bb99d0.1470641028.git.lv.zheng@intel.com
Switched to a new branch 'test'
10f0124 ACPI: Add -acpifadt to allow FADT revision changes

=== OUTPUT BEGIN ===
Checking PATCH 1/1: ACPI: Add -acpifadt to allow FADT revision changes...
ERROR: code indent should never use tabs
#31: FILE: hw/i386/acpi-build.c:281:
+^I  uint8_t bit_width, uint8_t bit_offset,$

ERROR: code indent should never use tabs
#32: FILE: hw/i386/acpi-build.c:282:
+^I  uint8_t access_width, uint64_t address)$

ERROR: spaces required around that '=' (ctx:VxW)
#37: FILE: hw/i386/acpi-build.c:287:
+    gas->access_width= access_width;
                      ^

WARNING: consider using qemu_strtoul in preference to strtoul
#187: FILE: vl.c:2310:
+    rev = strtoul(arg, NULL, 0);

total: 3 errors, 1 warnings, 162 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PATCH v2] ACPI: Add -acpifadt to allow FADT revision changes
  2016-08-08  7:28 [Qemu-devel] [PATCH] ACPI: Add -acpifadt to allow FADT revision changes Lv Zheng
  2016-08-08  7:35 ` no-reply
@ 2016-08-08  8:16 ` Lv Zheng
  2016-08-08  9:01   ` Paolo Bonzini
  2016-08-08 11:25 ` [Qemu-devel] [PATCH] " Igor Mammedov
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 32+ messages in thread
From: Lv Zheng @ 2016-08-08  8:16 UTC (permalink / raw)
  To: Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, Lv Zheng, qemu-devel, qemu-arm

This patch allows FADT to be built with different revisions. When the revision
is greater than 1.0, 64-bit address fields may also be filled.

Note that FADT revision 2 has never been defined by the ACPI specification. So
this patch only adds an option -acpifadt to allow revision 1,3,5 to be
configured by the users.

1. Tested by booting a linux image, the 64-bit addresses are correctly filled
   in the dumped FADT.
2. Tested by booting a Windows image, no boot failure can be seen.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
History:

v2: Fix coding style issues.
---
 hw/i386/acpi-build.c   |   62 ++++++++++++++++++++++++++++++++++++++++++------
 include/hw/acpi/acpi.h |    1 +
 qemu-options.hx        |    9 +++++++
 vl.c                   |   23 ++++++++++++++++++
 4 files changed, 88 insertions(+), 7 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ce7cbc5..4479695 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker *linker)
     facs->length = cpu_to_le32(sizeof(*facs));
 }
 
+/* GAS */
+static void
+build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
+          uint8_t bit_width, uint8_t bit_offset,
+          uint8_t access_width, uint64_t address)
+{
+    gas->space_id = space_id;
+    gas->bit_width = bit_width;
+    gas->bit_offset = bit_offset;
+    gas->access_width = access_width;
+    gas->address = address;
+}
+
 /* Load chipset information in FADT */
-static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
+static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo *pm,
+                       uint8_t revision)
 {
     fadt->model = 1;
     fadt->reserved1 = 0;
@@ -309,6 +323,25 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
         fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
     }
     fadt->century = RTC_CENTURY;
+
+    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
+    if (revision >= 3) {
+        /* EVT, CNT, TMR register matches hw/acpi/core.c */
+        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
+                  32, 0, 0, cpu_to_le64(pm->io_base));
+        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
+                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
+        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
+                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
+        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
+                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm->gpe0_blk));
+    }
+
+    /* Build dummy ACPI 5.0 fields */
+    if (revision >= 5) {
+        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
+        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
+    }
 }
 
 
@@ -316,9 +349,9 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
 static void
 build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
            unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
-           const char *oem_id, const char *oem_table_id)
+           const char *oem_id, const char *oem_table_id, uint8_t revision)
 {
-    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
+    AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
     unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
     unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
 
@@ -328,13 +361,28 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
         ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
 
     /* DSDT address to be filled by Guest linker */
-    fadt_setup(fadt, pm);
     bios_linker_loader_add_pointer(linker,
         ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
         ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
 
-    build_header(linker, table_data,
-                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
+    if (revision > 2) {
+        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
+        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
+
+        /* FACS address to be filled by Guest linker */
+        bios_linker_loader_add_pointer(linker,
+            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
+            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
+
+        /* DSDT address to be filled by Guest linker */
+        bios_linker_loader_add_pointer(linker,
+            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->Xdsdt),
+            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
+    }
+
+    fadt_setup(fadt, pm, revision);
+    build_header(linker, table_data, (void *)fadt, "FACP", sizeof(*fadt),
+                 revision, oem_id, oem_table_id);
 }
 
 void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
@@ -2681,7 +2729,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
     fadt = tables_blob->len;
     acpi_add_table(table_offsets, tables_blob);
     build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
-               slic_oem.id, slic_oem.table_id);
+               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
     aml_len += tables_blob->len - fadt;
 
     acpi_add_table(table_offsets, tables_blob);
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 7b3d93c..63df38d 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq);
 
 /* acpi.c */
 extern int acpi_enabled;
+extern uint8_t acpi_fadt_rev;
 extern char unsigned *acpi_tables;
 extern size_t acpi_tables_len;
 
diff --git a/qemu-options.hx b/qemu-options.hx
index a71aaf8..cff34f6 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1492,6 +1492,15 @@ STEXI
 Disable HPET support.
 ETEXI
 
+DEF("acpifadt", HAS_ARG, QEMU_OPTION_acpifadt, \
+    "-acpifadt  n    configure FADT revision number (1, 3, 5)\n",
+    QEMU_ARCH_ALL)
+STEXI
+@item -acpifadt @var{n}
+@findex -acpifadt
+Configure FADT revision number, default is 1.
+ETEXI
+
 DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
     "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
     "                ACPI table description\n", QEMU_ARCH_I386)
diff --git a/vl.c b/vl.c
index e7c2c62..220e36d 100644
--- a/vl.c
+++ b/vl.c
@@ -64,6 +64,7 @@ int main(int argc, char **argv)
 #include "hw/bt.h"
 #include "sysemu/watchdog.h"
 #include "hw/smbios/smbios.h"
+#include "hw/acpi/acpi.h"
 #include "hw/xen/xen.h"
 #include "hw/qdev.h"
 #include "hw/loader.h"
@@ -158,6 +159,7 @@ int max_cpus = 1;
 int smp_cores = 1;
 int smp_threads = 1;
 int acpi_enabled = 1;
+uint8_t acpi_fadt_rev = 1;
 int no_hpet = 0;
 int fd_bootchk = 1;
 static int no_reboot;
@@ -2301,6 +2303,24 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
     return 0;
 }
 
+static void fadt_parse(const char *arg)
+{
+    unsigned long rev;
+    int err;
+
+    err = qemu_strtoul(arg, NULL, 10, &rev);
+    if (err) {
+        error_printf("Invalid FADT revision.\n");
+        exit(1);
+    }
+    if (rev != 1 && rev != 3 && rev != 5) {
+        error_printf("Unsupported FADT revision %lu, "
+                     "please specify 1,3,5.\n", rev);
+        exit(1);
+    }
+    acpi_fadt_rev = rev;
+}
+
 static int device_help_func(void *opaque, QemuOpts *opts, Error **errp)
 {
     return qdev_device_help(opts);
@@ -3622,6 +3642,9 @@ int main(int argc, char **argv, char **envp)
                 qdev_prop_register_global(&slew_lost_ticks);
                 break;
             }
+            case QEMU_OPTION_acpifadt:
+                fadt_parse(optarg);
+                break;
             case QEMU_OPTION_acpitable:
                 opts = qemu_opts_parse_noisily(qemu_find_opts("acpi"),
                                                optarg, true);
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v2] ACPI: Add -acpifadt to allow FADT revision changes
  2016-08-08  8:16 ` [Qemu-devel] [PATCH v2] " Lv Zheng
@ 2016-08-08  9:01   ` Paolo Bonzini
  2016-08-09 21:06     ` Zheng, Lv
  0 siblings, 1 reply; 32+ messages in thread
From: Paolo Bonzini @ 2016-08-08  9:01 UTC (permalink / raw)
  To: Lv Zheng, Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: qemu-arm, Lv Zheng, qemu-devel



On 08/08/2016 10:16, Lv Zheng wrote:
> This patch allows FADT to be built with different revisions. When the revision
> is greater than 1.0, 64-bit address fields may also be filled.
> 
> Note that FADT revision 2 has never been defined by the ACPI specification. So
> this patch only adds an option -acpifadt to allow revision 1,3,5 to be
> configured by the users.
> 
> 1. Tested by booting a linux image, the 64-bit addresses are correctly filled
>    in the dumped FADT.
> 2. Tested by booting a Windows image, no boot failure can be seen.
> 
> Signed-off-by: Lv Zheng <lv.zheng@intel.com>

Hi, please make this a suboption of -acpitable instead.  We try not to
add new command-line options without supporting them in QemuOpts too.

Paolo

> ---
> History:
> 
> v2: Fix coding style issues.
> ---
>  hw/i386/acpi-build.c   |   62 ++++++++++++++++++++++++++++++++++++++++++------
>  include/hw/acpi/acpi.h |    1 +
>  qemu-options.hx        |    9 +++++++
>  vl.c                   |   23 ++++++++++++++++++
>  4 files changed, 88 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index ce7cbc5..4479695 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker *linker)
>      facs->length = cpu_to_le32(sizeof(*facs));
>  }
>  
> +/* GAS */
> +static void
> +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> +          uint8_t bit_width, uint8_t bit_offset,
> +          uint8_t access_width, uint64_t address)
> +{
> +    gas->space_id = space_id;
> +    gas->bit_width = bit_width;
> +    gas->bit_offset = bit_offset;
> +    gas->access_width = access_width;
> +    gas->address = address;
> +}
> +
>  /* Load chipset information in FADT */
> -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo *pm,
> +                       uint8_t revision)
>  {
>      fadt->model = 1;
>      fadt->reserved1 = 0;
> @@ -309,6 +323,25 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
>          fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
>      }
>      fadt->century = RTC_CENTURY;
> +
> +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> +    if (revision >= 3) {
> +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> +        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
> +                  32, 0, 0, cpu_to_le64(pm->io_base));
> +        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
> +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm->gpe0_blk));
> +    }
> +
> +    /* Build dummy ACPI 5.0 fields */
> +    if (revision >= 5) {
> +        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
> +        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
> +    }
>  }
>  
>  
> @@ -316,9 +349,9 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
>  static void
>  build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
>             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> -           const char *oem_id, const char *oem_table_id)
> +           const char *oem_id, const char *oem_table_id, uint8_t revision)
>  {
> -    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
> +    AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
>      unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
>      unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
>  
> @@ -328,13 +361,28 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
>          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
>  
>      /* DSDT address to be filled by Guest linker */
> -    fadt_setup(fadt, pm);
>      bios_linker_loader_add_pointer(linker,
>          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
>          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
>  
> -    build_header(linker, table_data,
> -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
> +    if (revision > 2) {
> +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
> +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
> +
> +        /* FACS address to be filled by Guest linker */
> +        bios_linker_loader_add_pointer(linker,
> +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
> +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> +
> +        /* DSDT address to be filled by Guest linker */
> +        bios_linker_loader_add_pointer(linker,
> +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->Xdsdt),
> +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> +    }
> +
> +    fadt_setup(fadt, pm, revision);
> +    build_header(linker, table_data, (void *)fadt, "FACP", sizeof(*fadt),
> +                 revision, oem_id, oem_table_id);
>  }
>  
>  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> @@ -2681,7 +2729,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
>      fadt = tables_blob->len;
>      acpi_add_table(table_offsets, tables_blob);
>      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> -               slic_oem.id, slic_oem.table_id);
> +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
>      aml_len += tables_blob->len - fadt;
>  
>      acpi_add_table(table_offsets, tables_blob);
> diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> index 7b3d93c..63df38d 100644
> --- a/include/hw/acpi/acpi.h
> +++ b/include/hw/acpi/acpi.h
> @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq);
>  
>  /* acpi.c */
>  extern int acpi_enabled;
> +extern uint8_t acpi_fadt_rev;
>  extern char unsigned *acpi_tables;
>  extern size_t acpi_tables_len;
>  
> diff --git a/qemu-options.hx b/qemu-options.hx
> index a71aaf8..cff34f6 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1492,6 +1492,15 @@ STEXI
>  Disable HPET support.
>  ETEXI
>  
> +DEF("acpifadt", HAS_ARG, QEMU_OPTION_acpifadt, \
> +    "-acpifadt  n    configure FADT revision number (1, 3, 5)\n",
> +    QEMU_ARCH_ALL)
> +STEXI
> +@item -acpifadt @var{n}
> +@findex -acpifadt
> +Configure FADT revision number, default is 1.
> +ETEXI
> +
>  DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
>      "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
>      "                ACPI table description\n", QEMU_ARCH_I386)
> diff --git a/vl.c b/vl.c
> index e7c2c62..220e36d 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -64,6 +64,7 @@ int main(int argc, char **argv)
>  #include "hw/bt.h"
>  #include "sysemu/watchdog.h"
>  #include "hw/smbios/smbios.h"
> +#include "hw/acpi/acpi.h"
>  #include "hw/xen/xen.h"
>  #include "hw/qdev.h"
>  #include "hw/loader.h"
> @@ -158,6 +159,7 @@ int max_cpus = 1;
>  int smp_cores = 1;
>  int smp_threads = 1;
>  int acpi_enabled = 1;
> +uint8_t acpi_fadt_rev = 1;
>  int no_hpet = 0;
>  int fd_bootchk = 1;
>  static int no_reboot;
> @@ -2301,6 +2303,24 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
>      return 0;
>  }
>  
> +static void fadt_parse(const char *arg)
> +{
> +    unsigned long rev;
> +    int err;
> +
> +    err = qemu_strtoul(arg, NULL, 10, &rev);
> +    if (err) {
> +        error_printf("Invalid FADT revision.\n");
> +        exit(1);
> +    }
> +    if (rev != 1 && rev != 3 && rev != 5) {
> +        error_printf("Unsupported FADT revision %lu, "
> +                     "please specify 1,3,5.\n", rev);
> +        exit(1);
> +    }
> +    acpi_fadt_rev = rev;
> +}
> +
>  static int device_help_func(void *opaque, QemuOpts *opts, Error **errp)
>  {
>      return qdev_device_help(opts);
> @@ -3622,6 +3642,9 @@ int main(int argc, char **argv, char **envp)
>                  qdev_prop_register_global(&slew_lost_ticks);
>                  break;
>              }
> +            case QEMU_OPTION_acpifadt:
> +                fadt_parse(optarg);
> +                break;
>              case QEMU_OPTION_acpitable:
>                  opts = qemu_opts_parse_noisily(qemu_find_opts("acpi"),
>                                                 optarg, true);
> 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH] ACPI: Add -acpifadt to allow FADT revision changes
  2016-08-08  7:28 [Qemu-devel] [PATCH] ACPI: Add -acpifadt to allow FADT revision changes Lv Zheng
  2016-08-08  7:35 ` no-reply
  2016-08-08  8:16 ` [Qemu-devel] [PATCH v2] " Lv Zheng
@ 2016-08-08 11:25 ` Igor Mammedov
  2016-08-11  9:06 ` [Qemu-devel] [PATCH v3 0/2] ACPI: Add FADT revision support Lv Zheng
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 32+ messages in thread
From: Igor Mammedov @ 2016-08-08 11:25 UTC (permalink / raw)
  To: Lv Zheng; +Cc: Michael S. Tsirkin, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm

On Mon,  8 Aug 2016 15:28:33 +0800
Lv Zheng <lv.zheng@intel.com> wrote:

> This patch allows FADT to be built with different revisions. When the revision
> is greater than 1.0, 64-bit address fields may also be filled.
> 
> Note that FADT revision 2 has never been defined by the ACPI specification. So
> this patch only adds an option -acpifadt to allow revision 1,3,5 to be
> configured by the users.
> 
> 1. Tested by booting a linux image, the 64-bit addresses are correctly filled
>    in the dumped FADT.
> 2. Tested by booting a Windows image, no boot failure can be seen.

By itself patch's useless as currently all addresses for tables are below 4Gb
and io ports are uint16_t so they are also don't need 64bit pointers.
This patch should be a part of some series that actually makes use of it.

Could you provide a reasoning behind this patch?


> Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> ---
>  hw/i386/acpi-build.c   |   62 ++++++++++++++++++++++++++++++++++++++++++------
>  include/hw/acpi/acpi.h |    1 +
>  qemu-options.hx        |    9 +++++++
>  vl.c                   |   18 ++++++++++++++
>  4 files changed, 83 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index ce7cbc5..1f664de 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker *linker)
>      facs->length = cpu_to_le32(sizeof(*facs));
>  }
>  
> +/* GAS */
> +static void
> +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> +	  uint8_t bit_width, uint8_t bit_offset,
> +	  uint8_t access_width, uint64_t address)
> +{
> +    gas->space_id = space_id;
> +    gas->bit_width = bit_width;
> +    gas->bit_offset = bit_offset;
> +    gas->access_width= access_width;
> +    gas->address = address;
> +}
> +
>  /* Load chipset information in FADT */
> -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo *pm,
> +                       uint8_t revision)
>  {
>      fadt->model = 1;
>      fadt->reserved1 = 0;
> @@ -309,6 +323,25 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
>          fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
>      }
>      fadt->century = RTC_CENTURY;
> +
> +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> +    if (revision >= 3) {
> +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> +        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
> +                  32, 0, 0, cpu_to_le64(pm->io_base));
> +        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
> +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm->gpe0_blk));
> +    }
> +
> +    /* Build dummy ACPI 5.0 fields */
> +    if (revision >= 5) {
> +        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
> +        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
> +    }
>  }
>  
>  
> @@ -316,9 +349,9 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
>  static void
>  build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
>             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> -           const char *oem_id, const char *oem_table_id)
> +           const char *oem_id, const char *oem_table_id, uint8_t revision)
>  {
> -    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
> +    AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
>      unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
>      unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
>  
> @@ -328,13 +361,28 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
>          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
>  
>      /* DSDT address to be filled by Guest linker */
> -    fadt_setup(fadt, pm);
>      bios_linker_loader_add_pointer(linker,
>          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
>          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
>  
> -    build_header(linker, table_data,
> -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
> +    if (revision > 2) {
> +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
> +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
> +
> +        /* FACS address to be filled by Guest linker */
> +        bios_linker_loader_add_pointer(linker,
> +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
> +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> +
> +        /* DSDT address to be filled by Guest linker */
> +        bios_linker_loader_add_pointer(linker,
> +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->Xdsdt),
> +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> +    }
> +
> +    fadt_setup(fadt, pm, revision);
> +    build_header(linker, table_data, (void *)fadt, "FACP", sizeof(*fadt),
> +                 revision, oem_id, oem_table_id);
>  }
>  
>  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> @@ -2681,7 +2729,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
>      fadt = tables_blob->len;
>      acpi_add_table(table_offsets, tables_blob);
>      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> -               slic_oem.id, slic_oem.table_id);
> +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
>      aml_len += tables_blob->len - fadt;
>  
>      acpi_add_table(table_offsets, tables_blob);
> diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> index 7b3d93c..63df38d 100644
> --- a/include/hw/acpi/acpi.h
> +++ b/include/hw/acpi/acpi.h
> @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq);
>  
>  /* acpi.c */
>  extern int acpi_enabled;
> +extern uint8_t acpi_fadt_rev;
>  extern char unsigned *acpi_tables;
>  extern size_t acpi_tables_len;
>  
> diff --git a/qemu-options.hx b/qemu-options.hx
> index a71aaf8..cff34f6 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1492,6 +1492,15 @@ STEXI
>  Disable HPET support.
>  ETEXI
>  
> +DEF("acpifadt", HAS_ARG, QEMU_OPTION_acpifadt, \
> +    "-acpifadt  n    configure FADT revision number (1, 3, 5)\n",
> +    QEMU_ARCH_ALL)
> +STEXI
> +@item -acpifadt @var{n}
> +@findex -acpifadt
> +Configure FADT revision number, default is 1.
> +ETEXI
> +
>  DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
>      "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
>      "                ACPI table description\n", QEMU_ARCH_I386)
> diff --git a/vl.c b/vl.c
> index e7c2c62..5fe2414 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -64,6 +64,7 @@ int main(int argc, char **argv)
>  #include "hw/bt.h"
>  #include "sysemu/watchdog.h"
>  #include "hw/smbios/smbios.h"
> +#include "hw/acpi/acpi.h"
>  #include "hw/xen/xen.h"
>  #include "hw/qdev.h"
>  #include "hw/loader.h"
> @@ -158,6 +159,7 @@ int max_cpus = 1;
>  int smp_cores = 1;
>  int smp_threads = 1;
>  int acpi_enabled = 1;
> +uint8_t acpi_fadt_rev = 1;
>  int no_hpet = 0;
>  int fd_bootchk = 1;
>  static int no_reboot;
> @@ -2301,6 +2303,19 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
>      return 0;
>  }
>  
> +static void fadt_parse(const char *arg)
> +{
> +    uint32_t rev;
> +
> +    rev = strtoul(arg, NULL, 0);
> +    if (rev != 1 && rev != 3 && rev != 5) {
> +        error_printf("Unsupported FADT revision %d,"
> +                     "please specify 1,3,5.\n", rev);
> +        exit(1);
> +    }
> +    acpi_fadt_rev = rev;
> +}
> +
>  static int device_help_func(void *opaque, QemuOpts *opts, Error **errp)
>  {
>      return qdev_device_help(opts);
> @@ -3622,6 +3637,9 @@ int main(int argc, char **argv, char **envp)
>                  qdev_prop_register_global(&slew_lost_ticks);
>                  break;
>              }
> +            case QEMU_OPTION_acpifadt:
> +                fadt_parse(optarg);
> +                break;
>              case QEMU_OPTION_acpitable:
>                  opts = qemu_opts_parse_noisily(qemu_find_opts("acpi"),
>                                                 optarg, true);

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v2] ACPI: Add -acpifadt to allow FADT revision changes
  2016-08-08  9:01   ` Paolo Bonzini
@ 2016-08-09 21:06     ` Zheng, Lv
  0 siblings, 0 replies; 32+ messages in thread
From: Zheng, Lv @ 2016-08-09 21:06 UTC (permalink / raw)
  To: Paolo Bonzini, Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: qemu-arm, Lv Zheng, qemu-devel

Hi,

> From: Paolo Bonzini [mailto:paolo.bonzini@gmail.com] On Behalf Of Paolo
> Bonzini
> Subject: Re: [PATCH v2] ACPI: Add -acpifadt to allow FADT revision changes
> 
> 
> 
> On 08/08/2016 10:16, Lv Zheng wrote:
> > This patch allows FADT to be built with different revisions. When the
> revision
> > is greater than 1.0, 64-bit address fields may also be filled.
> >
> > Note that FADT revision 2 has never been defined by the ACPI
> specification. So
> > this patch only adds an option -acpifadt to allow revision 1,3,5 to be
> > configured by the users.
> >
> > 1. Tested by booting a linux image, the 64-bit addresses are correctly
> filled
> >    in the dumped FADT.
> > 2. Tested by booting a Windows image, no boot failure can be seen.
> >
> > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> 
> Hi, please make this a suboption of -acpitable instead.  We try not to
> add new command-line options without supporting them in QemuOpts
> too.
[Lv Zheng] 
OK. I'll prepare a v3 patch to address this.
Thanks for the review.

Cheers
-Lv

> 
> Paolo
> 
> > ---
> > History:
> >
> > v2: Fix coding style issues.
> > ---
> >  hw/i386/acpi-build.c   |   62
> ++++++++++++++++++++++++++++++++++++++++++------
> >  include/hw/acpi/acpi.h |    1 +
> >  qemu-options.hx        |    9 +++++++
> >  vl.c                   |   23 ++++++++++++++++++
> >  4 files changed, 88 insertions(+), 7 deletions(-)
> >
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index ce7cbc5..4479695 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker
> *linker)
> >      facs->length = cpu_to_le32(sizeof(*facs));
> >  }
> >
> > +/* GAS */
> > +static void
> > +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> > +          uint8_t bit_width, uint8_t bit_offset,
> > +          uint8_t access_width, uint64_t address)
> > +{
> > +    gas->space_id = space_id;
> > +    gas->bit_width = bit_width;
> > +    gas->bit_offset = bit_offset;
> > +    gas->access_width = access_width;
> > +    gas->address = address;
> > +}
> > +
> >  /* Load chipset information in FADT */
> > -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> > +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo
> *pm,
> > +                       uint8_t revision)
> >  {
> >      fadt->model = 1;
> >      fadt->reserved1 = 0;
> > @@ -309,6 +323,25 @@ static void fadt_setup(AcpiFadtDescriptorRev1
> *fadt, AcpiPmInfo *pm)
> >          fadt->flags |= cpu_to_le32(1 <<
> ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
> >      }
> >      fadt->century = RTC_CENTURY;
> > +
> > +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> > +    if (revision >= 3) {
> > +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> > +        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
> > +                  32, 0, 0, cpu_to_le64(pm->io_base));
> > +        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
> > +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> > +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> > +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> > +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> > +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm->gpe0_blk));
> > +    }
> > +
> > +    /* Build dummy ACPI 5.0 fields */
> > +    if (revision >= 5) {
> > +        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0, 0,
> 0);
> > +        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
> > +    }
> >  }
> >
> >
> > @@ -316,9 +349,9 @@ static void fadt_setup(AcpiFadtDescriptorRev1
> *fadt, AcpiPmInfo *pm)
> >  static void
> >  build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
> >             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> > -           const char *oem_id, const char *oem_table_id)
> > +           const char *oem_id, const char *oem_table_id, uint8_t revision)
> >  {
> > -    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data,
> sizeof(*fadt));
> > +    AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data,
> sizeof(*fadt));
> >      unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data-
> >data;
> >      unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> >
> > @@ -328,13 +361,28 @@ build_fadt(GArray *table_data, BIOSLinker
> *linker, AcpiPmInfo *pm,
> >          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> >
> >      /* DSDT address to be filled by Guest linker */
> > -    fadt_setup(fadt, pm);
> >      bios_linker_loader_add_pointer(linker,
> >          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
> >          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> >
> > -    build_header(linker, table_data,
> > -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
> > +    if (revision > 2) {
> > +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
> > +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
> > +
> > +        /* FACS address to be filled by Guest linker */
> > +        bios_linker_loader_add_pointer(linker,
> > +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
> > +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > +
> > +        /* DSDT address to be filled by Guest linker */
> > +        bios_linker_loader_add_pointer(linker,
> > +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->Xdsdt),
> > +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > +    }
> > +
> > +    fadt_setup(fadt, pm, revision);
> > +    build_header(linker, table_data, (void *)fadt, "FACP", sizeof(*fadt),
> > +                 revision, oem_id, oem_table_id);
> >  }
> >
> >  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> > @@ -2681,7 +2729,7 @@ void acpi_build(AcpiBuildTables *tables,
> MachineState *machine)
> >      fadt = tables_blob->len;
> >      acpi_add_table(table_offsets, tables_blob);
> >      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> > -               slic_oem.id, slic_oem.table_id);
> > +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
> >      aml_len += tables_blob->len - fadt;
> >
> >      acpi_add_table(table_offsets, tables_blob);
> > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > index 7b3d93c..63df38d 100644
> > --- a/include/hw/acpi/acpi.h
> > +++ b/include/hw/acpi/acpi.h
> > @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs,
> qemu_irq irq);
> >
> >  /* acpi.c */
> >  extern int acpi_enabled;
> > +extern uint8_t acpi_fadt_rev;
> >  extern char unsigned *acpi_tables;
> >  extern size_t acpi_tables_len;
> >
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index a71aaf8..cff34f6 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -1492,6 +1492,15 @@ STEXI
> >  Disable HPET support.
> >  ETEXI
> >
> > +DEF("acpifadt", HAS_ARG, QEMU_OPTION_acpifadt, \
> > +    "-acpifadt  n    configure FADT revision number (1, 3, 5)\n",
> > +    QEMU_ARCH_ALL)
> > +STEXI
> > +@item -acpifadt @var{n}
> > +@findex -acpifadt
> > +Configure FADT revision number, default is 1.
> > +ETEXI
> > +
> >  DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
> >      "-acpitable
> [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compi
> ler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
> >      "                ACPI table description\n", QEMU_ARCH_I386)
> > diff --git a/vl.c b/vl.c
> > index e7c2c62..220e36d 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -64,6 +64,7 @@ int main(int argc, char **argv)
> >  #include "hw/bt.h"
> >  #include "sysemu/watchdog.h"
> >  #include "hw/smbios/smbios.h"
> > +#include "hw/acpi/acpi.h"
> >  #include "hw/xen/xen.h"
> >  #include "hw/qdev.h"
> >  #include "hw/loader.h"
> > @@ -158,6 +159,7 @@ int max_cpus = 1;
> >  int smp_cores = 1;
> >  int smp_threads = 1;
> >  int acpi_enabled = 1;
> > +uint8_t acpi_fadt_rev = 1;
> >  int no_hpet = 0;
> >  int fd_bootchk = 1;
> >  static int no_reboot;
> > @@ -2301,6 +2303,24 @@ static int parse_fw_cfg(void *opaque,
> QemuOpts *opts, Error **errp)
> >      return 0;
> >  }
> >
> > +static void fadt_parse(const char *arg)
> > +{
> > +    unsigned long rev;
> > +    int err;
> > +
> > +    err = qemu_strtoul(arg, NULL, 10, &rev);
> > +    if (err) {
> > +        error_printf("Invalid FADT revision.\n");
> > +        exit(1);
> > +    }
> > +    if (rev != 1 && rev != 3 && rev != 5) {
> > +        error_printf("Unsupported FADT revision %lu, "
> > +                     "please specify 1,3,5.\n", rev);
> > +        exit(1);
> > +    }
> > +    acpi_fadt_rev = rev;
> > +}
> > +
> >  static int device_help_func(void *opaque, QemuOpts *opts, Error
> **errp)
> >  {
> >      return qdev_device_help(opts);
> > @@ -3622,6 +3642,9 @@ int main(int argc, char **argv, char **envp)
> >                  qdev_prop_register_global(&slew_lost_ticks);
> >                  break;
> >              }
> > +            case QEMU_OPTION_acpifadt:
> > +                fadt_parse(optarg);
> > +                break;
> >              case QEMU_OPTION_acpitable:
> >                  opts = qemu_opts_parse_noisily(qemu_find_opts("acpi"),
> >                                                 optarg, true);
> >

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PATCH v3 0/2] ACPI: Add FADT revision support
  2016-08-08  7:28 [Qemu-devel] [PATCH] ACPI: Add -acpifadt to allow FADT revision changes Lv Zheng
                   ` (2 preceding siblings ...)
  2016-08-08 11:25 ` [Qemu-devel] [PATCH] " Igor Mammedov
@ 2016-08-11  9:06 ` Lv Zheng
  2016-08-11  9:06   ` [Qemu-devel] [PATCH v3 1/2] ACPI: Cleanup -acpitable option code Lv Zheng
                     ` (2 more replies)
  2016-08-11  9:12 ` [Qemu-devel] [PATCH v4 " Lv Zheng
  2016-08-11  9:36 ` [Qemu-devel] [PATCH v5 0/2] ACPI: Add FADT revision support Lv Zheng
  5 siblings, 3 replies; 32+ messages in thread
From: Lv Zheng @ 2016-08-11  9:06 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, Lv Zheng, qemu-devel, qemu-arm

This patchset adds revision support for FADT.

Lv Zheng (2):
  ACPI: Cleanup -acpitable option code
  ACPI: Add -acpitable fadt= to allow FADT revision changes

 hw/acpi/core.c         |   50 +++++++++++++++++++++++++------
 hw/i386/acpi-build.c   |   76 ++++++++++++++++++++++++++++++++++++++++++------
 include/hw/acpi/acpi.h |    1 +
 qapi-schema.json       |   27 +++++------------
 qemu-options.hx        |   15 ++++++++--
 5 files changed, 129 insertions(+), 40 deletions(-)

-- 
1.7.10

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PATCH v3 1/2] ACPI: Cleanup -acpitable option code
  2016-08-11  9:06 ` [Qemu-devel] [PATCH v3 0/2] ACPI: Add FADT revision support Lv Zheng
@ 2016-08-11  9:06   ` Lv Zheng
  2016-08-11  9:06   ` [Qemu-devel] [PATCH v3 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes Lv Zheng
  2016-08-11  9:11   ` [Qemu-devel] [PATCH v3 0/2] ACPI: Add FADT revision support no-reply
  2 siblings, 0 replies; 32+ messages in thread
From: Lv Zheng @ 2016-08-11  9:06 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, Lv Zheng, qemu-devel, qemu-arm

In -acpitable options, at least/most one data/file sub-option is mandatory,
this patch cleans up the code to reflect this in a managed manner so that
the follow-up mandatory sub-options can be added to -acpitable.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 hw/acpi/core.c   |   32 +++++++++++++++++++++++---------
 qapi-schema.json |   27 ++++++++-------------------
 qemu-options.hx  |    7 +++++--
 3 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index e890a5d..cd1f9e4 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -89,8 +89,6 @@ static int acpi_checksum(const uint8_t *data, int len)
  * It is valid to call this function with
  * (@blob == NULL && bloblen == 0 && !has_header).
  *
- * @hdrs->file and @hdrs->data are ignored.
- *
  * SIZE_MAX is considered "infinity" in this function.
  *
  * The number of tables that can be installed is not limited, but the 16-bit
@@ -229,7 +227,8 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
                                       ACPI_TABLE_PFX_SIZE, acpi_payload_size);
 }
 
-void acpi_table_add(const QemuOpts *opts, Error **errp)
+static void acpi_table_from_file(bool has_header, const char *file,
+                                 AcpiTableOptions *hdrs, Error **errp)
 {
     AcpiTableOptions *hdrs = NULL;
     Error *err = NULL;
@@ -249,12 +248,8 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
     if (err) {
         goto out;
     }
-    if (hdrs->has_file == hdrs->has_data) {
-        error_setg(&err, "'-acpitable' requires one of 'data' or 'file'");
-        goto out;
-    }
 
-    pathnames = g_strsplit(hdrs->has_file ? hdrs->file : hdrs->data, ":", 0);
+    pathnames = g_strsplit(file, ":", 0);
     if (pathnames == NULL || pathnames[0] == NULL) {
         error_setg(&err, "'-acpitable' requires at least one pathname");
         goto out;
@@ -291,7 +286,7 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
         close(fd);
     }
 
-    acpi_table_install(blob, bloblen, hdrs->has_file, hdrs, &err);
+    acpi_table_install(blob, bloblen, has_header, hdrs, &err);
 
 out:
     g_free(blob);
@@ -301,6 +296,25 @@ out:
     error_propagate(errp, err);
 }
 
+void acpi_table_add(const QemuOpts *opts, Error **errp)
+{
+    const char *val;
+
+    val = qemu_opt_get((QemuOpts *)opts, "file");
+    if (val) {
+        acpi_table_from_file(true, val, hdrs, errp);
+        return;
+    }
+
+    val = qemu_opt_get((QemuOpts *)opts, "data");
+    if (val) {
+        acpi_table_from_file(false, val, hdrs, errp);
+        return;
+    }
+
+    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
+}
+
 static bool acpi_table_builtin = false;
 
 void acpi_table_add_builtin(const QemuOpts *opts, Error **errp)
diff --git a/qapi-schema.json b/qapi-schema.json
index 5658723..a5e219f 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3597,17 +3597,18 @@
 ##
 # @AcpiTableOptions
 #
-# Specify an ACPI table on the command line to load.
+# Specify ACPI table options for the table loaded on the command line.
 #
-# At most one of @file and @data can be specified. The list of files specified
-# by any one of them is loaded and concatenated in order. If both are omitted,
-# @data is implied.
+# ACPI table can be loaded via 'file' and 'data' options. At most one of
+# 'file' and 'data' can be specified. The list of files specified by any one
+# of them is loaded and concatenated in order. If both # are omitted, 'data'
+# is implied.
 #
 # Other fields / optargs can be used to override fields of the generic ACPI
 # table header; refer to the ACPI specification 5.0, section 5.2.6 System
 # Description Table Header. If a header field is not overridden, then the
-# corresponding value from the concatenated blob is used (in case of @file), or
-# it is filled in with a hard-coded value (in case of @data).
+# corresponding value from the concatenated blob is used (in case of 'file'),
+# or it is filled in with a hard-coded value (in case of 'data').
 #
 # String fields are copied into the matching ACPI member from lowest address
 # upwards, and silently truncated / NUL-padded to length.
@@ -3628,16 +3629,6 @@
 # @asl_compiler_rev: #optional revision number of the utility that created the
 #                    table (4 bytes)
 #
-# @file: #optional colon (:) separated list of pathnames to load and
-#        concatenate as table data. The resultant binary blob is expected to
-#        have an ACPI table header. At least one file is required. This field
-#        excludes @data.
-#
-# @data: #optional colon (:) separated list of pathnames to load and
-#        concatenate as table data. The resultant binary blob must not have an
-#        ACPI table header. At least one file is required. This field excludes
-#        @file.
-#
 # Since 1.5
 ##
 { 'struct': 'AcpiTableOptions',
@@ -3648,9 +3639,7 @@
     '*oem_table_id':      'str',
     '*oem_rev':           'uint32',
     '*asl_compiler_id':   'str',
-    '*asl_compiler_rev':  'uint32',
-    '*file':              'str',
-    '*data':              'str' }}
+    '*asl_compiler_rev':  'uint32' }}
 
 ##
 # @CommandLineParameterType:
diff --git a/qemu-options.hx b/qemu-options.hx
index a71aaf8..5fe7f87 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1493,10 +1493,13 @@ Disable HPET support.
 ETEXI
 
 DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
-    "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
+    "-acpitable {data|file}=file1[:file2]...\n"
+    "             [,sig=str][,rev=n]\n"
+    "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
+    "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
     "                ACPI table description\n", QEMU_ARCH_I386)
 STEXI
-@item -acpitable [sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}][,data=@var{file1}[:@var{file2}]...]
+@item -acpitable data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
 @findex -acpitable
 Add ACPI table with specified header fields and context from specified files.
 For file=, take whole ACPI table from the specified files, including all
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PATCH v3 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-11  9:06 ` [Qemu-devel] [PATCH v3 0/2] ACPI: Add FADT revision support Lv Zheng
  2016-08-11  9:06   ` [Qemu-devel] [PATCH v3 1/2] ACPI: Cleanup -acpitable option code Lv Zheng
@ 2016-08-11  9:06   ` Lv Zheng
  2016-08-11  9:11   ` [Qemu-devel] [PATCH v3 0/2] ACPI: Add FADT revision support no-reply
  2 siblings, 0 replies; 32+ messages in thread
From: Lv Zheng @ 2016-08-11  9:06 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, Lv Zheng, qemu-devel, qemu-arm

This patch allows FADT to be built with different revisions. When the revision
is greater than 1.0, 64-bit address fields may also be filled.

Note that FADT revision 2 has never been defined by the ACPI specification. So
this patch only adds an option -acpitable fadt= to allow revision 1,3,5 to be
configured by the users.

1. Tested by booting a linux image, the 64-bit addresses are correctly filled
   in the dumped FADT.
2. Tested by booting a Windows image, no boot failure can be seen.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 hw/acpi/core.c         |   26 ++++++++++++++---
 hw/i386/acpi-build.c   |   76 ++++++++++++++++++++++++++++++++++++++++++------
 include/hw/acpi/acpi.h |    1 +
 qemu-options.hx        |    8 ++++-
 4 files changed, 97 insertions(+), 14 deletions(-)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index cd1f9e4..832c86b 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -19,6 +19,7 @@
  * GNU GPL, version 2 or (at your option) any later version.
  */
 #include "qemu/osdep.h"
+#include "qemu/cutils.h"
 #include "sysemu/sysemu.h"
 #include "hw/hw.h"
 #include "hw/i386/pc.h"
@@ -54,6 +55,7 @@ static const char unsigned dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
 
 char unsigned *acpi_tables;
 size_t acpi_tables_len;
+uint8_t acpi_fadt_rev = 1;
 
 static QemuOptsList qemu_acpi_opts = {
     .name = "acpi",
@@ -228,7 +230,7 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
 }
 
 static void acpi_table_from_file(bool has_header, const char *file,
-                                 AcpiTableOptions *hdrs, Error **errp)
+                                 const QemuOpts *opts, Error **errp)
 {
     AcpiTableOptions *hdrs = NULL;
     Error *err = NULL;
@@ -302,17 +304,33 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
 
     val = qemu_opt_get((QemuOpts *)opts, "file");
     if (val) {
-        acpi_table_from_file(true, val, hdrs, errp);
+        acpi_table_from_file(true, val, opts, errp);
         return;
     }
 
     val = qemu_opt_get((QemuOpts *)opts, "data");
     if (val) {
-        acpi_table_from_file(false, val, hdrs, errp);
+        acpi_table_from_file(false, val, opts, errp);
         return;
     }
 
-    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
+    val = qemu_opt_get((QemuOpts *)opts, "fadt");
+    if (val) {
+        unsigned long rev;
+        int err;
+
+        err = qemu_strtoul(val, NULL, 10, &rev);
+        if (err ||
+            (rev != 1 && rev != 3 && rev != 5)) {
+            error_setg(errp, "Unsupported FADT revision %s, "
+                       "please specify 1,3,5", val);
+            return;
+        }
+        acpi_fadt_rev = rev;
+        return;
+    }
+
+    error_setg(errp, "'-acpitable' requires one of 'data','file' or 'fadt'");
 }
 
 static bool acpi_table_builtin = false;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ce7cbc5..e5a711a 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker *linker)
     facs->length = cpu_to_le32(sizeof(*facs));
 }
 
+/* GAS */
+static void
+build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
+          uint8_t bit_width, uint8_t bit_offset,
+          uint8_t access_width, uint64_t address)
+{
+    gas->space_id = space_id;
+    gas->bit_width = bit_width;
+    gas->bit_offset = bit_offset;
+    gas->access_width = access_width;
+    gas->address = address;
+}
+
 /* Load chipset information in FADT */
-static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
+static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo *pm,
+                       uint8_t revision)
 {
     fadt->model = 1;
     fadt->reserved1 = 0;
@@ -309,6 +323,25 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
         fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
     }
     fadt->century = RTC_CENTURY;
+
+    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
+    if (revision >= 3) {
+        /* EVT, CNT, TMR register matches hw/acpi/core.c */
+        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
+                  32, 0, 0, cpu_to_le64(pm->io_base));
+        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
+                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
+        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
+                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
+        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
+                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm->gpe0_blk));
+    }
+
+    /* Build dummy ACPI 5.0 fields */
+    if (revision >= 5) {
+        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
+        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
+    }
 }
 
 
@@ -316,11 +349,21 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
 static void
 build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
            unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
-           const char *oem_id, const char *oem_table_id)
+           const char *oem_id, const char *oem_table_id, uint8_t revision)
 {
-    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
-    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
-    unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
+    AcpiFadtDescriptorRev5_1 *fadt;
+    unsigned fw_ctrl_offset;
+    unsigned dsdt_entry_offset;
+    unsigned fadt_len;
+
+    if (revision == 1) {
+        fadt_len = sizeof (AcpiFadtDescriptorRev1);
+    } else {
+        fadt_len = sizeof (AcpiFadtDescriptorRev5_1);
+    }
+    fadt = acpi_data_push(table_data, fadt_len);
+    fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
+    dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
 
     /* FACS address to be filled by Guest linker */
     bios_linker_loader_add_pointer(linker,
@@ -328,13 +371,28 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
         ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
 
     /* DSDT address to be filled by Guest linker */
-    fadt_setup(fadt, pm);
     bios_linker_loader_add_pointer(linker,
         ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
         ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
 
-    build_header(linker, table_data,
-                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
+    if (revision > 2) {
+        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
+        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
+
+        /* FACS address to be filled by Guest linker */
+        bios_linker_loader_add_pointer(linker,
+            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
+            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
+
+        /* DSDT address to be filled by Guest linker */
+        bios_linker_loader_add_pointer(linker,
+            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->Xdsdt),
+            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
+    }
+
+    fadt_setup(fadt, pm, revision);
+    build_header(linker, table_data, (void *)fadt, "FACP", fadt_len,
+                 revision, oem_id, oem_table_id);
 }
 
 void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
@@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
     fadt = tables_blob->len;
     acpi_add_table(table_offsets, tables_blob);
     build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
-               slic_oem.id, slic_oem.table_id);
+               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
     aml_len += tables_blob->len - fadt;
 
     acpi_add_table(table_offsets, tables_blob);
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 7b3d93c..63df38d 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq);
 
 /* acpi.c */
 extern int acpi_enabled;
+extern uint8_t acpi_fadt_rev;
 extern char unsigned *acpi_tables;
 extern size_t acpi_tables_len;
 
diff --git a/qemu-options.hx b/qemu-options.hx
index 5fe7f87..d61dd92 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
     "             [,sig=str][,rev=n]\n"
     "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
     "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
-    "                ACPI table description\n", QEMU_ARCH_I386)
+    "                ACPI table description\n"
+    "-acpitable fadt=n\n"
+    "                Configure FADT revision\n",
+    QEMU_ARCH_I386)
 STEXI
 @item -acpitable data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
 @findex -acpitable
@@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU, then the SLIC's oem_id and oem_table_id
 fields will override the same in the RSDT and the FADT (a.k.a. FACP), in order
 to ensure the field matches required by the Microsoft SLIC spec and the ACPI
 spec.
+
+@item -acpitable fadt=@var{n}
+Configure FADT revision to 1, 3, 5, default 1.
 ETEXI
 
 DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v3 0/2] ACPI: Add FADT revision support
  2016-08-11  9:06 ` [Qemu-devel] [PATCH v3 0/2] ACPI: Add FADT revision support Lv Zheng
  2016-08-11  9:06   ` [Qemu-devel] [PATCH v3 1/2] ACPI: Cleanup -acpitable option code Lv Zheng
  2016-08-11  9:06   ` [Qemu-devel] [PATCH v3 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes Lv Zheng
@ 2016-08-11  9:11   ` no-reply
  2 siblings, 0 replies; 32+ messages in thread
From: no-reply @ 2016-08-11  9:11 UTC (permalink / raw)
  To: lv.zheng
  Cc: famz, pbonzini, crosthwaite.peter, rth, mst, imammedo,
	shannon.zhao, qemu-arm, zetalog, qemu-devel

Hi,

Your series seems to have some coding style problems. See output below for
more information:

Message-id: cover.1470905888.git.lv.zheng@intel.com
Subject: [Qemu-devel] [PATCH v3 0/2] ACPI: Add FADT revision support
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git show --no-patch --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/cover.1470905888.git.lv.zheng@intel.com -> patchew/cover.1470905888.git.lv.zheng@intel.com
Switched to a new branch 'test'
13b8a80 ACPI: Add -acpitable fadt= to allow FADT revision changes
d395c84 ACPI: Cleanup -acpitable option code

=== OUTPUT BEGIN ===
Checking PATCH 1/2: ACPI: Cleanup -acpitable option code...
Checking PATCH 2/2: ACPI: Add -acpitable fadt= to allow FADT revision changes...
ERROR: space prohibited between function name and open parenthesis '('
#156: FILE: hw/i386/acpi-build.c:359:
+        fadt_len = sizeof (AcpiFadtDescriptorRev1);

ERROR: space prohibited between function name and open parenthesis '('
#158: FILE: hw/i386/acpi-build.c:361:
+        fadt_len = sizeof (AcpiFadtDescriptorRev5_1);

total: 2 errors, 0 warnings, 197 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PATCH v4 0/2] ACPI: Add FADT revision support
  2016-08-08  7:28 [Qemu-devel] [PATCH] ACPI: Add -acpifadt to allow FADT revision changes Lv Zheng
                   ` (3 preceding siblings ...)
  2016-08-11  9:06 ` [Qemu-devel] [PATCH v3 0/2] ACPI: Add FADT revision support Lv Zheng
@ 2016-08-11  9:12 ` Lv Zheng
  2016-08-11  9:12   ` [Qemu-devel] [PATCH v4 1/2] ACPI: Cleanup -acpitable option code Lv Zheng
  2016-08-11  9:12   ` [Qemu-devel] [PATCH v4 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes Lv Zheng
  2016-08-11  9:36 ` [Qemu-devel] [PATCH v5 0/2] ACPI: Add FADT revision support Lv Zheng
  5 siblings, 2 replies; 32+ messages in thread
From: Lv Zheng @ 2016-08-11  9:12 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, Lv Zheng, qemu-devel, qemu-arm

This patchset adds revision support for FADT.

History:
v1:
  Initial support
v2:
  Coding style cleanup
v3:
  Cleanup -acpitable code (remove useless hdrs->data/file)
  Change -acpifadt to -acpitable fadt=
  Shrink v1 FADT table length
v4:
  Coding style cleanup

Lv Zheng (2):
  ACPI: Cleanup -acpitable option code
  ACPI: Add -acpitable fadt= to allow FADT revision changes

 hw/acpi/core.c         |   50 +++++++++++++++++++++++++------
 hw/i386/acpi-build.c   |   76 ++++++++++++++++++++++++++++++++++++++++++------
 include/hw/acpi/acpi.h |    1 +
 qapi-schema.json       |   27 +++++------------
 qemu-options.hx        |   15 ++++++++--
 5 files changed, 129 insertions(+), 40 deletions(-)

-- 
1.7.10

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PATCH v4 1/2] ACPI: Cleanup -acpitable option code
  2016-08-11  9:12 ` [Qemu-devel] [PATCH v4 " Lv Zheng
@ 2016-08-11  9:12   ` Lv Zheng
  2016-08-11  9:17     ` Zheng, Lv
  2016-08-11  9:12   ` [Qemu-devel] [PATCH v4 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes Lv Zheng
  1 sibling, 1 reply; 32+ messages in thread
From: Lv Zheng @ 2016-08-11  9:12 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, Lv Zheng, qemu-devel, qemu-arm

In -acpitable options, at least/most one data/file sub-option is mandatory,
this patch cleans up the code to reflect this in a managed manner so that
the follow-up mandatory sub-options can be added to -acpitable.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 hw/acpi/core.c   |   32 +++++++++++++++++++++++---------
 qapi-schema.json |   27 ++++++++-------------------
 qemu-options.hx  |    7 +++++--
 3 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index e890a5d..cd1f9e4 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -89,8 +89,6 @@ static int acpi_checksum(const uint8_t *data, int len)
  * It is valid to call this function with
  * (@blob == NULL && bloblen == 0 && !has_header).
  *
- * @hdrs->file and @hdrs->data are ignored.
- *
  * SIZE_MAX is considered "infinity" in this function.
  *
  * The number of tables that can be installed is not limited, but the 16-bit
@@ -229,7 +227,8 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
                                       ACPI_TABLE_PFX_SIZE, acpi_payload_size);
 }
 
-void acpi_table_add(const QemuOpts *opts, Error **errp)
+static void acpi_table_from_file(bool has_header, const char *file,
+                                 AcpiTableOptions *hdrs, Error **errp)
 {
     AcpiTableOptions *hdrs = NULL;
     Error *err = NULL;
@@ -249,12 +248,8 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
     if (err) {
         goto out;
     }
-    if (hdrs->has_file == hdrs->has_data) {
-        error_setg(&err, "'-acpitable' requires one of 'data' or 'file'");
-        goto out;
-    }
 
-    pathnames = g_strsplit(hdrs->has_file ? hdrs->file : hdrs->data, ":", 0);
+    pathnames = g_strsplit(file, ":", 0);
     if (pathnames == NULL || pathnames[0] == NULL) {
         error_setg(&err, "'-acpitable' requires at least one pathname");
         goto out;
@@ -291,7 +286,7 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
         close(fd);
     }
 
-    acpi_table_install(blob, bloblen, hdrs->has_file, hdrs, &err);
+    acpi_table_install(blob, bloblen, has_header, hdrs, &err);
 
 out:
     g_free(blob);
@@ -301,6 +296,25 @@ out:
     error_propagate(errp, err);
 }
 
+void acpi_table_add(const QemuOpts *opts, Error **errp)
+{
+    const char *val;
+
+    val = qemu_opt_get((QemuOpts *)opts, "file");
+    if (val) {
+        acpi_table_from_file(true, val, hdrs, errp);
+        return;
+    }
+
+    val = qemu_opt_get((QemuOpts *)opts, "data");
+    if (val) {
+        acpi_table_from_file(false, val, hdrs, errp);
+        return;
+    }
+
+    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
+}
+
 static bool acpi_table_builtin = false;
 
 void acpi_table_add_builtin(const QemuOpts *opts, Error **errp)
diff --git a/qapi-schema.json b/qapi-schema.json
index 5658723..a5e219f 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3597,17 +3597,18 @@
 ##
 # @AcpiTableOptions
 #
-# Specify an ACPI table on the command line to load.
+# Specify ACPI table options for the table loaded on the command line.
 #
-# At most one of @file and @data can be specified. The list of files specified
-# by any one of them is loaded and concatenated in order. If both are omitted,
-# @data is implied.
+# ACPI table can be loaded via 'file' and 'data' options. At most one of
+# 'file' and 'data' can be specified. The list of files specified by any one
+# of them is loaded and concatenated in order. If both # are omitted, 'data'
+# is implied.
 #
 # Other fields / optargs can be used to override fields of the generic ACPI
 # table header; refer to the ACPI specification 5.0, section 5.2.6 System
 # Description Table Header. If a header field is not overridden, then the
-# corresponding value from the concatenated blob is used (in case of @file), or
-# it is filled in with a hard-coded value (in case of @data).
+# corresponding value from the concatenated blob is used (in case of 'file'),
+# or it is filled in with a hard-coded value (in case of 'data').
 #
 # String fields are copied into the matching ACPI member from lowest address
 # upwards, and silently truncated / NUL-padded to length.
@@ -3628,16 +3629,6 @@
 # @asl_compiler_rev: #optional revision number of the utility that created the
 #                    table (4 bytes)
 #
-# @file: #optional colon (:) separated list of pathnames to load and
-#        concatenate as table data. The resultant binary blob is expected to
-#        have an ACPI table header. At least one file is required. This field
-#        excludes @data.
-#
-# @data: #optional colon (:) separated list of pathnames to load and
-#        concatenate as table data. The resultant binary blob must not have an
-#        ACPI table header. At least one file is required. This field excludes
-#        @file.
-#
 # Since 1.5
 ##
 { 'struct': 'AcpiTableOptions',
@@ -3648,9 +3639,7 @@
     '*oem_table_id':      'str',
     '*oem_rev':           'uint32',
     '*asl_compiler_id':   'str',
-    '*asl_compiler_rev':  'uint32',
-    '*file':              'str',
-    '*data':              'str' }}
+    '*asl_compiler_rev':  'uint32' }}
 
 ##
 # @CommandLineParameterType:
diff --git a/qemu-options.hx b/qemu-options.hx
index a71aaf8..5fe7f87 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1493,10 +1493,13 @@ Disable HPET support.
 ETEXI
 
 DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
-    "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
+    "-acpitable {data|file}=file1[:file2]...\n"
+    "             [,sig=str][,rev=n]\n"
+    "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
+    "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
     "                ACPI table description\n", QEMU_ARCH_I386)
 STEXI
-@item -acpitable [sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}][,data=@var{file1}[:@var{file2}]...]
+@item -acpitable data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
 @findex -acpitable
 Add ACPI table with specified header fields and context from specified files.
 For file=, take whole ACPI table from the specified files, including all
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PATCH v4 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-11  9:12 ` [Qemu-devel] [PATCH v4 " Lv Zheng
  2016-08-11  9:12   ` [Qemu-devel] [PATCH v4 1/2] ACPI: Cleanup -acpitable option code Lv Zheng
@ 2016-08-11  9:12   ` Lv Zheng
  1 sibling, 0 replies; 32+ messages in thread
From: Lv Zheng @ 2016-08-11  9:12 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, Lv Zheng, qemu-devel, qemu-arm

This patch allows FADT to be built with different revisions. When the revision
is greater than 1.0, 64-bit address fields may also be filled.

Note that FADT revision 2 has never been defined by the ACPI specification. So
this patch only adds an option -acpitable fadt= to allow revision 1,3,5 to be
configured by the users.

1. Tested by booting a linux image, the 64-bit addresses are correctly filled
   in the dumped FADT.
2. Tested by booting a Windows image, no boot failure can be seen.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 hw/acpi/core.c         |   26 ++++++++++++++---
 hw/i386/acpi-build.c   |   76 ++++++++++++++++++++++++++++++++++++++++++------
 include/hw/acpi/acpi.h |    1 +
 qemu-options.hx        |    8 ++++-
 4 files changed, 97 insertions(+), 14 deletions(-)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index cd1f9e4..832c86b 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -19,6 +19,7 @@
  * GNU GPL, version 2 or (at your option) any later version.
  */
 #include "qemu/osdep.h"
+#include "qemu/cutils.h"
 #include "sysemu/sysemu.h"
 #include "hw/hw.h"
 #include "hw/i386/pc.h"
@@ -54,6 +55,7 @@ static const char unsigned dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
 
 char unsigned *acpi_tables;
 size_t acpi_tables_len;
+uint8_t acpi_fadt_rev = 1;
 
 static QemuOptsList qemu_acpi_opts = {
     .name = "acpi",
@@ -228,7 +230,7 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
 }
 
 static void acpi_table_from_file(bool has_header, const char *file,
-                                 AcpiTableOptions *hdrs, Error **errp)
+                                 const QemuOpts *opts, Error **errp)
 {
     AcpiTableOptions *hdrs = NULL;
     Error *err = NULL;
@@ -302,17 +304,33 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
 
     val = qemu_opt_get((QemuOpts *)opts, "file");
     if (val) {
-        acpi_table_from_file(true, val, hdrs, errp);
+        acpi_table_from_file(true, val, opts, errp);
         return;
     }
 
     val = qemu_opt_get((QemuOpts *)opts, "data");
     if (val) {
-        acpi_table_from_file(false, val, hdrs, errp);
+        acpi_table_from_file(false, val, opts, errp);
         return;
     }
 
-    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
+    val = qemu_opt_get((QemuOpts *)opts, "fadt");
+    if (val) {
+        unsigned long rev;
+        int err;
+
+        err = qemu_strtoul(val, NULL, 10, &rev);
+        if (err ||
+            (rev != 1 && rev != 3 && rev != 5)) {
+            error_setg(errp, "Unsupported FADT revision %s, "
+                       "please specify 1,3,5", val);
+            return;
+        }
+        acpi_fadt_rev = rev;
+        return;
+    }
+
+    error_setg(errp, "'-acpitable' requires one of 'data','file' or 'fadt'");
 }
 
 static bool acpi_table_builtin = false;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ce7cbc5..baba41f 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker *linker)
     facs->length = cpu_to_le32(sizeof(*facs));
 }
 
+/* GAS */
+static void
+build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
+          uint8_t bit_width, uint8_t bit_offset,
+          uint8_t access_width, uint64_t address)
+{
+    gas->space_id = space_id;
+    gas->bit_width = bit_width;
+    gas->bit_offset = bit_offset;
+    gas->access_width = access_width;
+    gas->address = address;
+}
+
 /* Load chipset information in FADT */
-static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
+static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo *pm,
+                       uint8_t revision)
 {
     fadt->model = 1;
     fadt->reserved1 = 0;
@@ -309,6 +323,25 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
         fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
     }
     fadt->century = RTC_CENTURY;
+
+    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
+    if (revision >= 3) {
+        /* EVT, CNT, TMR register matches hw/acpi/core.c */
+        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
+                  32, 0, 0, cpu_to_le64(pm->io_base));
+        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
+                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
+        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
+                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
+        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
+                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm->gpe0_blk));
+    }
+
+    /* Build dummy ACPI 5.0 fields */
+    if (revision >= 5) {
+        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
+        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
+    }
 }
 
 
@@ -316,11 +349,21 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
 static void
 build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
            unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
-           const char *oem_id, const char *oem_table_id)
+           const char *oem_id, const char *oem_table_id, uint8_t revision)
 {
-    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
-    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
-    unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
+    AcpiFadtDescriptorRev5_1 *fadt;
+    unsigned fw_ctrl_offset;
+    unsigned dsdt_entry_offset;
+    unsigned fadt_len;
+
+    if (revision == 1) {
+        fadt_len = sizeof(AcpiFadtDescriptorRev1);
+    } else {
+        fadt_len = sizeof(AcpiFadtDescriptorRev5_1);
+    }
+    fadt = acpi_data_push(table_data, fadt_len);
+    fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
+    dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
 
     /* FACS address to be filled by Guest linker */
     bios_linker_loader_add_pointer(linker,
@@ -328,13 +371,28 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
         ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
 
     /* DSDT address to be filled by Guest linker */
-    fadt_setup(fadt, pm);
     bios_linker_loader_add_pointer(linker,
         ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
         ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
 
-    build_header(linker, table_data,
-                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
+    if (revision > 2) {
+        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
+        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
+
+        /* FACS address to be filled by Guest linker */
+        bios_linker_loader_add_pointer(linker,
+            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
+            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
+
+        /* DSDT address to be filled by Guest linker */
+        bios_linker_loader_add_pointer(linker,
+            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->Xdsdt),
+            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
+    }
+
+    fadt_setup(fadt, pm, revision);
+    build_header(linker, table_data, (void *)fadt, "FACP", fadt_len,
+                 revision, oem_id, oem_table_id);
 }
 
 void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
@@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
     fadt = tables_blob->len;
     acpi_add_table(table_offsets, tables_blob);
     build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
-               slic_oem.id, slic_oem.table_id);
+               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
     aml_len += tables_blob->len - fadt;
 
     acpi_add_table(table_offsets, tables_blob);
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 7b3d93c..63df38d 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq);
 
 /* acpi.c */
 extern int acpi_enabled;
+extern uint8_t acpi_fadt_rev;
 extern char unsigned *acpi_tables;
 extern size_t acpi_tables_len;
 
diff --git a/qemu-options.hx b/qemu-options.hx
index 5fe7f87..d61dd92 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
     "             [,sig=str][,rev=n]\n"
     "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
     "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
-    "                ACPI table description\n", QEMU_ARCH_I386)
+    "                ACPI table description\n"
+    "-acpitable fadt=n\n"
+    "                Configure FADT revision\n",
+    QEMU_ARCH_I386)
 STEXI
 @item -acpitable data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
 @findex -acpitable
@@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU, then the SLIC's oem_id and oem_table_id
 fields will override the same in the RSDT and the FADT (a.k.a. FACP), in order
 to ensure the field matches required by the Microsoft SLIC spec and the ACPI
 spec.
+
+@item -acpitable fadt=@var{n}
+Configure FADT revision to 1, 3, 5, default 1.
 ETEXI
 
 DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v4 1/2] ACPI: Cleanup -acpitable option code
  2016-08-11  9:12   ` [Qemu-devel] [PATCH v4 1/2] ACPI: Cleanup -acpitable option code Lv Zheng
@ 2016-08-11  9:17     ` Zheng, Lv
  0 siblings, 0 replies; 32+ messages in thread
From: Zheng, Lv @ 2016-08-11  9:17 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, qemu-devel, qemu-arm

Hi, 

> From: Zheng, Lv
> Subject: [PATCH v4 1/2] ACPI: Cleanup -acpitable option code
> 
> In -acpitable options, at least/most one data/file sub-option is mandatory,
> this patch cleans up the code to reflect this in a managed manner so that
> the follow-up mandatory sub-options can be added to -acpitable.
> 
> Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> ---
>  hw/acpi/core.c   |   32 +++++++++++++++++++++++---------
>  qapi-schema.json |   27 ++++++++-------------------
>  qemu-options.hx  |    7 +++++--
>  3 files changed, 36 insertions(+), 30 deletions(-)
> 
> diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> index e890a5d..cd1f9e4 100644
> --- a/hw/acpi/core.c
> +++ b/hw/acpi/core.c
> @@ -89,8 +89,6 @@ static int acpi_checksum(const uint8_t *data, int len)
>   * It is valid to call this function with
>   * (@blob == NULL && bloblen == 0 && !has_header).
>   *
> - * @hdrs->file and @hdrs->data are ignored.
> - *
>   * SIZE_MAX is considered "infinity" in this function.
>   *
>   * The number of tables that can be installed is not limited, but the 16-bit
> @@ -229,7 +227,8 @@ static void acpi_table_install(const char unsigned
> *blob, size_t bloblen,
>                                        ACPI_TABLE_PFX_SIZE, acpi_payload_size);
>  }
> 
> -void acpi_table_add(const QemuOpts *opts, Error **errp)
> +static void acpi_table_from_file(bool has_header, const char *file,
> +                                 AcpiTableOptions *hdrs, Error **errp)
[Lv Zheng] 
It looks this patch still has problem here.
Please ignore the v3/v4 submissions.
Sorry for the noise.

Thanks
Lv

>  {
>      AcpiTableOptions *hdrs = NULL;
>      Error *err = NULL;
> @@ -249,12 +248,8 @@ void acpi_table_add(const QemuOpts *opts,
> Error **errp)
>      if (err) {
>          goto out;
>      }
> -    if (hdrs->has_file == hdrs->has_data) {
> -        error_setg(&err, "'-acpitable' requires one of 'data' or 'file'");
> -        goto out;
> -    }
> 
> -    pathnames = g_strsplit(hdrs->has_file ? hdrs->file : hdrs->data, ":", 0);
> +    pathnames = g_strsplit(file, ":", 0);
>      if (pathnames == NULL || pathnames[0] == NULL) {
>          error_setg(&err, "'-acpitable' requires at least one pathname");
>          goto out;
> @@ -291,7 +286,7 @@ void acpi_table_add(const QemuOpts *opts, Error
> **errp)
>          close(fd);
>      }
> 
> -    acpi_table_install(blob, bloblen, hdrs->has_file, hdrs, &err);
> +    acpi_table_install(blob, bloblen, has_header, hdrs, &err);
> 
>  out:
>      g_free(blob);
> @@ -301,6 +296,25 @@ out:
>      error_propagate(errp, err);
>  }
> 
> +void acpi_table_add(const QemuOpts *opts, Error **errp)
> +{
> +    const char *val;
> +
> +    val = qemu_opt_get((QemuOpts *)opts, "file");
> +    if (val) {
> +        acpi_table_from_file(true, val, hdrs, errp);
> +        return;
> +    }
> +
> +    val = qemu_opt_get((QemuOpts *)opts, "data");
> +    if (val) {
> +        acpi_table_from_file(false, val, hdrs, errp);
> +        return;
> +    }
> +
> +    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> +}
> +
>  static bool acpi_table_builtin = false;
> 
>  void acpi_table_add_builtin(const QemuOpts *opts, Error **errp)
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 5658723..a5e219f 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -3597,17 +3597,18 @@
>  ##
>  # @AcpiTableOptions
>  #
> -# Specify an ACPI table on the command line to load.
> +# Specify ACPI table options for the table loaded on the command line.
>  #
> -# At most one of @file and @data can be specified. The list of files
> specified
> -# by any one of them is loaded and concatenated in order. If both are
> omitted,
> -# @data is implied.
> +# ACPI table can be loaded via 'file' and 'data' options. At most one of
> +# 'file' and 'data' can be specified. The list of files specified by any one
> +# of them is loaded and concatenated in order. If both # are omitted,
> 'data'
> +# is implied.
>  #
>  # Other fields / optargs can be used to override fields of the generic ACPI
>  # table header; refer to the ACPI specification 5.0, section 5.2.6 System
>  # Description Table Header. If a header field is not overridden, then the
> -# corresponding value from the concatenated blob is used (in case of
> @file), or
> -# it is filled in with a hard-coded value (in case of @data).
> +# corresponding value from the concatenated blob is used (in case of
> 'file'),
> +# or it is filled in with a hard-coded value (in case of 'data').
>  #
>  # String fields are copied into the matching ACPI member from lowest
> address
>  # upwards, and silently truncated / NUL-padded to length.
> @@ -3628,16 +3629,6 @@
>  # @asl_compiler_rev: #optional revision number of the utility that
> created the
>  #                    table (4 bytes)
>  #
> -# @file: #optional colon (:) separated list of pathnames to load and
> -#        concatenate as table data. The resultant binary blob is expected to
> -#        have an ACPI table header. At least one file is required. This field
> -#        excludes @data.
> -#
> -# @data: #optional colon (:) separated list of pathnames to load and
> -#        concatenate as table data. The resultant binary blob must not have
> an
> -#        ACPI table header. At least one file is required. This field excludes
> -#        @file.
> -#
>  # Since 1.5
>  ##
>  { 'struct': 'AcpiTableOptions',
> @@ -3648,9 +3639,7 @@
>      '*oem_table_id':      'str',
>      '*oem_rev':           'uint32',
>      '*asl_compiler_id':   'str',
> -    '*asl_compiler_rev':  'uint32',
> -    '*file':              'str',
> -    '*data':              'str' }}
> +    '*asl_compiler_rev':  'uint32' }}
> 
>  ##
>  # @CommandLineParameterType:
> diff --git a/qemu-options.hx b/qemu-options.hx
> index a71aaf8..5fe7f87 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1493,10 +1493,13 @@ Disable HPET support.
>  ETEXI
> 
>  DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
> -    "-acpitable
> [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compi
> ler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
> +    "-acpitable {data|file}=file1[:file2]...\n"
> +    "             [,sig=str][,rev=n]\n"
> +    "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
> +    "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
>      "                ACPI table description\n", QEMU_ARCH_I386)
>  STEXI
> -@item -acpitable
> [sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{st
> r}][,oem_rev=@var{n}]
> [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}][,data=@var{file1
> }[:@var{file2}]...]
> +@item -acpitable
> data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@
> var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}]
> [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
>  @findex -acpitable
>  Add ACPI table with specified header fields and context from specified files.
>  For file=, take whole ACPI table from the specified files, including all
> --
> 1.7.10

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PATCH v5 0/2] ACPI: Add FADT revision support
  2016-08-08  7:28 [Qemu-devel] [PATCH] ACPI: Add -acpifadt to allow FADT revision changes Lv Zheng
                   ` (4 preceding siblings ...)
  2016-08-11  9:12 ` [Qemu-devel] [PATCH v4 " Lv Zheng
@ 2016-08-11  9:36 ` Lv Zheng
  2016-08-11  9:36   ` [Qemu-devel] [PATCH v5 1/2] ACPI: Cleanup -acpitable option code Lv Zheng
  2016-08-11  9:36   ` [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes Lv Zheng
  5 siblings, 2 replies; 32+ messages in thread
From: Lv Zheng @ 2016-08-11  9:36 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, Lv Zheng, qemu-devel, qemu-arm

This patchset adds revision support for FADT.

History:
v1:
  Initial support
v2:
  Coding style cleanup
v3:
  Cleanup -acpitable code (remove useless hdrs->data/file)
  Change -acpifadt to -acpitable fadt=
  Shrink v1 FADT table length
v4:
  Coding style cleanup
v5:
  Correct change block residency

Lv Zheng (2):
  ACPI: Cleanup -acpitable option code
  ACPI: Add -acpitable fadt= to allow FADT revision changes

 hw/acpi/core.c         |   50 +++++++++++++++++++++++++------
 hw/i386/acpi-build.c   |   76 ++++++++++++++++++++++++++++++++++++++++++------
 include/hw/acpi/acpi.h |    1 +
 qapi-schema.json       |   26 +++++------------
 qemu-options.hx        |   15 ++++++++--
 5 files changed, 128 insertions(+), 40 deletions(-)

-- 
1.7.10

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PATCH v5 1/2] ACPI: Cleanup -acpitable option code
  2016-08-11  9:36 ` [Qemu-devel] [PATCH v5 0/2] ACPI: Add FADT revision support Lv Zheng
@ 2016-08-11  9:36   ` Lv Zheng
  2016-08-12 14:51     ` Igor Mammedov
  2016-08-11  9:36   ` [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes Lv Zheng
  1 sibling, 1 reply; 32+ messages in thread
From: Lv Zheng @ 2016-08-11  9:36 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, Lv Zheng, qemu-devel, qemu-arm

In -acpitable options, at least/most one data/file sub-option is mandatory,
this patch cleans up the code to reflect this in a managed manner so that
the follow-up mandatory sub-options can be added to -acpitable.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 hw/acpi/core.c   |   32 +++++++++++++++++++++++---------
 qapi-schema.json |   26 +++++++-------------------
 qemu-options.hx  |    7 +++++--
 3 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index e890a5d..85e0e94 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -89,8 +89,6 @@ static int acpi_checksum(const uint8_t *data, int len)
  * It is valid to call this function with
  * (@blob == NULL && bloblen == 0 && !has_header).
  *
- * @hdrs->file and @hdrs->data are ignored.
- *
  * SIZE_MAX is considered "infinity" in this function.
  *
  * The number of tables that can be installed is not limited, but the 16-bit
@@ -229,7 +227,8 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
                                       ACPI_TABLE_PFX_SIZE, acpi_payload_size);
 }
 
-void acpi_table_add(const QemuOpts *opts, Error **errp)
+static void acpi_table_from_file(bool has_header, const char *file,
+                                 const QemuOpts *opts, Error **errp)
 {
     AcpiTableOptions *hdrs = NULL;
     Error *err = NULL;
@@ -249,12 +248,8 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
     if (err) {
         goto out;
     }
-    if (hdrs->has_file == hdrs->has_data) {
-        error_setg(&err, "'-acpitable' requires one of 'data' or 'file'");
-        goto out;
-    }
 
-    pathnames = g_strsplit(hdrs->has_file ? hdrs->file : hdrs->data, ":", 0);
+    pathnames = g_strsplit(file, ":", 0);
     if (pathnames == NULL || pathnames[0] == NULL) {
         error_setg(&err, "'-acpitable' requires at least one pathname");
         goto out;
@@ -291,7 +286,7 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
         close(fd);
     }
 
-    acpi_table_install(blob, bloblen, hdrs->has_file, hdrs, &err);
+    acpi_table_install(blob, bloblen, has_header, hdrs, &err);
 
 out:
     g_free(blob);
@@ -301,6 +296,25 @@ out:
     error_propagate(errp, err);
 }
 
+void acpi_table_add(const QemuOpts *opts, Error **errp)
+{
+    const char *val;
+
+    val = qemu_opt_get((QemuOpts *)opts, "file");
+    if (val) {
+        acpi_table_from_file(true, val, opts, errp);
+        return;
+    }
+
+    val = qemu_opt_get((QemuOpts *)opts, "data");
+    if (val) {
+        acpi_table_from_file(false, val, opts, errp);
+        return;
+    }
+
+    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
+}
+
 static bool acpi_table_builtin = false;
 
 void acpi_table_add_builtin(const QemuOpts *opts, Error **errp)
diff --git a/qapi-schema.json b/qapi-schema.json
index 5658723..75b8b3b 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3597,17 +3597,17 @@
 ##
 # @AcpiTableOptions
 #
-# Specify an ACPI table on the command line to load.
+# Specify ACPI table options for the table loaded on the command line.
 #
-# At most one of @file and @data can be specified. The list of files specified
-# by any one of them is loaded and concatenated in order. If both are omitted,
-# @data is implied.
+# ACPI table can be loaded via 'file' and 'data' options. At most one of
+# 'file' and 'data' can be specified. The list of files specified by any one
+# of them is loaded and concatenated in order.
 #
 # Other fields / optargs can be used to override fields of the generic ACPI
 # table header; refer to the ACPI specification 5.0, section 5.2.6 System
 # Description Table Header. If a header field is not overridden, then the
-# corresponding value from the concatenated blob is used (in case of @file), or
-# it is filled in with a hard-coded value (in case of @data).
+# corresponding value from the concatenated blob is used (in case of 'file'),
+# or it is filled in with a hard-coded value (in case of 'data').
 #
 # String fields are copied into the matching ACPI member from lowest address
 # upwards, and silently truncated / NUL-padded to length.
@@ -3628,16 +3628,6 @@
 # @asl_compiler_rev: #optional revision number of the utility that created the
 #                    table (4 bytes)
 #
-# @file: #optional colon (:) separated list of pathnames to load and
-#        concatenate as table data. The resultant binary blob is expected to
-#        have an ACPI table header. At least one file is required. This field
-#        excludes @data.
-#
-# @data: #optional colon (:) separated list of pathnames to load and
-#        concatenate as table data. The resultant binary blob must not have an
-#        ACPI table header. At least one file is required. This field excludes
-#        @file.
-#
 # Since 1.5
 ##
 { 'struct': 'AcpiTableOptions',
@@ -3648,9 +3638,7 @@
     '*oem_table_id':      'str',
     '*oem_rev':           'uint32',
     '*asl_compiler_id':   'str',
-    '*asl_compiler_rev':  'uint32',
-    '*file':              'str',
-    '*data':              'str' }}
+    '*asl_compiler_rev':  'uint32' }}
 
 ##
 # @CommandLineParameterType:
diff --git a/qemu-options.hx b/qemu-options.hx
index a71aaf8..5fe7f87 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1493,10 +1493,13 @@ Disable HPET support.
 ETEXI
 
 DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
-    "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
+    "-acpitable {data|file}=file1[:file2]...\n"
+    "             [,sig=str][,rev=n]\n"
+    "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
+    "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
     "                ACPI table description\n", QEMU_ARCH_I386)
 STEXI
-@item -acpitable [sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}][,data=@var{file1}[:@var{file2}]...]
+@item -acpitable data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
 @findex -acpitable
 Add ACPI table with specified header fields and context from specified files.
 For file=, take whole ACPI table from the specified files, including all
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-11  9:36 ` [Qemu-devel] [PATCH v5 0/2] ACPI: Add FADT revision support Lv Zheng
  2016-08-11  9:36   ` [Qemu-devel] [PATCH v5 1/2] ACPI: Cleanup -acpitable option code Lv Zheng
@ 2016-08-11  9:36   ` Lv Zheng
  2016-08-11 12:42     ` Igor Mammedov
  2016-08-12 14:59     ` Paolo Bonzini
  1 sibling, 2 replies; 32+ messages in thread
From: Lv Zheng @ 2016-08-11  9:36 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, Lv Zheng, qemu-devel, qemu-arm

This patch allows FADT to be built with different revisions. When the revision
is greater than 1.0, 64-bit address fields may also be filled.

Note that FADT revision 2 has never been defined by the ACPI specification. So
this patch only adds an option -acpitable fadt= to allow revision 1,3,5 to be
configured by the users.

1. Tested by booting a linux image, the 64-bit addresses are correctly filled
   in the dumped FADT.
2. Tested by booting a Windows image, no boot failure can be seen.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 hw/acpi/core.c         |   20 ++++++++++++-
 hw/i386/acpi-build.c   |   76 ++++++++++++++++++++++++++++++++++++++++++------
 include/hw/acpi/acpi.h |    1 +
 qemu-options.hx        |    8 ++++-
 4 files changed, 94 insertions(+), 11 deletions(-)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 85e0e94..832c86b 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -19,6 +19,7 @@
  * GNU GPL, version 2 or (at your option) any later version.
  */
 #include "qemu/osdep.h"
+#include "qemu/cutils.h"
 #include "sysemu/sysemu.h"
 #include "hw/hw.h"
 #include "hw/i386/pc.h"
@@ -54,6 +55,7 @@ static const char unsigned dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
 
 char unsigned *acpi_tables;
 size_t acpi_tables_len;
+uint8_t acpi_fadt_rev = 1;
 
 static QemuOptsList qemu_acpi_opts = {
     .name = "acpi",
@@ -312,7 +314,23 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
         return;
     }
 
-    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
+    val = qemu_opt_get((QemuOpts *)opts, "fadt");
+    if (val) {
+        unsigned long rev;
+        int err;
+
+        err = qemu_strtoul(val, NULL, 10, &rev);
+        if (err ||
+            (rev != 1 && rev != 3 && rev != 5)) {
+            error_setg(errp, "Unsupported FADT revision %s, "
+                       "please specify 1,3,5", val);
+            return;
+        }
+        acpi_fadt_rev = rev;
+        return;
+    }
+
+    error_setg(errp, "'-acpitable' requires one of 'data','file' or 'fadt'");
 }
 
 static bool acpi_table_builtin = false;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ce7cbc5..8be6578 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker *linker)
     facs->length = cpu_to_le32(sizeof(*facs));
 }
 
+/* GAS */
+static void
+build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
+          uint8_t bit_width, uint8_t bit_offset,
+          uint8_t access_width, uint64_t address)
+{
+    gas->space_id = space_id;
+    gas->bit_width = bit_width;
+    gas->bit_offset = bit_offset;
+    gas->access_width = access_width;
+    gas->address = address;
+}
+
 /* Load chipset information in FADT */
-static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
+static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo *pm,
+                       uint8_t revision)
 {
     fadt->model = 1;
     fadt->reserved1 = 0;
@@ -309,6 +323,25 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
         fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
     }
     fadt->century = RTC_CENTURY;
+
+    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
+    if (revision >= 3) {
+        /* EVT, CNT, TMR register matches hw/acpi/core.c */
+        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
+                  32, 0, 0, cpu_to_le64(pm->io_base));
+        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
+                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
+        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
+                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
+        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
+                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm->gpe0_blk));
+    }
+
+    /* Build dummy ACPI 5.0 fields */
+    if (revision >= 5) {
+        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
+        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
+    }
 }
 
 
@@ -316,11 +349,21 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
 static void
 build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
            unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
-           const char *oem_id, const char *oem_table_id)
+           const char *oem_id, const char *oem_table_id, uint8_t revision)
 {
-    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
-    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
-    unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
+    AcpiFadtDescriptorRev5_1 *fadt;
+    unsigned fw_ctrl_offset;
+    unsigned dsdt_entry_offset;
+    unsigned fadt_len;
+
+    if (revision == 1) {
+        fadt_len = sizeof(AcpiFadtDescriptorRev1);
+    } else {
+        fadt_len = sizeof(AcpiFadtDescriptorRev5_1);
+    }
+    fadt = acpi_data_push(table_data, fadt_len);
+    fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
+    dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
 
     /* FACS address to be filled by Guest linker */
     bios_linker_loader_add_pointer(linker,
@@ -328,13 +371,28 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
         ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
 
     /* DSDT address to be filled by Guest linker */
-    fadt_setup(fadt, pm);
     bios_linker_loader_add_pointer(linker,
         ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
         ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
 
-    build_header(linker, table_data,
-                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
+    if (revision > 2) {
+        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
+        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
+
+        /* FACS address to be filled by Guest linker */
+        bios_linker_loader_add_pointer(linker,
+            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
+            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
+
+        /* DSDT address to be filled by Guest linker */
+        bios_linker_loader_add_pointer(linker,
+            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->Xdsdt),
+            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
+    }
+
+    fadt_setup(fadt, pm, revision);
+    build_header(linker, table_data, (void *)fadt, "FACP", fadt_len,
+                 revision, oem_id, oem_table_id);
 }
 
 void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
@@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
     fadt = tables_blob->len;
     acpi_add_table(table_offsets, tables_blob);
     build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
-               slic_oem.id, slic_oem.table_id);
+               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
     aml_len += tables_blob->len - fadt;
 
     acpi_add_table(table_offsets, tables_blob);
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 7b3d93c..63df38d 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq);
 
 /* acpi.c */
 extern int acpi_enabled;
+extern uint8_t acpi_fadt_rev;
 extern char unsigned *acpi_tables;
 extern size_t acpi_tables_len;
 
diff --git a/qemu-options.hx b/qemu-options.hx
index 5fe7f87..d61dd92 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
     "             [,sig=str][,rev=n]\n"
     "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
     "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
-    "                ACPI table description\n", QEMU_ARCH_I386)
+    "                ACPI table description\n"
+    "-acpitable fadt=n\n"
+    "                Configure FADT revision\n",
+    QEMU_ARCH_I386)
 STEXI
 @item -acpitable data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
 @findex -acpitable
@@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU, then the SLIC's oem_id and oem_table_id
 fields will override the same in the RSDT and the FADT (a.k.a. FACP), in order
 to ensure the field matches required by the Microsoft SLIC spec and the ACPI
 spec.
+
+@item -acpitable fadt=@var{n}
+Configure FADT revision to 1, 3, 5, default 1.
 ETEXI
 
 DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-11  9:36   ` [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes Lv Zheng
@ 2016-08-11 12:42     ` Igor Mammedov
  2016-08-12  0:47       ` Zheng, Lv
  2016-08-12 14:59     ` Paolo Bonzini
  1 sibling, 1 reply; 32+ messages in thread
From: Igor Mammedov @ 2016-08-11 12:42 UTC (permalink / raw)
  To: Lv Zheng
  Cc: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm

On Thu, 11 Aug 2016 17:36:45 +0800
Lv Zheng <lv.zheng@intel.com> wrote:

> This patch allows FADT to be built with different revisions. When the revision
> is greater than 1.0, 64-bit address fields may also be filled.
> 
> Note that FADT revision 2 has never been defined by the ACPI specification. So
> this patch only adds an option -acpitable fadt= to allow revision 1,3,5 to be
> configured by the users.
> 
> 1. Tested by booting a linux image, the 64-bit addresses are correctly filled
>    in the dumped FADT.
> 2. Tested by booting a Windows image, no boot failure can be seen.

series still doesn't say why do you need 64-bit addresses in FADT,
current Seabios/OVMF allocates tables below 4Gb and gpe/pm
register blocks are below 4gb as well so there is no point in
accepting theses patches and adding extra CLI options as these
patches do.

If we'd ever need to bump FADT revision, I'd first try to increase it
unconditionally and test/see if it would not upset legacy guests
Windows starting from XP, RHEL4/5/6
If it works then these patches are not necessary,
(this approach worked  just fine for bumping up DSDT revision to 2
it would be possible to use 64-bit math in ASL/AML).

if it doesn't, I still won't do it this way but rather:
 - make new revision used by default
 - add compat property to piix4_pm/ich9-lpc to force legacy revision
 - turn on legacy revision for old machine types using added above property

That way we won't regress existing setups as old machines will stay
the same and only new machine types will be affected. And users that
actually want to play with legacy revision on new machine types could
force it by using above property.

> 
> Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> ---
>  hw/acpi/core.c         |   20 ++++++++++++-
>  hw/i386/acpi-build.c   |   76 ++++++++++++++++++++++++++++++++++++++++++------
>  include/hw/acpi/acpi.h |    1 +
>  qemu-options.hx        |    8 ++++-
>  4 files changed, 94 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> index 85e0e94..832c86b 100644
> --- a/hw/acpi/core.c
> +++ b/hw/acpi/core.c
> @@ -19,6 +19,7 @@
>   * GNU GPL, version 2 or (at your option) any later version.
>   */
>  #include "qemu/osdep.h"
> +#include "qemu/cutils.h"
>  #include "sysemu/sysemu.h"
>  #include "hw/hw.h"
>  #include "hw/i386/pc.h"
> @@ -54,6 +55,7 @@ static const char unsigned dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
>  
>  char unsigned *acpi_tables;
>  size_t acpi_tables_len;
> +uint8_t acpi_fadt_rev = 1;
>  
>  static QemuOptsList qemu_acpi_opts = {
>      .name = "acpi",
> @@ -312,7 +314,23 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
>          return;
>      }
>  
> -    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
> +    if (val) {
> +        unsigned long rev;
> +        int err;
> +
> +        err = qemu_strtoul(val, NULL, 10, &rev);
> +        if (err ||
> +            (rev != 1 && rev != 3 && rev != 5)) {
> +            error_setg(errp, "Unsupported FADT revision %s, "
> +                       "please specify 1,3,5", val);
> +            return;
> +        }
> +        acpi_fadt_rev = rev;
> +        return;
> +    }
> +
> +    error_setg(errp, "'-acpitable' requires one of 'data','file' or 'fadt'");
>  }
>  
>  static bool acpi_table_builtin = false;
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index ce7cbc5..8be6578 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker *linker)
>      facs->length = cpu_to_le32(sizeof(*facs));
>  }
>  
> +/* GAS */
> +static void
> +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> +          uint8_t bit_width, uint8_t bit_offset,
> +          uint8_t access_width, uint64_t address)
> +{
> +    gas->space_id = space_id;
> +    gas->bit_width = bit_width;
> +    gas->bit_offset = bit_offset;
> +    gas->access_width = access_width;
> +    gas->address = address;
> +}
> +
>  /* Load chipset information in FADT */
> -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo *pm,
> +                       uint8_t revision)
>  {
>      fadt->model = 1;
>      fadt->reserved1 = 0;
> @@ -309,6 +323,25 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
>          fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
>      }
>      fadt->century = RTC_CENTURY;
> +
> +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> +    if (revision >= 3) {
> +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> +        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
> +                  32, 0, 0, cpu_to_le64(pm->io_base));
> +        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
> +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm->gpe0_blk));
> +    }
> +
> +    /* Build dummy ACPI 5.0 fields */
> +    if (revision >= 5) {
> +        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
> +        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
> +    }
>  }
>  
>  
> @@ -316,11 +349,21 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
>  static void
>  build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
>             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> -           const char *oem_id, const char *oem_table_id)
> +           const char *oem_id, const char *oem_table_id, uint8_t revision)
>  {
> -    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
> -    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
> -    unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> +    AcpiFadtDescriptorRev5_1 *fadt;
> +    unsigned fw_ctrl_offset;
> +    unsigned dsdt_entry_offset;
> +    unsigned fadt_len;
> +
> +    if (revision == 1) {
> +        fadt_len = sizeof(AcpiFadtDescriptorRev1);
> +    } else {
> +        fadt_len = sizeof(AcpiFadtDescriptorRev5_1);
> +    }
> +    fadt = acpi_data_push(table_data, fadt_len);
> +    fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
> +    dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
>  
>      /* FACS address to be filled by Guest linker */
>      bios_linker_loader_add_pointer(linker,
> @@ -328,13 +371,28 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
>          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
>  
>      /* DSDT address to be filled by Guest linker */
> -    fadt_setup(fadt, pm);
>      bios_linker_loader_add_pointer(linker,
>          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
>          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
>  
> -    build_header(linker, table_data,
> -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
> +    if (revision > 2) {
> +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
> +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
> +
> +        /* FACS address to be filled by Guest linker */
> +        bios_linker_loader_add_pointer(linker,
> +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
> +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> +
> +        /* DSDT address to be filled by Guest linker */
> +        bios_linker_loader_add_pointer(linker,
> +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->Xdsdt),
> +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> +    }
> +
> +    fadt_setup(fadt, pm, revision);
> +    build_header(linker, table_data, (void *)fadt, "FACP", fadt_len,
> +                 revision, oem_id, oem_table_id);
>  }
>  
>  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> @@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
>      fadt = tables_blob->len;
>      acpi_add_table(table_offsets, tables_blob);
>      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> -               slic_oem.id, slic_oem.table_id);
> +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
>      aml_len += tables_blob->len - fadt;
>  
>      acpi_add_table(table_offsets, tables_blob);
> diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> index 7b3d93c..63df38d 100644
> --- a/include/hw/acpi/acpi.h
> +++ b/include/hw/acpi/acpi.h
> @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq);
>  
>  /* acpi.c */
>  extern int acpi_enabled;
> +extern uint8_t acpi_fadt_rev;
>  extern char unsigned *acpi_tables;
>  extern size_t acpi_tables_len;
>  
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 5fe7f87..d61dd92 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
>      "             [,sig=str][,rev=n]\n"
>      "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
>      "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
> -    "                ACPI table description\n", QEMU_ARCH_I386)
> +    "                ACPI table description\n"
> +    "-acpitable fadt=n\n"
> +    "                Configure FADT revision\n",
> +    QEMU_ARCH_I386)
>  STEXI
>  @item -acpitable data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
>  @findex -acpitable
> @@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU, then the SLIC's oem_id and oem_table_id
>  fields will override the same in the RSDT and the FADT (a.k.a. FACP), in order
>  to ensure the field matches required by the Microsoft SLIC spec and the ACPI
>  spec.
> +
> +@item -acpitable fadt=@var{n}
> +Configure FADT revision to 1, 3, 5, default 1.
>  ETEXI
>  
>  DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-11 12:42     ` Igor Mammedov
@ 2016-08-12  0:47       ` Zheng, Lv
  2016-08-12  3:07         ` Michael S. Tsirkin
  2016-08-12 14:55         ` Igor Mammedov
  0 siblings, 2 replies; 32+ messages in thread
From: Zheng, Lv @ 2016-08-12  0:47 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm

Hi, Igor

Thanks for the review.

> From: Igor Mammedov [mailto:imammedo@redhat.com]
> Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> revision changes
> 
> On Thu, 11 Aug 2016 17:36:45 +0800
> Lv Zheng <lv.zheng@intel.com> wrote:
> 
> > This patch allows FADT to be built with different revisions. When the
> revision
> > is greater than 1.0, 64-bit address fields may also be filled.
> >
> > Note that FADT revision 2 has never been defined by the ACPI
> specification. So
> > this patch only adds an option -acpitable fadt= to allow revision 1,3,5 to
> be
> > configured by the users.
> >
> > 1. Tested by booting a linux image, the 64-bit addresses are correctly
> filled
> >    in the dumped FADT.
> > 2. Tested by booting a Windows image, no boot failure can be seen.
> 
> series still doesn't say why do you need 64-bit addresses in FADT,
> current Seabios/OVMF allocates tables below 4Gb and gpe/pm
> register blocks are below 4gb as well so there is no point in
> accepting theses patches and adding extra CLI options as these
> patches do.
[Lv Zheng] 
This patch is used by us to probe Windows FADT behavior.
Current known behavior includes:
1. On x86, Windows requires BIOS to have 2 FADTs, 1 is in RSDT, and probably is a v1 table, the other is in XSDT, and probably is a v3+ table.
2. v2 FADT never exists in the spec, it is used in very early years, by IA64 prototype machines.
3. If the FADT in RSDT takes effective, then Windows actually ignores 64-bit GAS fields, but uses 32-bit register fields.
But there are still many uncertainties:
1. What if the FADT in XSDT takes effective?
2. What's the behavior on IA64/ARM platforms?
If we could have an option here, we could continue the probing work, trying every combination. 

Thus the original purpose of this commit is - probing de-facto standard behavior.

> 
> If we'd ever need to bump FADT revision, I'd first try to increase it
> unconditionally and test/see if it would not upset legacy guests
> Windows starting from XP, RHEL4/5/6
> If it works then these patches are not necessary,
> (this approach worked  just fine for bumping up DSDT revision to 2
> it would be possible to use 64-bit math in ASL/AML).
> 
> if it doesn't, I still won't do it this way but rather:
>  - make new revision used by default
>  - add compat property to piix4_pm/ich9-lpc to force legacy revision
>  - turn on legacy revision for old machine types using added above
> property
> 
> That way we won't regress existing setups as old machines will stay
> the same and only new machine types will be affected. And users that
> actually want to play with legacy revision on new machine types could
> force it by using above property.
> 
[Lv Zheng] 
But it seems the code in this commit contains useful stuffs for qemu.

As I said previously, it seems Windows requires 2 FADTs.
So having a revision parameter for build_fadt() seems to be necessary.
Because if qemu wants to increase FADT revision, qemu may do this in this way:
1. Invoke build_fadt() with revision 1, and put it into RSDT;
2. Invoke build_fadt() with latest revision, and put it into XSDT.
Also we know latest revision FADT is useful, it contains reduced hardware support.
And some of new ACPI features rely this model.

So I'm sure that this commit contains useful stuffs for qemu to do future extension.

But I don't know if you want to keep the new -acpitable fadt= option.
Let me ask:
1. Are there any issues in PATCH 01? Maybe my understanding of qemu option code is not correct.
2. IMO, this option should be useful for a long period because we need it to help probing Windows behavior, so can we have it upstreamed?

Best regards
Lv

> >
> > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > ---
> >  hw/acpi/core.c         |   20 ++++++++++++-
> >  hw/i386/acpi-build.c   |   76
> ++++++++++++++++++++++++++++++++++++++++++------
> >  include/hw/acpi/acpi.h |    1 +
> >  qemu-options.hx        |    8 ++++-
> >  4 files changed, 94 insertions(+), 11 deletions(-)
> >
> > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > index 85e0e94..832c86b 100644
> > --- a/hw/acpi/core.c
> > +++ b/hw/acpi/core.c
> > @@ -19,6 +19,7 @@
> >   * GNU GPL, version 2 or (at your option) any later version.
> >   */
> >  #include "qemu/osdep.h"
> > +#include "qemu/cutils.h"
> >  #include "sysemu/sysemu.h"
> >  #include "hw/hw.h"
> >  #include "hw/i386/pc.h"
> > @@ -54,6 +55,7 @@ static const char unsigned
> dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
> >
> >  char unsigned *acpi_tables;
> >  size_t acpi_tables_len;
> > +uint8_t acpi_fadt_rev = 1;
> >
> >  static QemuOptsList qemu_acpi_opts = {
> >      .name = "acpi",
> > @@ -312,7 +314,23 @@ void acpi_table_add(const QemuOpts *opts,
> Error **errp)
> >          return;
> >      }
> >
> > -    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> > +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
> > +    if (val) {
> > +        unsigned long rev;
> > +        int err;
> > +
> > +        err = qemu_strtoul(val, NULL, 10, &rev);
> > +        if (err ||
> > +            (rev != 1 && rev != 3 && rev != 5)) {
> > +            error_setg(errp, "Unsupported FADT revision %s, "
> > +                       "please specify 1,3,5", val);
> > +            return;
> > +        }
> > +        acpi_fadt_rev = rev;
> > +        return;
> > +    }
> > +
> > +    error_setg(errp, "'-acpitable' requires one of 'data','file' or 'fadt'");
> >  }
> >
> >  static bool acpi_table_builtin = false;
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index ce7cbc5..8be6578 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker
> *linker)
> >      facs->length = cpu_to_le32(sizeof(*facs));
> >  }
> >
> > +/* GAS */
> > +static void
> > +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> > +          uint8_t bit_width, uint8_t bit_offset,
> > +          uint8_t access_width, uint64_t address)
> > +{
> > +    gas->space_id = space_id;
> > +    gas->bit_width = bit_width;
> > +    gas->bit_offset = bit_offset;
> > +    gas->access_width = access_width;
> > +    gas->address = address;
> > +}
> > +
> >  /* Load chipset information in FADT */
> > -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> > +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo
> *pm,
> > +                       uint8_t revision)
> >  {
> >      fadt->model = 1;
> >      fadt->reserved1 = 0;
> > @@ -309,6 +323,25 @@ static void fadt_setup(AcpiFadtDescriptorRev1
> *fadt, AcpiPmInfo *pm)
> >          fadt->flags |= cpu_to_le32(1 <<
> ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
> >      }
> >      fadt->century = RTC_CENTURY;
> > +
> > +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> > +    if (revision >= 3) {
> > +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> > +        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
> > +                  32, 0, 0, cpu_to_le64(pm->io_base));
> > +        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
> > +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> > +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> > +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> > +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> > +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm->gpe0_blk));
> > +    }
> > +
> > +    /* Build dummy ACPI 5.0 fields */
> > +    if (revision >= 5) {
> > +        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0, 0,
> 0);
> > +        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
> > +    }
> >  }
> >
> >
> > @@ -316,11 +349,21 @@ static void
> fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> >  static void
> >  build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
> >             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> > -           const char *oem_id, const char *oem_table_id)
> > +           const char *oem_id, const char *oem_table_id, uint8_t revision)
> >  {
> > -    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data,
> sizeof(*fadt));
> > -    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data-
> >data;
> > -    unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> > +    AcpiFadtDescriptorRev5_1 *fadt;
> > +    unsigned fw_ctrl_offset;
> > +    unsigned dsdt_entry_offset;
> > +    unsigned fadt_len;
> > +
> > +    if (revision == 1) {
> > +        fadt_len = sizeof(AcpiFadtDescriptorRev1);
> > +    } else {
> > +        fadt_len = sizeof(AcpiFadtDescriptorRev5_1);
> > +    }
> > +    fadt = acpi_data_push(table_data, fadt_len);
> > +    fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
> > +    dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> >
> >      /* FACS address to be filled by Guest linker */
> >      bios_linker_loader_add_pointer(linker,
> > @@ -328,13 +371,28 @@ build_fadt(GArray *table_data, BIOSLinker
> *linker, AcpiPmInfo *pm,
> >          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> >
> >      /* DSDT address to be filled by Guest linker */
> > -    fadt_setup(fadt, pm);
> >      bios_linker_loader_add_pointer(linker,
> >          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
> >          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> >
> > -    build_header(linker, table_data,
> > -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
> > +    if (revision > 2) {
> > +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
> > +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
> > +
> > +        /* FACS address to be filled by Guest linker */
> > +        bios_linker_loader_add_pointer(linker,
> > +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
> > +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > +
> > +        /* DSDT address to be filled by Guest linker */
> > +        bios_linker_loader_add_pointer(linker,
> > +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->Xdsdt),
> > +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > +    }
> > +
> > +    fadt_setup(fadt, pm, revision);
> > +    build_header(linker, table_data, (void *)fadt, "FACP", fadt_len,
> > +                 revision, oem_id, oem_table_id);
> >  }
> >
> >  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> > @@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables *tables,
> MachineState *machine)
> >      fadt = tables_blob->len;
> >      acpi_add_table(table_offsets, tables_blob);
> >      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> > -               slic_oem.id, slic_oem.table_id);
> > +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
> >      aml_len += tables_blob->len - fadt;
> >
> >      acpi_add_table(table_offsets, tables_blob);
> > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > index 7b3d93c..63df38d 100644
> > --- a/include/hw/acpi/acpi.h
> > +++ b/include/hw/acpi/acpi.h
> > @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs,
> qemu_irq irq);
> >
> >  /* acpi.c */
> >  extern int acpi_enabled;
> > +extern uint8_t acpi_fadt_rev;
> >  extern char unsigned *acpi_tables;
> >  extern size_t acpi_tables_len;
> >
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index 5fe7f87..d61dd92 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG,
> QEMU_OPTION_acpitable,
> >      "             [,sig=str][,rev=n]\n"
> >      "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
> >      "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
> > -    "                ACPI table description\n", QEMU_ARCH_I386)
> > +    "                ACPI table description\n"
> > +    "-acpitable fadt=n\n"
> > +    "                Configure FADT revision\n",
> > +    QEMU_ARCH_I386)
> >  STEXI
> >  @item -acpitable
> data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@
> var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}]
> [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
> >  @findex -acpitable
> > @@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU, then the
> SLIC's oem_id and oem_table_id
> >  fields will override the same in the RSDT and the FADT (a.k.a. FACP), in
> order
> >  to ensure the field matches required by the Microsoft SLIC spec and the
> ACPI
> >  spec.
> > +
> > +@item -acpitable fadt=@var{n}
> > +Configure FADT revision to 1, 3, 5, default 1.
> >  ETEXI
> >
> >  DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-12  0:47       ` Zheng, Lv
@ 2016-08-12  3:07         ` Michael S. Tsirkin
  2016-08-15  1:33           ` Zheng, Lv
  2016-08-12 14:55         ` Igor Mammedov
  1 sibling, 1 reply; 32+ messages in thread
From: Michael S. Tsirkin @ 2016-08-12  3:07 UTC (permalink / raw)
  To: Zheng, Lv
  Cc: Igor Mammedov, Paolo Bonzini, Peter Crosthwaite,
	Richard Henderson, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm

On Fri, Aug 12, 2016 at 12:47:04AM +0000, Zheng, Lv wrote:
> Hi, Igor
> 
> Thanks for the review.
> 
> > From: Igor Mammedov [mailto:imammedo@redhat.com]
> > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> > revision changes
> > 
> > On Thu, 11 Aug 2016 17:36:45 +0800
> > Lv Zheng <lv.zheng@intel.com> wrote:
> > 
> > > This patch allows FADT to be built with different revisions. When the
> > revision
> > > is greater than 1.0, 64-bit address fields may also be filled.
> > >
> > > Note that FADT revision 2 has never been defined by the ACPI
> > specification. So
> > > this patch only adds an option -acpitable fadt= to allow revision 1,3,5 to
> > be
> > > configured by the users.
> > >
> > > 1. Tested by booting a linux image, the 64-bit addresses are correctly
> > filled
> > >    in the dumped FADT.
> > > 2. Tested by booting a Windows image, no boot failure can be seen.
> > 
> > series still doesn't say why do you need 64-bit addresses in FADT,
> > current Seabios/OVMF allocates tables below 4Gb and gpe/pm
> > register blocks are below 4gb as well so there is no point in
> > accepting theses patches and adding extra CLI options as these
> > patches do.
> [Lv Zheng] 
> This patch is used by us to probe Windows FADT behavior.
> Current known behavior includes:
> 1. On x86, Windows requires BIOS to have 2 FADTs, 1 is in RSDT, and probably is a v1 table, the other is in XSDT, and probably is a v3+ table.

What does "requires" mean here? It seems to work fine without.

> 2. v2 FADT never exists in the spec, it is used in very early years, by IA64 prototype machines.
> 3. If the FADT in RSDT takes effective, then Windows actually ignores 64-bit GAS fields, but uses 32-bit register fields.
> But there are still many uncertainties:
> 1. What if the FADT in XSDT takes effective?
> 2. What's the behavior on IA64/ARM platforms?
> If we could have an option here, we could continue the probing work, trying every combination. 
> 
> Thus the original purpose of this commit is - probing de-facto standard behavior.

Nice, but why do we need PATCH 2 upstream? Is it hard for you to maintain
out of tree?

> > 
> > If we'd ever need to bump FADT revision, I'd first try to increase it
> > unconditionally and test/see if it would not upset legacy guests
> > Windows starting from XP, RHEL4/5/6
> > If it works then these patches are not necessary,
> > (this approach worked  just fine for bumping up DSDT revision to 2
> > it would be possible to use 64-bit math in ASL/AML).
> > 
> > if it doesn't, I still won't do it this way but rather:
> >  - make new revision used by default
> >  - add compat property to piix4_pm/ich9-lpc to force legacy revision
> >  - turn on legacy revision for old machine types using added above
> > property
> > 
> > That way we won't regress existing setups as old machines will stay
> > the same and only new machine types will be affected. And users that
> > actually want to play with legacy revision on new machine types could
> > force it by using above property.
> > 
> [Lv Zheng] 
> But it seems the code in this commit contains useful stuffs for qemu.
> 
> As I said previously, it seems Windows requires 2 FADTs.
> So having a revision parameter for build_fadt() seems to be necessary.
> Because if qemu wants to increase FADT revision, qemu may do this in this way:
> 1. Invoke build_fadt() with revision 1, and put it into RSDT;
> 2. Invoke build_fadt() with latest revision, and put it into XSDT.
> Also we know latest revision FADT is useful, it contains reduced hardware support.
> And some of new ACPI features rely this model.
> 
> So I'm sure that this commit contains useful stuffs for qemu to do future extension.
> 
> But I don't know if you want to keep the new -acpitable fadt= option.
> Let me ask:
> 1. Are there any issues in PATCH 01? Maybe my understanding of qemu option code is not correct.

Didn't review yet, I'll let Igor review first.

> 2. IMO, this option should be useful for a long period because we need it to help probing Windows behavior, so can we have it upstreamed?

ATM PATCH 2 does not seem generally useful.

> 
> Best regards
> Lv
> 
> > >
> > > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > > ---
> > >  hw/acpi/core.c         |   20 ++++++++++++-
> > >  hw/i386/acpi-build.c   |   76
> > ++++++++++++++++++++++++++++++++++++++++++------
> > >  include/hw/acpi/acpi.h |    1 +
> > >  qemu-options.hx        |    8 ++++-
> > >  4 files changed, 94 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > > index 85e0e94..832c86b 100644
> > > --- a/hw/acpi/core.c
> > > +++ b/hw/acpi/core.c
> > > @@ -19,6 +19,7 @@
> > >   * GNU GPL, version 2 or (at your option) any later version.
> > >   */
> > >  #include "qemu/osdep.h"
> > > +#include "qemu/cutils.h"
> > >  #include "sysemu/sysemu.h"
> > >  #include "hw/hw.h"
> > >  #include "hw/i386/pc.h"
> > > @@ -54,6 +55,7 @@ static const char unsigned
> > dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
> > >
> > >  char unsigned *acpi_tables;
> > >  size_t acpi_tables_len;
> > > +uint8_t acpi_fadt_rev = 1;
> > >
> > >  static QemuOptsList qemu_acpi_opts = {
> > >      .name = "acpi",
> > > @@ -312,7 +314,23 @@ void acpi_table_add(const QemuOpts *opts,
> > Error **errp)
> > >          return;
> > >      }
> > >
> > > -    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> > > +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
> > > +    if (val) {
> > > +        unsigned long rev;
> > > +        int err;
> > > +
> > > +        err = qemu_strtoul(val, NULL, 10, &rev);
> > > +        if (err ||
> > > +            (rev != 1 && rev != 3 && rev != 5)) {
> > > +            error_setg(errp, "Unsupported FADT revision %s, "
> > > +                       "please specify 1,3,5", val);
> > > +            return;
> > > +        }
> > > +        acpi_fadt_rev = rev;
> > > +        return;
> > > +    }
> > > +
> > > +    error_setg(errp, "'-acpitable' requires one of 'data','file' or 'fadt'");
> > >  }
> > >
> > >  static bool acpi_table_builtin = false;
> > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > index ce7cbc5..8be6578 100644
> > > --- a/hw/i386/acpi-build.c
> > > +++ b/hw/i386/acpi-build.c
> > > @@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker
> > *linker)
> > >      facs->length = cpu_to_le32(sizeof(*facs));
> > >  }
> > >
> > > +/* GAS */
> > > +static void
> > > +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> > > +          uint8_t bit_width, uint8_t bit_offset,
> > > +          uint8_t access_width, uint64_t address)
> > > +{
> > > +    gas->space_id = space_id;
> > > +    gas->bit_width = bit_width;
> > > +    gas->bit_offset = bit_offset;
> > > +    gas->access_width = access_width;
> > > +    gas->address = address;
> > > +}
> > > +
> > >  /* Load chipset information in FADT */
> > > -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> > > +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo
> > *pm,
> > > +                       uint8_t revision)
> > >  {
> > >      fadt->model = 1;
> > >      fadt->reserved1 = 0;
> > > @@ -309,6 +323,25 @@ static void fadt_setup(AcpiFadtDescriptorRev1
> > *fadt, AcpiPmInfo *pm)
> > >          fadt->flags |= cpu_to_le32(1 <<
> > ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
> > >      }
> > >      fadt->century = RTC_CENTURY;
> > > +
> > > +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> > > +    if (revision >= 3) {
> > > +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> > > +        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
> > > +                  32, 0, 0, cpu_to_le64(pm->io_base));
> > > +        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
> > > +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> > > +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> > > +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> > > +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> > > +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm->gpe0_blk));
> > > +    }
> > > +
> > > +    /* Build dummy ACPI 5.0 fields */
> > > +    if (revision >= 5) {
> > > +        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0, 0,
> > 0);
> > > +        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
> > > +    }
> > >  }
> > >
> > >
> > > @@ -316,11 +349,21 @@ static void
> > fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> > >  static void
> > >  build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
> > >             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> > > -           const char *oem_id, const char *oem_table_id)
> > > +           const char *oem_id, const char *oem_table_id, uint8_t revision)
> > >  {
> > > -    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data,
> > sizeof(*fadt));
> > > -    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data-
> > >data;
> > > -    unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> > > +    AcpiFadtDescriptorRev5_1 *fadt;
> > > +    unsigned fw_ctrl_offset;
> > > +    unsigned dsdt_entry_offset;
> > > +    unsigned fadt_len;
> > > +
> > > +    if (revision == 1) {
> > > +        fadt_len = sizeof(AcpiFadtDescriptorRev1);
> > > +    } else {
> > > +        fadt_len = sizeof(AcpiFadtDescriptorRev5_1);
> > > +    }
> > > +    fadt = acpi_data_push(table_data, fadt_len);
> > > +    fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
> > > +    dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> > >
> > >      /* FACS address to be filled by Guest linker */
> > >      bios_linker_loader_add_pointer(linker,
> > > @@ -328,13 +371,28 @@ build_fadt(GArray *table_data, BIOSLinker
> > *linker, AcpiPmInfo *pm,
> > >          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > >
> > >      /* DSDT address to be filled by Guest linker */
> > > -    fadt_setup(fadt, pm);
> > >      bios_linker_loader_add_pointer(linker,
> > >          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
> > >          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > >
> > > -    build_header(linker, table_data,
> > > -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
> > > +    if (revision > 2) {
> > > +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
> > > +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
> > > +
> > > +        /* FACS address to be filled by Guest linker */
> > > +        bios_linker_loader_add_pointer(linker,
> > > +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
> > > +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > +
> > > +        /* DSDT address to be filled by Guest linker */
> > > +        bios_linker_loader_add_pointer(linker,
> > > +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->Xdsdt),
> > > +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > +    }
> > > +
> > > +    fadt_setup(fadt, pm, revision);
> > > +    build_header(linker, table_data, (void *)fadt, "FACP", fadt_len,
> > > +                 revision, oem_id, oem_table_id);
> > >  }
> > >
> > >  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> > > @@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables *tables,
> > MachineState *machine)
> > >      fadt = tables_blob->len;
> > >      acpi_add_table(table_offsets, tables_blob);
> > >      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> > > -               slic_oem.id, slic_oem.table_id);
> > > +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
> > >      aml_len += tables_blob->len - fadt;
> > >
> > >      acpi_add_table(table_offsets, tables_blob);
> > > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > > index 7b3d93c..63df38d 100644
> > > --- a/include/hw/acpi/acpi.h
> > > +++ b/include/hw/acpi/acpi.h
> > > @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs,
> > qemu_irq irq);
> > >
> > >  /* acpi.c */
> > >  extern int acpi_enabled;
> > > +extern uint8_t acpi_fadt_rev;
> > >  extern char unsigned *acpi_tables;
> > >  extern size_t acpi_tables_len;
> > >
> > > diff --git a/qemu-options.hx b/qemu-options.hx
> > > index 5fe7f87..d61dd92 100644
> > > --- a/qemu-options.hx
> > > +++ b/qemu-options.hx
> > > @@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG,
> > QEMU_OPTION_acpitable,
> > >      "             [,sig=str][,rev=n]\n"
> > >      "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
> > >      "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
> > > -    "                ACPI table description\n", QEMU_ARCH_I386)
> > > +    "                ACPI table description\n"
> > > +    "-acpitable fadt=n\n"
> > > +    "                Configure FADT revision\n",
> > > +    QEMU_ARCH_I386)
> > >  STEXI
> > >  @item -acpitable
> > data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@
> > var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}]
> > [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
> > >  @findex -acpitable
> > > @@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU, then the
> > SLIC's oem_id and oem_table_id
> > >  fields will override the same in the RSDT and the FADT (a.k.a. FACP), in
> > order
> > >  to ensure the field matches required by the Microsoft SLIC spec and the
> > ACPI
> > >  spec.
> > > +
> > > +@item -acpitable fadt=@var{n}
> > > +Configure FADT revision to 1, 3, 5, default 1.
> > >  ETEXI
> > >
> > >  DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 1/2] ACPI: Cleanup -acpitable option code
  2016-08-11  9:36   ` [Qemu-devel] [PATCH v5 1/2] ACPI: Cleanup -acpitable option code Lv Zheng
@ 2016-08-12 14:51     ` Igor Mammedov
  2016-08-15  5:23       ` Zheng, Lv
  0 siblings, 1 reply; 32+ messages in thread
From: Igor Mammedov @ 2016-08-12 14:51 UTC (permalink / raw)
  To: Lv Zheng
  Cc: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm,
	eblake, armbru

On Thu, 11 Aug 2016 17:36:38 +0800
Lv Zheng <lv.zheng@intel.com> wrote:

> In -acpitable options, at least/most one data/file sub-option is mandatory,
> this patch cleans up the code to reflect this in a managed manner so that
> the follow-up mandatory sub-options can be added to -acpitable.
> 
> Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> ---
>  hw/acpi/core.c   |   32 +++++++++++++++++++++++---------
>  qapi-schema.json |   26 +++++++-------------------
>  qemu-options.hx  |    7 +++++--
>  3 files changed, 35 insertions(+), 30 deletions(-)
> 
> diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> index e890a5d..85e0e94 100644
> --- a/hw/acpi/core.c
> +++ b/hw/acpi/core.c
> @@ -89,8 +89,6 @@ static int acpi_checksum(const uint8_t *data, int len)
>   * It is valid to call this function with
>   * (@blob == NULL && bloblen == 0 && !has_header).
>   *
> - * @hdrs->file and @hdrs->data are ignored.
> - *
unrelated change?

>   * SIZE_MAX is considered "infinity" in this function.
>   *
>   * The number of tables that can be installed is not limited, but the 16-bit
> @@ -229,7 +227,8 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
>                                        ACPI_TABLE_PFX_SIZE, acpi_payload_size);
>  }
>  
> -void acpi_table_add(const QemuOpts *opts, Error **errp)
> +static void acpi_table_from_file(bool has_header, const char *file,
> +                                 const QemuOpts *opts, Error **errp)
>  {
>      AcpiTableOptions *hdrs = NULL;
>      Error *err = NULL;
> @@ -249,12 +248,8 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
>      if (err) {
>          goto out;
>      }
> -    if (hdrs->has_file == hdrs->has_data) {
> -        error_setg(&err, "'-acpitable' requires one of 'data' or 'file'");
> -        goto out;
> -    }
>  
> -    pathnames = g_strsplit(hdrs->has_file ? hdrs->file : hdrs->data, ":", 0);
> +    pathnames = g_strsplit(file, ":", 0);
>      if (pathnames == NULL || pathnames[0] == NULL) {
>          error_setg(&err, "'-acpitable' requires at least one pathname");
>          goto out;
> @@ -291,7 +286,7 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
>          close(fd);
>      }
>  
> -    acpi_table_install(blob, bloblen, hdrs->has_file, hdrs, &err);
> +    acpi_table_install(blob, bloblen, has_header, hdrs, &err);
>  
>  out:
>      g_free(blob);
> @@ -301,6 +296,25 @@ out:
>      error_propagate(errp, err);
>  }
>  
> +void acpi_table_add(const QemuOpts *opts, Error **errp)
> +{
> +    const char *val;
> +
> +    val = qemu_opt_get((QemuOpts *)opts, "file");
> +    if (val) {
> +        acpi_table_from_file(true, val, opts, errp);
> +        return;
> +    }
> +
> +    val = qemu_opt_get((QemuOpts *)opts, "data");
> +    if (val) {
> +        acpi_table_from_file(false, val, opts, errp);
> +        return;
> +    }
> +
> +    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> +}
> +
>  static bool acpi_table_builtin = false;
>  
>  void acpi_table_add_builtin(const QemuOpts *opts, Error **errp)
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 5658723..75b8b3b 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -3597,17 +3597,17 @@
>  ##
>  # @AcpiTableOptions
>  #
> -# Specify an ACPI table on the command line to load.
> +# Specify ACPI table options for the table loaded on the command line.
>  #
> -# At most one of @file and @data can be specified. The list of files specified
> -# by any one of them is loaded and concatenated in order.


> -# If both are omitted, @data is implied.
You are removing this bit of documentation, which is still true


> +# ACPI table can be loaded via 'file' and 'data' options. At most one of
> +# 'file' and 'data' can be specified. The list of files specified by any one
> +# of them is loaded and concatenated in order.
>  #
>  # Other fields / optargs can be used to override fields of the generic ACPI
>  # table header; refer to the ACPI specification 5.0, section 5.2.6 System
>  # Description Table Header. If a header field is not overridden, then the
> -# corresponding value from the concatenated blob is used (in case of @file), or
> -# it is filled in with a hard-coded value (in case of @data).
> +# corresponding value from the concatenated blob is used (in case of 'file'),
> +# or it is filled in with a hard-coded value (in case of 'data').
>  #
>  # String fields are copied into the matching ACPI member from lowest address
>  # upwards, and silently truncated / NUL-padded to length.
> @@ -3628,16 +3628,6 @@
>  # @asl_compiler_rev: #optional revision number of the utility that created the
>  #                    table (4 bytes)
>  #
> -# @file: #optional colon (:) separated list of pathnames to load and
> -#        concatenate as table data. The resultant binary blob is expected to
> -#        have an ACPI table header. At least one file is required. This field
> -#        excludes @data.
> -#
> -# @data: #optional colon (:) separated list of pathnames to load and
> -#        concatenate as table data. The resultant binary blob must not have an
> -#        ACPI table header. At least one file is required. This field excludes
> -#        @file.
> -#
>  # Since 1.5
>  ##
>  { 'struct': 'AcpiTableOptions',
> @@ -3648,9 +3638,7 @@
>      '*oem_table_id':      'str',
>      '*oem_rev':           'uint32',
>      '*asl_compiler_id':   'str',
> -    '*asl_compiler_rev':  'uint32',
> -    '*file':              'str',
> -    '*data':              'str' }}
> +    '*asl_compiler_rev':  'uint32' }}
it's probably is not ok to remove fields here
as it might break existing users that expect them

>  
>  ##
>  # @CommandLineParameterType:
> diff --git a/qemu-options.hx b/qemu-options.hx
> index a71aaf8..5fe7f87 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1493,10 +1493,13 @@ Disable HPET support.
>  ETEXI
>  
>  DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
> -    "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
> +    "-acpitable {data|file}=file1[:file2]...\n"
> +    "             [,sig=str][,rev=n]\n"
> +    "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
> +    "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
>      "                ACPI table description\n", QEMU_ARCH_I386)
>  STEXI
> -@item -acpitable [sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}][,data=@var{file1}[:@var{file2}]...]
> +@item -acpitable data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
>  @findex -acpitable
>  Add ACPI table with specified header fields and context from specified files.
>  For file=, take whole ACPI table from the specified files, including all

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-12  0:47       ` Zheng, Lv
  2016-08-12  3:07         ` Michael S. Tsirkin
@ 2016-08-12 14:55         ` Igor Mammedov
  2016-08-15  4:18           ` Zheng, Lv
  1 sibling, 1 reply; 32+ messages in thread
From: Igor Mammedov @ 2016-08-12 14:55 UTC (permalink / raw)
  To: Zheng, Lv
  Cc: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm

On Fri, 12 Aug 2016 00:47:04 +0000
"Zheng, Lv" <lv.zheng@intel.com> wrote:

> Hi, Igor
> 
> Thanks for the review.
> 
> > From: Igor Mammedov [mailto:imammedo@redhat.com]
> > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> > revision changes
> > 
> > On Thu, 11 Aug 2016 17:36:45 +0800
> > Lv Zheng <lv.zheng@intel.com> wrote:
> >   
> > > This patch allows FADT to be built with different revisions. When the  
> > revision  
> > > is greater than 1.0, 64-bit address fields may also be filled.
> > >
> > > Note that FADT revision 2 has never been defined by the ACPI  
> > specification. So  
> > > this patch only adds an option -acpitable fadt= to allow revision 1,3,5 to  
> > be  
> > > configured by the users.
> > >
> > > 1. Tested by booting a linux image, the 64-bit addresses are correctly  
> > filled  
> > >    in the dumped FADT.
> > > 2. Tested by booting a Windows image, no boot failure can be seen.  
> > 
> > series still doesn't say why do you need 64-bit addresses in FADT,
> > current Seabios/OVMF allocates tables below 4Gb and gpe/pm
> > register blocks are below 4gb as well so there is no point in
> > accepting theses patches and adding extra CLI options as these
> > patches do.  
> [Lv Zheng] 
> This patch is used by us to probe Windows FADT behavior.
> Current known behavior includes:
> 1. On x86, Windows requires BIOS to have 2 FADTs, 1 is in RSDT, and probably is a v1 table, the other is in XSDT, and probably is a v3+ table.
RDST is not limited to rev 1 only
it can as easily reference v2/3/4/5/6 tables
differences between RSDT and XSDT is that the former is able to point
to tables located below 4G only.

> 2. v2 FADT never exists in the spec, it is used in very early years, by IA64 prototype machines.
> 3. If the FADT in RSDT takes effective, then Windows actually ignores 64-bit GAS fields, but uses 32-bit register fields.
> But there are still many uncertainties:
> 1. What if the FADT in XSDT takes effective?
ACPI 6.0 spec says:
"An ACPI-compatible OS must use the XSDT if present."
hence XSDT referenced FADT must be used, but that's Windows
so I won't bet that it actually does what spec mandates.

> 2. What's the behavior on IA64/ARM platforms?
For ARM virt machine, QEMU currently provides ACPI 5.1 variant of FADT.

> If we could have an option here, we could continue the probing work, trying every combination. 
> 
> Thus the original purpose of this commit is - probing de-facto standard behavior.
What I'd suggest is try to bump up revision unconditionally to 5.1 (same as ARM)
so it would provide 64-bit fields although not really used by QEMU
and upstream it (provided it won't break anything).

As for probing part with 64-bit fields actually used,
I'd keep it out of tree as it doesn't make sense for upstream
QEMU to have it since all addresses are below 4Gb and it's not
going to change to keep compatibility with legacy OSes.

That would keep out of tree bits minimal and at the same time
reduce maintenance headache on QEMU side since it won't have
to maintain extra -acpitable option forever.

> 
> > 
> > If we'd ever need to bump FADT revision, I'd first try to increase it
> > unconditionally and test/see if it would not upset legacy guests
> > Windows starting from XP, RHEL4/5/6
> > If it works then these patches are not necessary,
> > (this approach worked  just fine for bumping up DSDT revision to 2
> > it would be possible to use 64-bit math in ASL/AML).
> > 
> > if it doesn't, I still won't do it this way but rather:
> >  - make new revision used by default
> >  - add compat property to piix4_pm/ich9-lpc to force legacy revision
> >  - turn on legacy revision for old machine types using added above
> > property
> > 
> > That way we won't regress existing setups as old machines will stay
> > the same and only new machine types will be affected. And users that
> > actually want to play with legacy revision on new machine types could
> > force it by using above property.
> >   
> [Lv Zheng] 
> But it seems the code in this commit contains useful stuffs for qemu.
> 
> As I said previously, it seems Windows requires 2 FADTs.
Windows boots just fine with 1 FADT so far.

I wonder, what Windows version does require 2 FADTs?

> So having a revision parameter for build_fadt() seems to be necessary.
> Because if qemu wants to increase FADT revision, qemu may do this in this way:
> 1. Invoke build_fadt() with revision 1, and put it into RSDT;
> 2. Invoke build_fadt() with latest revision, and put it into XSDT.
> Also we know latest revision FADT is useful, it contains reduced hardware support.
> And some of new ACPI features rely this model.
providing revision number is not enough, each revision might have
its own FADT structure, and it would be a bunch of code to maintain
only to play and see if Windows is happy about it.
I'd keep that out of tree.

> So I'm sure that this commit contains useful stuffs for qemu to do future extension.
> 
> But I don't know if you want to keep the new -acpitable fadt= option.
> Let me ask:
> 1. Are there any issues in PATCH 01? Maybe my understanding of qemu option code is not correct.
I'd not touch -acpitable as you did even for out of tree code
but instead add property to piix4_pm/ich9-lpc that would enable
testing bits you need, for example "enable_64bit_gpe" then
you could easily switch it on for tests by doing following:

 $QEMU -global piix4_pm.enable_64bit_gpe=on ...

grep for "disable_s3" option and see how it's used/implemented.

That way you won't risk breaking -acpitable CLI option behavior
and keep experiment bits relatively isolated (easier to rebase)
and it would be easier to upstream some if they make sense for
general usage.

You also might want to look at the work Michael have done wrt XSDT[1]
when we played with initial implementation of ACPI bits for ARM
but in the end we've picked RSDT there as well.

1) just google for "qemu-devel XSDT"

> 2. IMO, this option should be useful for a long period because we need it to help probing Windows behavior, so can we have it upstreamed?
> 
> Best regards
> Lv
> 
> > >
> > > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > > ---
> > >  hw/acpi/core.c         |   20 ++++++++++++-
> > >  hw/i386/acpi-build.c   |   76  
> > ++++++++++++++++++++++++++++++++++++++++++------  
> > >  include/hw/acpi/acpi.h |    1 +
> > >  qemu-options.hx        |    8 ++++-
> > >  4 files changed, 94 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > > index 85e0e94..832c86b 100644
> > > --- a/hw/acpi/core.c
> > > +++ b/hw/acpi/core.c
> > > @@ -19,6 +19,7 @@
> > >   * GNU GPL, version 2 or (at your option) any later version.
> > >   */
> > >  #include "qemu/osdep.h"
> > > +#include "qemu/cutils.h"
> > >  #include "sysemu/sysemu.h"
> > >  #include "hw/hw.h"
> > >  #include "hw/i386/pc.h"
> > > @@ -54,6 +55,7 @@ static const char unsigned  
> > dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =  
> > >
> > >  char unsigned *acpi_tables;
> > >  size_t acpi_tables_len;
> > > +uint8_t acpi_fadt_rev = 1;
> > >
> > >  static QemuOptsList qemu_acpi_opts = {
> > >      .name = "acpi",
> > > @@ -312,7 +314,23 @@ void acpi_table_add(const QemuOpts *opts,  
> > Error **errp)  
> > >          return;
> > >      }
> > >
> > > -    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> > > +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
> > > +    if (val) {
> > > +        unsigned long rev;
> > > +        int err;
> > > +
> > > +        err = qemu_strtoul(val, NULL, 10, &rev);
> > > +        if (err ||
> > > +            (rev != 1 && rev != 3 && rev != 5)) {
> > > +            error_setg(errp, "Unsupported FADT revision %s, "
> > > +                       "please specify 1,3,5", val);
> > > +            return;
> > > +        }
> > > +        acpi_fadt_rev = rev;
> > > +        return;
> > > +    }
> > > +
> > > +    error_setg(errp, "'-acpitable' requires one of 'data','file' or 'fadt'");
> > >  }
> > >
> > >  static bool acpi_table_builtin = false;
> > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > index ce7cbc5..8be6578 100644
> > > --- a/hw/i386/acpi-build.c
> > > +++ b/hw/i386/acpi-build.c
> > > @@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker  
> > *linker)  
> > >      facs->length = cpu_to_le32(sizeof(*facs));
> > >  }
> > >
> > > +/* GAS */
> > > +static void
> > > +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> > > +          uint8_t bit_width, uint8_t bit_offset,
> > > +          uint8_t access_width, uint64_t address)
> > > +{
> > > +    gas->space_id = space_id;
> > > +    gas->bit_width = bit_width;
> > > +    gas->bit_offset = bit_offset;
> > > +    gas->access_width = access_width;
> > > +    gas->address = address;
> > > +}
> > > +
> > >  /* Load chipset information in FADT */
> > > -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> > > +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo  
> > *pm,  
> > > +                       uint8_t revision)
> > >  {
> > >      fadt->model = 1;
> > >      fadt->reserved1 = 0;
> > > @@ -309,6 +323,25 @@ static void fadt_setup(AcpiFadtDescriptorRev1  
> > *fadt, AcpiPmInfo *pm)  
> > >          fadt->flags |= cpu_to_le32(1 <<  
> > ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);  
> > >      }
> > >      fadt->century = RTC_CENTURY;
> > > +
> > > +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> > > +    if (revision >= 3) {
> > > +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> > > +        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
> > > +                  32, 0, 0, cpu_to_le64(pm->io_base));
> > > +        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
> > > +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> > > +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> > > +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> > > +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> > > +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm->gpe0_blk));
> > > +    }
> > > +
> > > +    /* Build dummy ACPI 5.0 fields */
> > > +    if (revision >= 5) {
> > > +        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0, 0,  
> > 0);  
> > > +        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0, 0, 0);
> > > +    }
> > >  }
> > >
> > >
> > > @@ -316,11 +349,21 @@ static void  
> > fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)  
> > >  static void
> > >  build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
> > >             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> > > -           const char *oem_id, const char *oem_table_id)
> > > +           const char *oem_id, const char *oem_table_id, uint8_t revision)
> > >  {
> > > -    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data,  
> > sizeof(*fadt));  
> > > -    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data-
> > >data;
> > > -    unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> > > +    AcpiFadtDescriptorRev5_1 *fadt;
> > > +    unsigned fw_ctrl_offset;
> > > +    unsigned dsdt_entry_offset;
> > > +    unsigned fadt_len;
> > > +
> > > +    if (revision == 1) {
> > > +        fadt_len = sizeof(AcpiFadtDescriptorRev1);
> > > +    } else {
> > > +        fadt_len = sizeof(AcpiFadtDescriptorRev5_1);
> > > +    }
> > > +    fadt = acpi_data_push(table_data, fadt_len);
> > > +    fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
> > > +    dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> > >
> > >      /* FACS address to be filled by Guest linker */
> > >      bios_linker_loader_add_pointer(linker,
> > > @@ -328,13 +371,28 @@ build_fadt(GArray *table_data, BIOSLinker  
> > *linker, AcpiPmInfo *pm,  
> > >          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > >
> > >      /* DSDT address to be filled by Guest linker */
> > > -    fadt_setup(fadt, pm);
> > >      bios_linker_loader_add_pointer(linker,
> > >          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
> > >          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > >
> > > -    build_header(linker, table_data,
> > > -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
> > > +    if (revision > 2) {
> > > +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
> > > +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
> > > +
> > > +        /* FACS address to be filled by Guest linker */
> > > +        bios_linker_loader_add_pointer(linker,
> > > +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
> > > +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > +
> > > +        /* DSDT address to be filled by Guest linker */
> > > +        bios_linker_loader_add_pointer(linker,
> > > +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->Xdsdt),
> > > +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > +    }
> > > +
> > > +    fadt_setup(fadt, pm, revision);
> > > +    build_header(linker, table_data, (void *)fadt, "FACP", fadt_len,
> > > +                 revision, oem_id, oem_table_id);
> > >  }
> > >
> > >  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> > > @@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables *tables,  
> > MachineState *machine)  
> > >      fadt = tables_blob->len;
> > >      acpi_add_table(table_offsets, tables_blob);
> > >      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> > > -               slic_oem.id, slic_oem.table_id);
> > > +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
> > >      aml_len += tables_blob->len - fadt;
> > >
> > >      acpi_add_table(table_offsets, tables_blob);
> > > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > > index 7b3d93c..63df38d 100644
> > > --- a/include/hw/acpi/acpi.h
> > > +++ b/include/hw/acpi/acpi.h
> > > @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs,  
> > qemu_irq irq);  
> > >
> > >  /* acpi.c */
> > >  extern int acpi_enabled;
> > > +extern uint8_t acpi_fadt_rev;
> > >  extern char unsigned *acpi_tables;
> > >  extern size_t acpi_tables_len;
> > >
> > > diff --git a/qemu-options.hx b/qemu-options.hx
> > > index 5fe7f87..d61dd92 100644
> > > --- a/qemu-options.hx
> > > +++ b/qemu-options.hx
> > > @@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG,  
> > QEMU_OPTION_acpitable,  
> > >      "             [,sig=str][,rev=n]\n"
> > >      "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
> > >      "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
> > > -    "                ACPI table description\n", QEMU_ARCH_I386)
> > > +    "                ACPI table description\n"
> > > +    "-acpitable fadt=n\n"
> > > +    "                Configure FADT revision\n",
> > > +    QEMU_ARCH_I386)
> > >  STEXI
> > >  @item -acpitable  
> > data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@
> > var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}]
> > [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]  
> > >  @findex -acpitable
> > > @@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU, then the  
> > SLIC's oem_id and oem_table_id  
> > >  fields will override the same in the RSDT and the FADT (a.k.a. FACP), in  
> > order  
> > >  to ensure the field matches required by the Microsoft SLIC spec and the  
> > ACPI  
> > >  spec.
> > > +
> > > +@item -acpitable fadt=@var{n}
> > > +Configure FADT revision to 1, 3, 5, default 1.
> > >  ETEXI
> > >
> > >  DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,  
> 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-11  9:36   ` [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes Lv Zheng
  2016-08-11 12:42     ` Igor Mammedov
@ 2016-08-12 14:59     ` Paolo Bonzini
  2016-08-15  1:42       ` Zheng, Lv
  1 sibling, 1 reply; 32+ messages in thread
From: Paolo Bonzini @ 2016-08-12 14:59 UTC (permalink / raw)
  To: Lv Zheng, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, qemu-devel, qemu-arm



On 11/08/2016 11:36, Lv Zheng wrote:
>  
> -    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
> +    if (val) {
> +        unsigned long rev;

Don't use qemu_opt_get.  Add the field to AcpiTableOptions in
qapi-schema.json, and then use hdrs->has_fadt, hdrs->fadt.

Paolo

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-12  3:07         ` Michael S. Tsirkin
@ 2016-08-15  1:33           ` Zheng, Lv
  2016-08-15  1:47             ` Michael S. Tsirkin
  0 siblings, 1 reply; 32+ messages in thread
From: Zheng, Lv @ 2016-08-15  1:33 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Igor Mammedov, Paolo Bonzini, Peter Crosthwaite,
	Richard Henderson, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm

Hi,

> From: Michael S. Tsirkin [mailto:mst@redhat.com]
> Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> revision changes
> 
> On Fri, Aug 12, 2016 at 12:47:04AM +0000, Zheng, Lv wrote:
> > Hi, Igor
> >
> > Thanks for the review.
> >
> > > From: Igor Mammedov [mailto:imammedo@redhat.com]
> > > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> > > revision changes
> > >
> > > On Thu, 11 Aug 2016 17:36:45 +0800
> > > Lv Zheng <lv.zheng@intel.com> wrote:
> > >
> > > > This patch allows FADT to be built with different revisions. When the
> > > revision
> > > > is greater than 1.0, 64-bit address fields may also be filled.
> > > >
> > > > Note that FADT revision 2 has never been defined by the ACPI
> > > specification. So
> > > > this patch only adds an option -acpitable fadt= to allow revision 1,3,5
> to
> > > be
> > > > configured by the users.
> > > >
> > > > 1. Tested by booting a linux image, the 64-bit addresses are correctly
> > > filled
> > > >    in the dumped FADT.
> > > > 2. Tested by booting a Windows image, no boot failure can be seen.
> > >
> > > series still doesn't say why do you need 64-bit addresses in FADT,
> > > current Seabios/OVMF allocates tables below 4Gb and gpe/pm
> > > register blocks are below 4gb as well so there is no point in
> > > accepting theses patches and adding extra CLI options as these
> > > patches do.
> > [Lv Zheng]
> > This patch is used by us to probe Windows FADT behavior.
> > Current known behavior includes:
> > 1. On x86, Windows requires BIOS to have 2 FADTs, 1 is in RSDT, and
> probably is a v1 table, the other is in XSDT, and probably is a v3+ table.
> 
> What does "requires" mean here? It seems to work fine without.

Let me reword:
Windows requires BIOS to provide 2 FADTs when both RSDT and XSDT are provided.

> 
> > 2. v2 FADT never exists in the spec, it is used in very early years, by IA64
> prototype machines.
> > 3. If the FADT in RSDT takes effective, then Windows actually ignores 64-
> bit GAS fields, but uses 32-bit register fields.
> > But there are still many uncertainties:
> > 1. What if the FADT in XSDT takes effective?
> > 2. What's the behavior on IA64/ARM platforms?
> > If we could have an option here, we could continue the probing work,
> trying every combination.
> >
> > Thus the original purpose of this commit is - probing de-facto standard
> behavior.
> 
> Nice, but why do we need PATCH 2 upstream? Is it hard for you to
> maintain
> out of tree?

Not hard.
I just may encounter problems if I want to put a document in Linux kernel related to FADT support and Windows behavior proofs.
I'll remove this option.

> 
> > >
> > > If we'd ever need to bump FADT revision, I'd first try to increase it
> > > unconditionally and test/see if it would not upset legacy guests
> > > Windows starting from XP, RHEL4/5/6
> > > If it works then these patches are not necessary,
> > > (this approach worked  just fine for bumping up DSDT revision to 2
> > > it would be possible to use 64-bit math in ASL/AML).
> > >
> > > if it doesn't, I still won't do it this way but rather:
> > >  - make new revision used by default
> > >  - add compat property to piix4_pm/ich9-lpc to force legacy revision
> > >  - turn on legacy revision for old machine types using added above
> > > property
> > >
> > > That way we won't regress existing setups as old machines will stay
> > > the same and only new machine types will be affected. And users that
> > > actually want to play with legacy revision on new machine types could
> > > force it by using above property.
> > >
> > [Lv Zheng]
> > But it seems the code in this commit contains useful stuffs for qemu.
> >
> > As I said previously, it seems Windows requires 2 FADTs.
> > So having a revision parameter for build_fadt() seems to be necessary.
> > Because if qemu wants to increase FADT revision, qemu may do this in
> this way:
> > 1. Invoke build_fadt() with revision 1, and put it into RSDT;
> > 2. Invoke build_fadt() with latest revision, and put it into XSDT.
> > Also we know latest revision FADT is useful, it contains reduced
> hardware support.
> > And some of new ACPI features rely this model.
> >
> > So I'm sure that this commit contains useful stuffs for qemu to do future
> extension.
> >
> > But I don't know if you want to keep the new -acpitable fadt= option.
> > Let me ask:
> > 1. Are there any issues in PATCH 01? Maybe my understanding of qemu
> option code is not correct.
> 
> Didn't review yet, I'll let Igor review first.
> 
> > 2. IMO, this option should be useful for a long period because we need it
> to help probing Windows behavior, so can we have it upstreamed?
> 
> ATM PATCH 2 does not seem generally useful.

OK. I see.

Thanks
Lv

> 
> >
> > Best regards
> > Lv
> >
> > > >
> > > > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > > > ---
> > > >  hw/acpi/core.c         |   20 ++++++++++++-
> > > >  hw/i386/acpi-build.c   |   76
> > > ++++++++++++++++++++++++++++++++++++++++++------
> > > >  include/hw/acpi/acpi.h |    1 +
> > > >  qemu-options.hx        |    8 ++++-
> > > >  4 files changed, 94 insertions(+), 11 deletions(-)
> > > >
> > > > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > > > index 85e0e94..832c86b 100644
> > > > --- a/hw/acpi/core.c
> > > > +++ b/hw/acpi/core.c
> > > > @@ -19,6 +19,7 @@
> > > >   * GNU GPL, version 2 or (at your option) any later version.
> > > >   */
> > > >  #include "qemu/osdep.h"
> > > > +#include "qemu/cutils.h"
> > > >  #include "sysemu/sysemu.h"
> > > >  #include "hw/hw.h"
> > > >  #include "hw/i386/pc.h"
> > > > @@ -54,6 +55,7 @@ static const char unsigned
> > > dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
> > > >
> > > >  char unsigned *acpi_tables;
> > > >  size_t acpi_tables_len;
> > > > +uint8_t acpi_fadt_rev = 1;
> > > >
> > > >  static QemuOptsList qemu_acpi_opts = {
> > > >      .name = "acpi",
> > > > @@ -312,7 +314,23 @@ void acpi_table_add(const QemuOpts
> *opts,
> > > Error **errp)
> > > >          return;
> > > >      }
> > > >
> > > > -    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> > > > +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
> > > > +    if (val) {
> > > > +        unsigned long rev;
> > > > +        int err;
> > > > +
> > > > +        err = qemu_strtoul(val, NULL, 10, &rev);
> > > > +        if (err ||
> > > > +            (rev != 1 && rev != 3 && rev != 5)) {
> > > > +            error_setg(errp, "Unsupported FADT revision %s, "
> > > > +                       "please specify 1,3,5", val);
> > > > +            return;
> > > > +        }
> > > > +        acpi_fadt_rev = rev;
> > > > +        return;
> > > > +    }
> > > > +
> > > > +    error_setg(errp, "'-acpitable' requires one of 'data','file' or 'fadt'");
> > > >  }
> > > >
> > > >  static bool acpi_table_builtin = false;
> > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > index ce7cbc5..8be6578 100644
> > > > --- a/hw/i386/acpi-build.c
> > > > +++ b/hw/i386/acpi-build.c
> > > > @@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker
> > > *linker)
> > > >      facs->length = cpu_to_le32(sizeof(*facs));
> > > >  }
> > > >
> > > > +/* GAS */
> > > > +static void
> > > > +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> > > > +          uint8_t bit_width, uint8_t bit_offset,
> > > > +          uint8_t access_width, uint64_t address)
> > > > +{
> > > > +    gas->space_id = space_id;
> > > > +    gas->bit_width = bit_width;
> > > > +    gas->bit_offset = bit_offset;
> > > > +    gas->access_width = access_width;
> > > > +    gas->address = address;
> > > > +}
> > > > +
> > > >  /* Load chipset information in FADT */
> > > > -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo
> *pm)
> > > > +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo
> > > *pm,
> > > > +                       uint8_t revision)
> > > >  {
> > > >      fadt->model = 1;
> > > >      fadt->reserved1 = 0;
> > > > @@ -309,6 +323,25 @@ static void
> fadt_setup(AcpiFadtDescriptorRev1
> > > *fadt, AcpiPmInfo *pm)
> > > >          fadt->flags |= cpu_to_le32(1 <<
> > > ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
> > > >      }
> > > >      fadt->century = RTC_CENTURY;
> > > > +
> > > > +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> > > > +    if (revision >= 3) {
> > > > +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> > > > +        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
> > > > +                  32, 0, 0, cpu_to_le64(pm->io_base));
> > > > +        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
> > > > +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> > > > +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> > > > +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> > > > +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> > > > +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm-
> >gpe0_blk));
> > > > +    }
> > > > +
> > > > +    /* Build dummy ACPI 5.0 fields */
> > > > +    if (revision >= 5) {
> > > > +        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0,
> 0,
> > > 0);
> > > > +        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0,
> 0, 0);
> > > > +    }
> > > >  }
> > > >
> > > >
> > > > @@ -316,11 +349,21 @@ static void
> > > fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> > > >  static void
> > > >  build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
> > > >             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> > > > -           const char *oem_id, const char *oem_table_id)
> > > > +           const char *oem_id, const char *oem_table_id, uint8_t
> revision)
> > > >  {
> > > > -    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data,
> > > sizeof(*fadt));
> > > > -    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl -
> table_data-
> > > >data;
> > > > -    unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data-
> >data;
> > > > +    AcpiFadtDescriptorRev5_1 *fadt;
> > > > +    unsigned fw_ctrl_offset;
> > > > +    unsigned dsdt_entry_offset;
> > > > +    unsigned fadt_len;
> > > > +
> > > > +    if (revision == 1) {
> > > > +        fadt_len = sizeof(AcpiFadtDescriptorRev1);
> > > > +    } else {
> > > > +        fadt_len = sizeof(AcpiFadtDescriptorRev5_1);
> > > > +    }
> > > > +    fadt = acpi_data_push(table_data, fadt_len);
> > > > +    fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
> > > > +    dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> > > >
> > > >      /* FACS address to be filled by Guest linker */
> > > >      bios_linker_loader_add_pointer(linker,
> > > > @@ -328,13 +371,28 @@ build_fadt(GArray *table_data,
> BIOSLinker
> > > *linker, AcpiPmInfo *pm,
> > > >          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > >
> > > >      /* DSDT address to be filled by Guest linker */
> > > > -    fadt_setup(fadt, pm);
> > > >      bios_linker_loader_add_pointer(linker,
> > > >          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
> > > >          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > >
> > > > -    build_header(linker, table_data,
> > > > -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id,
> oem_table_id);
> > > > +    if (revision > 2) {
> > > > +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
> > > > +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
> > > > +
> > > > +        /* FACS address to be filled by Guest linker */
> > > > +        bios_linker_loader_add_pointer(linker,
> > > > +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
> > > > +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > > +
> > > > +        /* DSDT address to be filled by Guest linker */
> > > > +        bios_linker_loader_add_pointer(linker,
> > > > +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt-
> >Xdsdt),
> > > > +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > > +    }
> > > > +
> > > > +    fadt_setup(fadt, pm, revision);
> > > > +    build_header(linker, table_data, (void *)fadt, "FACP", fadt_len,
> > > > +                 revision, oem_id, oem_table_id);
> > > >  }
> > > >
> > > >  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> > > > @@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables *tables,
> > > MachineState *machine)
> > > >      fadt = tables_blob->len;
> > > >      acpi_add_table(table_offsets, tables_blob);
> > > >      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> > > > -               slic_oem.id, slic_oem.table_id);
> > > > +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
> > > >      aml_len += tables_blob->len - fadt;
> > > >
> > > >      acpi_add_table(table_offsets, tables_blob);
> > > > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > > > index 7b3d93c..63df38d 100644
> > > > --- a/include/hw/acpi/acpi.h
> > > > +++ b/include/hw/acpi/acpi.h
> > > > @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs,
> > > qemu_irq irq);
> > > >
> > > >  /* acpi.c */
> > > >  extern int acpi_enabled;
> > > > +extern uint8_t acpi_fadt_rev;
> > > >  extern char unsigned *acpi_tables;
> > > >  extern size_t acpi_tables_len;
> > > >
> > > > diff --git a/qemu-options.hx b/qemu-options.hx
> > > > index 5fe7f87..d61dd92 100644
> > > > --- a/qemu-options.hx
> > > > +++ b/qemu-options.hx
> > > > @@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG,
> > > QEMU_OPTION_acpitable,
> > > >      "             [,sig=str][,rev=n]\n"
> > > >      "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
> > > >      "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
> > > > -    "                ACPI table description\n", QEMU_ARCH_I386)
> > > > +    "                ACPI table description\n"
> > > > +    "-acpitable fadt=n\n"
> > > > +    "                Configure FADT revision\n",
> > > > +    QEMU_ARCH_I386)
> > > >  STEXI
> > > >  @item -acpitable
> > >
> data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@
> > > var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}]
> > > [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
> > > >  @findex -acpitable
> > > > @@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU, then
> the
> > > SLIC's oem_id and oem_table_id
> > > >  fields will override the same in the RSDT and the FADT (a.k.a. FACP),
> in
> > > order
> > > >  to ensure the field matches required by the Microsoft SLIC spec and
> the
> > > ACPI
> > > >  spec.
> > > > +
> > > > +@item -acpitable fadt=@var{n}
> > > > +Configure FADT revision to 1, 3, 5, default 1.
> > > >  ETEXI
> > > >
> > > >  DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-12 14:59     ` Paolo Bonzini
@ 2016-08-15  1:42       ` Zheng, Lv
  2016-08-17 11:42         ` Paolo Bonzini
  0 siblings, 1 reply; 32+ messages in thread
From: Zheng, Lv @ 2016-08-15  1:42 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, qemu-devel, qemu-arm

Hi, Paolo

> From: Paolo Bonzini [mailto:pbonzini@redhat.com]
> Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> revision changes
> 
> 
> 
> On 11/08/2016 11:36, Lv Zheng wrote:
> >
> > -    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> > +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
> > +    if (val) {
> > +        unsigned long rev;
> 
> Don't use qemu_opt_get.  Add the field to AcpiTableOptions in
> qapi-schema.json, and then use hdrs->has_fadt, hdrs->fadt.


1. If I do so, users may be confused when only -acpitable fadt=3 is
    specified (no user tables are provided), qemu may exit because of 
    "data or file option missing".
2. If we doesn't want qemu exit in the above case, code in
    acpi_table_add() will be too complicated.
3. If I put fadt into AcpiTableOptions in the schema,
    hdrs->has_fadt/hdrs->fadt will become 2 more useless options
    (just like hders->file/hdrs->data/hdrs->has_file/hdrs->has_data,
    see comments of acpi_table_install()) passed to acpi_table_install().

That's why I enhanced -acpitable to convert it into an option with 3
mandatory sub-options:
-acpitable data/file ....
-acpitable fadt ....

Thanks
Lv

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-15  1:33           ` Zheng, Lv
@ 2016-08-15  1:47             ` Michael S. Tsirkin
  2016-08-15  2:18               ` Zheng, Lv
  0 siblings, 1 reply; 32+ messages in thread
From: Michael S. Tsirkin @ 2016-08-15  1:47 UTC (permalink / raw)
  To: Zheng, Lv
  Cc: Igor Mammedov, Paolo Bonzini, Peter Crosthwaite,
	Richard Henderson, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm

On Mon, Aug 15, 2016 at 01:33:41AM +0000, Zheng, Lv wrote:
> Hi,
> 
> > From: Michael S. Tsirkin [mailto:mst@redhat.com]
> > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> > revision changes
> > 
> > On Fri, Aug 12, 2016 at 12:47:04AM +0000, Zheng, Lv wrote:
> > > Hi, Igor
> > >
> > > Thanks for the review.
> > >
> > > > From: Igor Mammedov [mailto:imammedo@redhat.com]
> > > > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> > > > revision changes
> > > >
> > > > On Thu, 11 Aug 2016 17:36:45 +0800
> > > > Lv Zheng <lv.zheng@intel.com> wrote:
> > > >
> > > > > This patch allows FADT to be built with different revisions. When the
> > > > revision
> > > > > is greater than 1.0, 64-bit address fields may also be filled.
> > > > >
> > > > > Note that FADT revision 2 has never been defined by the ACPI
> > > > specification. So
> > > > > this patch only adds an option -acpitable fadt= to allow revision 1,3,5
> > to
> > > > be
> > > > > configured by the users.
> > > > >
> > > > > 1. Tested by booting a linux image, the 64-bit addresses are correctly
> > > > filled
> > > > >    in the dumped FADT.
> > > > > 2. Tested by booting a Windows image, no boot failure can be seen.
> > > >
> > > > series still doesn't say why do you need 64-bit addresses in FADT,
> > > > current Seabios/OVMF allocates tables below 4Gb and gpe/pm
> > > > register blocks are below 4gb as well so there is no point in
> > > > accepting theses patches and adding extra CLI options as these
> > > > patches do.
> > > [Lv Zheng]
> > > This patch is used by us to probe Windows FADT behavior.
> > > Current known behavior includes:
> > > 1. On x86, Windows requires BIOS to have 2 FADTs, 1 is in RSDT, and
> > probably is a v1 table, the other is in XSDT, and probably is a v3+ table.
> > 
> > What does "requires" mean here? It seems to work fine without.
> 
> Let me reword:
> Windows requires BIOS to provide 2 FADTs when both RSDT and XSDT are provided.

That's good to know, thanks.
Do you see a reason to have both at the moment?

> > 
> > > 2. v2 FADT never exists in the spec, it is used in very early years, by IA64
> > prototype machines.
> > > 3. If the FADT in RSDT takes effective, then Windows actually ignores 64-
> > bit GAS fields, but uses 32-bit register fields.
> > > But there are still many uncertainties:
> > > 1. What if the FADT in XSDT takes effective?
> > > 2. What's the behavior on IA64/ARM platforms?
> > > If we could have an option here, we could continue the probing work,
> > trying every combination.
> > >
> > > Thus the original purpose of this commit is - probing de-facto standard
> > behavior.
> > 
> > Nice, but why do we need PATCH 2 upstream? Is it hard for you to
> > maintain
> > out of tree?
> 
> Not hard.
> I just may encounter problems if I want to put a document in Linux kernel related to FADT support and Windows behavior proofs.
> I'll remove this option.
> 
> > 
> > > >
> > > > If we'd ever need to bump FADT revision, I'd first try to increase it
> > > > unconditionally and test/see if it would not upset legacy guests
> > > > Windows starting from XP, RHEL4/5/6
> > > > If it works then these patches are not necessary,
> > > > (this approach worked  just fine for bumping up DSDT revision to 2
> > > > it would be possible to use 64-bit math in ASL/AML).
> > > >
> > > > if it doesn't, I still won't do it this way but rather:
> > > >  - make new revision used by default
> > > >  - add compat property to piix4_pm/ich9-lpc to force legacy revision
> > > >  - turn on legacy revision for old machine types using added above
> > > > property
> > > >
> > > > That way we won't regress existing setups as old machines will stay
> > > > the same and only new machine types will be affected. And users that
> > > > actually want to play with legacy revision on new machine types could
> > > > force it by using above property.
> > > >
> > > [Lv Zheng]
> > > But it seems the code in this commit contains useful stuffs for qemu.
> > >
> > > As I said previously, it seems Windows requires 2 FADTs.
> > > So having a revision parameter for build_fadt() seems to be necessary.
> > > Because if qemu wants to increase FADT revision, qemu may do this in
> > this way:
> > > 1. Invoke build_fadt() with revision 1, and put it into RSDT;
> > > 2. Invoke build_fadt() with latest revision, and put it into XSDT.
> > > Also we know latest revision FADT is useful, it contains reduced
> > hardware support.
> > > And some of new ACPI features rely this model.
> > >
> > > So I'm sure that this commit contains useful stuffs for qemu to do future
> > extension.
> > >
> > > But I don't know if you want to keep the new -acpitable fadt= option.
> > > Let me ask:
> > > 1. Are there any issues in PATCH 01? Maybe my understanding of qemu
> > option code is not correct.
> > 
> > Didn't review yet, I'll let Igor review first.
> > 
> > > 2. IMO, this option should be useful for a long period because we need it
> > to help probing Windows behavior, so can we have it upstreamed?
> > 
> > ATM PATCH 2 does not seem generally useful.
> 
> OK. I see.
> 
> Thanks
> Lv
> 
> > 
> > >
> > > Best regards
> > > Lv
> > >
> > > > >
> > > > > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > > > > ---
> > > > >  hw/acpi/core.c         |   20 ++++++++++++-
> > > > >  hw/i386/acpi-build.c   |   76
> > > > ++++++++++++++++++++++++++++++++++++++++++------
> > > > >  include/hw/acpi/acpi.h |    1 +
> > > > >  qemu-options.hx        |    8 ++++-
> > > > >  4 files changed, 94 insertions(+), 11 deletions(-)
> > > > >
> > > > > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > > > > index 85e0e94..832c86b 100644
> > > > > --- a/hw/acpi/core.c
> > > > > +++ b/hw/acpi/core.c
> > > > > @@ -19,6 +19,7 @@
> > > > >   * GNU GPL, version 2 or (at your option) any later version.
> > > > >   */
> > > > >  #include "qemu/osdep.h"
> > > > > +#include "qemu/cutils.h"
> > > > >  #include "sysemu/sysemu.h"
> > > > >  #include "hw/hw.h"
> > > > >  #include "hw/i386/pc.h"
> > > > > @@ -54,6 +55,7 @@ static const char unsigned
> > > > dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
> > > > >
> > > > >  char unsigned *acpi_tables;
> > > > >  size_t acpi_tables_len;
> > > > > +uint8_t acpi_fadt_rev = 1;
> > > > >
> > > > >  static QemuOptsList qemu_acpi_opts = {
> > > > >      .name = "acpi",
> > > > > @@ -312,7 +314,23 @@ void acpi_table_add(const QemuOpts
> > *opts,
> > > > Error **errp)
> > > > >          return;
> > > > >      }
> > > > >
> > > > > -    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> > > > > +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
> > > > > +    if (val) {
> > > > > +        unsigned long rev;
> > > > > +        int err;
> > > > > +
> > > > > +        err = qemu_strtoul(val, NULL, 10, &rev);
> > > > > +        if (err ||
> > > > > +            (rev != 1 && rev != 3 && rev != 5)) {
> > > > > +            error_setg(errp, "Unsupported FADT revision %s, "
> > > > > +                       "please specify 1,3,5", val);
> > > > > +            return;
> > > > > +        }
> > > > > +        acpi_fadt_rev = rev;
> > > > > +        return;
> > > > > +    }
> > > > > +
> > > > > +    error_setg(errp, "'-acpitable' requires one of 'data','file' or 'fadt'");
> > > > >  }
> > > > >
> > > > >  static bool acpi_table_builtin = false;
> > > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > > index ce7cbc5..8be6578 100644
> > > > > --- a/hw/i386/acpi-build.c
> > > > > +++ b/hw/i386/acpi-build.c
> > > > > @@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker
> > > > *linker)
> > > > >      facs->length = cpu_to_le32(sizeof(*facs));
> > > > >  }
> > > > >
> > > > > +/* GAS */
> > > > > +static void
> > > > > +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> > > > > +          uint8_t bit_width, uint8_t bit_offset,
> > > > > +          uint8_t access_width, uint64_t address)
> > > > > +{
> > > > > +    gas->space_id = space_id;
> > > > > +    gas->bit_width = bit_width;
> > > > > +    gas->bit_offset = bit_offset;
> > > > > +    gas->access_width = access_width;
> > > > > +    gas->address = address;
> > > > > +}
> > > > > +
> > > > >  /* Load chipset information in FADT */
> > > > > -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo
> > *pm)
> > > > > +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo
> > > > *pm,
> > > > > +                       uint8_t revision)
> > > > >  {
> > > > >      fadt->model = 1;
> > > > >      fadt->reserved1 = 0;
> > > > > @@ -309,6 +323,25 @@ static void
> > fadt_setup(AcpiFadtDescriptorRev1
> > > > *fadt, AcpiPmInfo *pm)
> > > > >          fadt->flags |= cpu_to_le32(1 <<
> > > > ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
> > > > >      }
> > > > >      fadt->century = RTC_CENTURY;
> > > > > +
> > > > > +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> > > > > +    if (revision >= 3) {
> > > > > +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> > > > > +        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
> > > > > +                  32, 0, 0, cpu_to_le64(pm->io_base));
> > > > > +        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
> > > > > +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> > > > > +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> > > > > +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> > > > > +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> > > > > +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm-
> > >gpe0_blk));
> > > > > +    }
> > > > > +
> > > > > +    /* Build dummy ACPI 5.0 fields */
> > > > > +    if (revision >= 5) {
> > > > > +        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0,
> > 0,
> > > > 0);
> > > > > +        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0,
> > 0, 0);
> > > > > +    }
> > > > >  }
> > > > >
> > > > >
> > > > > @@ -316,11 +349,21 @@ static void
> > > > fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> > > > >  static void
> > > > >  build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
> > > > >             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> > > > > -           const char *oem_id, const char *oem_table_id)
> > > > > +           const char *oem_id, const char *oem_table_id, uint8_t
> > revision)
> > > > >  {
> > > > > -    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data,
> > > > sizeof(*fadt));
> > > > > -    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl -
> > table_data-
> > > > >data;
> > > > > -    unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data-
> > >data;
> > > > > +    AcpiFadtDescriptorRev5_1 *fadt;
> > > > > +    unsigned fw_ctrl_offset;
> > > > > +    unsigned dsdt_entry_offset;
> > > > > +    unsigned fadt_len;
> > > > > +
> > > > > +    if (revision == 1) {
> > > > > +        fadt_len = sizeof(AcpiFadtDescriptorRev1);
> > > > > +    } else {
> > > > > +        fadt_len = sizeof(AcpiFadtDescriptorRev5_1);
> > > > > +    }
> > > > > +    fadt = acpi_data_push(table_data, fadt_len);
> > > > > +    fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
> > > > > +    dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> > > > >
> > > > >      /* FACS address to be filled by Guest linker */
> > > > >      bios_linker_loader_add_pointer(linker,
> > > > > @@ -328,13 +371,28 @@ build_fadt(GArray *table_data,
> > BIOSLinker
> > > > *linker, AcpiPmInfo *pm,
> > > > >          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > > >
> > > > >      /* DSDT address to be filled by Guest linker */
> > > > > -    fadt_setup(fadt, pm);
> > > > >      bios_linker_loader_add_pointer(linker,
> > > > >          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
> > > > >          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > > >
> > > > > -    build_header(linker, table_data,
> > > > > -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id,
> > oem_table_id);
> > > > > +    if (revision > 2) {
> > > > > +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
> > > > > +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
> > > > > +
> > > > > +        /* FACS address to be filled by Guest linker */
> > > > > +        bios_linker_loader_add_pointer(linker,
> > > > > +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
> > > > > +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > > > +
> > > > > +        /* DSDT address to be filled by Guest linker */
> > > > > +        bios_linker_loader_add_pointer(linker,
> > > > > +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt-
> > >Xdsdt),
> > > > > +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > > > +    }
> > > > > +
> > > > > +    fadt_setup(fadt, pm, revision);
> > > > > +    build_header(linker, table_data, (void *)fadt, "FACP", fadt_len,
> > > > > +                 revision, oem_id, oem_table_id);
> > > > >  }
> > > > >
> > > > >  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> > > > > @@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables *tables,
> > > > MachineState *machine)
> > > > >      fadt = tables_blob->len;
> > > > >      acpi_add_table(table_offsets, tables_blob);
> > > > >      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> > > > > -               slic_oem.id, slic_oem.table_id);
> > > > > +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
> > > > >      aml_len += tables_blob->len - fadt;
> > > > >
> > > > >      acpi_add_table(table_offsets, tables_blob);
> > > > > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > > > > index 7b3d93c..63df38d 100644
> > > > > --- a/include/hw/acpi/acpi.h
> > > > > +++ b/include/hw/acpi/acpi.h
> > > > > @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs,
> > > > qemu_irq irq);
> > > > >
> > > > >  /* acpi.c */
> > > > >  extern int acpi_enabled;
> > > > > +extern uint8_t acpi_fadt_rev;
> > > > >  extern char unsigned *acpi_tables;
> > > > >  extern size_t acpi_tables_len;
> > > > >
> > > > > diff --git a/qemu-options.hx b/qemu-options.hx
> > > > > index 5fe7f87..d61dd92 100644
> > > > > --- a/qemu-options.hx
> > > > > +++ b/qemu-options.hx
> > > > > @@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG,
> > > > QEMU_OPTION_acpitable,
> > > > >      "             [,sig=str][,rev=n]\n"
> > > > >      "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
> > > > >      "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
> > > > > -    "                ACPI table description\n", QEMU_ARCH_I386)
> > > > > +    "                ACPI table description\n"
> > > > > +    "-acpitable fadt=n\n"
> > > > > +    "                Configure FADT revision\n",
> > > > > +    QEMU_ARCH_I386)
> > > > >  STEXI
> > > > >  @item -acpitable
> > > >
> > data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@
> > > > var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}]
> > > > [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
> > > > >  @findex -acpitable
> > > > > @@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU, then
> > the
> > > > SLIC's oem_id and oem_table_id
> > > > >  fields will override the same in the RSDT and the FADT (a.k.a. FACP),
> > in
> > > > order
> > > > >  to ensure the field matches required by the Microsoft SLIC spec and
> > the
> > > > ACPI
> > > > >  spec.
> > > > > +
> > > > > +@item -acpitable fadt=@var{n}
> > > > > +Configure FADT revision to 1, 3, 5, default 1.
> > > > >  ETEXI
> > > > >
> > > > >  DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-15  1:47             ` Michael S. Tsirkin
@ 2016-08-15  2:18               ` Zheng, Lv
  2016-08-15  2:23                 ` Michael S. Tsirkin
  0 siblings, 1 reply; 32+ messages in thread
From: Zheng, Lv @ 2016-08-15  2:18 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Igor Mammedov, Paolo Bonzini, Peter Crosthwaite,
	Richard Henderson, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm

Hi, 

> From: Michael S. Tsirkin [mailto:mst@redhat.com]
> Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> revision changes
> 
> On Mon, Aug 15, 2016 at 01:33:41AM +0000, Zheng, Lv wrote:
> > Hi,
> >
> > > From: Michael S. Tsirkin [mailto:mst@redhat.com]
> > > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> > > revision changes
> > >
> > > On Fri, Aug 12, 2016 at 12:47:04AM +0000, Zheng, Lv wrote:
> > > > Hi, Igor
> > > >
> > > > Thanks for the review.
> > > >
> > > > > From: Igor Mammedov [mailto:imammedo@redhat.com]
> > > > > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow
> FADT
> > > > > revision changes
> > > > >
> > > > > On Thu, 11 Aug 2016 17:36:45 +0800
> > > > > Lv Zheng <lv.zheng@intel.com> wrote:
> > > > >
> > > > > > This patch allows FADT to be built with different revisions. When
> the
> > > > > revision
> > > > > > is greater than 1.0, 64-bit address fields may also be filled.
> > > > > >
> > > > > > Note that FADT revision 2 has never been defined by the ACPI
> > > > > specification. So
> > > > > > this patch only adds an option -acpitable fadt= to allow revision
> 1,3,5
> > > to
> > > > > be
> > > > > > configured by the users.
> > > > > >
> > > > > > 1. Tested by booting a linux image, the 64-bit addresses are
> correctly
> > > > > filled
> > > > > >    in the dumped FADT.
> > > > > > 2. Tested by booting a Windows image, no boot failure can be
> seen.
> > > > >
> > > > > series still doesn't say why do you need 64-bit addresses in FADT,
> > > > > current Seabios/OVMF allocates tables below 4Gb and gpe/pm
> > > > > register blocks are below 4gb as well so there is no point in
> > > > > accepting theses patches and adding extra CLI options as these
> > > > > patches do.
> > > > [Lv Zheng]
> > > > This patch is used by us to probe Windows FADT behavior.
> > > > Current known behavior includes:
> > > > 1. On x86, Windows requires BIOS to have 2 FADTs, 1 is in RSDT, and
> > > probably is a v1 table, the other is in XSDT, and probably is a v3+ table.
> > >
> > > What does "requires" mean here? It seems to work fine without.
> >
> > Let me reword:
> > Windows requires BIOS to provide 2 FADTs when both RSDT and XSDT
> are provided.
> 
> That's good to know, thanks.
> Do you see a reason to have both at the moment?

If qemu always uses RSDT, then all Windows clones should support such an old BIOS because all Windows clones are backward compatible.

But, ACPI 2.0+/5.0+ introduced new features, (for example, reduced hardware model).
My investigation result shows if an FADT is provided via RSDT, windows will ignore some of its fields. 
So if qemu starts to support new features, then qemu may need to provide both RSDT and XSDT.
As a result, qemu may need to provide 2 FADTs.

However, there is no real ACPI 2.0+ support in qemu/x86 code.
So this feature (having a version parameter for FADT setup) is just a good-to-have feature.
With which, developers may start to introduce some ACPI 2.0+ features.

Thanks
Lv

> 
> > >
> > > > 2. v2 FADT never exists in the spec, it is used in very early years, by
> IA64
> > > prototype machines.
> > > > 3. If the FADT in RSDT takes effective, then Windows actually ignores
> 64-
> > > bit GAS fields, but uses 32-bit register fields.
> > > > But there are still many uncertainties:
> > > > 1. What if the FADT in XSDT takes effective?
> > > > 2. What's the behavior on IA64/ARM platforms?
> > > > If we could have an option here, we could continue the probing work,
> > > trying every combination.
> > > >
> > > > Thus the original purpose of this commit is - probing de-facto
> standard
> > > behavior.
> > >
> > > Nice, but why do we need PATCH 2 upstream? Is it hard for you to
> > > maintain
> > > out of tree?
> >
> > Not hard.
> > I just may encounter problems if I want to put a document in Linux
> kernel related to FADT support and Windows behavior proofs.
> > I'll remove this option.
> >
> > >
> > > > >
> > > > > If we'd ever need to bump FADT revision, I'd first try to increase it
> > > > > unconditionally and test/see if it would not upset legacy guests
> > > > > Windows starting from XP, RHEL4/5/6
> > > > > If it works then these patches are not necessary,
> > > > > (this approach worked  just fine for bumping up DSDT revision to 2
> > > > > it would be possible to use 64-bit math in ASL/AML).
> > > > >
> > > > > if it doesn't, I still won't do it this way but rather:
> > > > >  - make new revision used by default
> > > > >  - add compat property to piix4_pm/ich9-lpc to force legacy
> revision
> > > > >  - turn on legacy revision for old machine types using added above
> > > > > property
> > > > >
> > > > > That way we won't regress existing setups as old machines will stay
> > > > > the same and only new machine types will be affected. And users
> that
> > > > > actually want to play with legacy revision on new machine types
> could
> > > > > force it by using above property.
> > > > >
> > > > [Lv Zheng]
> > > > But it seems the code in this commit contains useful stuffs for qemu.
> > > >
> > > > As I said previously, it seems Windows requires 2 FADTs.
> > > > So having a revision parameter for build_fadt() seems to be
> necessary.
> > > > Because if qemu wants to increase FADT revision, qemu may do this
> in
> > > this way:
> > > > 1. Invoke build_fadt() with revision 1, and put it into RSDT;
> > > > 2. Invoke build_fadt() with latest revision, and put it into XSDT.
> > > > Also we know latest revision FADT is useful, it contains reduced
> > > hardware support.
> > > > And some of new ACPI features rely this model.
> > > >
> > > > So I'm sure that this commit contains useful stuffs for qemu to do
> future
> > > extension.
> > > >
> > > > But I don't know if you want to keep the new -acpitable fadt= option.
> > > > Let me ask:
> > > > 1. Are there any issues in PATCH 01? Maybe my understanding of
> qemu
> > > option code is not correct.
> > >
> > > Didn't review yet, I'll let Igor review first.
> > >
> > > > 2. IMO, this option should be useful for a long period because we
> need it
> > > to help probing Windows behavior, so can we have it upstreamed?
> > >
> > > ATM PATCH 2 does not seem generally useful.
> >
> > OK. I see.
> >
> > Thanks
> > Lv
> >
> > >
> > > >
> > > > Best regards
> > > > Lv
> > > >
> > > > > >
> > > > > > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > > > > > ---
> > > > > >  hw/acpi/core.c         |   20 ++++++++++++-
> > > > > >  hw/i386/acpi-build.c   |   76
> > > > > ++++++++++++++++++++++++++++++++++++++++++------
> > > > > >  include/hw/acpi/acpi.h |    1 +
> > > > > >  qemu-options.hx        |    8 ++++-
> > > > > >  4 files changed, 94 insertions(+), 11 deletions(-)
> > > > > >
> > > > > > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > > > > > index 85e0e94..832c86b 100644
> > > > > > --- a/hw/acpi/core.c
> > > > > > +++ b/hw/acpi/core.c
> > > > > > @@ -19,6 +19,7 @@
> > > > > >   * GNU GPL, version 2 or (at your option) any later version.
> > > > > >   */
> > > > > >  #include "qemu/osdep.h"
> > > > > > +#include "qemu/cutils.h"
> > > > > >  #include "sysemu/sysemu.h"
> > > > > >  #include "hw/hw.h"
> > > > > >  #include "hw/i386/pc.h"
> > > > > > @@ -54,6 +55,7 @@ static const char unsigned
> > > > > dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
> > > > > >
> > > > > >  char unsigned *acpi_tables;
> > > > > >  size_t acpi_tables_len;
> > > > > > +uint8_t acpi_fadt_rev = 1;
> > > > > >
> > > > > >  static QemuOptsList qemu_acpi_opts = {
> > > > > >      .name = "acpi",
> > > > > > @@ -312,7 +314,23 @@ void acpi_table_add(const QemuOpts
> > > *opts,
> > > > > Error **errp)
> > > > > >          return;
> > > > > >      }
> > > > > >
> > > > > > -    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> > > > > > +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
> > > > > > +    if (val) {
> > > > > > +        unsigned long rev;
> > > > > > +        int err;
> > > > > > +
> > > > > > +        err = qemu_strtoul(val, NULL, 10, &rev);
> > > > > > +        if (err ||
> > > > > > +            (rev != 1 && rev != 3 && rev != 5)) {
> > > > > > +            error_setg(errp, "Unsupported FADT revision %s, "
> > > > > > +                       "please specify 1,3,5", val);
> > > > > > +            return;
> > > > > > +        }
> > > > > > +        acpi_fadt_rev = rev;
> > > > > > +        return;
> > > > > > +    }
> > > > > > +
> > > > > > +    error_setg(errp, "'-acpitable' requires one of 'data','file' or
> 'fadt'");
> > > > > >  }
> > > > > >
> > > > > >  static bool acpi_table_builtin = false;
> > > > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > > > index ce7cbc5..8be6578 100644
> > > > > > --- a/hw/i386/acpi-build.c
> > > > > > +++ b/hw/i386/acpi-build.c
> > > > > > @@ -276,8 +276,22 @@ build_facs(GArray *table_data,
> BIOSLinker
> > > > > *linker)
> > > > > >      facs->length = cpu_to_le32(sizeof(*facs));
> > > > > >  }
> > > > > >
> > > > > > +/* GAS */
> > > > > > +static void
> > > > > > +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> > > > > > +          uint8_t bit_width, uint8_t bit_offset,
> > > > > > +          uint8_t access_width, uint64_t address)
> > > > > > +{
> > > > > > +    gas->space_id = space_id;
> > > > > > +    gas->bit_width = bit_width;
> > > > > > +    gas->bit_offset = bit_offset;
> > > > > > +    gas->access_width = access_width;
> > > > > > +    gas->address = address;
> > > > > > +}
> > > > > > +
> > > > > >  /* Load chipset information in FADT */
> > > > > > -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt,
> AcpiPmInfo
> > > *pm)
> > > > > > +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt,
> AcpiPmInfo
> > > > > *pm,
> > > > > > +                       uint8_t revision)
> > > > > >  {
> > > > > >      fadt->model = 1;
> > > > > >      fadt->reserved1 = 0;
> > > > > > @@ -309,6 +323,25 @@ static void
> > > fadt_setup(AcpiFadtDescriptorRev1
> > > > > *fadt, AcpiPmInfo *pm)
> > > > > >          fadt->flags |= cpu_to_le32(1 <<
> > > > > ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
> > > > > >      }
> > > > > >      fadt->century = RTC_CENTURY;
> > > > > > +
> > > > > > +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> > > > > > +    if (revision >= 3) {
> > > > > > +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> > > > > > +        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
> > > > > > +                  32, 0, 0, cpu_to_le64(pm->io_base));
> > > > > > +        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
> > > > > > +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> > > > > > +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> > > > > > +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> > > > > > +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> > > > > > +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm-
> > > >gpe0_blk));
> > > > > > +    }
> > > > > > +
> > > > > > +    /* Build dummy ACPI 5.0 fields */
> > > > > > +    if (revision >= 5) {
> > > > > > +        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY,
> 0, 0,
> > > 0,
> > > > > 0);
> > > > > > +        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0,
> 0,
> > > 0, 0);
> > > > > > +    }
> > > > > >  }
> > > > > >
> > > > > >
> > > > > > @@ -316,11 +349,21 @@ static void
> > > > > fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> > > > > >  static void
> > > > > >  build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo
> *pm,
> > > > > >             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> > > > > > -           const char *oem_id, const char *oem_table_id)
> > > > > > +           const char *oem_id, const char *oem_table_id, uint8_t
> > > revision)
> > > > > >  {
> > > > > > -    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data,
> > > > > sizeof(*fadt));
> > > > > > -    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl -
> > > table_data-
> > > > > >data;
> > > > > > -    unsigned dsdt_entry_offset = (char *)&fadt->dsdt -
> table_data-
> > > >data;
> > > > > > +    AcpiFadtDescriptorRev5_1 *fadt;
> > > > > > +    unsigned fw_ctrl_offset;
> > > > > > +    unsigned dsdt_entry_offset;
> > > > > > +    unsigned fadt_len;
> > > > > > +
> > > > > > +    if (revision == 1) {
> > > > > > +        fadt_len = sizeof(AcpiFadtDescriptorRev1);
> > > > > > +    } else {
> > > > > > +        fadt_len = sizeof(AcpiFadtDescriptorRev5_1);
> > > > > > +    }
> > > > > > +    fadt = acpi_data_push(table_data, fadt_len);
> > > > > > +    fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data-
> >data;
> > > > > > +    dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> > > > > >
> > > > > >      /* FACS address to be filled by Guest linker */
> > > > > >      bios_linker_loader_add_pointer(linker,
> > > > > > @@ -328,13 +371,28 @@ build_fadt(GArray *table_data,
> > > BIOSLinker
> > > > > *linker, AcpiPmInfo *pm,
> > > > > >          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > > > >
> > > > > >      /* DSDT address to be filled by Guest linker */
> > > > > > -    fadt_setup(fadt, pm);
> > > > > >      bios_linker_loader_add_pointer(linker,
> > > > > >          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt-
> >dsdt),
> > > > > >          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > > > >
> > > > > > -    build_header(linker, table_data,
> > > > > > -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id,
> > > oem_table_id);
> > > > > > +    if (revision > 2) {
> > > > > > +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
> > > > > > +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data-
> >data;
> > > > > > +
> > > > > > +        /* FACS address to be filled by Guest linker */
> > > > > > +        bios_linker_loader_add_pointer(linker,
> > > > > > +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt-
> >Xfacs),
> > > > > > +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > > > > +
> > > > > > +        /* DSDT address to be filled by Guest linker */
> > > > > > +        bios_linker_loader_add_pointer(linker,
> > > > > > +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt-
> > > >Xdsdt),
> > > > > > +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > > > > +    }
> > > > > > +
> > > > > > +    fadt_setup(fadt, pm, revision);
> > > > > > +    build_header(linker, table_data, (void *)fadt, "FACP", fadt_len,
> > > > > > +                 revision, oem_id, oem_table_id);
> > > > > >  }
> > > > > >
> > > > > >  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> > > > > > @@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables
> *tables,
> > > > > MachineState *machine)
> > > > > >      fadt = tables_blob->len;
> > > > > >      acpi_add_table(table_offsets, tables_blob);
> > > > > >      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> > > > > > -               slic_oem.id, slic_oem.table_id);
> > > > > > +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
> > > > > >      aml_len += tables_blob->len - fadt;
> > > > > >
> > > > > >      acpi_add_table(table_offsets, tables_blob);
> > > > > > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > > > > > index 7b3d93c..63df38d 100644
> > > > > > --- a/include/hw/acpi/acpi.h
> > > > > > +++ b/include/hw/acpi/acpi.h
> > > > > > @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS
> *acpi_regs,
> > > > > qemu_irq irq);
> > > > > >
> > > > > >  /* acpi.c */
> > > > > >  extern int acpi_enabled;
> > > > > > +extern uint8_t acpi_fadt_rev;
> > > > > >  extern char unsigned *acpi_tables;
> > > > > >  extern size_t acpi_tables_len;
> > > > > >
> > > > > > diff --git a/qemu-options.hx b/qemu-options.hx
> > > > > > index 5fe7f87..d61dd92 100644
> > > > > > --- a/qemu-options.hx
> > > > > > +++ b/qemu-options.hx
> > > > > > @@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG,
> > > > > QEMU_OPTION_acpitable,
> > > > > >      "             [,sig=str][,rev=n]\n"
> > > > > >      "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
> > > > > >      "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
> > > > > > -    "                ACPI table description\n", QEMU_ARCH_I386)
> > > > > > +    "                ACPI table description\n"
> > > > > > +    "-acpitable fadt=n\n"
> > > > > > +    "                Configure FADT revision\n",
> > > > > > +    QEMU_ARCH_I386)
> > > > > >  STEXI
> > > > > >  @item -acpitable
> > > > >
> > >
> data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@
> > > > > var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}]
> > > > > [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
> > > > > >  @findex -acpitable
> > > > > > @@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU,
> then
> > > the
> > > > > SLIC's oem_id and oem_table_id
> > > > > >  fields will override the same in the RSDT and the FADT (a.k.a.
> FACP),
> > > in
> > > > > order
> > > > > >  to ensure the field matches required by the Microsoft SLIC spec
> and
> > > the
> > > > > ACPI
> > > > > >  spec.
> > > > > > +
> > > > > > +@item -acpitable fadt=@var{n}
> > > > > > +Configure FADT revision to 1, 3, 5, default 1.
> > > > > >  ETEXI
> > > > > >
> > > > > >  DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-15  2:18               ` Zheng, Lv
@ 2016-08-15  2:23                 ` Michael S. Tsirkin
  2016-08-15  3:18                   ` Zheng, Lv
  0 siblings, 1 reply; 32+ messages in thread
From: Michael S. Tsirkin @ 2016-08-15  2:23 UTC (permalink / raw)
  To: Zheng, Lv
  Cc: Igor Mammedov, Paolo Bonzini, Peter Crosthwaite,
	Richard Henderson, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm

On Mon, Aug 15, 2016 at 02:18:55AM +0000, Zheng, Lv wrote:
> Hi, 
> 
> > From: Michael S. Tsirkin [mailto:mst@redhat.com]
> > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> > revision changes
> > 
> > On Mon, Aug 15, 2016 at 01:33:41AM +0000, Zheng, Lv wrote:
> > > Hi,
> > >
> > > > From: Michael S. Tsirkin [mailto:mst@redhat.com]
> > > > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> > > > revision changes
> > > >
> > > > On Fri, Aug 12, 2016 at 12:47:04AM +0000, Zheng, Lv wrote:
> > > > > Hi, Igor
> > > > >
> > > > > Thanks for the review.
> > > > >
> > > > > > From: Igor Mammedov [mailto:imammedo@redhat.com]
> > > > > > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow
> > FADT
> > > > > > revision changes
> > > > > >
> > > > > > On Thu, 11 Aug 2016 17:36:45 +0800
> > > > > > Lv Zheng <lv.zheng@intel.com> wrote:
> > > > > >
> > > > > > > This patch allows FADT to be built with different revisions. When
> > the
> > > > > > revision
> > > > > > > is greater than 1.0, 64-bit address fields may also be filled.
> > > > > > >
> > > > > > > Note that FADT revision 2 has never been defined by the ACPI
> > > > > > specification. So
> > > > > > > this patch only adds an option -acpitable fadt= to allow revision
> > 1,3,5
> > > > to
> > > > > > be
> > > > > > > configured by the users.
> > > > > > >
> > > > > > > 1. Tested by booting a linux image, the 64-bit addresses are
> > correctly
> > > > > > filled
> > > > > > >    in the dumped FADT.
> > > > > > > 2. Tested by booting a Windows image, no boot failure can be
> > seen.
> > > > > >
> > > > > > series still doesn't say why do you need 64-bit addresses in FADT,
> > > > > > current Seabios/OVMF allocates tables below 4Gb and gpe/pm
> > > > > > register blocks are below 4gb as well so there is no point in
> > > > > > accepting theses patches and adding extra CLI options as these
> > > > > > patches do.
> > > > > [Lv Zheng]
> > > > > This patch is used by us to probe Windows FADT behavior.
> > > > > Current known behavior includes:
> > > > > 1. On x86, Windows requires BIOS to have 2 FADTs, 1 is in RSDT, and
> > > > probably is a v1 table, the other is in XSDT, and probably is a v3+ table.
> > > >
> > > > What does "requires" mean here? It seems to work fine without.
> > >
> > > Let me reword:
> > > Windows requires BIOS to provide 2 FADTs when both RSDT and XSDT
> > are provided.
> > 
> > That's good to know, thanks.
> > Do you see a reason to have both at the moment?
> 
> If qemu always uses RSDT, then all Windows clones should support such an old BIOS because all Windows clones are backward compatible.
> 
> But, ACPI 2.0+/5.0+ introduced new features, (for example, reduced hardware model).
> My investigation result shows if an FADT is provided via RSDT, windows will ignore some of its fields. 
> So if qemu starts to support new features, then qemu may need to provide both RSDT and XSDT.
> As a result, qemu may need to provide 2 FADTs.
> 
> However, there is no real ACPI 2.0+ support in qemu/x86 code.
> So this feature (having a version parameter for FADT setup) is just a good-to-have feature.
> With which, developers may start to introduce some ACPI 2.0+ features.
> 
> Thanks
> Lv

Right. Let's include this when we actually need some of the
features that require an XSDT.

Pls note that OVMF currently won't do the right thing
if you have both an RSDT and an XSDT: it will try to
install two copies of all tables.
If you are interested in this, please take a look at
the OVMF code and fix it up.

> > 
> > > >
> > > > > 2. v2 FADT never exists in the spec, it is used in very early years, by
> > IA64
> > > > prototype machines.
> > > > > 3. If the FADT in RSDT takes effective, then Windows actually ignores
> > 64-
> > > > bit GAS fields, but uses 32-bit register fields.
> > > > > But there are still many uncertainties:
> > > > > 1. What if the FADT in XSDT takes effective?
> > > > > 2. What's the behavior on IA64/ARM platforms?
> > > > > If we could have an option here, we could continue the probing work,
> > > > trying every combination.
> > > > >
> > > > > Thus the original purpose of this commit is - probing de-facto
> > standard
> > > > behavior.
> > > >
> > > > Nice, but why do we need PATCH 2 upstream? Is it hard for you to
> > > > maintain
> > > > out of tree?
> > >
> > > Not hard.
> > > I just may encounter problems if I want to put a document in Linux
> > kernel related to FADT support and Windows behavior proofs.
> > > I'll remove this option.
> > >
> > > >
> > > > > >
> > > > > > If we'd ever need to bump FADT revision, I'd first try to increase it
> > > > > > unconditionally and test/see if it would not upset legacy guests
> > > > > > Windows starting from XP, RHEL4/5/6
> > > > > > If it works then these patches are not necessary,
> > > > > > (this approach worked  just fine for bumping up DSDT revision to 2
> > > > > > it would be possible to use 64-bit math in ASL/AML).
> > > > > >
> > > > > > if it doesn't, I still won't do it this way but rather:
> > > > > >  - make new revision used by default
> > > > > >  - add compat property to piix4_pm/ich9-lpc to force legacy
> > revision
> > > > > >  - turn on legacy revision for old machine types using added above
> > > > > > property
> > > > > >
> > > > > > That way we won't regress existing setups as old machines will stay
> > > > > > the same and only new machine types will be affected. And users
> > that
> > > > > > actually want to play with legacy revision on new machine types
> > could
> > > > > > force it by using above property.
> > > > > >
> > > > > [Lv Zheng]
> > > > > But it seems the code in this commit contains useful stuffs for qemu.
> > > > >
> > > > > As I said previously, it seems Windows requires 2 FADTs.
> > > > > So having a revision parameter for build_fadt() seems to be
> > necessary.
> > > > > Because if qemu wants to increase FADT revision, qemu may do this
> > in
> > > > this way:
> > > > > 1. Invoke build_fadt() with revision 1, and put it into RSDT;
> > > > > 2. Invoke build_fadt() with latest revision, and put it into XSDT.
> > > > > Also we know latest revision FADT is useful, it contains reduced
> > > > hardware support.
> > > > > And some of new ACPI features rely this model.
> > > > >
> > > > > So I'm sure that this commit contains useful stuffs for qemu to do
> > future
> > > > extension.
> > > > >
> > > > > But I don't know if you want to keep the new -acpitable fadt= option.
> > > > > Let me ask:
> > > > > 1. Are there any issues in PATCH 01? Maybe my understanding of
> > qemu
> > > > option code is not correct.
> > > >
> > > > Didn't review yet, I'll let Igor review first.
> > > >
> > > > > 2. IMO, this option should be useful for a long period because we
> > need it
> > > > to help probing Windows behavior, so can we have it upstreamed?
> > > >
> > > > ATM PATCH 2 does not seem generally useful.
> > >
> > > OK. I see.
> > >
> > > Thanks
> > > Lv
> > >
> > > >
> > > > >
> > > > > Best regards
> > > > > Lv
> > > > >
> > > > > > >
> > > > > > > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > > > > > > ---
> > > > > > >  hw/acpi/core.c         |   20 ++++++++++++-
> > > > > > >  hw/i386/acpi-build.c   |   76
> > > > > > ++++++++++++++++++++++++++++++++++++++++++------
> > > > > > >  include/hw/acpi/acpi.h |    1 +
> > > > > > >  qemu-options.hx        |    8 ++++-
> > > > > > >  4 files changed, 94 insertions(+), 11 deletions(-)
> > > > > > >
> > > > > > > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > > > > > > index 85e0e94..832c86b 100644
> > > > > > > --- a/hw/acpi/core.c
> > > > > > > +++ b/hw/acpi/core.c
> > > > > > > @@ -19,6 +19,7 @@
> > > > > > >   * GNU GPL, version 2 or (at your option) any later version.
> > > > > > >   */
> > > > > > >  #include "qemu/osdep.h"
> > > > > > > +#include "qemu/cutils.h"
> > > > > > >  #include "sysemu/sysemu.h"
> > > > > > >  #include "hw/hw.h"
> > > > > > >  #include "hw/i386/pc.h"
> > > > > > > @@ -54,6 +55,7 @@ static const char unsigned
> > > > > > dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
> > > > > > >
> > > > > > >  char unsigned *acpi_tables;
> > > > > > >  size_t acpi_tables_len;
> > > > > > > +uint8_t acpi_fadt_rev = 1;
> > > > > > >
> > > > > > >  static QemuOptsList qemu_acpi_opts = {
> > > > > > >      .name = "acpi",
> > > > > > > @@ -312,7 +314,23 @@ void acpi_table_add(const QemuOpts
> > > > *opts,
> > > > > > Error **errp)
> > > > > > >          return;
> > > > > > >      }
> > > > > > >
> > > > > > > -    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> > > > > > > +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
> > > > > > > +    if (val) {
> > > > > > > +        unsigned long rev;
> > > > > > > +        int err;
> > > > > > > +
> > > > > > > +        err = qemu_strtoul(val, NULL, 10, &rev);
> > > > > > > +        if (err ||
> > > > > > > +            (rev != 1 && rev != 3 && rev != 5)) {
> > > > > > > +            error_setg(errp, "Unsupported FADT revision %s, "
> > > > > > > +                       "please specify 1,3,5", val);
> > > > > > > +            return;
> > > > > > > +        }
> > > > > > > +        acpi_fadt_rev = rev;
> > > > > > > +        return;
> > > > > > > +    }
> > > > > > > +
> > > > > > > +    error_setg(errp, "'-acpitable' requires one of 'data','file' or
> > 'fadt'");
> > > > > > >  }
> > > > > > >
> > > > > > >  static bool acpi_table_builtin = false;
> > > > > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > > > > index ce7cbc5..8be6578 100644
> > > > > > > --- a/hw/i386/acpi-build.c
> > > > > > > +++ b/hw/i386/acpi-build.c
> > > > > > > @@ -276,8 +276,22 @@ build_facs(GArray *table_data,
> > BIOSLinker
> > > > > > *linker)
> > > > > > >      facs->length = cpu_to_le32(sizeof(*facs));
> > > > > > >  }
> > > > > > >
> > > > > > > +/* GAS */
> > > > > > > +static void
> > > > > > > +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> > > > > > > +          uint8_t bit_width, uint8_t bit_offset,
> > > > > > > +          uint8_t access_width, uint64_t address)
> > > > > > > +{
> > > > > > > +    gas->space_id = space_id;
> > > > > > > +    gas->bit_width = bit_width;
> > > > > > > +    gas->bit_offset = bit_offset;
> > > > > > > +    gas->access_width = access_width;
> > > > > > > +    gas->address = address;
> > > > > > > +}
> > > > > > > +
> > > > > > >  /* Load chipset information in FADT */
> > > > > > > -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt,
> > AcpiPmInfo
> > > > *pm)
> > > > > > > +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt,
> > AcpiPmInfo
> > > > > > *pm,
> > > > > > > +                       uint8_t revision)
> > > > > > >  {
> > > > > > >      fadt->model = 1;
> > > > > > >      fadt->reserved1 = 0;
> > > > > > > @@ -309,6 +323,25 @@ static void
> > > > fadt_setup(AcpiFadtDescriptorRev1
> > > > > > *fadt, AcpiPmInfo *pm)
> > > > > > >          fadt->flags |= cpu_to_le32(1 <<
> > > > > > ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
> > > > > > >      }
> > > > > > >      fadt->century = RTC_CENTURY;
> > > > > > > +
> > > > > > > +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> > > > > > > +    if (revision >= 3) {
> > > > > > > +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> > > > > > > +        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
> > > > > > > +                  32, 0, 0, cpu_to_le64(pm->io_base));
> > > > > > > +        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
> > > > > > > +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> > > > > > > +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> > > > > > > +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> > > > > > > +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> > > > > > > +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm-
> > > > >gpe0_blk));
> > > > > > > +    }
> > > > > > > +
> > > > > > > +    /* Build dummy ACPI 5.0 fields */
> > > > > > > +    if (revision >= 5) {
> > > > > > > +        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY,
> > 0, 0,
> > > > 0,
> > > > > > 0);
> > > > > > > +        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0,
> > 0,
> > > > 0, 0);
> > > > > > > +    }
> > > > > > >  }
> > > > > > >
> > > > > > >
> > > > > > > @@ -316,11 +349,21 @@ static void
> > > > > > fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> > > > > > >  static void
> > > > > > >  build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo
> > *pm,
> > > > > > >             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> > > > > > > -           const char *oem_id, const char *oem_table_id)
> > > > > > > +           const char *oem_id, const char *oem_table_id, uint8_t
> > > > revision)
> > > > > > >  {
> > > > > > > -    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data,
> > > > > > sizeof(*fadt));
> > > > > > > -    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl -
> > > > table_data-
> > > > > > >data;
> > > > > > > -    unsigned dsdt_entry_offset = (char *)&fadt->dsdt -
> > table_data-
> > > > >data;
> > > > > > > +    AcpiFadtDescriptorRev5_1 *fadt;
> > > > > > > +    unsigned fw_ctrl_offset;
> > > > > > > +    unsigned dsdt_entry_offset;
> > > > > > > +    unsigned fadt_len;
> > > > > > > +
> > > > > > > +    if (revision == 1) {
> > > > > > > +        fadt_len = sizeof(AcpiFadtDescriptorRev1);
> > > > > > > +    } else {
> > > > > > > +        fadt_len = sizeof(AcpiFadtDescriptorRev5_1);
> > > > > > > +    }
> > > > > > > +    fadt = acpi_data_push(table_data, fadt_len);
> > > > > > > +    fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data-
> > >data;
> > > > > > > +    dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> > > > > > >
> > > > > > >      /* FACS address to be filled by Guest linker */
> > > > > > >      bios_linker_loader_add_pointer(linker,
> > > > > > > @@ -328,13 +371,28 @@ build_fadt(GArray *table_data,
> > > > BIOSLinker
> > > > > > *linker, AcpiPmInfo *pm,
> > > > > > >          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > > > > >
> > > > > > >      /* DSDT address to be filled by Guest linker */
> > > > > > > -    fadt_setup(fadt, pm);
> > > > > > >      bios_linker_loader_add_pointer(linker,
> > > > > > >          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt-
> > >dsdt),
> > > > > > >          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > > > > >
> > > > > > > -    build_header(linker, table_data,
> > > > > > > -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id,
> > > > oem_table_id);
> > > > > > > +    if (revision > 2) {
> > > > > > > +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
> > > > > > > +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data-
> > >data;
> > > > > > > +
> > > > > > > +        /* FACS address to be filled by Guest linker */
> > > > > > > +        bios_linker_loader_add_pointer(linker,
> > > > > > > +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt-
> > >Xfacs),
> > > > > > > +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > > > > > +
> > > > > > > +        /* DSDT address to be filled by Guest linker */
> > > > > > > +        bios_linker_loader_add_pointer(linker,
> > > > > > > +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt-
> > > > >Xdsdt),
> > > > > > > +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > > > > > +    }
> > > > > > > +
> > > > > > > +    fadt_setup(fadt, pm, revision);
> > > > > > > +    build_header(linker, table_data, (void *)fadt, "FACP", fadt_len,
> > > > > > > +                 revision, oem_id, oem_table_id);
> > > > > > >  }
> > > > > > >
> > > > > > >  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> > > > > > > @@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables
> > *tables,
> > > > > > MachineState *machine)
> > > > > > >      fadt = tables_blob->len;
> > > > > > >      acpi_add_table(table_offsets, tables_blob);
> > > > > > >      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> > > > > > > -               slic_oem.id, slic_oem.table_id);
> > > > > > > +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
> > > > > > >      aml_len += tables_blob->len - fadt;
> > > > > > >
> > > > > > >      acpi_add_table(table_offsets, tables_blob);
> > > > > > > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > > > > > > index 7b3d93c..63df38d 100644
> > > > > > > --- a/include/hw/acpi/acpi.h
> > > > > > > +++ b/include/hw/acpi/acpi.h
> > > > > > > @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS
> > *acpi_regs,
> > > > > > qemu_irq irq);
> > > > > > >
> > > > > > >  /* acpi.c */
> > > > > > >  extern int acpi_enabled;
> > > > > > > +extern uint8_t acpi_fadt_rev;
> > > > > > >  extern char unsigned *acpi_tables;
> > > > > > >  extern size_t acpi_tables_len;
> > > > > > >
> > > > > > > diff --git a/qemu-options.hx b/qemu-options.hx
> > > > > > > index 5fe7f87..d61dd92 100644
> > > > > > > --- a/qemu-options.hx
> > > > > > > +++ b/qemu-options.hx
> > > > > > > @@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG,
> > > > > > QEMU_OPTION_acpitable,
> > > > > > >      "             [,sig=str][,rev=n]\n"
> > > > > > >      "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
> > > > > > >      "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
> > > > > > > -    "                ACPI table description\n", QEMU_ARCH_I386)
> > > > > > > +    "                ACPI table description\n"
> > > > > > > +    "-acpitable fadt=n\n"
> > > > > > > +    "                Configure FADT revision\n",
> > > > > > > +    QEMU_ARCH_I386)
> > > > > > >  STEXI
> > > > > > >  @item -acpitable
> > > > > >
> > > >
> > data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@
> > > > > > var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}]
> > > > > > [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
> > > > > > >  @findex -acpitable
> > > > > > > @@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU,
> > then
> > > > the
> > > > > > SLIC's oem_id and oem_table_id
> > > > > > >  fields will override the same in the RSDT and the FADT (a.k.a.
> > FACP),
> > > > in
> > > > > > order
> > > > > > >  to ensure the field matches required by the Microsoft SLIC spec
> > and
> > > > the
> > > > > > ACPI
> > > > > > >  spec.
> > > > > > > +
> > > > > > > +@item -acpitable fadt=@var{n}
> > > > > > > +Configure FADT revision to 1, 3, 5, default 1.
> > > > > > >  ETEXI
> > > > > > >
> > > > > > >  DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-15  2:23                 ` Michael S. Tsirkin
@ 2016-08-15  3:18                   ` Zheng, Lv
  0 siblings, 0 replies; 32+ messages in thread
From: Zheng, Lv @ 2016-08-15  3:18 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Igor Mammedov, Paolo Bonzini, Peter Crosthwaite,
	Richard Henderson, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm

Hi, Michael

> From: Michael S. Tsirkin [mailto:mst@redhat.com]
> Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> revision changes
> 
> On Mon, Aug 15, 2016 at 02:18:55AM +0000, Zheng, Lv wrote:
> > Hi,
> >
> > > From: Michael S. Tsirkin [mailto:mst@redhat.com]
> > > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> > > revision changes
> > >
> > > On Mon, Aug 15, 2016 at 01:33:41AM +0000, Zheng, Lv wrote:
> > > > Hi,
> > > >
> > > > > From: Michael S. Tsirkin [mailto:mst@redhat.com]
> > > > > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow
> FADT
> > > > > revision changes
> > > > >
> > > > > On Fri, Aug 12, 2016 at 12:47:04AM +0000, Zheng, Lv wrote:
> > > > > > Hi, Igor
> > > > > >
> > > > > > Thanks for the review.
> > > > > >
> > > > > > > From: Igor Mammedov [mailto:imammedo@redhat.com]
> > > > > > > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow
> > > FADT
> > > > > > > revision changes
> > > > > > >
> > > > > > > On Thu, 11 Aug 2016 17:36:45 +0800
> > > > > > > Lv Zheng <lv.zheng@intel.com> wrote:
> > > > > > >
> > > > > > > > This patch allows FADT to be built with different revisions.
> When
> > > the
> > > > > > > revision
> > > > > > > > is greater than 1.0, 64-bit address fields may also be filled.
> > > > > > > >
> > > > > > > > Note that FADT revision 2 has never been defined by the ACPI
> > > > > > > specification. So
> > > > > > > > this patch only adds an option -acpitable fadt= to allow
> revision
> > > 1,3,5
> > > > > to
> > > > > > > be
> > > > > > > > configured by the users.
> > > > > > > >
> > > > > > > > 1. Tested by booting a linux image, the 64-bit addresses are
> > > correctly
> > > > > > > filled
> > > > > > > >    in the dumped FADT.
> > > > > > > > 2. Tested by booting a Windows image, no boot failure can be
> > > seen.
> > > > > > >
> > > > > > > series still doesn't say why do you need 64-bit addresses in
> FADT,
> > > > > > > current Seabios/OVMF allocates tables below 4Gb and gpe/pm
> > > > > > > register blocks are below 4gb as well so there is no point in
> > > > > > > accepting theses patches and adding extra CLI options as these
> > > > > > > patches do.
> > > > > > [Lv Zheng]
> > > > > > This patch is used by us to probe Windows FADT behavior.
> > > > > > Current known behavior includes:
> > > > > > 1. On x86, Windows requires BIOS to have 2 FADTs, 1 is in RSDT,
> and
> > > > > probably is a v1 table, the other is in XSDT, and probably is a v3+
> table.
> > > > >
> > > > > What does "requires" mean here? It seems to work fine without.
> > > >
> > > > Let me reword:
> > > > Windows requires BIOS to provide 2 FADTs when both RSDT and
> XSDT
> > > are provided.
> > >
> > > That's good to know, thanks.
> > > Do you see a reason to have both at the moment?
> >
> > If qemu always uses RSDT, then all Windows clones should support such
> an old BIOS because all Windows clones are backward compatible.
> >
> > But, ACPI 2.0+/5.0+ introduced new features, (for example, reduced
> hardware model).
> > My investigation result shows if an FADT is provided via RSDT, windows
> will ignore some of its fields.
> > So if qemu starts to support new features, then qemu may need to
> provide both RSDT and XSDT.
> > As a result, qemu may need to provide 2 FADTs.
> >
> > However, there is no real ACPI 2.0+ support in qemu/x86 code.
> > So this feature (having a version parameter for FADT setup) is just a
> good-to-have feature.
> > With which, developers may start to introduce some ACPI 2.0+ features.
> >
> > Thanks
> > Lv
> 
> Right. Let's include this when we actually need some of the
> features that require an XSDT.

OK.
I should:
1. remove -acpitable fadt option since it is only for the purpose of probing Windows behavior;
2. do not increase FADT version since currently there is no XSDT in qemu/x86.

> 
> Pls note that OVMF currently won't do the right thing
> if you have both an RSDT and an XSDT: it will try to
> install two copies of all tables.
> If you are interested in this, please take a look at
> the OVMF code and fix it up.

Good to know this.
I'll try when I have bandwidth.

Thanks and best regards
Lv

> 
> > >
> > > > >
> > > > > > 2. v2 FADT never exists in the spec, it is used in very early years,
> by
> > > IA64
> > > > > prototype machines.
> > > > > > 3. If the FADT in RSDT takes effective, then Windows actually
> ignores
> > > 64-
> > > > > bit GAS fields, but uses 32-bit register fields.
> > > > > > But there are still many uncertainties:
> > > > > > 1. What if the FADT in XSDT takes effective?
> > > > > > 2. What's the behavior on IA64/ARM platforms?
> > > > > > If we could have an option here, we could continue the probing
> work,
> > > > > trying every combination.
> > > > > >
> > > > > > Thus the original purpose of this commit is - probing de-facto
> > > standard
> > > > > behavior.
> > > > >
> > > > > Nice, but why do we need PATCH 2 upstream? Is it hard for you to
> > > > > maintain
> > > > > out of tree?
> > > >
> > > > Not hard.
> > > > I just may encounter problems if I want to put a document in Linux
> > > kernel related to FADT support and Windows behavior proofs.
> > > > I'll remove this option.
> > > >
> > > > >
> > > > > > >
> > > > > > > If we'd ever need to bump FADT revision, I'd first try to increase
> it
> > > > > > > unconditionally and test/see if it would not upset legacy guests
> > > > > > > Windows starting from XP, RHEL4/5/6
> > > > > > > If it works then these patches are not necessary,
> > > > > > > (this approach worked  just fine for bumping up DSDT revision
> to 2
> > > > > > > it would be possible to use 64-bit math in ASL/AML).
> > > > > > >
> > > > > > > if it doesn't, I still won't do it this way but rather:
> > > > > > >  - make new revision used by default
> > > > > > >  - add compat property to piix4_pm/ich9-lpc to force legacy
> > > revision
> > > > > > >  - turn on legacy revision for old machine types using added
> above
> > > > > > > property
> > > > > > >
> > > > > > > That way we won't regress existing setups as old machines will
> stay
> > > > > > > the same and only new machine types will be affected. And
> users
> > > that
> > > > > > > actually want to play with legacy revision on new machine
> types
> > > could
> > > > > > > force it by using above property.
> > > > > > >
> > > > > > [Lv Zheng]
> > > > > > But it seems the code in this commit contains useful stuffs for
> qemu.
> > > > > >
> > > > > > As I said previously, it seems Windows requires 2 FADTs.
> > > > > > So having a revision parameter for build_fadt() seems to be
> > > necessary.
> > > > > > Because if qemu wants to increase FADT revision, qemu may do
> this
> > > in
> > > > > this way:
> > > > > > 1. Invoke build_fadt() with revision 1, and put it into RSDT;
> > > > > > 2. Invoke build_fadt() with latest revision, and put it into XSDT.
> > > > > > Also we know latest revision FADT is useful, it contains reduced
> > > > > hardware support.
> > > > > > And some of new ACPI features rely this model.
> > > > > >
> > > > > > So I'm sure that this commit contains useful stuffs for qemu to
> do
> > > future
> > > > > extension.
> > > > > >
> > > > > > But I don't know if you want to keep the new -acpitable fadt=
> option.
> > > > > > Let me ask:
> > > > > > 1. Are there any issues in PATCH 01? Maybe my understanding of
> > > qemu
> > > > > option code is not correct.
> > > > >
> > > > > Didn't review yet, I'll let Igor review first.
> > > > >
> > > > > > 2. IMO, this option should be useful for a long period because we
> > > need it
> > > > > to help probing Windows behavior, so can we have it upstreamed?
> > > > >
> > > > > ATM PATCH 2 does not seem generally useful.
> > > >
> > > > OK. I see.
> > > >
> > > > Thanks
> > > > Lv
> > > >
> > > > >
> > > > > >
> > > > > > Best regards
> > > > > > Lv
> > > > > >
> > > > > > > >
> > > > > > > > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > > > > > > > ---
> > > > > > > >  hw/acpi/core.c         |   20 ++++++++++++-
> > > > > > > >  hw/i386/acpi-build.c   |   76
> > > > > > > ++++++++++++++++++++++++++++++++++++++++++------
> > > > > > > >  include/hw/acpi/acpi.h |    1 +
> > > > > > > >  qemu-options.hx        |    8 ++++-
> > > > > > > >  4 files changed, 94 insertions(+), 11 deletions(-)
> > > > > > > >
> > > > > > > > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > > > > > > > index 85e0e94..832c86b 100644
> > > > > > > > --- a/hw/acpi/core.c
> > > > > > > > +++ b/hw/acpi/core.c
> > > > > > > > @@ -19,6 +19,7 @@
> > > > > > > >   * GNU GPL, version 2 or (at your option) any later version.
> > > > > > > >   */
> > > > > > > >  #include "qemu/osdep.h"
> > > > > > > > +#include "qemu/cutils.h"
> > > > > > > >  #include "sysemu/sysemu.h"
> > > > > > > >  #include "hw/hw.h"
> > > > > > > >  #include "hw/i386/pc.h"
> > > > > > > > @@ -54,6 +55,7 @@ static const char unsigned
> > > > > > > dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
> > > > > > > >
> > > > > > > >  char unsigned *acpi_tables;
> > > > > > > >  size_t acpi_tables_len;
> > > > > > > > +uint8_t acpi_fadt_rev = 1;
> > > > > > > >
> > > > > > > >  static QemuOptsList qemu_acpi_opts = {
> > > > > > > >      .name = "acpi",
> > > > > > > > @@ -312,7 +314,23 @@ void acpi_table_add(const
> QemuOpts
> > > > > *opts,
> > > > > > > Error **errp)
> > > > > > > >          return;
> > > > > > > >      }
> > > > > > > >
> > > > > > > > -    error_setg(errp, "'-acpitable' requires one of 'data' or
> 'file'");
> > > > > > > > +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
> > > > > > > > +    if (val) {
> > > > > > > > +        unsigned long rev;
> > > > > > > > +        int err;
> > > > > > > > +
> > > > > > > > +        err = qemu_strtoul(val, NULL, 10, &rev);
> > > > > > > > +        if (err ||
> > > > > > > > +            (rev != 1 && rev != 3 && rev != 5)) {
> > > > > > > > +            error_setg(errp, "Unsupported FADT revision %s, "
> > > > > > > > +                       "please specify 1,3,5", val);
> > > > > > > > +            return;
> > > > > > > > +        }
> > > > > > > > +        acpi_fadt_rev = rev;
> > > > > > > > +        return;
> > > > > > > > +    }
> > > > > > > > +
> > > > > > > > +    error_setg(errp, "'-acpitable' requires one of 'data','file' or
> > > 'fadt'");
> > > > > > > >  }
> > > > > > > >
> > > > > > > >  static bool acpi_table_builtin = false;
> > > > > > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > > > > > index ce7cbc5..8be6578 100644
> > > > > > > > --- a/hw/i386/acpi-build.c
> > > > > > > > +++ b/hw/i386/acpi-build.c
> > > > > > > > @@ -276,8 +276,22 @@ build_facs(GArray *table_data,
> > > BIOSLinker
> > > > > > > *linker)
> > > > > > > >      facs->length = cpu_to_le32(sizeof(*facs));
> > > > > > > >  }
> > > > > > > >
> > > > > > > > +/* GAS */
> > > > > > > > +static void
> > > > > > > > +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> > > > > > > > +          uint8_t bit_width, uint8_t bit_offset,
> > > > > > > > +          uint8_t access_width, uint64_t address)
> > > > > > > > +{
> > > > > > > > +    gas->space_id = space_id;
> > > > > > > > +    gas->bit_width = bit_width;
> > > > > > > > +    gas->bit_offset = bit_offset;
> > > > > > > > +    gas->access_width = access_width;
> > > > > > > > +    gas->address = address;
> > > > > > > > +}
> > > > > > > > +
> > > > > > > >  /* Load chipset information in FADT */
> > > > > > > > -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt,
> > > AcpiPmInfo
> > > > > *pm)
> > > > > > > > +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt,
> > > AcpiPmInfo
> > > > > > > *pm,
> > > > > > > > +                       uint8_t revision)
> > > > > > > >  {
> > > > > > > >      fadt->model = 1;
> > > > > > > >      fadt->reserved1 = 0;
> > > > > > > > @@ -309,6 +323,25 @@ static void
> > > > > fadt_setup(AcpiFadtDescriptorRev1
> > > > > > > *fadt, AcpiPmInfo *pm)
> > > > > > > >          fadt->flags |= cpu_to_le32(1 <<
> > > > > > > ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
> > > > > > > >      }
> > > > > > > >      fadt->century = RTC_CENTURY;
> > > > > > > > +
> > > > > > > > +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> > > > > > > > +    if (revision >= 3) {
> > > > > > > > +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> > > > > > > > +        build_gas(&fadt->xpm1a_event_block,
> AML_SYSTEM_IO,
> > > > > > > > +                  32, 0, 0, cpu_to_le64(pm->io_base));
> > > > > > > > +        build_gas(&fadt->xpm1a_control_block,
> AML_SYSTEM_IO,
> > > > > > > > +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> > > > > > > > +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> > > > > > > > +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> > > > > > > > +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> > > > > > > > +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm-
> > > > > >gpe0_blk));
> > > > > > > > +    }
> > > > > > > > +
> > > > > > > > +    /* Build dummy ACPI 5.0 fields */
> > > > > > > > +    if (revision >= 5) {
> > > > > > > > +        build_gas(&fadt->sleep_control,
> AML_SYSTEM_MEMORY,
> > > 0, 0,
> > > > > 0,
> > > > > > > 0);
> > > > > > > > +        build_gas(&fadt->sleep_status,
> AML_SYSTEM_MEMORY, 0,
> > > 0,
> > > > > 0, 0);
> > > > > > > > +    }
> > > > > > > >  }
> > > > > > > >
> > > > > > > >
> > > > > > > > @@ -316,11 +349,21 @@ static void
> > > > > > > fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> > > > > > > >  static void
> > > > > > > >  build_fadt(GArray *table_data, BIOSLinker *linker,
> AcpiPmInfo
> > > *pm,
> > > > > > > >             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> > > > > > > > -           const char *oem_id, const char *oem_table_id)
> > > > > > > > +           const char *oem_id, const char *oem_table_id,
> uint8_t
> > > > > revision)
> > > > > > > >  {
> > > > > > > > -    AcpiFadtDescriptorRev1 *fadt =
> acpi_data_push(table_data,
> > > > > > > sizeof(*fadt));
> > > > > > > > -    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl -
> > > > > table_data-
> > > > > > > >data;
> > > > > > > > -    unsigned dsdt_entry_offset = (char *)&fadt->dsdt -
> > > table_data-
> > > > > >data;
> > > > > > > > +    AcpiFadtDescriptorRev5_1 *fadt;
> > > > > > > > +    unsigned fw_ctrl_offset;
> > > > > > > > +    unsigned dsdt_entry_offset;
> > > > > > > > +    unsigned fadt_len;
> > > > > > > > +
> > > > > > > > +    if (revision == 1) {
> > > > > > > > +        fadt_len = sizeof(AcpiFadtDescriptorRev1);
> > > > > > > > +    } else {
> > > > > > > > +        fadt_len = sizeof(AcpiFadtDescriptorRev5_1);
> > > > > > > > +    }
> > > > > > > > +    fadt = acpi_data_push(table_data, fadt_len);
> > > > > > > > +    fw_ctrl_offset = (char *)&fadt->firmware_ctrl -
> table_data-
> > > >data;
> > > > > > > > +    dsdt_entry_offset = (char *)&fadt->dsdt - table_data-
> >data;
> > > > > > > >
> > > > > > > >      /* FACS address to be filled by Guest linker */
> > > > > > > >      bios_linker_loader_add_pointer(linker,
> > > > > > > > @@ -328,13 +371,28 @@ build_fadt(GArray *table_data,
> > > > > BIOSLinker
> > > > > > > *linker, AcpiPmInfo *pm,
> > > > > > > >          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > > > > > >
> > > > > > > >      /* DSDT address to be filled by Guest linker */
> > > > > > > > -    fadt_setup(fadt, pm);
> > > > > > > >      bios_linker_loader_add_pointer(linker,
> > > > > > > >          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt-
> > > >dsdt),
> > > > > > > >          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > > > > > >
> > > > > > > > -    build_header(linker, table_data,
> > > > > > > > -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id,
> > > > > oem_table_id);
> > > > > > > > +    if (revision > 2) {
> > > > > > > > +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data-
> >data;
> > > > > > > > +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data-
> > > >data;
> > > > > > > > +
> > > > > > > > +        /* FACS address to be filled by Guest linker */
> > > > > > > > +        bios_linker_loader_add_pointer(linker,
> > > > > > > > +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt-
> > > >Xfacs),
> > > > > > > > +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > > > > > > +
> > > > > > > > +        /* DSDT address to be filled by Guest linker */
> > > > > > > > +        bios_linker_loader_add_pointer(linker,
> > > > > > > > +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset,
> sizeof(fadt-
> > > > > >Xdsdt),
> > > > > > > > +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > > > > > > +    }
> > > > > > > > +
> > > > > > > > +    fadt_setup(fadt, pm, revision);
> > > > > > > > +    build_header(linker, table_data, (void *)fadt, "FACP",
> fadt_len,
> > > > > > > > +                 revision, oem_id, oem_table_id);
> > > > > > > >  }
> > > > > > > >
> > > > > > > >  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> > > > > > > > @@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables
> > > *tables,
> > > > > > > MachineState *machine)
> > > > > > > >      fadt = tables_blob->len;
> > > > > > > >      acpi_add_table(table_offsets, tables_blob);
> > > > > > > >      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> > > > > > > > -               slic_oem.id, slic_oem.table_id);
> > > > > > > > +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
> > > > > > > >      aml_len += tables_blob->len - fadt;
> > > > > > > >
> > > > > > > >      acpi_add_table(table_offsets, tables_blob);
> > > > > > > > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > > > > > > > index 7b3d93c..63df38d 100644
> > > > > > > > --- a/include/hw/acpi/acpi.h
> > > > > > > > +++ b/include/hw/acpi/acpi.h
> > > > > > > > @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS
> > > *acpi_regs,
> > > > > > > qemu_irq irq);
> > > > > > > >
> > > > > > > >  /* acpi.c */
> > > > > > > >  extern int acpi_enabled;
> > > > > > > > +extern uint8_t acpi_fadt_rev;
> > > > > > > >  extern char unsigned *acpi_tables;
> > > > > > > >  extern size_t acpi_tables_len;
> > > > > > > >
> > > > > > > > diff --git a/qemu-options.hx b/qemu-options.hx
> > > > > > > > index 5fe7f87..d61dd92 100644
> > > > > > > > --- a/qemu-options.hx
> > > > > > > > +++ b/qemu-options.hx
> > > > > > > > @@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG,
> > > > > > > QEMU_OPTION_acpitable,
> > > > > > > >      "             [,sig=str][,rev=n]\n"
> > > > > > > >      "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
> > > > > > > >      "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
> > > > > > > > -    "                ACPI table description\n", QEMU_ARCH_I386)
> > > > > > > > +    "                ACPI table description\n"
> > > > > > > > +    "-acpitable fadt=n\n"
> > > > > > > > +    "                Configure FADT revision\n",
> > > > > > > > +    QEMU_ARCH_I386)
> > > > > > > >  STEXI
> > > > > > > >  @item -acpitable
> > > > > > >
> > > > >
> > >
> data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@
> > > > > > > var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}]
> > > > > > > [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
> > > > > > > >  @findex -acpitable
> > > > > > > > @@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU,
> > > then
> > > > > the
> > > > > > > SLIC's oem_id and oem_table_id
> > > > > > > >  fields will override the same in the RSDT and the FADT (a.k.a.
> > > FACP),
> > > > > in
> > > > > > > order
> > > > > > > >  to ensure the field matches required by the Microsoft SLIC
> spec
> > > and
> > > > > the
> > > > > > > ACPI
> > > > > > > >  spec.
> > > > > > > > +
> > > > > > > > +@item -acpitable fadt=@var{n}
> > > > > > > > +Configure FADT revision to 1, 3, 5, default 1.
> > > > > > > >  ETEXI
> > > > > > > >
> > > > > > > >  DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-12 14:55         ` Igor Mammedov
@ 2016-08-15  4:18           ` Zheng, Lv
  0 siblings, 0 replies; 32+ messages in thread
From: Zheng, Lv @ 2016-08-15  4:18 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm

Hi, Igor

> From: Igor Mammedov [mailto:imammedo@redhat.com]
> Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> revision changes
> 
> On Fri, 12 Aug 2016 00:47:04 +0000
> "Zheng, Lv" <lv.zheng@intel.com> wrote:
> 
> > Hi, Igor
> >
> > Thanks for the review.
> >
> > > From: Igor Mammedov [mailto:imammedo@redhat.com]
> > > Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
> > > revision changes
> > >
> > > On Thu, 11 Aug 2016 17:36:45 +0800
> > > Lv Zheng <lv.zheng@intel.com> wrote:
> > >
> > > > This patch allows FADT to be built with different revisions. When the
> > > revision
> > > > is greater than 1.0, 64-bit address fields may also be filled.
> > > >
> > > > Note that FADT revision 2 has never been defined by the ACPI
> > > specification. So
> > > > this patch only adds an option -acpitable fadt= to allow revision 1,3,5
> to
> > > be
> > > > configured by the users.
> > > >
> > > > 1. Tested by booting a linux image, the 64-bit addresses are correctly
> > > filled
> > > >    in the dumped FADT.
> > > > 2. Tested by booting a Windows image, no boot failure can be seen.
> > >
> > > series still doesn't say why do you need 64-bit addresses in FADT,
> > > current Seabios/OVMF allocates tables below 4Gb and gpe/pm
> > > register blocks are below 4gb as well so there is no point in
> > > accepting theses patches and adding extra CLI options as these
> > > patches do.
> > [Lv Zheng]
> > This patch is used by us to probe Windows FADT behavior.
> > Current known behavior includes:
> > 1. On x86, Windows requires BIOS to have 2 FADTs, 1 is in RSDT, and
> probably is a v1 table, the other is in XSDT, and probably is a v3+ table.
> RDST is not limited to rev 1 only
> it can as easily reference v2/3/4/5/6 tables
> differences between RSDT and XSDT is that the former is able to point
> to tables located below 4G only.

I tried v3 FADT using RSDT.
Windows can boot with a v3 table where both v1/v3 fields are filled.
But if I remove v1 compatible fields but leave v3 compatible fields in this FADT, Windows cannot boot.

So it looks there can be possible restrictions related to FADT.

> 
> > 2. v2 FADT never exists in the spec, it is used in very early years, by IA64
> prototype machines.
> > 3. If the FADT in RSDT takes effective, then Windows actually ignores 64-
> bit GAS fields, but uses 32-bit register fields.
> > But there are still many uncertainties:
> > 1. What if the FADT in XSDT takes effective?
> ACPI 6.0 spec says:
> "An ACPI-compatible OS must use the XSDT if present."
> hence XSDT referenced FADT must be used, but that's Windows
> so I won't bet that it actually does what spec mandates.

I'm trying to enable XSDT in qemu to investigate this.

> 
> > 2. What's the behavior on IA64/ARM platforms?
> For ARM virt machine, QEMU currently provides ACPI 5.1 variant of FADT.

OK.

> 
> > If we could have an option here, we could continue the probing work,
> trying every combination.
> >
> > Thus the original purpose of this commit is - probing de-facto standard
> behavior.
> What I'd suggest is try to bump up revision unconditionally to 5.1 (same as
> ARM)
> so it would provide 64-bit fields although not really used by QEMU
> and upstream it (provided it won't break anything).

OK.


> 
> As for probing part with 64-bit fields actually used,
> I'd keep it out of tree as it doesn't make sense for upstream
> QEMU to have it since all addresses are below 4Gb and it's not
> going to change to keep compatibility with legacy OSes.
> 
> That would keep out of tree bits minimal and at the same time
> reduce maintenance headache on QEMU side since it won't have
> to maintain extra -acpitable option forever.

OK.

> 
> >
> > >
> > > If we'd ever need to bump FADT revision, I'd first try to increase it
> > > unconditionally and test/see if it would not upset legacy guests
> > > Windows starting from XP, RHEL4/5/6
> > > If it works then these patches are not necessary,
> > > (this approach worked  just fine for bumping up DSDT revision to 2
> > > it would be possible to use 64-bit math in ASL/AML).
> > >
> > > if it doesn't, I still won't do it this way but rather:
> > >  - make new revision used by default
> > >  - add compat property to piix4_pm/ich9-lpc to force legacy revision
> > >  - turn on legacy revision for old machine types using added above
> > > property
> > >
> > > That way we won't regress existing setups as old machines will stay
> > > the same and only new machine types will be affected. And users that
> > > actually want to play with legacy revision on new machine types could
> > > force it by using above property.
> > >
> > [Lv Zheng]
> > But it seems the code in this commit contains useful stuffs for qemu.
> >
> > As I said previously, it seems Windows requires 2 FADTs.
> Windows boots just fine with 1 FADT so far.
> 
> I wonder, what Windows version does require 2 FADTs?

No, it's my bad wording.
Windows requires 2 FADTs when XSDT is provided.
My guess is XSDT has been supported since Windows Vista.

> 
> > So having a revision parameter for build_fadt() seems to be necessary.
> > Because if qemu wants to increase FADT revision, qemu may do this in
> this way:
> > 1. Invoke build_fadt() with revision 1, and put it into RSDT;
> > 2. Invoke build_fadt() with latest revision, and put it into XSDT.
> > Also we know latest revision FADT is useful, it contains reduced
> hardware support.
> > And some of new ACPI features rely this model.
> providing revision number is not enough, each revision might have
> its own FADT structure, and it would be a bunch of code to maintain
> only to play and see if Windows is happy about it.
> I'd keep that out of tree.

OK.

> 
> > So I'm sure that this commit contains useful stuffs for qemu to do future
> extension.
> >
> > But I don't know if you want to keep the new -acpitable fadt= option.
> > Let me ask:
> > 1. Are there any issues in PATCH 01? Maybe my understanding of qemu
> option code is not correct.
> I'd not touch -acpitable as you did even for out of tree code
> but instead add property to piix4_pm/ich9-lpc that would enable
> testing bits you need, for example "enable_64bit_gpe" then
> you could easily switch it on for tests by doing following:
> 
>  $QEMU -global piix4_pm.enable_64bit_gpe=on ...
> 
> grep for "disable_s3" option and see how it's used/implemented.
> 
> That way you won't risk breaking -acpitable CLI option behavior
> and keep experiment bits relatively isolated (easier to rebase)
> and it would be easier to upstream some if they make sense for
> general usage.

OK.
Sounds good.

> 
> You also might want to look at the work Michael have done wrt XSDT[1]
> when we played with initial implementation of ACPI bits for ARM
> but in the end we've picked RSDT there as well.
> 
> 1) just google for "qemu-devel XSDT"

Good to know, I may also need this to do my FADT investigations.

Thanks and best regards
Lv

> 
> > 2. IMO, this option should be useful for a long period because we need it
> to help probing Windows behavior, so can we have it upstreamed?
> >
> > Best regards
> > Lv
> >
> > > >
> > > > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > > > ---
> > > >  hw/acpi/core.c         |   20 ++++++++++++-
> > > >  hw/i386/acpi-build.c   |   76
> > > ++++++++++++++++++++++++++++++++++++++++++------
> > > >  include/hw/acpi/acpi.h |    1 +
> > > >  qemu-options.hx        |    8 ++++-
> > > >  4 files changed, 94 insertions(+), 11 deletions(-)
> > > >
> > > > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > > > index 85e0e94..832c86b 100644
> > > > --- a/hw/acpi/core.c
> > > > +++ b/hw/acpi/core.c
> > > > @@ -19,6 +19,7 @@
> > > >   * GNU GPL, version 2 or (at your option) any later version.
> > > >   */
> > > >  #include "qemu/osdep.h"
> > > > +#include "qemu/cutils.h"
> > > >  #include "sysemu/sysemu.h"
> > > >  #include "hw/hw.h"
> > > >  #include "hw/i386/pc.h"
> > > > @@ -54,6 +55,7 @@ static const char unsigned
> > > dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
> > > >
> > > >  char unsigned *acpi_tables;
> > > >  size_t acpi_tables_len;
> > > > +uint8_t acpi_fadt_rev = 1;
> > > >
> > > >  static QemuOptsList qemu_acpi_opts = {
> > > >      .name = "acpi",
> > > > @@ -312,7 +314,23 @@ void acpi_table_add(const QemuOpts
> *opts,
> > > Error **errp)
> > > >          return;
> > > >      }
> > > >
> > > > -    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> > > > +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
> > > > +    if (val) {
> > > > +        unsigned long rev;
> > > > +        int err;
> > > > +
> > > > +        err = qemu_strtoul(val, NULL, 10, &rev);
> > > > +        if (err ||
> > > > +            (rev != 1 && rev != 3 && rev != 5)) {
> > > > +            error_setg(errp, "Unsupported FADT revision %s, "
> > > > +                       "please specify 1,3,5", val);
> > > > +            return;
> > > > +        }
> > > > +        acpi_fadt_rev = rev;
> > > > +        return;
> > > > +    }
> > > > +
> > > > +    error_setg(errp, "'-acpitable' requires one of 'data','file' or 'fadt'");
> > > >  }
> > > >
> > > >  static bool acpi_table_builtin = false;
> > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > index ce7cbc5..8be6578 100644
> > > > --- a/hw/i386/acpi-build.c
> > > > +++ b/hw/i386/acpi-build.c
> > > > @@ -276,8 +276,22 @@ build_facs(GArray *table_data, BIOSLinker
> > > *linker)
> > > >      facs->length = cpu_to_le32(sizeof(*facs));
> > > >  }
> > > >
> > > > +/* GAS */
> > > > +static void
> > > > +build_gas(struct AcpiGenericAddress *gas, uint8_t space_id,
> > > > +          uint8_t bit_width, uint8_t bit_offset,
> > > > +          uint8_t access_width, uint64_t address)
> > > > +{
> > > > +    gas->space_id = space_id;
> > > > +    gas->bit_width = bit_width;
> > > > +    gas->bit_offset = bit_offset;
> > > > +    gas->access_width = access_width;
> > > > +    gas->address = address;
> > > > +}
> > > > +
> > > >  /* Load chipset information in FADT */
> > > > -static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo
> *pm)
> > > > +static void fadt_setup(AcpiFadtDescriptorRev5_1 *fadt, AcpiPmInfo
> > > *pm,
> > > > +                       uint8_t revision)
> > > >  {
> > > >      fadt->model = 1;
> > > >      fadt->reserved1 = 0;
> > > > @@ -309,6 +323,25 @@ static void
> fadt_setup(AcpiFadtDescriptorRev1
> > > *fadt, AcpiPmInfo *pm)
> > > >          fadt->flags |= cpu_to_le32(1 <<
> > > ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
> > > >      }
> > > >      fadt->century = RTC_CENTURY;
> > > > +
> > > > +    /* Build ACPI 2.0 (FADT version 3+) GAS fields */
> > > > +    if (revision >= 3) {
> > > > +        /* EVT, CNT, TMR register matches hw/acpi/core.c */
> > > > +        build_gas(&fadt->xpm1a_event_block, AML_SYSTEM_IO,
> > > > +                  32, 0, 0, cpu_to_le64(pm->io_base));
> > > > +        build_gas(&fadt->xpm1a_control_block, AML_SYSTEM_IO,
> > > > +                  16, 0, 0, cpu_to_le64(pm->io_base + 0x04));
> > > > +        build_gas(&fadt->xpm_timer_block, AML_SYSTEM_IO,
> > > > +                  32, 0, 0, cpu_to_le64(pm->io_base + 0x08));
> > > > +        build_gas(&fadt->xgpe0_block, AML_SYSTEM_IO,
> > > > +                  pm->gpe0_blk_len << 3, 0, 0, cpu_to_le64(pm-
> >gpe0_blk));
> > > > +    }
> > > > +
> > > > +    /* Build dummy ACPI 5.0 fields */
> > > > +    if (revision >= 5) {
> > > > +        build_gas(&fadt->sleep_control, AML_SYSTEM_MEMORY, 0, 0,
> 0,
> > > 0);
> > > > +        build_gas(&fadt->sleep_status, AML_SYSTEM_MEMORY, 0, 0,
> 0, 0);
> > > > +    }
> > > >  }
> > > >
> > > >
> > > > @@ -316,11 +349,21 @@ static void
> > > fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
> > > >  static void
> > > >  build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
> > > >             unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> > > > -           const char *oem_id, const char *oem_table_id)
> > > > +           const char *oem_id, const char *oem_table_id, uint8_t
> revision)
> > > >  {
> > > > -    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data,
> > > sizeof(*fadt));
> > > > -    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl -
> table_data-
> > > >data;
> > > > -    unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data-
> >data;
> > > > +    AcpiFadtDescriptorRev5_1 *fadt;
> > > > +    unsigned fw_ctrl_offset;
> > > > +    unsigned dsdt_entry_offset;
> > > > +    unsigned fadt_len;
> > > > +
> > > > +    if (revision == 1) {
> > > > +        fadt_len = sizeof(AcpiFadtDescriptorRev1);
> > > > +    } else {
> > > > +        fadt_len = sizeof(AcpiFadtDescriptorRev5_1);
> > > > +    }
> > > > +    fadt = acpi_data_push(table_data, fadt_len);
> > > > +    fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
> > > > +    dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> > > >
> > > >      /* FACS address to be filled by Guest linker */
> > > >      bios_linker_loader_add_pointer(linker,
> > > > @@ -328,13 +371,28 @@ build_fadt(GArray *table_data,
> BIOSLinker
> > > *linker, AcpiPmInfo *pm,
> > > >          ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > >
> > > >      /* DSDT address to be filled by Guest linker */
> > > > -    fadt_setup(fadt, pm);
> > > >      bios_linker_loader_add_pointer(linker,
> > > >          ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
> > > >          ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > >
> > > > -    build_header(linker, table_data,
> > > > -                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id,
> oem_table_id);
> > > > +    if (revision > 2) {
> > > > +        fw_ctrl_offset = (char *)&fadt->Xfacs - table_data->data;
> > > > +        dsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
> > > > +
> > > > +        /* FACS address to be filled by Guest linker */
> > > > +        bios_linker_loader_add_pointer(linker,
> > > > +            ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->Xfacs),
> > > > +            ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > > > +
> > > > +        /* DSDT address to be filled by Guest linker */
> > > > +        bios_linker_loader_add_pointer(linker,
> > > > +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt-
> >Xdsdt),
> > > > +            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > > > +    }
> > > > +
> > > > +    fadt_setup(fadt, pm, revision);
> > > > +    build_header(linker, table_data, (void *)fadt, "FACP", fadt_len,
> > > > +                 revision, oem_id, oem_table_id);
> > > >  }
> > > >
> > > >  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> > > > @@ -2681,7 +2739,7 @@ void acpi_build(AcpiBuildTables *tables,
> > > MachineState *machine)
> > > >      fadt = tables_blob->len;
> > > >      acpi_add_table(table_offsets, tables_blob);
> > > >      build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> > > > -               slic_oem.id, slic_oem.table_id);
> > > > +               slic_oem.id, slic_oem.table_id, acpi_fadt_rev);
> > > >      aml_len += tables_blob->len - fadt;
> > > >
> > > >      acpi_add_table(table_offsets, tables_blob);
> > > > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > > > index 7b3d93c..63df38d 100644
> > > > --- a/include/hw/acpi/acpi.h
> > > > +++ b/include/hw/acpi/acpi.h
> > > > @@ -173,6 +173,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs,
> > > qemu_irq irq);
> > > >
> > > >  /* acpi.c */
> > > >  extern int acpi_enabled;
> > > > +extern uint8_t acpi_fadt_rev;
> > > >  extern char unsigned *acpi_tables;
> > > >  extern size_t acpi_tables_len;
> > > >
> > > > diff --git a/qemu-options.hx b/qemu-options.hx
> > > > index 5fe7f87..d61dd92 100644
> > > > --- a/qemu-options.hx
> > > > +++ b/qemu-options.hx
> > > > @@ -1497,7 +1497,10 @@ DEF("acpitable", HAS_ARG,
> > > QEMU_OPTION_acpitable,
> > > >      "             [,sig=str][,rev=n]\n"
> > > >      "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
> > > >      "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
> > > > -    "                ACPI table description\n", QEMU_ARCH_I386)
> > > > +    "                ACPI table description\n"
> > > > +    "-acpitable fadt=n\n"
> > > > +    "                Configure FADT revision\n",
> > > > +    QEMU_ARCH_I386)
> > > >  STEXI
> > > >  @item -acpitable
> > >
> data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@
> > > var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}]
> > > [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
> > > >  @findex -acpitable
> > > > @@ -1511,6 +1514,9 @@ If a SLIC table is supplied to QEMU, then
> the
> > > SLIC's oem_id and oem_table_id
> > > >  fields will override the same in the RSDT and the FADT (a.k.a. FACP),
> in
> > > order
> > > >  to ensure the field matches required by the Microsoft SLIC spec and
> the
> > > ACPI
> > > >  spec.
> > > > +
> > > > +@item -acpitable fadt=@var{n}
> > > > +Configure FADT revision to 1, 3, 5, default 1.
> > > >  ETEXI
> > > >
> > > >  DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
> >

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 1/2] ACPI: Cleanup -acpitable option code
  2016-08-12 14:51     ` Igor Mammedov
@ 2016-08-15  5:23       ` Zheng, Lv
  0 siblings, 0 replies; 32+ messages in thread
From: Zheng, Lv @ 2016-08-15  5:23 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Paolo Bonzini, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Shannon Zhao, Lv Zheng, qemu-devel, qemu-arm,
	eblake, armbru

Hi, Igor

> From: Igor Mammedov [mailto:imammedo@redhat.com]
> Subject: Re: [PATCH v5 1/2] ACPI: Cleanup -acpitable option code
> 
> On Thu, 11 Aug 2016 17:36:38 +0800
> Lv Zheng <lv.zheng@intel.com> wrote:
> 
> > In -acpitable options, at least/most one data/file sub-option is mandatory,
> > this patch cleans up the code to reflect this in a managed manner so that
> > the follow-up mandatory sub-options can be added to -acpitable.
> >
> > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > ---
> >  hw/acpi/core.c   |   32 +++++++++++++++++++++++---------
> >  qapi-schema.json |   26 +++++++-------------------
> >  qemu-options.hx  |    7 +++++--
> >  3 files changed, 35 insertions(+), 30 deletions(-)
> >
> > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > index e890a5d..85e0e94 100644
> > --- a/hw/acpi/core.c
> > +++ b/hw/acpi/core.c
> > @@ -89,8 +89,6 @@ static int acpi_checksum(const uint8_t *data, int len)
> >   * It is valid to call this function with
> >   * (@blob == NULL && bloblen == 0 && !has_header).
> >   *
> > - * @hdrs->file and @hdrs->data are ignored.
> > - *
> unrelated change?

When file/data become mandatory sub-options,
AcpiTableOptions doesn't have to contain file/data/has_file/has_data.
Because the value of the sub-option "file" or "data" has already been obtained in acpi_table_add() by invoking qemu_opt_get().
Thus I made this change.
And passed the sub-option value via new "const char *file" parameter.

> 
> >   * SIZE_MAX is considered "infinity" in this function.
> >   *
> >   * The number of tables that can be installed is not limited, but the 16-bit
> > @@ -229,7 +227,8 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
> >                                        ACPI_TABLE_PFX_SIZE, acpi_payload_size);
> >  }
> >
> > -void acpi_table_add(const QemuOpts *opts, Error **errp)
> > +static void acpi_table_from_file(bool has_header, const char *file,
> > +                                 const QemuOpts *opts, Error **errp)
> >  {
> >      AcpiTableOptions *hdrs = NULL;
> >      Error *err = NULL;
> > @@ -249,12 +248,8 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
> >      if (err) {
> >          goto out;
> >      }
> > -    if (hdrs->has_file == hdrs->has_data) {
> > -        error_setg(&err, "'-acpitable' requires one of 'data' or 'file'");
> > -        goto out;
> > -    }
> >
> > -    pathnames = g_strsplit(hdrs->has_file ? hdrs->file : hdrs->data, ":", 0);
> > +    pathnames = g_strsplit(file, ":", 0);
> >      if (pathnames == NULL || pathnames[0] == NULL) {
> >          error_setg(&err, "'-acpitable' requires at least one pathname");
> >          goto out;
> > @@ -291,7 +286,7 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
> >          close(fd);
> >      }
> >
> > -    acpi_table_install(blob, bloblen, hdrs->has_file, hdrs, &err);
> > +    acpi_table_install(blob, bloblen, has_header, hdrs, &err);
> >
> >  out:
> >      g_free(blob);
> > @@ -301,6 +296,25 @@ out:
> >      error_propagate(errp, err);
> >  }
> >
> > +void acpi_table_add(const QemuOpts *opts, Error **errp)
> > +{
> > +    const char *val;
> > +
> > +    val = qemu_opt_get((QemuOpts *)opts, "file");
> > +    if (val) {
> > +        acpi_table_from_file(true, val, opts, errp);
> > +        return;
> > +    }
> > +
> > +    val = qemu_opt_get((QemuOpts *)opts, "data");
> > +    if (val) {
> > +        acpi_table_from_file(false, val, opts, errp);
> > +        return;
> > +    }
> > +
> > +    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
> > +}
> > +
> >  static bool acpi_table_builtin = false;
> >
> >  void acpi_table_add_builtin(const QemuOpts *opts, Error **errp)
> > diff --git a/qapi-schema.json b/qapi-schema.json
> > index 5658723..75b8b3b 100644
> > --- a/qapi-schema.json
> > +++ b/qapi-schema.json
> > @@ -3597,17 +3597,17 @@
> >  ##
> >  # @AcpiTableOptions
> >  #
> > -# Specify an ACPI table on the command line to load.
> > +# Specify ACPI table options for the table loaded on the command line.
> >  #
> > -# At most one of @file and @data can be specified. The list of files specified
> > -# by any one of them is loaded and concatenated in order.
> 
> 
> > -# If both are omitted, @data is implied.
> You are removing this bit of documentation, which is still true

I shouldn't remove it.

It seems this implication is still working after applying my changes.
I booted qemu with -acpitable ssdt-local.aml,sig=SSDT and it worked same as -acpitable file=ssdt-local.aml.
ssdt-local.aml is loaded as an SSDT table.

How is this implication achieved in the code?

> 
> 
> > +# ACPI table can be loaded via 'file' and 'data' options. At most one of
> > +# 'file' and 'data' can be specified. The list of files specified by any one
> > +# of them is loaded and concatenated in order.
> >  #
> >  # Other fields / optargs can be used to override fields of the generic ACPI
> >  # table header; refer to the ACPI specification 5.0, section 5.2.6 System
> >  # Description Table Header. If a header field is not overridden, then the
> > -# corresponding value from the concatenated blob is used (in case of @file), or
> > -# it is filled in with a hard-coded value (in case of @data).
> > +# corresponding value from the concatenated blob is used (in case of 'file'),
> > +# or it is filled in with a hard-coded value (in case of 'data').
> >  #
> >  # String fields are copied into the matching ACPI member from lowest address
> >  # upwards, and silently truncated / NUL-padded to length.
> > @@ -3628,16 +3628,6 @@
> >  # @asl_compiler_rev: #optional revision number of the utility that created the
> >  #                    table (4 bytes)
> >  #
> > -# @file: #optional colon (:) separated list of pathnames to load and
> > -#        concatenate as table data. The resultant binary blob is expected to
> > -#        have an ACPI table header. At least one file is required. This field
> > -#        excludes @data.
> > -#
> > -# @data: #optional colon (:) separated list of pathnames to load and
> > -#        concatenate as table data. The resultant binary blob must not have an
> > -#        ACPI table header. At least one file is required. This field excludes
> > -#        @file.
> > -#
> >  # Since 1.5
> >  ##
> >  { 'struct': 'AcpiTableOptions',
> > @@ -3648,9 +3638,7 @@
> >      '*oem_table_id':      'str',
> >      '*oem_rev':           'uint32',
> >      '*asl_compiler_id':   'str',
> > -    '*asl_compiler_rev':  'uint32',
> > -    '*file':              'str',
> > -    '*data':              'str' }}
> > +    '*asl_compiler_rev':  'uint32' }}
> it's probably is not ok to remove fields here
> as it might break existing users that expect them

That's what I don't know and need to ask.

In the current code base, I can only see AcpiTableOptions used in acpi_table_install().
While it is commented that hdrs->file/data are useless for acpi_table_install().

Are there any external users for AcpiTableOptions?

Thanks and best regards
Lv

> 
> >
> >  ##
> >  # @CommandLineParameterType:
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index a71aaf8..5fe7f87 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -1493,10 +1493,13 @@ Disable HPET support.
> >  ETEXI
> >
> >  DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
> > -    "-acpitable
> [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=
> n][,{data|file}=file1[:file2]...]\n"
> > +    "-acpitable {data|file}=file1[:file2]...\n"
> > +    "             [,sig=str][,rev=n]\n"
> > +    "             [,oem_id=str][,oem_table_id=str][,oem_rev=n]\n"
> > +    "             [,asl_compiler_id=str][,asl_compiler_rev=n]\n"
> >      "                ACPI table description\n", QEMU_ARCH_I386)
> >  STEXI
> > -@item -acpitable
> [sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}]
> [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}][,data=@var{file1}[:@var{file2}]...]
> > +@item -acpitable
> data=@var{file1}[:@var{file2}]...[,sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{
> str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}]
> >  @findex -acpitable
> >  Add ACPI table with specified header fields and context from specified files.
> >  For file=, take whole ACPI table from the specified files, including all

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes
  2016-08-15  1:42       ` Zheng, Lv
@ 2016-08-17 11:42         ` Paolo Bonzini
  0 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-08-17 11:42 UTC (permalink / raw)
  To: Zheng, Lv, Peter Crosthwaite, Richard Henderson,
	Michael S. Tsirkin, Igor Mammedov, Shannon Zhao
  Cc: Lv Zheng, qemu-devel, qemu-arm



On 15/08/2016 03:42, Zheng, Lv wrote:
> Hi, Paolo
> 
>> From: Paolo Bonzini [mailto:pbonzini@redhat.com]
>> Subject: Re: [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT
>> revision changes
>>
>>
>>
>> On 11/08/2016 11:36, Lv Zheng wrote:
>>>
>>> -    error_setg(errp, "'-acpitable' requires one of 'data' or 'file'");
>>> +    val = qemu_opt_get((QemuOpts *)opts, "fadt");
>>> +    if (val) {
>>> +        unsigned long rev;
>>
>> Don't use qemu_opt_get.  Add the field to AcpiTableOptions in
>> qapi-schema.json, and then use hdrs->has_fadt, hdrs->fadt.
> 
> 
> 1. If I do so, users may be confused when only -acpitable fadt=3 is
>     specified (no user tables are provided), qemu may exit because of 
>     "data or file option missing".
> 2. If we doesn't want qemu exit in the above case, code in
>     acpi_table_add() will be too complicated.
> 3. If I put fadt into AcpiTableOptions in the schema,
>     hdrs->has_fadt/hdrs->fadt will become 2 more useless options
>     (just like hders->file/hdrs->data/hdrs->has_file/hdrs->has_data,
>     see comments of acpi_table_install()) passed to acpi_table_install().
> 
> That's why I enhanced -acpitable to convert it into an option with 3
> mandatory sub-options:
> -acpitable data/file ....
> -acpitable fadt ....

But most arguments of -acpitable (e.g. oem_id) apply to FADT as well.  
In fact "-acpitable fadt=3" perhaps could be written as "-acpitable fadt,rev=3".

So one possibility if you add '*fadt': 'bool' to AcpiTableOptions is the following:

    if (hdrs->has_file + hdrs->has_data + hdrs->has_fadt > 1) {
        error_setg(&err, "'-acpitable' requires one of 'data' or 'file' or 'fadt'");
        goto out;
    }
    if (hdrs->has_fadt && hdrs->fadt) {
        fadt_options = hdrs;
        return;
    }

Paolo

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2016-08-17 11:42 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-08  7:28 [Qemu-devel] [PATCH] ACPI: Add -acpifadt to allow FADT revision changes Lv Zheng
2016-08-08  7:35 ` no-reply
2016-08-08  8:16 ` [Qemu-devel] [PATCH v2] " Lv Zheng
2016-08-08  9:01   ` Paolo Bonzini
2016-08-09 21:06     ` Zheng, Lv
2016-08-08 11:25 ` [Qemu-devel] [PATCH] " Igor Mammedov
2016-08-11  9:06 ` [Qemu-devel] [PATCH v3 0/2] ACPI: Add FADT revision support Lv Zheng
2016-08-11  9:06   ` [Qemu-devel] [PATCH v3 1/2] ACPI: Cleanup -acpitable option code Lv Zheng
2016-08-11  9:06   ` [Qemu-devel] [PATCH v3 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes Lv Zheng
2016-08-11  9:11   ` [Qemu-devel] [PATCH v3 0/2] ACPI: Add FADT revision support no-reply
2016-08-11  9:12 ` [Qemu-devel] [PATCH v4 " Lv Zheng
2016-08-11  9:12   ` [Qemu-devel] [PATCH v4 1/2] ACPI: Cleanup -acpitable option code Lv Zheng
2016-08-11  9:17     ` Zheng, Lv
2016-08-11  9:12   ` [Qemu-devel] [PATCH v4 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes Lv Zheng
2016-08-11  9:36 ` [Qemu-devel] [PATCH v5 0/2] ACPI: Add FADT revision support Lv Zheng
2016-08-11  9:36   ` [Qemu-devel] [PATCH v5 1/2] ACPI: Cleanup -acpitable option code Lv Zheng
2016-08-12 14:51     ` Igor Mammedov
2016-08-15  5:23       ` Zheng, Lv
2016-08-11  9:36   ` [Qemu-devel] [PATCH v5 2/2] ACPI: Add -acpitable fadt= to allow FADT revision changes Lv Zheng
2016-08-11 12:42     ` Igor Mammedov
2016-08-12  0:47       ` Zheng, Lv
2016-08-12  3:07         ` Michael S. Tsirkin
2016-08-15  1:33           ` Zheng, Lv
2016-08-15  1:47             ` Michael S. Tsirkin
2016-08-15  2:18               ` Zheng, Lv
2016-08-15  2:23                 ` Michael S. Tsirkin
2016-08-15  3:18                   ` Zheng, Lv
2016-08-12 14:55         ` Igor Mammedov
2016-08-15  4:18           ` Zheng, Lv
2016-08-12 14:59     ` Paolo Bonzini
2016-08-15  1:42       ` Zheng, Lv
2016-08-17 11:42         ` Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.