On Thu, 29 Nov 2018 14:24:25 +0100 Samuel Ortiz <sa...@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 <sa...@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