Instead of filling a mapped and packed C structure field in random order
and being careful about endianness and sizes, build_rsdp() now uses
build_append_int_noprefix() to compose RSDP table.
This makes for an easier to review and maintain code that is almost
matching 1:1 the ACPI spec itself.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
hw/arm/virt-acpi-build.c | 42 +++++++++++++++++++++-------------------
1 file changed, 22 insertions(+), 20 deletions(-)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index ce8bfa5a37..4782aea4fe 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -368,35 +368,37 @@ static void acpi_dsdt_add_power_button(Aml *scope)
/* RSDP */
static void
-build_rsdp(GArray *rsdp_table, BIOSLinker *linker, AcpiRsdpData *rsdp_data)
+build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data)
{
- AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
- unsigned xsdt_pa_size = sizeof(rsdp->xsdt_physical_address);
- unsigned xsdt_pa_offset =
- (char *)&rsdp->xsdt_physical_address - rsdp_table->data;
-
- bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
+ bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, tbl, 16,
true /* fseg memory */);
- memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));
- memcpy(rsdp->oem_id, rsdp_data->oem_id, sizeof(rsdp->oem_id));
- rsdp->length = cpu_to_le32(sizeof(*rsdp));
- rsdp->revision = rsdp_data->revision;
+ g_array_append_vals(tbl, "RSD PTR ", 8); /* Signature */
+ build_append_int_noprefix(tbl, 0, 1); /* Checksum */
+ g_array_append_vals(tbl, rsdp_data->oem_id, 6); /* OEMID */
+ build_append_int_noprefix(tbl, rsdp_data->revision, 1); /* Revision */
+ build_append_int_noprefix(tbl, 0, 4); /* RsdtAddress */
+ build_append_int_noprefix(tbl, 36, 4); /* Length */
- /* Address to be filled by Guest linker */
- bios_linker_loader_add_pointer(linker,
- ACPI_BUILD_RSDP_FILE, xsdt_pa_offset, xsdt_pa_size,
- ACPI_BUILD_TABLE_FILE, *rsdp_data->xsdt_tbl_offset);
+ /* XSDT address to be filled by guest linker */
+ build_append_int_noprefix(tbl, 0, 8); /* XsdtAddress */
+ bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
+ 24, 8,
+ ACPI_BUILD_TABLE_FILE,
+ *rsdp_data->xsdt_tbl_offset);
- /* Checksum to be filled by Guest linker */
+ build_append_int_noprefix(tbl, 0, 1); /* Extended Checksum */
+ build_append_int_noprefix(tbl, 0, 3); /* Reserved */
+
+ /* Checksum to be filled by guest linker */
bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
- (char *)rsdp - rsdp_table->data, 20 /* ACPI rev 1.0 RSDP size */,
- (char *)&rsdp->checksum - rsdp_table->data);
+ 0, 20, /* ACPI rev 1.0 RSDP size */
+ 8);
/* Extended checksum to be filled by Guest linker */
bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
- (char *)rsdp - rsdp_table->data, 36 /* ACPI rev 2.0 RSDP size */,
- (char *)&rsdp->extended_checksum - rsdp_table->data);
+ 0, 36, /* ACPI rev 2.0 RSDP size */
+ 32);
}
static void
--
2.19.2
On Thu, Nov 29, 2018 at 02:24:25PM +0100, Samuel Ortiz wrote: > Instead of filling a mapped and packed C structure field in random order > and being careful about endianness and sizes, build_rsdp() now uses > build_append_int_noprefix() to compose RSDP table. > > This makes for an easier to review and maintain code that is almost > matching 1:1 the ACPI spec itself. > > Signed-off-by: Samuel Ortiz <sameo@linux.intel.com> > --- > hw/arm/virt-acpi-build.c | 42 +++++++++++++++++++++------------------- > 1 file changed, 22 insertions(+), 20 deletions(-) Reviewed-by: Andrew Jones <drjones@redhat.com>
On Thu, 29 Nov 2018 14:24:25 +0100
Samuel Ortiz <sameo@linux.intel.com> wrote:
> Instead of filling a mapped and packed C structure field in random order
> and being careful about endianness and sizes, build_rsdp() now uses
> build_append_int_noprefix() to compose RSDP table.
>
> This makes for an easier to review and maintain code that is almost
> matching 1:1 the ACPI spec itself.
nit if you happen to respin:
This makes review and maintaining code easier and ..
> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
> ---
> hw/arm/virt-acpi-build.c | 42 +++++++++++++++++++++-------------------
> 1 file changed, 22 insertions(+), 20 deletions(-)
>
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index ce8bfa5a37..4782aea4fe 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -368,35 +368,37 @@ static void acpi_dsdt_add_power_button(Aml *scope)
>
> /* RSDP */
> static void
> -build_rsdp(GArray *rsdp_table, BIOSLinker *linker, AcpiRsdpData *rsdp_data)
> +build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data)
> {
> - AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
> - unsigned xsdt_pa_size = sizeof(rsdp->xsdt_physical_address);
> - unsigned xsdt_pa_offset =
> - (char *)&rsdp->xsdt_physical_address - rsdp_table->data;
> -
> - bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
> + bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, tbl, 16,
> true /* fseg memory */);
>
> - memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));
> - memcpy(rsdp->oem_id, rsdp_data->oem_id, sizeof(rsdp->oem_id));
> - rsdp->length = cpu_to_le32(sizeof(*rsdp));
> - rsdp->revision = rsdp_data->revision;
> + g_array_append_vals(tbl, "RSD PTR ", 8); /* Signature */
> + build_append_int_noprefix(tbl, 0, 1); /* Checksum */
> + g_array_append_vals(tbl, rsdp_data->oem_id, 6); /* OEMID */
> + build_append_int_noprefix(tbl, rsdp_data->revision, 1); /* Revision */
> + build_append_int_noprefix(tbl, 0, 4); /* RsdtAddress */
> + build_append_int_noprefix(tbl, 36, 4); /* Length */
>
> - /* Address to be filled by Guest linker */
> - bios_linker_loader_add_pointer(linker,
> - ACPI_BUILD_RSDP_FILE, xsdt_pa_offset, xsdt_pa_size,
> - ACPI_BUILD_TABLE_FILE, *rsdp_data->xsdt_tbl_offset);
> + /* XSDT address to be filled by guest linker */
> + build_append_int_noprefix(tbl, 0, 8); /* XsdtAddress */
> + bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
> + 24, 8,
> + ACPI_BUILD_TABLE_FILE,
> + *rsdp_data->xsdt_tbl_offset);
>
> - /* Checksum to be filled by Guest linker */
> + build_append_int_noprefix(tbl, 0, 1); /* Extended Checksum */
> + build_append_int_noprefix(tbl, 0, 3); /* Reserved */
> +
> + /* Checksum to be filled by guest linker */
> bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
> - (char *)rsdp - rsdp_table->data, 20 /* ACPI rev 1.0 RSDP size */,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
this is always 0 with all current users and you a replacing it with 0
constant. That's fine but that assumes that above condition stays always true.
I'd add assert at the beginning of function to make sure that
tbl length is 0
or as an alternative
build_rsdp(...)
{
start_off = tbl->len;
...
bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, start_off, 20 ...
so it won't explode even if RSDP isn't at the beginning of file.
If you go for the later than bios_linker_loader_add_pointer() will also need similar treatment
> - (char *)&rsdp->checksum - rsdp_table->data);
> + 0, 20, /* ACPI rev 1.0 RSDP size */
> + 8);
>
> /* Extended checksum to be filled by Guest linker */
> bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
> - (char *)rsdp - rsdp_table->data, 36 /* ACPI rev 2.0 RSDP size */,
> - (char *)&rsdp->extended_checksum - rsdp_table->data);
> + 0, 36, /* ACPI rev 2.0 RSDP size */
> + 32);
> }
>
> static void
© 2016 - 2025 Red Hat, Inc.