From: "Richard W.M. Jones" <rjones@redhat.com>
To: mst@redhat.com
Cc: peter.maydell@linaro.org, ehabkost@redhat.com,
zhaoshenglong@huawei.com, qemu-devel@nongnu.org,
pbonzini@redhat.com, imammedo@redhat.com, rth@twiddle.net
Subject: [Qemu-devel] [PATCH 1/2] acpi: Allow ACPI default OEM ID and OEM table ID fields to be set.
Date: Wed, 2 Sep 2015 20:03:37 +0100 [thread overview]
Message-ID: <1441220618-4750-2-git-send-email-rjones@redhat.com> (raw)
In-Reply-To: <1441220618-4750-1-git-send-email-rjones@redhat.com>
When using qemu's internal ACPI table generation, qemu sets the fields
OEM ID and OEM table ID to arbitrary default values. OEM ID is set to
"BOCHS " and OEM table ID is set to "BXPCxxxx" where "xxxx" is
replaced by the ACPI table name (eg. "BXPCRSDT" for the RSDT table).
This patch allows you to override these default values.
Use one of these alternatives:
qemu -acpidefault oem_id=ABCD,oem_table_id=EFGH
qemu -acpidefault oem_id=ABCD,oem_table_id=EFGHIJKL
In the first case, the last four types of the OEM table name field are
set to the ACPI table name.
This does not affect the -acpitable option (for user-defined ACPI
tables), which has its own method for setting these fields.
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
---
hw/acpi/aml-build.c | 44 +++++++++++++++++++++++++++++++++---
hw/arm/virt-acpi-build.c | 5 ++++-
hw/i386/acpi-build.c | 5 ++++-
include/hw/acpi/aml-build.h | 3 +--
qemu-options.hx | 19 ++++++++++++++++
vl.c | 55 +++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 124 insertions(+), 7 deletions(-)
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 0d4b324..7a2a2fb 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -28,8 +28,13 @@
#include "hw/acpi/aml-build.h"
#include "qemu/bswap.h"
#include "qemu/bitops.h"
+#include "qemu/config-file.h"
+#include "qemu/option.h"
#include "hw/acpi/bios-linker-loader.h"
+#define ACPI_BUILD_APPNAME6 "BOCHS "
+#define ACPI_BUILD_APPNAME4 "BXPC"
+
static GArray *build_alloc_array(void)
{
return g_array_new(false, true /* clear */, 1);
@@ -1135,16 +1140,49 @@ Aml *aml_unicode(const char *str)
return var;
}
+/* The caller should pass in 6 and 8 byte char arrays resp. */
+void
+acpi_get_oem_defaults(const char *sig, char *oem_id, char *oem_table_id)
+{
+ QemuOpts *opts;
+ const char *opt_oem_id;
+ const char *opt_oem_table_id;
+
+ opts = qemu_opts_find(qemu_find_opts("acpidefault"), NULL);
+ if (opts == NULL) {
+ memcpy(oem_id, ACPI_BUILD_APPNAME6, 6);
+ memcpy(oem_table_id, ACPI_BUILD_APPNAME4, 4);
+ memcpy(oem_table_id + 4, sig, 4);
+ }
+
+ opt_oem_id = qemu_opt_get(opts, "oem_id");
+ if (opt_oem_id) {
+ memcpy(oem_id, opt_oem_id, 6);
+ }
+ opt_oem_table_id = qemu_opt_get(opts, "oem_table_id");
+ if (opt_oem_table_id) {
+ if (strlen(opt_oem_table_id) == 8) {
+ memcpy(oem_table_id, opt_oem_table_id, 8);
+ } else {
+ memcpy(oem_table_id, opt_oem_table_id, 4);
+ memcpy(oem_table_id + 4, sig, 4);
+ }
+ }
+}
+
void
build_header(GArray *linker, GArray *table_data,
AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
{
+ char oem_id[6], oem_table_id[8];
+
+ acpi_get_oem_defaults(sig, oem_id, oem_table_id);
+
memcpy(&h->signature, sig, 4);
h->length = cpu_to_le32(len);
h->revision = rev;
- memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
- memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
- memcpy(h->oem_table_id + 4, sig, 4);
+ memcpy(h->oem_id, oem_id, 6);
+ memcpy(h->oem_table_id, oem_table_id, 8);
h->oem_revision = cpu_to_le32(1);
memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
h->asl_compiler_revision = cpu_to_le32(1);
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index f365140..85677f2 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -314,13 +314,16 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, int irq)
static GArray *
build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
{
+ char oem_id[6], oem_table_id[8];
AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
+ acpi_get_oem_defaults("RSDP", oem_id, oem_table_id);
+
bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16,
true /* fseg memory */);
memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));
- memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, sizeof(rsdp->oem_id));
+ memcpy(rsdp->oem_id, oem_id, sizeof(oem_id));
rsdp->length = cpu_to_le32(sizeof(*rsdp));
rsdp->revision = 0x02;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 95e0c65..8cbf90d 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1593,13 +1593,16 @@ build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
static GArray *
build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
{
+ char oem_id[6], oem_table_id[8];
AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
+ acpi_get_oem_defaults("RSDP", oem_id, oem_table_id);
+
bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16,
true /* fseg memory */);
memcpy(&rsdp->signature, "RSD PTR ", 8);
- memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6);
+ memcpy(rsdp->oem_id, oem_id, sizeof(oem_id));
rsdp->rsdt_physical_address = cpu_to_le32(rsdt);
/* Address to be filled by Guest linker */
bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index e3afa13..85a3c2c 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -10,8 +10,6 @@
#define ACPI_BUILD_TABLE_MAX_SIZE 0x200000
#define ACPI_BUILD_APPNAME "Bochs"
-#define ACPI_BUILD_APPNAME6 "BOCHS "
-#define ACPI_BUILD_APPNAME4 "BXPC"
#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
#define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
@@ -276,6 +274,7 @@ Aml *aml_varpackage(uint32_t num_elements);
Aml *aml_touuid(const char *uuid);
Aml *aml_unicode(const char *str);
+void acpi_get_oem_defaults(const char *sig, char *oem_id, char *oem_table_id);
void
build_header(GArray *linker, GArray *table_data,
AcpiTableHeader *h, const char *sig, int len, uint8_t rev);
diff --git a/qemu-options.hx b/qemu-options.hx
index 77f5853..73c8e97 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2705,6 +2705,25 @@ Add named fw_cfg entry from file. @var{name} determines the name of
the entry in the fw_cfg file directory exposed to the guest.
ETEXI
+DEF("acpidefault", HAS_ARG, QEMU_OPTION_acpidefault,
+ "-acpidefault oem_id=<OEMID>,oem_table_id=<OEMTABLEID>\n"
+ " set default OEM ID (6 bytes) and OEM table ID (4 or 8 bytes)\n",
+ QEMU_ARCH_ALL)
+STEXI
+@item -acpidefault oem_id=@var{OEMID},file=@var{OEMTABLEID}
+@findex -acpidefault
+Set the default OEM ID and OEM table ID used in ACPI tables. The
+OEM ID should be 6 bytes (pad with spaces if needed), and the OEM
+table ID should be 4 or 8 bytes.
+
+If not set, qemu uses @code{"BOCHS "} and @code{"BXPCxxxx"} where
+@code{xxxx} is the table name (eg. @code{"BXPCRSDT"} in the RSDT table).
+
+If you are adding user-defined ACPI tables on the qemu command line,
+use @code{-acpitable} instead. The defaults here will not be used
+in this case.
+ETEXI
+
DEF("serial", HAS_ARG, QEMU_OPTION_serial, \
"-serial dev redirect the serial port to char device 'dev'\n",
QEMU_ARCH_ALL)
diff --git a/vl.c b/vl.c
index 584ca88..614c66f 100644
--- a/vl.c
+++ b/vl.c
@@ -517,6 +517,24 @@ static QemuOptsList qemu_fw_cfg_opts = {
},
};
+static QemuOptsList qemu_acpidefault_opts = {
+ .name = "acpidefault",
+ .merge_lists = true,
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_acpidefault_opts.head),
+ .desc = {
+ {
+ .name = "oem_id",
+ .type = QEMU_OPT_STRING,
+ .help = "Set default OEM ID (6 bytes)",
+ }, {
+ .name = "oem_table_id",
+ .type = QEMU_OPT_STRING,
+ .help = "Set default OEM table ID (4 or 8 bytes)",
+ },
+ { /* end of list */ }
+ },
+};
+
/**
* Get machine options
*
@@ -2287,6 +2305,30 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
return 0;
}
+static int check_acpi_option(QemuOpts *opts)
+{
+ const char *oem_id;
+ const char *oem_table_id;
+
+ oem_id = qemu_opt_get(opts, "oem_id");
+ if (oem_id) {
+ if (strlen(oem_id) != 6) {
+ error_report("-acpi oem_id parameter must be 6 bytes long");
+ return -1;
+ }
+ }
+ oem_table_id = qemu_opt_get(opts, "oem_table_id");
+ if (oem_table_id) {
+ size_t len = strlen(oem_table_id);
+ if (len != 4 && len != 8) {
+ error_report("-acpi oem_table_id parameter "
+ "must be 4 or 8 bytes long");
+ return -1;
+ }
+ }
+ return 0;
+}
+
static int device_help_func(void *opaque, QemuOpts *opts, Error **errp)
{
return qdev_device_help(opts);
@@ -3018,6 +3060,7 @@ int main(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_icount_opts);
qemu_add_opts(&qemu_semihosting_config_opts);
qemu_add_opts(&qemu_fw_cfg_opts);
+ qemu_add_opts(&qemu_acpidefault_opts);
runstate_init();
@@ -3653,6 +3696,13 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
break;
+ case QEMU_OPTION_acpidefault:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("acpidefault"),
+ optarg, false);
+ if (opts == NULL) {
+ exit(1);
+ }
+ break;
case QEMU_OPTION_enable_kvm:
olist = qemu_find_opts("machine");
qemu_opts_parse_noisily(olist, "accel=kvm", false);
@@ -4522,6 +4572,11 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
+ if (check_acpi_option(qemu_opts_find(qemu_find_opts("acpidefault"),
+ NULL)) < 0) {
+ exit(1);
+ }
+
/* init USB devices */
if (usb_enabled()) {
if (foreach_device_config(DEV_USB, usb_parse) < 0)
--
2.5.0
next prev parent reply other threads:[~2015-09-02 19:03 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-02 19:03 [Qemu-devel] [PATCH 1/2] acpi: Allow ACPI default OEM ID and OEM table ID fields to be set Richard W.M. Jones
2015-09-02 19:03 ` Richard W.M. Jones [this message]
2015-09-02 19:16 ` Richard W.M. Jones
2015-09-02 21:32 ` Michael S. Tsirkin
2015-09-03 15:09 ` Laszlo Ersek
2015-09-03 15:17 ` Michael Tokarev
2015-09-03 15:37 ` Laszlo Ersek
2015-09-03 16:33 ` Michael Tokarev
2015-09-03 16:44 ` Laszlo Ersek
2015-09-03 19:56 ` Michael S. Tsirkin
2015-09-03 19:55 ` Michael S. Tsirkin
2015-09-03 20:51 ` Richard W.M. Jones
2015-09-02 19:03 ` [Qemu-devel] [PATCH 2/2] acpi: Remove unused definition Richard W.M. Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1441220618-4750-2-git-send-email-rjones@redhat.com \
--to=rjones@redhat.com \
--cc=ehabkost@redhat.com \
--cc=imammedo@redhat.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
--cc=zhaoshenglong@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).