[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 13/16] acpi: Add a way to extend tables
From: |
minyard |
Subject: |
[Qemu-devel] [PATCH 13/16] acpi: Add a way to extend tables |
Date: |
Fri, 12 Dec 2014 13:15:48 -0600 |
From: Corey Minyard <address@hidden>
Add a function that can extend the contents of a given
ACPI table to add on new entries. This way devices that
have ACPI entries can add them.
Signed-off-by: Corey Minyard <address@hidden>
---
hw/acpi/core.c | 106 +++++++++++++++++++++++++++++++++----------------
include/hw/acpi/acpi.h | 2 +
2 files changed, 74 insertions(+), 34 deletions(-)
diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 51913d6..a4cb485 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -78,33 +78,16 @@ static int acpi_checksum(const uint8_t *data, int len)
return (-sum) & 0xff;
}
-
-/* Install a copy of the ACPI table specified in @blob.
- *
- * If @has_header is set, @blob starts with the System Description Table Header
- * structure. Otherwise, "dfl_hdr" is prepended. In any case, each header field
- * is optionally overwritten from @hdrs.
- *
- * 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
- * counter at the beginning of "acpi_tables" wraps around after UINT16_MAX.
- */
-static void acpi_table_install(const char unsigned *blob, size_t bloblen,
- bool has_header,
- const struct AcpiTableOptions *hdrs,
- Error **errp)
+static struct acpi_table_header *acpi_new_table(const unsigned char *blob,
+ size_t bloblen,
+ bool has_header,
+ size_t *rpayload_size,
+ Error **errp)
{
size_t body_start;
- const char unsigned *hdr_src;
+ const unsigned char *hdr_src;
size_t body_size, acpi_payload_size;
struct acpi_table_header *ext_hdr;
- unsigned changed_fields;
/* Calculate where the ACPI table body starts within the blob, plus where
* to copy the ACPI table header from.
@@ -124,7 +107,7 @@ static void acpi_table_install(const char unsigned *blob,
size_t bloblen,
error_setg(errp, "ACPI table claiming to have header is too "
"short, available: %zu, expected: %zu", bloblen,
body_start);
- return;
+ return NULL;
}
hdr_src = blob;
} else {
@@ -145,7 +128,7 @@ static void acpi_table_install(const char unsigned *blob,
size_t bloblen,
if (acpi_payload_size > UINT16_MAX) {
error_setg(errp, "ACPI table too big, requested: %zu, max: %u",
acpi_payload_size, (unsigned)UINT16_MAX);
- return;
+ return NULL;
}
/* We won't fail from here on. Initialize / extend the globals. */
@@ -173,29 +156,63 @@ static void acpi_table_install(const char unsigned *blob,
size_t bloblen,
stw_le_p(acpi_tables, lduw_le_p(acpi_tables) + 1u);
/* Update the header fields. The strings need not be NUL-terminated. */
- changed_fields = 0;
ext_hdr->_length = cpu_to_le16(acpi_payload_size);
- if (hdrs->has_sig) {
- strncpy(ext_hdr->sig, hdrs->sig, sizeof ext_hdr->sig);
- ++changed_fields;
- }
-
if (has_header && le32_to_cpu(ext_hdr->length) != acpi_payload_size) {
fprintf(stderr,
"warning: ACPI table has wrong length, header says "
"%" PRIu32 ", actual size %zu bytes\n",
le32_to_cpu(ext_hdr->length), acpi_payload_size);
}
+
ext_hdr->length = cpu_to_le32(acpi_payload_size);
+ *rpayload_size = acpi_payload_size;
+
+ return ext_hdr;
+}
+
+/* Install a copy of the ACPI table specified in @blob.
+ *
+ * If @has_header is set, @blob starts with the System Description Table Header
+ * structure. Otherwise, "dfl_hdr" is prepended. In any case, each header field
+ * is optionally overwritten from @hdrs.
+ *
+ * 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
+ * counter at the beginning of "acpi_tables" wraps around after UINT16_MAX.
+ */
+static void acpi_table_install(const char unsigned *blob, size_t bloblen,
+ bool has_header,
+ const struct AcpiTableOptions *hdrs,
+ Error **errp)
+{
+ struct acpi_table_header *ext_hdr;
+ size_t payload_size = 0;
+ unsigned changed_fields = 0;
+
+ ext_hdr = acpi_new_table(blob, bloblen, has_header, &payload_size, errp);
+ if (errp && !*errp) {
+ return;
+ }
+
+ ext_hdr->checksum = 0;
+
+ if (hdrs->has_sig) {
+ strncpy(ext_hdr->sig, hdrs->sig, sizeof ext_hdr->sig);
+ ++changed_fields;
+ }
if (hdrs->has_rev) {
ext_hdr->revision = hdrs->rev;
++changed_fields;
}
- ext_hdr->checksum = 0;
-
if (hdrs->has_oem_id) {
strncpy(ext_hdr->oem_id, hdrs->oem_id, sizeof ext_hdr->oem_id);
++changed_fields;
@@ -225,7 +242,28 @@ static void acpi_table_install(const char unsigned *blob,
size_t bloblen,
/* recalculate checksum */
ext_hdr->checksum = acpi_checksum((const char unsigned *)ext_hdr +
- ACPI_TABLE_PFX_SIZE, acpi_payload_size);
+ ACPI_TABLE_PFX_SIZE, payload_size);
+}
+
+/*
+ * Add a table from an internal driver.
+ */
+void acpi_append_to_table(const char *sig, void *blob, size_t bloblen,
+ Error **errp)
+{
+ struct acpi_table_header *ext_hdr;
+ size_t payload_size = 0;
+
+ ext_hdr = acpi_new_table(blob, bloblen, false, &payload_size, errp);
+ if (errp && *errp) {
+ return;
+ }
+
+ strncpy(ext_hdr->sig, sig, sizeof ext_hdr->sig);
+
+ /* recalculate checksum */
+ ext_hdr->checksum = acpi_checksum((const char unsigned *)ext_hdr +
+ ACPI_TABLE_PFX_SIZE, payload_size);
}
void acpi_table_add(const QemuOpts *opts, Error **errp)
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 1f678b4..acdd432 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -184,5 +184,7 @@ uint8_t *acpi_table_next(uint8_t *current);
unsigned acpi_table_len(void *current);
void acpi_table_add(const QemuOpts *opts, Error **errp);
void acpi_table_add_builtin(const QemuOpts *opts, Error **errp);
+void acpi_append_to_table(const char *sig, void *blob, size_t bloblen,
+ Error **errp);
#endif /* !QEMU_HW_ACPI_H */
--
1.8.3.1
- [Qemu-devel] [PATCH 03/16] ipmi: Add a KCS low-level interface, (continued)
- [Qemu-devel] [PATCH 03/16] ipmi: Add a KCS low-level interface, minyard, 2014/12/12
- [Qemu-devel] [PATCH 04/16] ipmi: Add a BT low-level interface, minyard, 2014/12/12
- [Qemu-devel] [PATCH 05/16] ipmi: Add a local BMC simulation, minyard, 2014/12/12
- [Qemu-devel] [PATCH 06/16] ipmi: Add an external connection simulation interface, minyard, 2014/12/12
- [Qemu-devel] [PATCH 07/16] ipmi: Add tests, minyard, 2014/12/12
- [Qemu-devel] [PATCH 08/16] ipmi: Add documentation, minyard, 2014/12/12
- [Qemu-devel] [PATCH 09/16] ipmi: Add migration capability to the IPMI device., minyard, 2014/12/12
- [Qemu-devel] [PATCH 10/16] pc: Postpone adding ACPI and SMBIOS to fw_cfg, minyard, 2014/12/12
- [Qemu-devel] [PATCH 11/16] smbios: Add a function to directly add an entry, minyard, 2014/12/12
- [Qemu-devel] [PATCH 12/16] ipmi: Add SMBIOS table entry, minyard, 2014/12/12
- [Qemu-devel] [PATCH 13/16] acpi: Add a way to extend tables,
minyard <=
- [Qemu-devel] [PATCH 14/16] acpi: Add table construction tools, minyard, 2014/12/12
- [Qemu-devel] [PATCH 15/16] ipmi: Add ACPI table entries for BMCs, minyard, 2014/12/12
- [Qemu-devel] [PATCH 16/16] ipmi: Add a thread to better simulate a BMC, minyard, 2014/12/12
- Re: [Qemu-devel] [PATCH 00/16] Add an IPMI device to qemu, Paolo Bonzini, 2014/12/15