qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* Question on UEFI ACPI tables setup and probing on arm64
@ 2020-10-30  2:50 Ying Fang
  2020-11-03 12:39 ` Igor Mammedov
  0 siblings, 1 reply; 7+ messages in thread
From: Ying Fang @ 2020-10-30  2:50 UTC (permalink / raw)
  To: QEMU Developers; +Cc: imammedo, qemu-arm, philmd, wangzhigang17, Peter Maydell

Hi,

I have a question on UEFI/ACPI tables setup and probing on arm64 platform.

Currently on arm64 platform guest can be booted with both fdt and ACPI
supported. If ACPI is enabled, [1] says the only defined method for
passing ACPI tables to the kernel is via the UEFI system configuration
table. So AFAIK, ACPI Should be dependent on UEFI.

What's more [2] says UEFI kernel support on the ARM architectures
is only available through a *stub*. The stub populates the FDT /chosen
node with some UEFI parameters describing the UEFI location info.

So i dump /sys/firmware/fdt from the guest, it does have something like:

/dts-v1/;

/ {
	#size-cells = <0x02>;
	#address-cells = <0x02>;

	chosen {
		linux,uefi-mmap-desc-ver = <0x01>;
		linux,uefi-mmap-desc-size = <0x30>;
		linux,uefi-mmap-size = <0x810>;
		linux,uefi-mmap-start = <0x04 0x3c0ce018>;
		linux,uefi-system-table = <0x04 0x3f8b0018>;
		bootargs = "BOOT_IMAGE=/vmlinuz-4.19.90-2003.4.0.0036.oe1.aarch64 
root=/dev/mapper/openeuler-root ro rd.lvm.lv=openeuler/root 
rd.lvm.lv=openeuler/swap video=VGA-1:640x480-32@60me 
smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15 
crashkernel=1024M,high video=efifb:off video=VGA-1:640x480-32@60me";
		linux,initrd-end = <0x04 0x3a85a5da>;
		linux,initrd-start = <0x04 0x392f2000>;
	};
};

But the question is that I did not see any code adding the uefi
in fdt chosen node in *arm_load_dtb* or anywhere else.
Qemu only maps the OVMF binary file into a pflash device.
So I'm really confused on how UEFI information is provided to
guest by qemu. Does anybody know of the details about it ?

[1] https://www.kernel.org/doc/html/latest/arm64/arm-acpi.html
[2] https://www.kernel.org/doc/Documentation/arm/uefi.rst

Thanks.
Ying


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Question on UEFI ACPI tables setup and probing on arm64
  2020-10-30  2:50 Question on UEFI ACPI tables setup and probing on arm64 Ying Fang
@ 2020-11-03 12:39 ` Igor Mammedov
  2020-11-04 21:46   ` Laszlo Ersek
  0 siblings, 1 reply; 7+ messages in thread
From: Igor Mammedov @ 2020-11-03 12:39 UTC (permalink / raw)
  To: Ying Fang
  Cc: Peter Maydell, lersek, QEMU Developers, qemu-arm, wangzhigang17, philmd

On Fri, 30 Oct 2020 10:50:01 +0800
Ying Fang <fangying1@huawei.com> wrote:

> Hi,
> 
> I have a question on UEFI/ACPI tables setup and probing on arm64 platform.

CCing Laszlo,
who might know how it's implemented.
 
> Currently on arm64 platform guest can be booted with both fdt and ACPI
> supported. If ACPI is enabled, [1] says the only defined method for
> passing ACPI tables to the kernel is via the UEFI system configuration
> table. So AFAIK, ACPI Should be dependent on UEFI.
> 
> What's more [2] says UEFI kernel support on the ARM architectures
> is only available through a *stub*. The stub populates the FDT /chosen
> node with some UEFI parameters describing the UEFI location info.
> 
> So i dump /sys/firmware/fdt from the guest, it does have something like:
> 
> /dts-v1/;
> 
> / {
> 	#size-cells = <0x02>;
> 	#address-cells = <0x02>;
> 
> 	chosen {
> 		linux,uefi-mmap-desc-ver = <0x01>;
> 		linux,uefi-mmap-desc-size = <0x30>;
> 		linux,uefi-mmap-size = <0x810>;
> 		linux,uefi-mmap-start = <0x04 0x3c0ce018>;
> 		linux,uefi-system-table = <0x04 0x3f8b0018>;
> 		bootargs = "BOOT_IMAGE=/vmlinuz-4.19.90-2003.4.0.0036.oe1.aarch64 
> root=/dev/mapper/openeuler-root ro rd.lvm.lv=openeuler/root 
> rd.lvm.lv=openeuler/swap video=VGA-1:640x480-32@60me 
> smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15 
> crashkernel=1024M,high video=efifb:off video=VGA-1:640x480-32@60me";
> 		linux,initrd-end = <0x04 0x3a85a5da>;
> 		linux,initrd-start = <0x04 0x392f2000>;
> 	};
> };
> 
> But the question is that I did not see any code adding the uefi
> in fdt chosen node in *arm_load_dtb* or anywhere else.
> Qemu only maps the OVMF binary file into a pflash device.
> So I'm really confused on how UEFI information is provided to
> guest by qemu. Does anybody know of the details about it ?
> 
> [1] https://www.kernel.org/doc/html/latest/arm64/arm-acpi.html
> [2] https://www.kernel.org/doc/Documentation/arm/uefi.rst
> 
> Thanks.
> Ying
> 



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Question on UEFI ACPI tables setup and probing on arm64
  2020-11-03 12:39 ` Igor Mammedov
@ 2020-11-04 21:46   ` Laszlo Ersek
  2020-11-04 21:57     ` Ard Biesheuvel
  2020-11-05  4:30     ` Ying Fang
  0 siblings, 2 replies; 7+ messages in thread
From: Laszlo Ersek @ 2020-11-04 21:46 UTC (permalink / raw)
  To: Igor Mammedov, Ying Fang
  Cc: Peter Maydell, Drew Jones, QEMU Developers, qemu-arm,
	wangzhigang17, Ard Biesheuvel (ARM address),
	philmd

+Ard, +Drew

On 11/03/20 13:39, Igor Mammedov wrote:
> On Fri, 30 Oct 2020 10:50:01 +0800
> Ying Fang <fangying1@huawei.com> wrote:
> 
>> Hi,
>>
>> I have a question on UEFI/ACPI tables setup and probing on arm64 platform.
> 
> CCing Laszlo,
> who might know how it's implemented.
>  
>> Currently on arm64 platform guest can be booted with both fdt and ACPI
>> supported. If ACPI is enabled, [1] says the only defined method for
>> passing ACPI tables to the kernel is via the UEFI system configuration
>> table. So AFAIK, ACPI Should be dependent on UEFI.

That's correct. The ACPI entry point (RSD PTR) on AARCH64 is defined in
terms of UEFI.

>>
>> What's more [2] says UEFI kernel support on the ARM architectures
>> is only available through a *stub*. The stub populates the FDT /chosen
>> node with some UEFI parameters describing the UEFI location info.

Yes.

>>
>> So i dump /sys/firmware/fdt from the guest, it does have something like:
>>
>> /dts-v1/;
>>
>> / {
>> 	#size-cells = <0x02>;
>> 	#address-cells = <0x02>;
>>
>> 	chosen {
>> 		linux,uefi-mmap-desc-ver = <0x01>;
>> 		linux,uefi-mmap-desc-size = <0x30>;
>> 		linux,uefi-mmap-size = <0x810>;
>> 		linux,uefi-mmap-start = <0x04 0x3c0ce018>;
>> 		linux,uefi-system-table = <0x04 0x3f8b0018>;
>> 		bootargs = "BOOT_IMAGE=/vmlinuz-4.19.90-2003.4.0.0036.oe1.aarch64 
>> root=/dev/mapper/openeuler-root ro rd.lvm.lv=openeuler/root 
>> rd.lvm.lv=openeuler/swap video=VGA-1:640x480-32@60me 
>> smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15 
>> crashkernel=1024M,high video=efifb:off video=VGA-1:640x480-32@60me";
>> 		linux,initrd-end = <0x04 0x3a85a5da>;
>> 		linux,initrd-start = <0x04 0x392f2000>;
>> 	};
>> };
>>
>> But the question is that I did not see any code adding the uefi
>> in fdt chosen node in *arm_load_dtb* or anywhere else.

That's because the "UEFI stub" is a part of the guest kernel. It wraps
the guest kernel image into a UEFI application binary. For a while, the
guest kernel runs as a UEFI application, stashing some UEFI artifacts in
*a* device tree, and then (after some other heavy lifting) jumping into
the kernel proper.

>> Qemu only maps the OVMF binary file into a pflash device.
>> So I'm really confused on how UEFI information is provided to
>> guest by qemu. Does anybody know of the details about it ?

It's complex, unfortunately.

(1) QEMU always generates a DTB for the guest firmware. This DTB is
placed at the base of the guest RAM.

See the arm_load_dtb() call in virt_machine_done() [hw/arm/virt.c] in
QEMU. I think.


(2) QEMU generates ACPI content, and exposes it via fw_cfg.

See the virt_acpi_setup() call in the same virt_machine_done() function
[hw/arm/virt.c] in QEMU.


(3) The fw_cfg device itself is apparent to the guest firmware via the
DTB from point (1). See the following steps in edk2:

(3a) "ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c"

This saves the initial DTB (from the base of guest RAM, where it could
be overwritten by whatever) to a dynamically allocated area. This
"stashing" occurs early.

(3b) "ArmVirtPkg/FdtClientDxe/FdtClientDxe.c"

This driver exposes the (dynamically reallocated / copied) DTB via a
custom UEFI protocol to the rest of the firmware. (This happens much
later.) This protocol / driver can be considered the "owner" of the
stashed DTB from (3a).

(3c) "ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c"

This is the fw_cfg device access library, discovering the fw_cfg
registers via the above UEFI protocol. The library is linked into each
firmware module that needs fw_cfg access.


(4) The firmware interprets QEMU's DTB for actual content (parsing
values, configuring hardware, accessing devices).

This occurs in a whole bunch of locations, mostly via consuming the
custom protocol from (3b). Some info that's needed very early is parsed
out of the DTB right in step (3a).


(5) The guest firmware has a dedicated driver that checks whether QEMU
was configured with ACPI enabled or disabled, and publishes that choice
to the rest of the firmware. This is necessary because some firmware
actions / infrastructure parts cannot (must not) proceed until this
decision has been interpreted.

See in edk2:

- ArmVirtPkg/PlatformHasAcpiDtDxe

This driver keys off of the presence of the "etc/table-loader" fw_cfg
file, coming from step (2), using the fw_cfg access library from step (3c).

If ACPI was enabled on the QEMU cmdline, then the rest of the firmware
is "level-triggered" to proceed with the ACPI infrastructure.

Otherwise, the rest of the firmware is "level-triggered" that DT was
chosen for the OS.

("Level-triggering" means the installation of custom NULL protocols,
which permits drivers dependent on DT vs ACPI to be dispatched.)


(6) If DT was selected (ACPI was disabled), per step (5), then
FdtClientDxe (introduced under step (3b)) has another job: it forwards
the original stashed DTB (see (3a)) to the guest OS.

This "DTB forwarding" occurs through a particular UEFI config table; the
GUID is B1B621D5-F19C-41A5-830B-D9152C69AAE0 -- known as
DEVICE_TREE_GUID in the kernel ("include/linux/efi.h").

See the OnPlatformHasDeviceTree() function in
"ArmVirtPkg/FdtClientDxe/FdtClientDxe.c", in edk2.


(7) If ACPI was selected instead, according to step (5), then through
the fw_cfg access described in (3c), the guest firmware "blindly"
processes the ACPI payload from QEMU (from step (2)).

This "blind processing" means that the guest firmware runs the "ACPI
linker/loader script" (the "etc/table-loader" fw_cfg file), installing a
number of ACPI tables for the guest OS. The guest firmware does not
interpret the ACPI tables.

"Installing ACPI tables" ultimately means exposing stuff under the
particular UEFI config table that stands for the RSD PTR -- the GUID is
8868E871-E4F1-11D3-BC22-0080C73C8881. (Known as ACPI_20_TABLE_GUID in
Linux, "include/linux/efi.h".)

See the following in edk2:

- OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf

In this case, the guest firmware does not forward QEMU's original DTB to
the guest OS.


(8) Ultimately, from the guest OS's point of view, a UEFI config table
for *either* the RSD PTR (ACPI_20_TABLE_GUID) *or* QEMU's DTB
(DEVICE_TREE_GUID) is going to exist.


(9) (Ard, please correct the below if necessary; thanks.)

The UEFI stub of the guest kernel (which is a UEFI application) uses a
device tree as its main communication channel to the (later-started)
kernel entry point, AIUI.

The UEFI stub basically inverts the importance of the UEFI system table
versus the device tree -- the UEFI stub *converts* the UEFI system table
(the multitude of UEFI config tables) into a device tree. This is my
understanding anyway.

(9a) If ACPI was disabled on the QEMU command line, then the guest
kernel *adopts* the device tree that was forwarded to it in (6), via the
UEFI config table marked with DEVICE_TREE_GUID.

(9b) If ACPI was enabled on the QEMU command line, then the UEFI stub
creates a brand new (empty) device tree (AIUI).

Either way, the UEFI system table is linked *under* the -- adopted or
new -- device tree, through the "chosen" node. And so, if ACPI was
enabled, the ACPI RSD PTR (coming from step (7)) becomes visible to the
kernel proper as well, through the UEFI config table with
ACPI_20_TABLE_GUID.

I believe this is implemented under "drivers/firmware/efi/libstub" in
the kernel tree.

Thanks,
Laszlo



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Question on UEFI ACPI tables setup and probing on arm64
  2020-11-04 21:46   ` Laszlo Ersek
@ 2020-11-04 21:57     ` Ard Biesheuvel
  2020-11-05  4:30     ` Ying Fang
  1 sibling, 0 replies; 7+ messages in thread
From: Ard Biesheuvel @ 2020-11-04 21:57 UTC (permalink / raw)
  To: Laszlo Ersek, Igor Mammedov, Ying Fang
  Cc: Peter Maydell, Drew Jones, QEMU Developers, qemu-arm,
	wangzhigang17, philmd

On 11/4/20 10:46 PM, Laszlo Ersek wrote:
...
> 
> (9) (Ard, please correct the below if necessary; thanks.)
> 
> The UEFI stub of the guest kernel (which is a UEFI application) uses a
> device tree as its main communication channel to the (later-started)
> kernel entry point, AIUI.
> 
> The UEFI stub basically inverts the importance of the UEFI system table
> versus the device tree -- the UEFI stub *converts* the UEFI system table
> (the multitude of UEFI config tables) into a device tree. This is my
> understanding anyway.
> 

Not entirely. The UEFI stub uses DT to communicate with the kernel 
proper, just like a non-EFI bootloader does. There are two pieces of 
information regarding EFI that the stub passes via the device tree:
- the EFI system table address
- the EFI memory map (address, size, descriptor size etc)

(Aside: unfortunately, we cannot pass the latter information via a EFI 
configuration table, given that we call SetVirtualAddressMap() in the 
stub, which causes the config_tables member of the system table to be 
converted into a virtual address. That virtual address can only be 
converted into a physical address if we have access to the EFI memory map.)

All other information passed between the EFI stub and the kernel proper 
is passed via Linux-specific EFI configuration tables.

> (9a) If ACPI was disabled on the QEMU command line, then the guest
> kernel *adopts* the device tree that was forwarded to it in (6), via the
> UEFI config table marked with DEVICE_TREE_GUID.
> 

Yes, although the EFI stub updates/augments it with the two data items 
mentioned above, as well as the kernel command line, initrd base and 
size and a KASLR seed [if enabled].

> (9b) If ACPI was enabled on the QEMU command line, then the UEFI stub
> creates a brand new (empty) device tree (AIUI).
>

... unless GRUB executed first and loaded a initrd, and passed this 
information via the device tree. In this case, GRUB creates an empty DT 
(Note that I posted the GRUB patches to implement LoadFile2 based initrd 
loading just a week or so ago)

> Either way, the UEFI system table is linked *under* the -- adopted or
> new -- device tree, through the "chosen" node. And so, if ACPI was
> enabled, the ACPI RSD PTR (coming from step (7)) becomes visible to the
> kernel proper as well, through the UEFI config table with
> ACPI_20_TABLE_GUID.
> 
> I believe this is implemented under "drivers/firmware/efi/libstub" in
> the kernel tree.
> 
> Thanks,
> Laszlo
> 



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Question on UEFI ACPI tables setup and probing on arm64
  2020-11-04 21:46   ` Laszlo Ersek
  2020-11-04 21:57     ` Ard Biesheuvel
@ 2020-11-05  4:30     ` Ying Fang
  2020-11-06 17:09       ` Laszlo Ersek
  1 sibling, 1 reply; 7+ messages in thread
From: Ying Fang @ 2020-11-05  4:30 UTC (permalink / raw)
  To: Laszlo Ersek, Igor Mammedov
  Cc: Peter Maydell, Drew Jones, QEMU Developers, qemu-arm,
	wangzhigang17, Ard Biesheuvel (ARM address),
	philmd



On 11/5/2020 5:46 AM, Laszlo Ersek wrote:
> +Ard, +Drew
> 
> On 11/03/20 13:39, Igor Mammedov wrote:
>> On Fri, 30 Oct 2020 10:50:01 +0800
>> Ying Fang <fangying1@huawei.com> wrote:
>>
>>> Hi,
>>>
>>> I have a question on UEFI/ACPI tables setup and probing on arm64 platform.
>>
>> CCing Laszlo,
>> who might know how it's implemented.
>>   
>>> Currently on arm64 platform guest can be booted with both fdt and ACPI
>>> supported. If ACPI is enabled, [1] says the only defined method for
>>> passing ACPI tables to the kernel is via the UEFI system configuration
>>> table. So AFAIK, ACPI Should be dependent on UEFI.
> 
> That's correct. The ACPI entry point (RSD PTR) on AARCH64 is defined in
> terms of UEFI.
> 
>>>
>>> What's more [2] says UEFI kernel support on the ARM architectures
>>> is only available through a *stub*. The stub populates the FDT /chosen
>>> node with some UEFI parameters describing the UEFI location info.
> 
> Yes.
> 
>>>
>>> So i dump /sys/firmware/fdt from the guest, it does have something like:
>>>
>>> /dts-v1/;
>>>
>>> / {
>>> 	#size-cells = <0x02>;
>>> 	#address-cells = <0x02>;
>>>
>>> 	chosen {
>>> 		linux,uefi-mmap-desc-ver = <0x01>;
>>> 		linux,uefi-mmap-desc-size = <0x30>;
>>> 		linux,uefi-mmap-size = <0x810>;
>>> 		linux,uefi-mmap-start = <0x04 0x3c0ce018>;
>>> 		linux,uefi-system-table = <0x04 0x3f8b0018>;
>>> 		bootargs = "BOOT_IMAGE=/vmlinuz-4.19.90-2003.4.0.0036.oe1.aarch64
>>> root=/dev/mapper/openeuler-root ro rd.lvm.lv=openeuler/root
>>> rd.lvm.lv=openeuler/swap video=VGA-1:640x480-32@60me
>>> smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15
>>> crashkernel=1024M,high video=efifb:off video=VGA-1:640x480-32@60me";
>>> 		linux,initrd-end = <0x04 0x3a85a5da>;
>>> 		linux,initrd-start = <0x04 0x392f2000>;
>>> 	};
>>> };
>>>
>>> But the question is that I did not see any code adding the uefi
>>> in fdt chosen node in *arm_load_dtb* or anywhere else.
> 
> That's because the "UEFI stub" is a part of the guest kernel. It wraps
> the guest kernel image into a UEFI application binary. For a while, the
> guest kernel runs as a UEFI application, stashing some UEFI artifacts in
> *a* device tree, and then (after some other heavy lifting) jumping into
> the kernel proper.
> 
>>> Qemu only maps the OVMF binary file into a pflash device.
>>> So I'm really confused on how UEFI information is provided to
>>> guest by qemu. Does anybody know of the details about it ?
> 
> It's complex, unfortunately.
> 
> (1) QEMU always generates a DTB for the guest firmware. This DTB is
> placed at the base of the guest RAM.
> 
> See the arm_load_dtb() call in virt_machine_done() [hw/arm/virt.c] in
> QEMU. I think.

Hi Laszlo. Thanks so much for sharing the details with us.
The reply nearly covers the boot sequence of aarch64 on the whole.

I see it in Qemu the *loader_start* is fixed at 1 GiB on the
physical address space which points to the DRAM base. In ArmVirtQemu.dsc
PcdDeviceTreeInitialBaseAddress is set 0x40000000 with correspondence.

Here I also see the discussion about DRAM base for ArmVirtQemu.
https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg03127.html

I am still not sure how UEFI knows that it is running on a ArmVirtQemu
machine type. Does UEFI derive it from the fdt *compatible* property ?

> 
> 
> (2) QEMU generates ACPI content, and exposes it via fw_cfg.
> 
> See the virt_acpi_setup() call in the same virt_machine_done() function
> [hw/arm/virt.c] in QEMU.
> 
> 
> (3) The fw_cfg device itself is apparent to the guest firmware via the
> DTB from point (1). See the following steps in edk2:
> 
> (3a) "ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c"
> 
> This saves the initial DTB (from the base of guest RAM, where it could
> be overwritten by whatever) to a dynamically allocated area. This
> "stashing" occurs early.
> 
> (3b) "ArmVirtPkg/FdtClientDxe/FdtClientDxe.c"
> 
> This driver exposes the (dynamically reallocated / copied) DTB via a
> custom UEFI protocol to the rest of the firmware. (This happens much
> later.) This protocol / driver can be considered the "owner" of the
> stashed DTB from (3a).
> 
> (3c) "ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c"
> 
> This is the fw_cfg device access library, discovering the fw_cfg
> registers via the above UEFI protocol. The library is linked into each
> firmware module that needs fw_cfg access.
> 
> 
> (4) The firmware interprets QEMU's DTB for actual content (parsing
> values, configuring hardware, accessing devices).
> 
> This occurs in a whole bunch of locations, mostly via consuming the
> custom protocol from (3b). Some info that's needed very early is parsed
> out of the DTB right in step (3a).
> 
> 
> (5) The guest firmware has a dedicated driver that checks whether QEMU
> was configured with ACPI enabled or disabled, and publishes that choice
> to the rest of the firmware. This is necessary because some firmware
> actions / infrastructure parts cannot (must not) proceed until this
> decision has been interpreted.
> 
> See in edk2:
> 
> - ArmVirtPkg/PlatformHasAcpiDtDxe
> 
> This driver keys off of the presence of the "etc/table-loader" fw_cfg
> file, coming from step (2), using the fw_cfg access library from step (3c).
> 
> If ACPI was enabled on the QEMU cmdline, then the rest of the firmware
> is "level-triggered" to proceed with the ACPI infrastructure.
> 
> Otherwise, the rest of the firmware is "level-triggered" that DT was
> chosen for the OS.
> 
> ("Level-triggering" means the installation of custom NULL protocols,
> which permits drivers dependent on DT vs ACPI to be dispatched.)
> 
> 
> (6) If DT was selected (ACPI was disabled), per step (5), then
> FdtClientDxe (introduced under step (3b)) has another job: it forwards
> the original stashed DTB (see (3a)) to the guest OS.
> 
> This "DTB forwarding" occurs through a particular UEFI config table; the
> GUID is B1B621D5-F19C-41A5-830B-D9152C69AAE0 -- known as
> DEVICE_TREE_GUID in the kernel ("include/linux/efi.h").
> 
> See the OnPlatformHasDeviceTree() function in
> "ArmVirtPkg/FdtClientDxe/FdtClientDxe.c", in edk2.
> 
> 
> (7) If ACPI was selected instead, according to step (5), then through
> the fw_cfg access described in (3c), the guest firmware "blindly"
> processes the ACPI payload from QEMU (from step (2)).
> 
> This "blind processing" means that the guest firmware runs the "ACPI
> linker/loader script" (the "etc/table-loader" fw_cfg file), installing a
> number of ACPI tables for the guest OS. The guest firmware does not
> interpret the ACPI tables.
> 
> "Installing ACPI tables" ultimately means exposing stuff under the
> particular UEFI config table that stands for the RSD PTR -- the GUID is
> 8868E871-E4F1-11D3-BC22-0080C73C8881. (Known as ACPI_20_TABLE_GUID in
> Linux, "include/linux/efi.h".)
> 
> See the following in edk2:
> 
> - OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf
> 
> In this case, the guest firmware does not forward QEMU's original DTB to
> the guest OS.
> 
> 
> (8) Ultimately, from the guest OS's point of view, a UEFI config table
> for *either* the RSD PTR (ACPI_20_TABLE_GUID) *or* QEMU's DTB
> (DEVICE_TREE_GUID) is going to exist.
> 
> 
> (9) (Ard, please correct the below if necessary; thanks.)
> 
> The UEFI stub of the guest kernel (which is a UEFI application) uses a
> device tree as its main communication channel to the (later-started)
> kernel entry point, AIUI.
> 
> The UEFI stub basically inverts the importance of the UEFI system table
> versus the device tree -- the UEFI stub *converts* the UEFI system table
> (the multitude of UEFI config tables) into a device tree. This is my
> understanding anyway.
> 
> (9a) If ACPI was disabled on the QEMU command line, then the guest
> kernel *adopts* the device tree that was forwarded to it in (6), via the
> UEFI config table marked with DEVICE_TREE_GUID.
> 
> (9b) If ACPI was enabled on the QEMU command line, then the UEFI stub
> creates a brand new (empty) device tree (AIUI).
> 
> Either way, the UEFI system table is linked *under* the -- adopted or
> new -- device tree, through the "chosen" node. And so, if ACPI was
> enabled, the ACPI RSD PTR (coming from step (7)) becomes visible to the
> kernel proper as well, through the UEFI config table with
> ACPI_20_TABLE_GUID.
> 
> I believe this is implemented under "drivers/firmware/efi/libstub" in
> the kernel tree.
> 
> Thanks,
> Laszlo
> 
> .
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Question on UEFI ACPI tables setup and probing on arm64
  2020-11-05  4:30     ` Ying Fang
@ 2020-11-06 17:09       ` Laszlo Ersek
  2020-11-10  1:42         ` Ying Fang
  0 siblings, 1 reply; 7+ messages in thread
From: Laszlo Ersek @ 2020-11-06 17:09 UTC (permalink / raw)
  To: Ying Fang, Igor Mammedov
  Cc: Peter Maydell, Drew Jones, QEMU Developers, qemu-arm,
	wangzhigang17, Ard Biesheuvel (ARM address),
	philmd

On 11/05/20 05:30, Ying Fang wrote:

> I see it in Qemu the *loader_start* is fixed at 1 GiB on the
> physical address space which points to the DRAM base. In ArmVirtQemu.dsc
> PcdDeviceTreeInitialBaseAddress is set 0x40000000 with correspondence.
> 
> Here I also see the discussion about DRAM base for ArmVirtQemu.
> https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg03127.html
> 
> I am still not sure how UEFI knows that it is running on a ArmVirtQemu
> machine type.

It doesn't know. It remains a convention.

This part is not auto-detected; the constants in QEMU and edk2 are
independently open-coded, their values were synchronized by human effort
initially.

The user or the management layer have to make sure they boot a UEFI
firmware binary on the machine type that is compatible with the machine
type.

There is some meta-data to help with that:

> Does UEFI derive it from the fdt *compatible* property ?

Please see the schema "docs/interop/firmware.json" in the QEMU tree; in
particular the @FirmwareTarget element.

For an actual example: QEMU bundles some edk2 firmware binaries (purely
as a convenience, not for production), and those are accompanied by
matching descriptor files. See
"pc-bios/descriptors/60-edk2-aarch64.json". (It is a template that's
fixed up during QEMU installation, but that's tangential here.)

    "targets": [
        {
            "architecture": "aarch64",
            "machines": [
                "virt-*"
            ]
        }
    ],

Thanks
Laszlo



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Question on UEFI ACPI tables setup and probing on arm64
  2020-11-06 17:09       ` Laszlo Ersek
@ 2020-11-10  1:42         ` Ying Fang
  0 siblings, 0 replies; 7+ messages in thread
From: Ying Fang @ 2020-11-10  1:42 UTC (permalink / raw)
  To: Laszlo Ersek, Igor Mammedov
  Cc: Peter Maydell, Drew Jones, QEMU Developers, qemu-arm,
	wangzhigang17, Ard Biesheuvel (ARM address),
	philmd



On 11/7/2020 1:09 AM, Laszlo Ersek wrote:
> On 11/05/20 05:30, Ying Fang wrote:
> 
>> I see it in Qemu the *loader_start* is fixed at 1 GiB on the
>> physical address space which points to the DRAM base. In ArmVirtQemu.dsc
>> PcdDeviceTreeInitialBaseAddress is set 0x40000000 with correspondence.
>>
>> Here I also see the discussion about DRAM base for ArmVirtQemu.
>> https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg03127.html
>>
>> I am still not sure how UEFI knows that it is running on a ArmVirtQemu
>> machine type.
> 
> It doesn't know. It remains a convention.
> 
> This part is not auto-detected; the constants in QEMU and edk2 are
> independently open-coded, their values were synchronized by human effort
> initially.
> 
> The user or the management layer have to make sure they boot a UEFI
> firmware binary on the machine type that is compatible with the machine
> type.
> 
> There is some meta-data to help with that:
> 

Thanks so much for the reply,
I now have the basic understanding how QEMU and EDK2 works together
after reading the docs and code there.

>> Does UEFI derive it from the fdt *compatible* property ?
> 
> Please see the schema "docs/interop/firmware.json" in the QEMU tree; in
> particular the @FirmwareTarget element.
> 
> For an actual example: QEMU bundles some edk2 firmware binaries (purely
> as a convenience, not for production), and those are accompanied by
> matching descriptor files. See
> "pc-bios/descriptors/60-edk2-aarch64.json". (It is a template that's
> fixed up during QEMU installation, but that's tangential here.)
> 
>      "targets": [
>          {
>              "architecture": "aarch64",
>              "machines": [
>                  "virt-*"
>              ]
>          }
>      ],
> 

Thanks, I'll look closer into it.

> Thanks
> Laszlo
> 
> .
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-11-10  1:43 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-30  2:50 Question on UEFI ACPI tables setup and probing on arm64 Ying Fang
2020-11-03 12:39 ` Igor Mammedov
2020-11-04 21:46   ` Laszlo Ersek
2020-11-04 21:57     ` Ard Biesheuvel
2020-11-05  4:30     ` Ying Fang
2020-11-06 17:09       ` Laszlo Ersek
2020-11-10  1:42         ` Ying Fang

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).