diff mbox series

[v5,05/24] hw: acpi: Implement XSDT support for RSDP

Message ID 20181105014047.26447-6-sameo@linux.intel.com
State New
Headers show
Series ACPI reorganization for hardware-reduced API addition | expand

Commit Message

Samuel Ortiz Nov. 5, 2018, 1:40 a.m. UTC
XSDT is the 64-bit version of the legacy ACPI RSDT (Root System
Description Table). RSDT only allow for 32-bit addressses and have thus
been deprecated. Since ACPI version 2.0, RSDPs should point at XSDTs and
no longer RSDTs, although RSDTs are still supported for backward
compatibility.

Since version 2.0, RSDPs should add an extended checksum, a complete table
length and a version field to the table.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
 include/hw/acpi/aml-build.h |  3 +++
 hw/acpi/aml-build.c         | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

Comments

Igor Mammedov Nov. 8, 2018, 2:16 p.m. UTC | #1
On Mon,  5 Nov 2018 02:40:28 +0100
Samuel Ortiz <sameo@linux.intel.com> wrote:

> XSDT is the 64-bit version of the legacy ACPI RSDT (Root System
> Description Table). RSDT only allow for 32-bit addressses and have thus
> been deprecated. Since ACPI version 2.0, RSDPs should point at XSDTs and
> no longer RSDTs, although RSDTs are still supported for backward
> compatibility.
> 
> Since version 2.0, RSDPs should add an extended checksum, a complete table
> length and a version field to the table.

This patch re-implements what arm/virt board already does
and fixes checksum bug in the later and at the same time
without a user (within the patch).

I'd suggest redo it a way similar to FADT refactoring
  patch 1: fix checksum bug in virt/arm
  patch 2: update reference tables in test
  patch 3: introduce AcpiRsdpData similar to commit 937d1b587
             (both arm and x86) wich stores all data in hos byte order
  patch 4: convert arm's impl. to build_append_int_noprefix() API (commit 5d7a334f7)
           ... move out to aml-build.c
  patch 5: reuse generalized arm's build_rsdp() for x86, dropping x86 specific one
      amending it to generate rev1 variant defined by revision in AcpiRsdpData
      (commit dd1b2037a)

  'make check V=1' shouldn't observe any ACPI tables changes after patch 2.

> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
> ---
>  include/hw/acpi/aml-build.h |  3 +++
>  hw/acpi/aml-build.c         | 37 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 40 insertions(+)
> 
> diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
> index c9bcb32d81..3580d0ce90 100644
> --- a/include/hw/acpi/aml-build.h
> +++ b/include/hw/acpi/aml-build.h
> @@ -393,6 +393,9 @@ void
>  build_rsdp(GArray *table_data,
>             BIOSLinker *linker, unsigned rsdt_tbl_offset);
>  void
> +build_rsdp_xsdt(GArray *table_data,
> +                BIOSLinker *linker, unsigned xsdt_tbl_offset);
> +void
>  build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
>             const char *oem_id, const char *oem_table_id);
>  void
> diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> index 51b608432f..a030d40674 100644
> --- a/hw/acpi/aml-build.c
> +++ b/hw/acpi/aml-build.c
> @@ -1651,6 +1651,43 @@ build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
>                   (void *)xsdt, "XSDT", xsdt_len, 1, oem_id, oem_table_id);
>  }
>  
> +/* RSDP pointing at an XSDT */
> +void
> +build_rsdp_xsdt(GArray *rsdp_table,
> +                BIOSLinker *linker, unsigned xsdt_tbl_offset)
> +{
> +    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;
> +    unsigned xsdt_offset =
> +        (char *)&rsdp->length - rsdp_table->data;
> +
> +    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
> +                             true /* fseg memory */);
> +
> +    memcpy(&rsdp->signature, "RSD PTR ", 8);
> +    memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6);
> +    rsdp->length = cpu_to_le32(sizeof(*rsdp));
> +    /* version 2, we will use the XSDT pointer */
> +    rsdp->revision = 0x02;
> +
> +    /* 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, xsdt_tbl_offset);
> +
> +    /* Legacy checksum to be filled by Guest linker */
> +    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
> +        (char *)rsdp - rsdp_table->data, xsdt_offset,
> +        (char *)&rsdp->checksum - rsdp_table->data);
> +
> +    /* Extended checksum to be filled by Guest linker */
> +    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
> +        (char *)rsdp - rsdp_table->data, sizeof *rsdp,
> +        (char *)&rsdp->extended_checksum - rsdp_table->data);
> +}
> +
>  void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
>                         uint64_t len, int node, MemoryAffinityFlags flags)
>  {
Samuel Ortiz Nov. 8, 2018, 2:36 p.m. UTC | #2
Hi Igor,

On Thu, Nov 08, 2018 at 03:16:23PM +0100, Igor Mammedov wrote:
> On Mon,  5 Nov 2018 02:40:28 +0100
> Samuel Ortiz <sameo@linux.intel.com> wrote:
> 
> > XSDT is the 64-bit version of the legacy ACPI RSDT (Root System
> > Description Table). RSDT only allow for 32-bit addressses and have thus
> > been deprecated. Since ACPI version 2.0, RSDPs should point at XSDTs and
> > no longer RSDTs, although RSDTs are still supported for backward
> > compatibility.
> > 
> > Since version 2.0, RSDPs should add an extended checksum, a complete table
> > length and a version field to the table.
> 
> This patch re-implements what arm/virt board already does
> and fixes checksum bug in the later and at the same time
> without a user (within the patch).
> 
> I'd suggest redo it a way similar to FADT refactoring
>   patch 1: fix checksum bug in virt/arm
>   patch 2: update reference tables in test
I now see what you meant with the ACPI reference tables, thanks.
I'll follow your advice.

Cheers,
Samuel.
Igor Mammedov Nov. 8, 2018, 2:53 p.m. UTC | #3
On Thu, 8 Nov 2018 15:16:23 +0100
Igor Mammedov <imammedo@redhat.com> wrote:

[...]
>   patch 4: convert arm's impl. to build_append_int_noprefix() API (commit 5d7a334f7)

>            ... move out to aml-build.c
my mistake, generally when we move something out,
we should do it in separate path preferably without any changes to the moved code
so it would be easier to review. So it should be a separate patch.

[...]
Michael S. Tsirkin Nov. 19, 2018, 6:27 p.m. UTC | #4
On Thu, Nov 08, 2018 at 03:16:23PM +0100, Igor Mammedov wrote:
> On Mon,  5 Nov 2018 02:40:28 +0100
> Samuel Ortiz <sameo@linux.intel.com> wrote:
> 
> > XSDT is the 64-bit version of the legacy ACPI RSDT (Root System
> > Description Table). RSDT only allow for 32-bit addressses and have thus
> > been deprecated. Since ACPI version 2.0, RSDPs should point at XSDTs and
> > no longer RSDTs, although RSDTs are still supported for backward
> > compatibility.
> > 
> > Since version 2.0, RSDPs should add an extended checksum, a complete table
> > length and a version field to the table.
> 
> This patch re-implements what arm/virt board already does
> and fixes checksum bug in the later and at the same time
> without a user (within the patch).
> 
> I'd suggest redo it a way similar to FADT refactoring
>   patch 1: fix checksum bug in virt/arm
>   patch 2: update reference tables in test
>   patch 3: introduce AcpiRsdpData similar to commit 937d1b587
>              (both arm and x86) wich stores all data in hos byte order
>   patch 4: convert arm's impl. to build_append_int_noprefix() API (commit 5d7a334f7)
>            ... move out to aml-build.c
>   patch 5: reuse generalized arm's build_rsdp() for x86, dropping x86 specific one
>       amending it to generate rev1 variant defined by revision in AcpiRsdpData
>       (commit dd1b2037a)
> 
>   'make check V=1' shouldn't observe any ACPI tables changes after patch 2.

And your next suggestion is to add patch 6.  I guess it's doable but
this will make a single patch a 6 patch series. At this rate this series
will be at 200 patches easily.

Automated checks are cool but hey it's easy to see what changed in a
disassembled table, and we do not update them blindly. So just note in
the comment that there's a table change for ARM and expected files need
to be updated and we should be fine IMHO.

> > Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
> > ---
> >  include/hw/acpi/aml-build.h |  3 +++
> >  hw/acpi/aml-build.c         | 37 +++++++++++++++++++++++++++++++++++++
> >  2 files changed, 40 insertions(+)
> > 
> > diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
> > index c9bcb32d81..3580d0ce90 100644
> > --- a/include/hw/acpi/aml-build.h
> > +++ b/include/hw/acpi/aml-build.h
> > @@ -393,6 +393,9 @@ void
> >  build_rsdp(GArray *table_data,
> >             BIOSLinker *linker, unsigned rsdt_tbl_offset);
> >  void
> > +build_rsdp_xsdt(GArray *table_data,
> > +                BIOSLinker *linker, unsigned xsdt_tbl_offset);
> > +void
> >  build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
> >             const char *oem_id, const char *oem_table_id);
> >  void
> > diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> > index 51b608432f..a030d40674 100644
> > --- a/hw/acpi/aml-build.c
> > +++ b/hw/acpi/aml-build.c
> > @@ -1651,6 +1651,43 @@ build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
> >                   (void *)xsdt, "XSDT", xsdt_len, 1, oem_id, oem_table_id);
> >  }
> >  
> > +/* RSDP pointing at an XSDT */
> > +void
> > +build_rsdp_xsdt(GArray *rsdp_table,
> > +                BIOSLinker *linker, unsigned xsdt_tbl_offset)
> > +{
> > +    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;
> > +    unsigned xsdt_offset =
> > +        (char *)&rsdp->length - rsdp_table->data;

There's a cleaner way to get at the offsets than pointer math:
1. save rsdp_table length before you push
2. add offset_of for fields

If switching to build_append_int_noprefix then it's even
easier - just save length before you append the int
you intend to patch.


> > +
> > +    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
> > +                             true /* fseg memory */);
> > +
> > +    memcpy(&rsdp->signature, "RSD PTR ", 8);
> > +    memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6);
> > +    rsdp->length = cpu_to_le32(sizeof(*rsdp));
> > +    /* version 2, we will use the XSDT pointer */
> > +    rsdp->revision = 0x02;
> > +
> > +    /* 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, xsdt_tbl_offset);
> > +
> > +    /* Legacy checksum to be filled by Guest linker */
> > +    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
> > +        (char *)rsdp - rsdp_table->data, xsdt_offset,
> > +        (char *)&rsdp->checksum - rsdp_table->data);
> > +
> > +    /* Extended checksum to be filled by Guest linker */
> > +    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
> > +        (char *)rsdp - rsdp_table->data, sizeof *rsdp,
> > +        (char *)&rsdp->extended_checksum - rsdp_table->data);
> > +}
> > +
> >  void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
> >                         uint64_t len, int node, MemoryAffinityFlags flags)
> >  {
Igor Mammedov Nov. 20, 2018, 8:23 a.m. UTC | #5
On Mon, 19 Nov 2018 13:27:14 -0500
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Nov 08, 2018 at 03:16:23PM +0100, Igor Mammedov wrote:
> > On Mon,  5 Nov 2018 02:40:28 +0100
> > Samuel Ortiz <sameo@linux.intel.com> wrote:
> >   
> > > XSDT is the 64-bit version of the legacy ACPI RSDT (Root System
> > > Description Table). RSDT only allow for 32-bit addressses and have thus
> > > been deprecated. Since ACPI version 2.0, RSDPs should point at XSDTs and
> > > no longer RSDTs, although RSDTs are still supported for backward
> > > compatibility.
> > > 
> > > Since version 2.0, RSDPs should add an extended checksum, a complete table
> > > length and a version field to the table.  
> > 
> > This patch re-implements what arm/virt board already does
> > and fixes checksum bug in the later and at the same time
> > without a user (within the patch).
> > 
> > I'd suggest redo it a way similar to FADT refactoring
> >   patch 1: fix checksum bug in virt/arm
> >   patch 2: update reference tables in test
> >   patch 3: introduce AcpiRsdpData similar to commit 937d1b587
> >              (both arm and x86) wich stores all data in hos byte order
> >   patch 4: convert arm's impl. to build_append_int_noprefix() API (commit 5d7a334f7)
> >            ... move out to aml-build.c
> >   patch 5: reuse generalized arm's build_rsdp() for x86, dropping x86 specific one
> >       amending it to generate rev1 variant defined by revision in AcpiRsdpData
> >       (commit dd1b2037a)
> > 
> >   'make check V=1' shouldn't observe any ACPI tables changes after patch 2.  
> 
> And your next suggestion is to add patch 6.  I guess it's doable but
> this will make a single patch a 6 patch series. At this rate this series
> will be at 200 patches easily.
> 
> Automated checks are cool but hey it's easy to see what changed in a
> disassembled table, and we do not update them blindly. So just note in
> the comment that there's a table change for ARM and expected files need
> to be updated and we should be fine IMHO.
Point was to move patches that change tables content first,
where we would pay extra attentions to changes in tables and
then refactoring which shouldn't cause any changes will be mostly
automatic  (at least at that point we won't have to worry about 
tables correctness)


> > > Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
> > > ---
> > >  include/hw/acpi/aml-build.h |  3 +++
> > >  hw/acpi/aml-build.c         | 37 +++++++++++++++++++++++++++++++++++++
> > >  2 files changed, 40 insertions(+)
> > > 
> > > diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
> > > index c9bcb32d81..3580d0ce90 100644
> > > --- a/include/hw/acpi/aml-build.h
> > > +++ b/include/hw/acpi/aml-build.h
> > > @@ -393,6 +393,9 @@ void
> > >  build_rsdp(GArray *table_data,
> > >             BIOSLinker *linker, unsigned rsdt_tbl_offset);
> > >  void
> > > +build_rsdp_xsdt(GArray *table_data,
> > > +                BIOSLinker *linker, unsigned xsdt_tbl_offset);
> > > +void
> > >  build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
> > >             const char *oem_id, const char *oem_table_id);
> > >  void
> > > diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> > > index 51b608432f..a030d40674 100644
> > > --- a/hw/acpi/aml-build.c
> > > +++ b/hw/acpi/aml-build.c
> > > @@ -1651,6 +1651,43 @@ build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
> > >                   (void *)xsdt, "XSDT", xsdt_len, 1, oem_id, oem_table_id);
> > >  }
> > >  
> > > +/* RSDP pointing at an XSDT */
> > > +void
> > > +build_rsdp_xsdt(GArray *rsdp_table,
> > > +                BIOSLinker *linker, unsigned xsdt_tbl_offset)
> > > +{
> > > +    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;
> > > +    unsigned xsdt_offset =
> > > +        (char *)&rsdp->length - rsdp_table->data;  
> 
> There's a cleaner way to get at the offsets than pointer math:
> 1. save rsdp_table length before you push
> 2. add offset_of for fields
> 
> If switching to build_append_int_noprefix then it's even
> easier - just save length before you append the int
> you intend to patch.
> 
> 
> > > +
> > > +    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
> > > +                             true /* fseg memory */);
> > > +
> > > +    memcpy(&rsdp->signature, "RSD PTR ", 8);
> > > +    memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6);
> > > +    rsdp->length = cpu_to_le32(sizeof(*rsdp));
> > > +    /* version 2, we will use the XSDT pointer */
> > > +    rsdp->revision = 0x02;
> > > +
> > > +    /* 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, xsdt_tbl_offset);
> > > +
> > > +    /* Legacy checksum to be filled by Guest linker */
> > > +    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
> > > +        (char *)rsdp - rsdp_table->data, xsdt_offset,
> > > +        (char *)&rsdp->checksum - rsdp_table->data);
> > > +
> > > +    /* Extended checksum to be filled by Guest linker */
> > > +    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
> > > +        (char *)rsdp - rsdp_table->data, sizeof *rsdp,
> > > +        (char *)&rsdp->extended_checksum - rsdp_table->data);
> > > +}
> > > +
> > >  void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
> > >                         uint64_t len, int node, MemoryAffinityFlags flags)
> > >  {
Samuel Ortiz Nov. 21, 2018, 2:42 p.m. UTC | #6
Hi Igor,

On Thu, Nov 08, 2018 at 03:16:23PM +0100, Igor Mammedov wrote:
> On Mon,  5 Nov 2018 02:40:28 +0100
> Samuel Ortiz <sameo@linux.intel.com> wrote:
> 
> > XSDT is the 64-bit version of the legacy ACPI RSDT (Root System
> > Description Table). RSDT only allow for 32-bit addressses and have thus
> > been deprecated. Since ACPI version 2.0, RSDPs should point at XSDTs and
> > no longer RSDTs, although RSDTs are still supported for backward
> > compatibility.
> > 
> > Since version 2.0, RSDPs should add an extended checksum, a complete table
> > length and a version field to the table.
> 
> This patch re-implements what arm/virt board already does
> and fixes checksum bug in the later and at the same time
> without a user (within the patch).
> 
> I'd suggest redo it a way similar to FADT refactoring
>   patch 1: fix checksum bug in virt/arm
>   patch 2: update reference tables in test
>   patch 3: introduce AcpiRsdpData similar to commit 937d1b587
>              (both arm and x86) wich stores all data in hos byte order
>   patch 4: convert arm's impl. to build_append_int_noprefix() API (commit 5d7a334f7)
>
>            ... move out to aml-build.c
>   patch 5: reuse generalized arm's build_rsdp() for x86, dropping x86 specific one
>       amending it to generate rev1 variant defined by revision in AcpiRsdpData
>       (commit dd1b2037a)
I agree patches #1, #2 and #5 make sense. 3 and 4 as well, but here
you're asking about something that's out of scope of the current serie.
I'll move those patches from this serie and build a 6 patches new serie
as suggested.

Cheers,
Samuel.
Igor Mammedov Nov. 22, 2018, 4:26 p.m. UTC | #7
On Wed, 21 Nov 2018 15:42:11 +0100
Samuel Ortiz <sameo@linux.intel.com> wrote:

> Hi Igor,
> 
> On Thu, Nov 08, 2018 at 03:16:23PM +0100, Igor Mammedov wrote:
> > On Mon,  5 Nov 2018 02:40:28 +0100
> > Samuel Ortiz <sameo@linux.intel.com> wrote:
> >   
> > > XSDT is the 64-bit version of the legacy ACPI RSDT (Root System
> > > Description Table). RSDT only allow for 32-bit addressses and have thus
> > > been deprecated. Since ACPI version 2.0, RSDPs should point at XSDTs and
> > > no longer RSDTs, although RSDTs are still supported for backward
> > > compatibility.
> > > 
> > > Since version 2.0, RSDPs should add an extended checksum, a complete table
> > > length and a version field to the table.  
> > 
> > This patch re-implements what arm/virt board already does
> > and fixes checksum bug in the later and at the same time
> > without a user (within the patch).
> > 
> > I'd suggest redo it a way similar to FADT refactoring
> >   patch 1: fix checksum bug in virt/arm
> >   patch 2: update reference tables in test
> >   patch 3: introduce AcpiRsdpData similar to commit 937d1b587
> >              (both arm and x86) wich stores all data in hos byte order
> >   patch 4: convert arm's impl. to build_append_int_noprefix() API (commit 5d7a334f7)
> >
> >            ... move out to aml-build.c
> >   patch 5: reuse generalized arm's build_rsdp() for x86, dropping x86 specific one
> >       amending it to generate rev1 variant defined by revision in AcpiRsdpData
> >       (commit dd1b2037a)  
> I agree patches #1, #2 and #5 make sense. 3 and 4 as well, but here
> you're asking about something that's out of scope of the current serie.
/me guilty of that, but I have excuses for doing so:
  * that's the only way to get rid of legacy approach given limited resources.
    So task goes to whomever touches old code. /others and me included/
    I'd be glad if someone would volunteer and do clean ups but in absence
    of such, the victim is interested party.
  * contributor to ACPI part learns how to use preferred approach,
    makes code more robust and clear as it's not possible to make
    endianness mistakes, very simple to review and notice mistakes
    as end result practically matches row by row a table described in spec.
  * there could be exceptions, like acpi/nvdimm.c also contributed by Intel
    whole file written in legacy style (it probably started before I started
    enforcing conversions, anyways it's late now and should be done as whole),
    or odd fixes to existing tables, or too complex case.
    (depending on case I might still ask for conversion)

My ranting aside, conversions I've asked for here are trivial and for
everyone's benefit /QEMU gets more maintainable code, users less bugs,
contributor knows requirements hence his patches go through less iterations,
hopefully if contributor stays around and does contributions/reviews to
acpi code, QEMU could get another co-maintainer for acpi part/

> I'll move those patches from this serie and build a 6 patches new serie
> as suggested.

Thanks!

> 
> Cheers,
> Samuel.
>
Samuel Ortiz Nov. 23, 2018, 9:36 a.m. UTC | #8
On Thu, Nov 22, 2018 at 05:26:52PM +0100, Igor Mammedov wrote:
> On Wed, 21 Nov 2018 15:42:11 +0100
> Samuel Ortiz <sameo@linux.intel.com> wrote:
> 
> > Hi Igor,
> > 
> > On Thu, Nov 08, 2018 at 03:16:23PM +0100, Igor Mammedov wrote:
> > > On Mon,  5 Nov 2018 02:40:28 +0100
> > > Samuel Ortiz <sameo@linux.intel.com> wrote:
> > >   
> > > > XSDT is the 64-bit version of the legacy ACPI RSDT (Root System
> > > > Description Table). RSDT only allow for 32-bit addressses and have thus
> > > > been deprecated. Since ACPI version 2.0, RSDPs should point at XSDTs and
> > > > no longer RSDTs, although RSDTs are still supported for backward
> > > > compatibility.
> > > > 
> > > > Since version 2.0, RSDPs should add an extended checksum, a complete table
> > > > length and a version field to the table.  
> > > 
> > > This patch re-implements what arm/virt board already does
> > > and fixes checksum bug in the later and at the same time
> > > without a user (within the patch).
> > > 
> > > I'd suggest redo it a way similar to FADT refactoring
> > >   patch 1: fix checksum bug in virt/arm
> > >   patch 2: update reference tables in test
> > >   patch 3: introduce AcpiRsdpData similar to commit 937d1b587
> > >              (both arm and x86) wich stores all data in hos byte order
> > >   patch 4: convert arm's impl. to build_append_int_noprefix() API (commit 5d7a334f7)
> > >
> > >            ... move out to aml-build.c
> > >   patch 5: reuse generalized arm's build_rsdp() for x86, dropping x86 specific one
> > >       amending it to generate rev1 variant defined by revision in AcpiRsdpData
> > >       (commit dd1b2037a)  
> > I agree patches #1, #2 and #5 make sense. 3 and 4 as well, but here
> > you're asking about something that's out of scope of the current serie.
> /me guilty of that, but I have excuses for doing so:
>   * that's the only way to get rid of legacy approach given limited resources.
>     So task goes to whomever touches old code. /others and me included/
>     I'd be glad if someone would volunteer and do clean ups but in absence
>     of such, the victim is interested party.
>   * contributor to ACPI part learns how to use preferred approach,
>     makes code more robust and clear as it's not possible to make
>     endianness mistakes, very simple to review and notice mistakes
>     as end result practically matches row by row a table described in spec.
I understand and agree with that. And to be clear: I'm happy to
contribute and work on that. But I'm also lucky to have an employer
that can afford to let me spend as much time as needed to do this kind
of refactoring/modernizing work. I just want to point out that other
potential newcomers to the project may not have that luxury.
I wonder (I sincerely do, I'm not making any assumptions) how much code
is left unmerged because the original submitter did not have the time or
budget to polish it up to the expected level.

Cheers,
Samuel.
diff mbox series

Patch

diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index c9bcb32d81..3580d0ce90 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -393,6 +393,9 @@  void
 build_rsdp(GArray *table_data,
            BIOSLinker *linker, unsigned rsdt_tbl_offset);
 void
+build_rsdp_xsdt(GArray *table_data,
+                BIOSLinker *linker, unsigned xsdt_tbl_offset);
+void
 build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
            const char *oem_id, const char *oem_table_id);
 void
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 51b608432f..a030d40674 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1651,6 +1651,43 @@  build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
                  (void *)xsdt, "XSDT", xsdt_len, 1, oem_id, oem_table_id);
 }
 
+/* RSDP pointing at an XSDT */
+void
+build_rsdp_xsdt(GArray *rsdp_table,
+                BIOSLinker *linker, unsigned xsdt_tbl_offset)
+{
+    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;
+    unsigned xsdt_offset =
+        (char *)&rsdp->length - rsdp_table->data;
+
+    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
+                             true /* fseg memory */);
+
+    memcpy(&rsdp->signature, "RSD PTR ", 8);
+    memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6);
+    rsdp->length = cpu_to_le32(sizeof(*rsdp));
+    /* version 2, we will use the XSDT pointer */
+    rsdp->revision = 0x02;
+
+    /* 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, xsdt_tbl_offset);
+
+    /* Legacy checksum to be filled by Guest linker */
+    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
+        (char *)rsdp - rsdp_table->data, xsdt_offset,
+        (char *)&rsdp->checksum - rsdp_table->data);
+
+    /* Extended checksum to be filled by Guest linker */
+    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
+        (char *)rsdp - rsdp_table->data, sizeof *rsdp,
+        (char *)&rsdp->extended_checksum - rsdp_table->data);
+}
+
 void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
                        uint64_t len, int node, MemoryAffinityFlags flags)
 {