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

[Xen-devel] Design doc of adding ACPI support for arm64 on Xen - version 5



This document is going to explain the design details of Xen booting with
ACPI on ARM. Maybe parts of it may not be appropriate. Any comments are
welcome.

Changes v4->v5:
* change the description of section 4 to make it more generic
* place EFI and ACPI tables at non-RAM space of Dom0

Changes v3->v4:
* add explanation for minimal DT and the properties
* drop "linux," prefix of the properties
* add explanation for the event channel flag
* create RSDP table since the "xsdt_physical_address" is changed
* since it uses hypervisor_id introduced by ACPI 6.0 to notify Dom0 the
  hypervisor ID, so it needs to limit minimum supported ACPI version for
  Xen on ARM to 6.0.

Changes v2->v3:
* remove the two HVM_PARAMs for grant table and let linux kernel use
  xlated_setup_gnttab_pages() to setup grant table.
* don't modify GTDT table
* add definition of event-channel interrupt flag
* state that route all Xen unused interrupt to Dom0
* state that reusing existing PCI bus_notifier for PCI devices MMIO
* mapping

To Xen itself booting with ACPI, this is similar to Linux kernel except
that Xen doesn't parse DSDT table. So I'll skip this part and focus on
how Xen prepares ACPI tables for Dom0 and how Xen passes them to Dom0.

1. Create minimal DT to pass required information to Dom0
----------------------------------------------------------
The UEFI stub is a feature that extends the Image/zImage into a valid
UEFI PE/COFF executable, including a loader application that makes it
possible to load the kernel directly from the UEFI shell, boot menu, or
one of the lightweight bootloaders like Gummiboot or rEFInd.
The kernel image built with stub support remains a valid kernel image
for booting in non-UEFI environments and the UEFI stub will be jumped
over for non-UEFI environments.

When booting in UEFI mode, the UEFI stub will create a minimal DT in
order to pass the command line and other informations (such as the EFI
memory table) to the kernel. And when booting with ACPI, kernel will get
command line, ACPI root table address and memory map information from
the minimal DT. Also, it will check if the DT contains only the /chosen
node to know whether it boots with DT or ACPI.

In addition, the current names of these properties with a "linux,"
prefix in the minimal DT are Linux specified. It needs to standardize
them so that other OS(such as FreeBSD) could reuse them in the future.
So we drop the "linux," prefix of UEFI parameters and change the names
in Linux kernel as well.

An example of the minimal DT:
/ {
    #address-cells = <2>;
    #size-cells = <1>;
    chosen {
        bootargs = "kernel=Image console=hvc0 earlycon=pl011,0x1c090000
root=/dev/vda2 rw rootfstype=ext4 init=/bin/sh acpi=force";
        linux,initrd-start = <0xXXXXXXXX>;
        linux,initrd-end = <0xXXXXXXXX>;
        uefi-system-table = <0xXXXXXXXX>;
        uefi-mmap-start = <0xXXXXXXXX>;
        uefi-mmap-size = <0xXXXXXXXX>;
        uefi-mmap-desc-size = <0xXXXXXXXX>;
        uefi-mmap-desc-ver = <0xXXXXXXXX>;
    };
};

For details loook at
https://github.com/torvalds/linux/blob/master/Documentation/arm/uefi.txt

2. Copy and change some EFI and ACPI tables
-------------------------------------------
a) Create EFI_SYSTEM_TABLE table
Copy the header from the origin and change the value of FirmwareVendor.
Create only one ConfigurationTable to store VendorGuid and VendorTable.
This EFI System Table is a made up one not copy of the host. The EFI
System Table will be passed to Dom0 through the property
"uefi-system-table" in the above minimal DT. So Dom0 could get ACPI root
table address through the ConfigurationTable.

b) Create EFI_MEMORY_DESCRIPTOR table
It needs to notify Dom0 where are the RAM regions. Add memory start and
size information of Dom0 in this table. It's passed to Dom0 through the
properties "uefi-mmap-start", "uefi-mmap-size", "uefi-mmap-desc-size"
and "uefi-mmap-desc-ver" of the minimal DT. Then Dom0 will get the
memory information through this EFI table.

c) Copy FADT table
Change the value of arm_boot_flags to enable PSCI and HVC.

Since there is no cpuid like x86 on ARM, here it's through the field
hypervisor_id of FADT table to tell Dom0 that the hypervisor is Xen.
Because hypervisor_id is introduced by ACPI 6.0, so it needs to limit
minimum supported ACPI version for Xen on ARM to 6.0.

Set the hypervisor_id to "XenVMM", then Dom0 could through HVM_PARAM to
get some informations for booting necessity, such as event-channel
interrupt.

d) Copy MADT table
It needs to change MADT table to restrict the number of vCPUs. We choose
to copy the first dom0_max_vcpus GICC entries of MADT to new created
MADT table when numa is not supported currently. If numa is supported in
the future, it would change the mpidr according to the cpu topology.
Also copy GICD as well.

e) Create STAO table
This table is a new added one that's used to define a list of ACPI
namespace names that are to be ignored by the OSPM in Dom0. Currently
we use it to tell OSPM that it should ignore UART defined in SPCR table.
Look at below url for details:
http://wiki.xenproject.org/mediawiki/images/0/02/Status-override-table.pdf

f) Copy XSDT table
Add a new table entry for STAO and change other table's entries.

g) Copy RSDP table
Change the value of xsdt_physical_address in RSDP table. As we create a
new XSDT table and the address of XSDT is changed, so it needs to update
the value of "xsdt_physical_address" in RSDP. So Dom0 could get the
right XSDT table rather than the old one. And it needs to update the
value of VendorTable in EFI Configuration Table which is created in
above step a).

h) The rest of tables are not copied or changed. They are reused
including DSDT, SPCR, GTDT, etc. It doesn't mask EL2 resources for Dom0
because the Linux kernel would not use EL2 resources when it boots at
EL1.

All above tables will be mapped to Dom0 non-RAM space(e.g. the space
after Dom0 RAM).

3. Dom0 gets grant table and event channel irq information
-----------------------------------------------------------
The OS will have to find a place himself in the memory map for the grant
table region. For instance, Linux can make usage of
xlated_setup_gnttab_pages.

To event channel interrupt, reuse HVM_PARAM_CALLBACK_IRQ and add a new
delivery type to get it.
val[63:56] == 3: val[15:8] is flag: val[7:0] is a PPI (ARM and ARM64
only)
The definition of flag reusing the definition of xenv table. Bit 0
stands interrupt mode(1: edge triggered, 0: level triggered) and bit 1
stands interrupt polarity(1: active low, 0: active high).

As said above, we assign the hypervisor_id be "XenVMM" to tell Dom0 that
it runs on Xen hypervisor. Then Dom0 could get it through hypercall
HVMOP_get_param.

4. Map MMIO regions
-------------------
Add a new XENMAPSPACE "XENMAPSPACE_dev_mmio" for mapping mmio region.
Dom0 could use the hypercall XENMEM_add_to_physmap or
XENMEM_add_to_physmap_batch to map the mmio regions of devices. The
usage of the hypercall's parameters:
- domid: DOMID_SELF.
- space: XENMAPSPACE_dev_mmio.
- size: Number of pages to go through.
- idxs: native physical addresses.
- gpfns: guest physical addresses where the mapping should appear.

For example, Linux could register a bus_notifier for platform and amba
bus. Within the notifier, check if the device is newly added, if so call
the hypercall to map the mmio regions. And for PCI bus devices, Linux
could reuse the existing PCI bus_notifier like X86.

5. Route device interrupts to Dom0
----------------------------------
Route all the SPI interrupts to Dom0 before Dom0 booting, except the
interrupts used by Xen. For uart, it could get the interrupt from SPCR
table and exclude it. For SMMU, it could get the interrupts from IORT
table and exclude them as well.

Thanks,
-- 
Shannon


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.