From: "Michael S. Tsirkin" <mst@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: seabios@seabios.org, Kevin O'Connor <kevin@koconnor.net>,
qemu-devel@nongnu.org, lersek@redhat.com, lists@philjordan.eu,
imammedo@redhat.com, phil@philjordan.eu,
programmingkidx@gmail.com, kraxel@redhat.com
Subject: Re: [Qemu-devel] [seabios PATCH 1/2] seabios: build RSDT from XSDT
Date: Wed, 26 Jul 2017 23:05:03 +0300 [thread overview]
Message-ID: <20170726230055-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <20170726094235.14267-2-pbonzini@redhat.com>
On Wed, Jul 26, 2017 at 11:42:34AM +0200, Paolo Bonzini wrote:
> Old operating systems would like to have a rev1 (ACPI 1.0) FADT, but
> new operating systems would like to have rev3 (ACPI 2.0).
>
> Since old operating systems do not know about XSDTs, the
> solution is to point the RSDT to a rev1 FADT and the XSDT to a
> rev3 FADT.
>
> But, edk2 is not able to handle QEMU providing two FADTs and barfs when
> it sees the second; edk2 subscribes to the view that the platform code
> (meaning not only OVMF, but transitively QEMU's ACPI table builder)
> should not handle such hacks; it's common edk2 code that should handle
> FADT rev1 vs. rev3 and RSDT vs. XSDT.
What exactly does it do wrt RSDT?
> These patches make SeaBIOS follow the same model as edk2, the only
> difference being how the two identify ACPI tables from the BIOS
> linker/loader script. For SeaBIOS, this task is actually much
> simpler since it can just look into the RSDP: if QEMU only
> provides an XSDT, SeaBIOS takes care of building the RSDT and
> rev1 FADT to satisfy ACPI 1.0-compliant operating systems.
>
> This part makes SeaBIOS build an RSDT out of an existing XSDT,
> patching the RSDP to point to the RSDT.
>
> Reviewed-by: Phil Dennis-Jordan <phil@philjordan.eu>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> src/fw/paravirt.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
> src/std/acpi.h | 11 +++++++++++
> 2 files changed, 59 insertions(+), 1 deletion(-)
>
> diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c
> index 5b23d78..927fd75 100644
> --- a/src/fw/paravirt.c
> +++ b/src/fw/paravirt.c
> @@ -25,6 +25,7 @@
> #include "x86.h" // cpuid
> #include "xen.h" // xen_biostable_setup
> #include "stacks.h" // yield
> +#include "std/acpi.h"
>
> // Amount of continuous ram under 4Gig
> u32 RamSize;
> @@ -147,6 +148,50 @@ static void msr_feature_control_setup(void)
> wrmsr_smp(MSR_IA32_FEATURE_CONTROL, feature_control_bits);
> }
>
> +static void
> +build_compatibility_rsdt(void)
> +{
> + if (RsdpAddr->rsdt_physical_address)
> + return;
> +
> + u64 xsdt_addr = RsdpAddr->xsdt_physical_address;
> + if (xsdt_addr & ~0xffffffffULL)
> + return;
> +
> + struct xsdt_descriptor_rev1 *xsdt = (void*)(u32)xsdt_addr;
> + void *end = (void*)xsdt + xsdt->length;
> + struct rsdt_descriptor_rev1 *rsdt;
> + int rsdt_size = offsetof(struct rsdt_descriptor_rev1, table_offset_entry[0]);
> + int i;
> + for (i=0; (void*)&xsdt->table_offset_entry[i] < end; i++) {
> + u64 tbl_addr = xsdt->table_offset_entry[i];
> + if (!tbl_addr || (tbl_addr & ~0xffffffffULL))
> + continue;
> + rsdt_size += 4;
> + }
> +
> + rsdt = malloc_high(rsdt_size);
> + RsdpAddr->rsdt_physical_address = (u32)rsdt;
> + RsdpAddr->checksum -= checksum(RsdpAddr,
> + offsetof(struct rsdp_descriptor, length));
> + RsdpAddr->extended_checksum -= checksum(RsdpAddr,
> + sizeof(struct rsdp_descriptor));
> +
> + memcpy(rsdt, xsdt, sizeof(struct acpi_table_header));
> + rsdt->signature = RSDT_SIGNATURE;
> + rsdt->length = rsdt_size;
> + rsdt->revision = 1;
> + int j;
> + for (i=j=0; (void*)&xsdt->table_offset_entry[i] < end; i++) {
> + u64 tbl_addr = xsdt->table_offset_entry[i];
> + if (!tbl_addr || (tbl_addr & ~0xffffffffULL))
> + continue;
> + rsdt->table_offset_entry[j++] = (u32)tbl_addr;
> + }
> +
> + rsdt->checksum -= checksum(rsdt, rsdt_size);
> +}
> +
> void
> qemu_platform_setup(void)
> {
> @@ -186,8 +231,10 @@ qemu_platform_setup(void)
>
> RsdpAddr = find_acpi_rsdp();
>
> - if (RsdpAddr)
> + if (RsdpAddr) {
> + build_compatibility_rsdt();
> return;
> + }
>
> /* If present, loader should have installed an RSDP.
> * Not installed? We might still be able to continue
> diff --git a/src/std/acpi.h b/src/std/acpi.h
> index c2ea707..a77b53c 100644
> --- a/src/std/acpi.h
> +++ b/src/std/acpi.h
> @@ -133,6 +133,17 @@ struct rsdt_descriptor_rev1
> } PACKED;
>
> /*
> + * ACPI 2.0 Extended System Description Table (XSDT)
> + */
> +#define XSDT_SIGNATURE 0x54445358 // XSDT
> +struct xsdt_descriptor_rev1
> +{
> + ACPI_TABLE_HEADER_DEF /* ACPI common table header */
> + u64 table_offset_entry[0]; /* Array of pointers to other */
> + /* ACPI tables */
> +} PACKED;
> +
> +/*
> * ACPI 1.0 Firmware ACPI Control Structure (FACS)
> */
> #define FACS_SIGNATURE 0x53434146 // FACS
> --
> 2.13.3
>
next prev parent reply other threads:[~2017-07-26 20:05 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-26 9:42 [Qemu-devel] [seabios PATCH for qemu 2.10 0/2] seabios: build ACPI 1.0-compatible ACPI tables Paolo Bonzini
2017-07-26 9:42 ` [Qemu-devel] [seabios PATCH 1/2] seabios: build RSDT from XSDT Paolo Bonzini
2017-07-26 20:05 ` Michael S. Tsirkin [this message]
2017-07-26 20:22 ` Paolo Bonzini
2017-07-26 9:42 ` [Qemu-devel] [seabios PATCH 2/2] seabios: create rev1 FADT in compatibility RSDT Paolo Bonzini
2017-08-01 17:32 ` [Qemu-devel] [seabios PATCH for qemu 2.10 0/2] seabios: build ACPI 1.0-compatible ACPI tables Michael S. Tsirkin
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=20170726230055-mutt-send-email-mst@kernel.org \
--to=mst@redhat.com \
--cc=imammedo@redhat.com \
--cc=kevin@koconnor.net \
--cc=kraxel@redhat.com \
--cc=lersek@redhat.com \
--cc=lists@philjordan.eu \
--cc=pbonzini@redhat.com \
--cc=phil@philjordan.eu \
--cc=programmingkidx@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=seabios@seabios.org \
/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).