qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC] copy OEM ACPI parameters from SLIC table to RSDT


From: Laszlo Ersek
Subject: Re: [Qemu-devel] [RFC] copy OEM ACPI parameters from SLIC table to RSDT
Date: Sun, 06 Apr 2014 14:21:16 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.4.0

On 04/06/14 13:08, Michael Tokarev wrote:
> 06.04.2014 14:53, Michael S. Tsirkin wrote:
>> On Sun, Apr 06, 2014 at 01:49:11PM +0400, Michael Tokarev wrote:
>>> When building RSDT table, pick OEM ID fields from uer-supplied SLIC
>>> table instead of using hard-coded QEMU defaults.  This way, say,
>>> OEM version of Windows7 can be run inside qemu using the same OEM
>>> activation as on bare metal, by pointing at system firmware:
>>>
>>>   -acpitable file=/sys/firmware/acpi/tables/SLIC
>>
>> Right, so this doesn't work in 1.7 either, right?
>> It's not a regression?
> 
> It doesn't work in 1.7 too, but it is not a regression.
> Before 1.7 I used a very similar approach patching seabios,
> for several years.  Here's one of the first versions of this
> approach -- http://lists.gnu.org/archive/html/qemu-devel/2011-03/msg03080.html
> 
> I used this approach since that time locally.
> For 1.7 I used seabios without acpi table loading interface, so
> old approach worked fine for me.  Here's the current seabios patch:
> 
> --- a/src/fw/acpi.c     2013-11-24 00:03:36.000000000 +0400
> +++ b/src/fw/acpi.c     2013-11-24 00:03:48.053886298 +0400
> @@ -20,6 +20,8 @@
> 
>  u32 acpi_pm1a_cnt VARFSEG;
> 
> +static const struct acpi_table_header *slic;
> +
>  static void
>  build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
>  {
> @@ -32,6 +34,9 @@ build_header(struct acpi_table_header *h
>      h->oem_revision = cpu_to_le32(1);
>      memcpy(h->asl_compiler_id, BUILD_APPNAME4, 4);
>      h->asl_compiler_revision = cpu_to_le32(1);
> +    if (slic && sig == RSDT_SIGNATURE)
> +        /* for win7/vista, RSDT oem should match SLIC, min 14 bytes */
> +        memcpy(h->oem_id, slic->oem_id, 6 + 4 + 4);
>      h->checksum -= checksum(h, len);
>  }
> 
> @@ -642,6 +647,8 @@ acpi_setup(void)
>              }
>          } else {
>              ACPI_INIT_TABLE(table);
> +            if (table->signature == 0x43494c53/*SLIC*/)
> +                slic = table;
>          }
>          if (tbl_idx == MAX_ACPI_TABLES) {
>              warn_noalloc();
> 
>>> Windows7 requires that OEM ID in RSDT matches those in SLIC to
>>> consider SLIC to be valid.
>>
>> Which fields need to match which, exactly?
> 
> As can be seen in the patch itself, that's 2 fields - oem_id [4]
> and oem_table_id[8], in SLIC and RSDT.  This is enough for win7
> at least.
> 
>>> This is somewhat hackish approach, but it works fairy well in
>>> practice.
>>>
>>> I'm not asking to apply this directly, but instead am trying to
>>> show what's needed to get win to work.  Maybe a new command-line
>>> option for that will do, maybe something else.
>>
>> I think it's kind of reasonable - seems better than
>> adding more flags - but I'd like to avoid
>> poking at acpi_tables array in acpi-build.c
>>
>> How about an API to set/query OEM ID?
> 
> Such an api might be useful, and it actually _is_ useful to keep
> compatibility with older guests, which is a slightly different
> but very important topic (for example, my win8 guest which were
> activated in qemu-1.1 does not work anymore in qemu-1.2, exactly
> because of changed OEM ID, -- it is the commit which updated
> qemu version number which breaks win8 activation here).
> 
> But this api wont help when we already have whole SLIC table as
> in the example above.
> 
> 
> Overall, the more I think about it, the less I consider it useful.
> Because it looks like windows vista and 7 era is finished (yes, the
> same thing applies to vista as well), now it is win8+ which does
> not use this OEM activation mechanism anymore.  Instead, it uses
> hw-based activation, for which we need to keep OEM ID in ACPI too.
> 
> Maybe back in 2010 when I faced this problem for the first time it
> was a good idea to have slic-based adoption for rsdt in qemu, now
> it isn't that important anymore.

I'd like to add two points (purely FYI, ie. in no way to contradict
anything you said -- actually, my 2nd point even seems to confirm what
you said):

(1) In the OVMF ACPI download patch, we skip qemu's RSDT and XSDT on
purpose:

https://github.com/tianocore/edk2/commit/96bbdbc856930abf38d0cc289536ebd11043f80f#diff-7e7e6f95dd6acdc67fcfdc854aa5f46eR603

That's because the EFI_ACPI_TABLE_PROTOCOL, which
- is specified in UEFI-2.4A, Chapter 19,
- has an edk2 reference implementation in
MdeModulePkg/Universal/Acpi/AcpiTableDxe/,
- OVMF uses to install ACPI tables

handles RSDT/XSDT automatically, outside of OVMF's jurisdiction.

In particular, the edk2 reference implementation of
EFI_ACPI_TABLE_PROTOCOL sets the RSDT's OemId and OemTableId fields from
the same in FADT (which qemu does provide, signature "FACP"):

https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c#L695

(2) I recently found this forum post from Chris Evich (CC'd):

  Libvirt + Fedora 20 + Windows 8.1 OEM + UEFI = Oh My!
  http://forums.fedoraforum.org/showthread.php?p=1694052

(scroll up to the start of the thread).

It's real-life evidence that handling the SLIC manually (plus some other
stuff), without adapting the OemId & OemTableId fields in RSDT/XSDT to
SLIC, is sufficient to keep the Windows 8.1 OEM guest happy.

(I found the forum post because I regularly google last week's OVMF
references, to see what's up. (As a side note, it's nice to see that
users have put OVMF's PlatformDxe to use (for setting the GOP
resolution) in less than ten days after that series was committed (SVN
r15375).))

Thanks
Laszlo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]