Skip to contentSkip to conversation

Add ACPI support for arm64 on Xen

PATCH In review shannon.zhao at linaro.org 10 participants 352 messages Nov 17, 2015 – Jan 8, 2016 Arm Samsung Exynos Page 1 of 3

lore
Share & tools
lore
#0 lore raw

v3 cover Add ACPI support for arm64 on Xen

From: Shannon Zhao <[email protected]>

This patch set adds ACPI support for arm64 on Xen. The design document could be found from [1].

Xen reads static tables described by ACPI standard (6.0) from uefi and configures timer, GIC and UART. ACPI tables are modified to enable PSCI, HVC and Xen specific information and mapped into Dom0 address space. A minimal device tree is created to pass EFI table which contains memory layout (which cannot be passed using ACPI) and RSDP pointer to Dom0 through the node "uefi" under /hypervisor node. Dom0 parses dynamic ACPI tables and configure other peripherals.

Patch 1 reverts "xen/arm: vgic-v2: Drop cbase from arch_domain" because d->arch.vgic.cbase will be used by creating Dom0 MADT table later. Patches 2-36 add ACPI support for Xen/uefi interface. Patches 37-62 add ACPI support for Xen/Dom0 interface.
Last patch "xen: arm64: Add ACPI support" enables the support for ACPI so that individual patches do not affect working xen code base.

ACPI is now configurable via command line option "acpi=". To boot from ACPI this parameter should be set to "force".

Patches are tested on FVP base model. Instructions for reproducing the setup and working code base can be found from the following repositories wiki[2], Xen[3], Linux[4], UEFI[5]. Also you can get the test scripts and firmware binaries from[6].

Note currently the EFI runtime service is not added in this patch set since I didn't figure out a good way to support that. Dom0 will check if Xen supports runtime service. If not, Dom0 will not initialize runtime services. It's a long time since previous patch set and most work has been done. So I send this patch set out without runtime service support and later I could continue working on adding runtime service support or maybe other people who know this better could help work on that based on this patch set.

Thanks,
Shannon

[1] http://lists.xen.org/archives/html/xen-devel/2015-11/msg00488.html
[2] https://wiki.linaro.org/LEG/Engineering/Xen_boot_on_FVP_ACPI_UEFI
[3] http://git.linaro.org/people/shannon.zhao/linux-mainline.git ACPI_XEN_ARM_Linux_V1
[4] http://git.linaro.org/people/shannon.zhao/xen.git ACPI_XEN_ARM_V3
[5] http://git.linaro.org/people/shannon.zhao/linaro-edk2.git acpi-xen-uefi-v3
[6] http://people.linaro.org/~shannon.zhao/ACPI_XEN/

Most changes since v2:
* Create Dom0 ACPI tables based on new design
* Pass UEFI information to Dom0 through "uefi" node under /hypervisor node within FDT
* Define HAVE_NUMA option for NUMA
* Make pmstat dependent on HAS_CPUFREQ
* Refactor some ACPI codes to be aligned wit Linux
* Add GICv3 ACPI support
* Add a hypercall for device MMIO mapping
* Add a hypercall for event-channel interrupt
* Map newly created EFI and ACPI tables to the Xen and Dom0 unused place

Bob Moore (3):
ACPICA: ACPI 6.0: Add changes for FADT table
ACPICA: ACPI 6.0: Add changes for MADT table.
ACPICA: ACPI 6.0: Add support for STAO table

Hanjun Guo (1):
ACPICA: ACPI 6.0: Add values for MADT GIC version field

Naresh Bhat (3):
acpi/NUMA: Build NUMA for x86 only arm/acpi: Print GIC information when MADT is parsed xen/arm64: Add ACPI support

Parth Dixit (17):
acpi/pmstat: Build pmstat for x86 only
arm/acpi: Emulate io ports for arm
arm/acpi: Add basic ACPI initialization
arm/acpi: Parse MADT to map logical cpu to MPIDR and get
cpu_possible_map
arm/smpboot: Move dt specific code in smp to seperate functions acpi/table: Introduce acpi_parse_entries
arm: Introduce a generic way to use a device from acpi arm/gic-v2: Add ACPI boot support for GICv2
arm/acpi: Add GTDT support updated by ACPI 5.1 arm/irq: Add helper function for setting interrupt type arm/acpi: Parse GTDT to initialize timer
arm/uart: Create generic uart initialization function arm/acpi: Initialize serial port from ACPI SPCR table arm/acpi: Read acpi memory info from uefi
arm/p2m: Add helper functions to map memory regions arm/acpi: Configure interrupts dynamically
arm/acpi: Add acpi parameter to enable/disable acpi

Shannon Zhao (38):
Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"
acpi: Don't do traditional BIOS table scan for ARM64
acpi: Refactor acpi_os_map_memory to be architecturally independent arm/acpi: Add arch_acpi_os_map_memory helper function for ARM arm/acpi: Add arm specific acpi header file
arm/acpi: Move end_boot_allocator after acpi_boot_table_init arm/acpi: Introduce ARM Boot Architecture Flags in FADT arm/acpi: Parse FADT table and get PSCI flags
arm/acpi: Add Generic Interrupt and Distributor struct arm/acpi: Add ACPI support for SMP initialization arm/gic-v2: Refactor gicv2_init into generic and dt specific parts arm/gic-v3: Refactor gicv3_init into generic and dt specific parts acpi/table: Introduce acpi_get_entry to get specified entry arm/gic-v3: Add ACPI boot support for GICv3
arm/gic: Add ACPI support for GIC preinit
arm/acpi: Add a helper function to get interrupt type
pl011: Refactor pl011 driver to dt and common initialization parts
serial: Rename SERHND_DTUART to SERHND_UART
arm/acpi: Define a enum for reserved tables
arm/acpi: Add placeholder for efi and acpi load address arm/acpi: Estimate memory required for acpi/efi tables arm/acpi: Add a helper function to get the acpi table offset arm/acpi: Prepare FADT table for Dom0
arm/acpi: Prepare MADT table for Dom0
arm/acpi: Prepare STAO table for Dom0
arm/acpi: Prepare XSDT table for Dom0
arm/acpi: Prepare RSDP table for Dom0
arm/acpi: Map rest tables for Dom0
xen/efi: store EFI system table in efi structure arm/acpi: Prepare EFI system table for Dom0
arm/acpi: Prepare EFI memory descriptor for Dom0 arm/acpi: Map the new created EFI and ACPI tables to Dom0 arm/acpi: Create min DT stub for Dom0
arm/acpi: Route all Xen unused SPIs to Dom0
arm/acpi: Deny MMIO access of UART
hvm/params: Add a new dilivery type for event-channel in
HVM_PARAM_CALLBACK_IRQ
xen/acpi: Fix event-channel interrupt when booting with ACPI xen/arm: Add a hypercall for device mmio mapping

 config/arm64.mk                    |   1 +
 xen/arch/arm/Makefile              |   1 +
 xen/arch/arm/acpi/Makefile         |   2 +
 xen/arch/arm/acpi/boot.c           | 214 ++++++++++++
 xen/arch/arm/acpi/lib.c            |  85 +++++
 xen/arch/arm/arm64/smpboot.c       |  12 +-
 xen/arch/arm/device.c              |  19 ++
 xen/arch/arm/domain.c              |   4 +
 xen/arch/arm/domain_build.c        | 667 ++++++++++++++++++++++++++++++++++++-
 xen/arch/arm/efi/efi-boot.h        |  23 ++
 xen/arch/arm/gic-v2.c              | 141 +++++++-
 xen/arch/arm/gic-v3.c              | 271 ++++++++++++---
 xen/arch/arm/gic.c                 |  55 ++-
 xen/arch/arm/irq.c                 |  22 +-
 xen/arch/arm/mm.c                  |   4 +
 xen/arch/arm/p2m.c                 |  60 ++++
 xen/arch/arm/psci.c                |  30 +-
 xen/arch/arm/setup.c               |  37 +-
 xen/arch/arm/smpboot.c             |  34 +-
 xen/arch/arm/time.c                |  73 +++-
 xen/arch/arm/vgic-v2.c             |  10 +-
 xen/arch/arm/vgic.c                |  19 ++
 xen/arch/arm/vuart.c               |   2 +-
 xen/arch/arm/xen.lds.S             |   7 +
 xen/arch/x86/Rules.mk              |   1 +
 xen/arch/x86/acpi/lib.c            |  16 +
 xen/common/efi/boot.c              | 182 ++++++++++
 xen/common/efi/runtime.c           |   2 +-
 xen/common/sysctl.c                |   2 +-
 xen/drivers/acpi/Makefile          |   4 +-
 xen/drivers/acpi/osl.c             |  14 +-
 xen/drivers/acpi/tables.c          | 120 ++++++-
 xen/drivers/char/Makefile          |   2 +-
 xen/drivers/char/arm-uart.c        | 136 ++++++++
 xen/drivers/char/cadence-uart.c    |   2 +-
 xen/drivers/char/dt-uart.c         | 107 ------
 xen/drivers/char/exynos4210-uart.c |   2 +-
 xen/drivers/char/omap-uart.c       |   2 +-
 xen/drivers/char/pl011.c           | 101 ++++--
 xen/drivers/char/scif-uart.c       |   2 +-
 xen/drivers/char/serial.c          |   2 +-
 xen/include/acpi/actbl.h           |  29 +-
 xen/include/acpi/actbl1.h          |  94 +++++-
 xen/include/acpi/actbl2.h          |   5 +
 xen/include/acpi/actbl3.h          | 114 ++++++-
 xen/include/asm-arm/acpi.h         | 108 ++++++
 xen/include/asm-arm/arm64/io.h     |  14 +
 xen/include/asm-arm/config.h       |   5 +
 xen/include/asm-arm/device.h       |  30 ++
 xen/include/asm-arm/domain.h       |   6 +
 xen/include/asm-arm/irq.h          |   2 +
 xen/include/asm-arm/p2m.h          |  15 +
 xen/include/asm-arm/setup.h        |  11 +
 xen/include/public/hvm/params.h    |   5 +
 xen/include/public/memory.h        |   1 +
 xen/include/xen/acpi.h             |  13 +
 xen/include/xen/efi.h              |   1 +
 xen/include/xen/serial.h           |   4 +-
 58 files changed, 2632 insertions(+), 315 deletions(-)
 create mode 100644 xen/arch/arm/acpi/Makefile
 create mode 100644 xen/arch/arm/acpi/boot.c
 create mode 100644 xen/arch/arm/acpi/lib.c
 create mode 100644 xen/drivers/char/arm-uart.c
 delete mode 100644 xen/drivers/char/dt-uart.c
 create mode 100644 xen/include/asm-arm/acpi.h
Signature · 1 line
2.1.0
#1 lore raw

PATCH v3 1/62 Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

From: Shannon Zhao <[email protected]>

This reverts commit 810a50db69703f715d199d6b3a5f08193155d48b.

Conflicts:

	xen/arch/arm/vgic-v2.c
---
 xen/arch/arm/vgic-v2.c       | 10 +++++-----
 xen/include/asm-arm/domain.h |  1 +
 2 files changed, 6 insertions(+), 5 deletions(-)
xen/arch/arm/vgic-v2.c +5 -5
index f7d784b..ba7ddac 100644
@@ -531,7 +531,7 @@ static int vgic_v2_vcpu_init(struct vcpu *v)
 static int vgic_v2_domain_init(struct domain *d)
 {
     int i, ret;
-    paddr_t cbase, csize;
+    paddr_t csize;
     paddr_t vbase;
 
     /*
@@ -541,6 +541,7 @@ static int vgic_v2_domain_init(struct domain *d)
     if ( is_hardware_domain(d) )
     {
         d->arch.vgic.dbase = vgic_v2_hw.dbase;
+        d->arch.vgic.cbase = vgic_v2_hw.cbase;
         /*
          * For the hardware domain, we always map the whole HW CPU
          * interface region in order to match the device tree (the "reg"
@@ -548,13 +549,13 @@ static int vgic_v2_domain_init(struct domain *d)
          * Note that we assume the size of the CPU interface is always
          * aligned to PAGE_SIZE.
          */
-        cbase = vgic_v2_hw.cbase;
         csize = vgic_v2_hw.csize;
         vbase = vgic_v2_hw.vbase;
     }
     else
     {
         d->arch.vgic.dbase = GUEST_GICD_BASE;
+        d->arch.vgic.cbase = GUEST_GICC_BASE;
         /*
          * The CPU interface exposed to the guest is always 8kB. We may
          * need to add an offset to the virtual CPU interface base
@@ -562,7 +563,6 @@ static int vgic_v2_domain_init(struct domain *d)
          * region.
          */
         BUILD_BUG_ON(GUEST_GICC_SIZE != SZ_8K);
-        cbase = GUEST_GICC_BASE;
         csize = GUEST_GICC_SIZE;
         vbase = vgic_v2_hw.vbase + vgic_v2_hw.aliased_offset;
     }
@@ -571,8 +571,8 @@ static int vgic_v2_domain_init(struct domain *d)
      * Map the gic virtual cpu interface in the gic cpu interface
      * region of the guest.
      */
-    ret = map_mmio_regions(d, paddr_to_pfn(cbase), csize / PAGE_SIZE,
-                           paddr_to_pfn(vbase));
+    ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase),
+                           csize / PAGE_SIZE, paddr_to_pfn(vbase));
     if ( ret )
         return ret;
 
xen/include/asm-arm/domain.h +1 -0
index e7e40da..1e61f30 100644
@@ -102,6 +102,7 @@ struct arch_domain
         struct pending_irq *pending_irqs;
         /* Base address for guest GIC */
         paddr_t dbase; /* Distributor base address */
+        paddr_t cbase; /* CPU base address */
 #ifdef HAS_GICV3
         /* GIC V3 addressing */
         /* List of contiguous occupied by the redistributors */
Signature · 1 line
2.1.0
#2 lore raw

PATCH v3 1/62 Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

Hi Shannon,

Why do you want to revert this patch?

Regards,

Quoted 81 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

This reverts commit 810a50db69703f715d199d6b3a5f08193155d48b.

Conflicts:

	xen/arch/arm/vgic-v2.c
---
 xen/arch/arm/vgic-v2.c       | 10 +++++-----
 xen/include/asm-arm/domain.h |  1 +
 2 files changed, 6 insertions(+), 5 deletions(-)
xen/arch/arm/vgic-v2.c +5 -5
index f7d784b..ba7ddac 100644
@@ -531,7 +531,7 @@ static int vgic_v2_vcpu_init(struct vcpu *v)
 static int vgic_v2_domain_init(struct domain *d)
 {
     int i, ret;
-    paddr_t cbase, csize;
+    paddr_t csize;
     paddr_t vbase;
 
     /*
@@ -541,6 +541,7 @@ static int vgic_v2_domain_init(struct domain *d)
     if ( is_hardware_domain(d) )
     {
         d->arch.vgic.dbase = vgic_v2_hw.dbase;
+        d->arch.vgic.cbase = vgic_v2_hw.cbase;
         /*
          * For the hardware domain, we always map the whole HW CPU
          * interface region in order to match the device tree (the "reg"
@@ -548,13 +549,13 @@ static int vgic_v2_domain_init(struct domain *d)
          * Note that we assume the size of the CPU interface is always
          * aligned to PAGE_SIZE.
          */
-        cbase = vgic_v2_hw.cbase;
         csize = vgic_v2_hw.csize;
         vbase = vgic_v2_hw.vbase;
     }
     else
     {
         d->arch.vgic.dbase = GUEST_GICD_BASE;
+        d->arch.vgic.cbase = GUEST_GICC_BASE;
         /*
          * The CPU interface exposed to the guest is always 8kB. We may
          * need to add an offset to the virtual CPU interface base
@@ -562,7 +563,6 @@ static int vgic_v2_domain_init(struct domain *d)
          * region.
          */
         BUILD_BUG_ON(GUEST_GICC_SIZE != SZ_8K);
-        cbase = GUEST_GICC_BASE;
         csize = GUEST_GICC_SIZE;
         vbase = vgic_v2_hw.vbase + vgic_v2_hw.aliased_offset;
     }
@@ -571,8 +571,8 @@ static int vgic_v2_domain_init(struct domain *d)
      * Map the gic virtual cpu interface in the gic cpu interface
      * region of the guest.
      */
-    ret = map_mmio_regions(d, paddr_to_pfn(cbase), csize / PAGE_SIZE,
-                           paddr_to_pfn(vbase));
+    ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase),
+                           csize / PAGE_SIZE, paddr_to_pfn(vbase));
     if ( ret )
         return ret;
 
xen/include/asm-arm/domain.h +1 -0
index e7e40da..1e61f30 100644
@@ -102,6 +102,7 @@ struct arch_domain
         struct pending_irq *pending_irqs;
         /* Base address for guest GIC */
         paddr_t dbase; /* Distributor base address */
+        paddr_t cbase; /* CPU base address */
 #ifdef HAS_GICV3
         /* GIC V3 addressing */
         /* List of contiguous occupied by the redistributors */
Signature · 1 line
Julien Grall
#3 lore raw

PATCH v3 1/62 Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

Hi Julien,

Quoted 4 lines · Julien Grall

Hi Shannon,

Why do you want to revert this patch?

Because d->arch.vgic.cbase will be used by creating Dom0 MADT table later. See [PATCH v3 43/62].
+ gicc.base_address = d->arch.vgic.cbase;

My previous way is get this from ACPI table but someone suggest get it from struct domain and I think this way is better too since it uses the value after being parsed.

And sorry that I didn't notice this patch before when you send it out to list.

Signature · 1 line
Shannon
#4 lore raw

PATCH v3 1/62 Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

Quoted 7 lines · Shannon Zhao

Hi Julien,

Quoted 4 lines · Julien Grall

Hi Shannon,

Why do you want to revert this patch?

Quoted 7 lines

Because d->arch.vgic.cbase will be used by creating Dom0 MADT table later. See [PATCH v3 43/62].
+ gicc.base_address = d->arch.vgic.cbase;

My previous way is get this from ACPI table but someone suggest get it from struct domain and I think this way is better too since it uses the value after being parsed.

It's pointless to store the value in arch_domain for something that it's only use during building...

We have struct kernel_info which store any information related to the DOM0 during the building.

Quoted 2 lines

And sorry that I didn't notice this patch before when you send it out to list.

In any case you have to explain in the commit message why you want to revert the patch.

Regards,

Signature · 1 line
Julien Grall
#5 lore raw

PATCH v3 1/62 Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

Quoted 12 lines · Julien Grall
Quoted 11 lines · Shannon Zhao
Quoted 11 lines

Hi Julien,

Quoted 4 lines · Julien Grall
Quoted 4 lines

Hi Shannon,

Why do you want to revert this patch?

Because d->arch.vgic.cbase will be used by creating Dom0 MADT table later. See [PATCH v3 43/62].
+ gicc.base_address = d->arch.vgic.cbase;

Quoted 9 lines
Quoted 3 lines
Quoted 3 lines

My previous way is get this from ACPI table but someone suggest get it from struct domain and I think this way is better too since it uses the value after being parsed.

It's pointless to store the value in arch_domain for something that it's only use during building...

We have struct kernel_info which store any information related to the DOM0 during the building.

Yeah, that would be better if it could use kernel_info. But the problem is that kernel_info is firstly used in construct_dom0(), while it needs to store the cbase in domain_create() which is called before construct_dom0(). And if we pass kernel_info as parameter to domain_create(), this would introduce more changes to common codes.

Do you have any better idea to handle this?

Thanks,

Signature · 1 line
Shannon
#6 lore raw

PATCH v3 1/62 Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

Hi Shannon,

Quoted 23 lines · Shannon Zhao
Quoted 12 lines · Julien Grall
Quoted 11 lines · Shannon Zhao
Quoted 11 lines

Hi Julien,

Quoted 4 lines · Julien Grall
Quoted 4 lines

Hi Shannon,

Why do you want to revert this patch?

Because d->arch.vgic.cbase will be used by creating Dom0 MADT table later. See [PATCH v3 43/62].
+ gicc.base_address = d->arch.vgic.cbase;

Quoted 9 lines
Quoted 3 lines
Quoted 3 lines

My previous way is get this from ACPI table but someone suggest get it from struct domain and I think this way is better too since it uses the value after being parsed.

It's pointless to store the value in arch_domain for something that it's only use during building...

We have struct kernel_info which store any information related to the DOM0 during the building.

Quoted 7 lines

Yeah, that would be better if it could use kernel_info. But the problem is that kernel_info is firstly used in construct_dom0(), while it needs to store the cbase in domain_create() which is called before construct_dom0(). And if we pass kernel_info as parameter to domain_create(), this would introduce more changes to common codes.

Do you have any better idea to handle this?

Yes, introducing callback to create the ACPI table in the GIC driver. See what we did for make_hwdom_dt_node.

We are trying to make the domain_build domain as agnostic as possible from the GIC version. However in patch #43, you implement specific version in the domain builder.

It will also not scale very well when we will introduce GICv2m and ITS.

The version of the GIC (ACPI_MADT_GIC_*) could be introduced in the vgic_ops.

The re-distributor could be moved in gic-v3.c and the generic interrupt controller in gic-v2.c.

Note it's a mandatory to emulate the same version as the hardware for the virtual GIC.

Regards,

Signature · 1 line
Julien Grall
#7 lore raw

PATCH v3 1/62 Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

Quoted 44 lines · Julien Grall

Hi Shannon,

Quoted 23 lines · Shannon Zhao
Quoted 12 lines · Julien Grall
Quoted 11 lines · Shannon Zhao
Quoted 11 lines

Hi Julien,

Quoted 4 lines · Julien Grall
Quoted 4 lines

Hi Shannon,

Why do you want to revert this patch?

Because d->arch.vgic.cbase will be used by creating Dom0 MADT table later. See [PATCH v3 43/62].
+ gicc.base_address = d->arch.vgic.cbase;

Quoted 9 lines
Quoted 3 lines
Quoted 3 lines

My previous way is get this from ACPI table but someone suggest get it from struct domain and I think this way is better too since it uses the value after being parsed.

It's pointless to store the value in arch_domain for something that it's only use during building...

We have struct kernel_info which store any information related to the DOM0 during the building.

Quoted 7 lines

Yeah, that would be better if it could use kernel_info. But the problem is that kernel_info is firstly used in construct_dom0(), while it needs to store the cbase in domain_create() which is called before construct_dom0(). And if we pass kernel_info as parameter to domain_create(), this would introduce more changes to common codes.

Do you have any better idea to handle this?

Yes, introducing callback to create the ACPI table in the GIC driver. See what we did for make_hwdom_dt_node.

We are trying to make the domain_build domain as agnostic as possible from the GIC version. However in patch #43, you implement specific version in the domain builder.

It will also not scale very well when we will introduce GICv2m and ITS.

Quoted 9 lines

The version of the GIC (ACPI_MADT_GIC_*) could be introduced in the vgic_ops.

The re-distributor could be moved in gic-v3.c and the generic interrupt controller in gic-v2.c.

Note it's a mandatory to emulate the same version as the hardware for the virtual GIC.

So it doesn't support vGICv2 on GICv3 hardware for Xen?

Thanks,

Signature · 1 line
Shannon
#8 lore raw

PATCH v3 1/62 Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

Quoted 4 lines · Shannon Zhao
Quoted 3 lines

Note it's a mandatory to emulate the same version as the hardware for the virtual GIC.

So it doesn't support vGICv2 on GICv3 hardware for Xen?

Sorry I forgot to say it was for DOM0. We support GICv2 on GICv3 only for guest.

Regards,

Signature · 1 line
Julien Grall
#9 lore raw

PATCH v3 1/62 Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

Quoted 9 lines · Julien Grall
Quoted 4 lines · Shannon Zhao
Quoted 3 lines

Note it's a mandatory to emulate the same version as the hardware for the virtual GIC.

So it doesn't support vGICv2 on GICv3 hardware for Xen?

Sorry I forgot to say it was for DOM0. We support GICv2 on GICv3 only for guest.

Ok, I see. Thanks for your explanation.

Signature · 1 line
Shannon
#10 lore raw

Re: [PATCH v3 01/62] Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

In reply to Julien Grall
Quoted 9 lines · Julien Grall
Quoted 4 lines · Shannon Zhao
Quoted 3 lines

Note it's a mandatory to emulate the same version as the hardware for the virtual GIC.

So it doesn't support vGICv2 on GICv3 hardware for Xen?

Sorry I forgot to say it was for DOM0. We support GICv2 on GICv3 only for guest.

Ok, I see. Thanks for your explanation.

Signature · 1 line
Shannon
#11 lore raw

Re: [PATCH v3 01/62] Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

In reply to Shannon Zhao
Quoted 4 lines · Shannon Zhao
Quoted 3 lines

Note it's a mandatory to emulate the same version as the hardware for the virtual GIC.

So it doesn't support vGICv2 on GICv3 hardware for Xen?

Sorry I forgot to say it was for DOM0. We support GICv2 on GICv3 only for guest.

Regards,

Signature · 1 line
Julien Grall
#12 lore raw

Re: [PATCH v3 01/62] Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

In reply to Julien Grall
Quoted 44 lines · Julien Grall

Hi Shannon,

Quoted 23 lines · Shannon Zhao
Quoted 12 lines · Julien Grall
Quoted 11 lines · Shannon Zhao
Quoted 11 lines

Hi Julien,

Quoted 4 lines · Julien Grall
Quoted 4 lines

Hi Shannon,

Why do you want to revert this patch?

Because d->arch.vgic.cbase will be used by creating Dom0 MADT table later. See [PATCH v3 43/62].
+ gicc.base_address = d->arch.vgic.cbase;

Quoted 9 lines
Quoted 3 lines
Quoted 3 lines

My previous way is get this from ACPI table but someone suggest get it from struct domain and I think this way is better too since it uses the value after being parsed.

It's pointless to store the value in arch_domain for something that it's only use during building...

We have struct kernel_info which store any information related to the DOM0 during the building.

Quoted 7 lines

Yeah, that would be better if it could use kernel_info. But the problem is that kernel_info is firstly used in construct_dom0(), while it needs to store the cbase in domain_create() which is called before construct_dom0(). And if we pass kernel_info as parameter to domain_create(), this would introduce more changes to common codes.

Do you have any better idea to handle this?

Yes, introducing callback to create the ACPI table in the GIC driver. See what we did for make_hwdom_dt_node.

We are trying to make the domain_build domain as agnostic as possible from the GIC version. However in patch #43, you implement specific version in the domain builder.

It will also not scale very well when we will introduce GICv2m and ITS.

Quoted 9 lines

The version of the GIC (ACPI_MADT_GIC_*) could be introduced in the vgic_ops.

The re-distributor could be moved in gic-v3.c and the generic interrupt controller in gic-v2.c.

Note it's a mandatory to emulate the same version as the hardware for the virtual GIC.

So it doesn't support vGICv2 on GICv3 hardware for Xen?

Thanks,

Signature · 1 line
Shannon
#13 lore raw

Re: [PATCH v3 01/62] Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

In reply to Shannon Zhao

Hi Shannon,

Quoted 23 lines · Shannon Zhao
Quoted 12 lines · Julien Grall
Quoted 11 lines · Shannon Zhao
Quoted 11 lines

Hi Julien,

Quoted 4 lines · Julien Grall
Quoted 4 lines

Hi Shannon,

Why do you want to revert this patch?

Because d->arch.vgic.cbase will be used by creating Dom0 MADT table later. See [PATCH v3 43/62].
+ gicc.base_address = d->arch.vgic.cbase;

Quoted 9 lines
Quoted 3 lines
Quoted 3 lines

My previous way is get this from ACPI table but someone suggest get it from struct domain and I think this way is better too since it uses the value after being parsed.

It's pointless to store the value in arch_domain for something that it's only use during building...

We have struct kernel_info which store any information related to the DOM0 during the building.

Quoted 7 lines

Yeah, that would be better if it could use kernel_info. But the problem is that kernel_info is firstly used in construct_dom0(), while it needs to store the cbase in domain_create() which is called before construct_dom0(). And if we pass kernel_info as parameter to domain_create(), this would introduce more changes to common codes.

Do you have any better idea to handle this?

Yes, introducing callback to create the ACPI table in the GIC driver. See what we did for make_hwdom_dt_node.

We are trying to make the domain_build domain as agnostic as possible from the GIC version. However in patch #43, you implement specific version in the domain builder.

It will also not scale very well when we will introduce GICv2m and ITS.

The version of the GIC (ACPI_MADT_GIC_*) could be introduced in the vgic_ops.

The re-distributor could be moved in gic-v3.c and the generic interrupt controller in gic-v2.c.

Note it's a mandatory to emulate the same version as the hardware for the virtual GIC.

Regards,

Signature · 1 line
Julien Grall
#14 lore raw

Re: [PATCH v3 01/62] Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

In reply to Julien Grall
Quoted 12 lines · Julien Grall
Quoted 11 lines · Shannon Zhao
Quoted 11 lines

Hi Julien,

Quoted 4 lines · Julien Grall
Quoted 4 lines

Hi Shannon,

Why do you want to revert this patch?

Because d->arch.vgic.cbase will be used by creating Dom0 MADT table later. See [PATCH v3 43/62].
+ gicc.base_address = d->arch.vgic.cbase;

Quoted 9 lines
Quoted 3 lines
Quoted 3 lines

My previous way is get this from ACPI table but someone suggest get it from struct domain and I think this way is better too since it uses the value after being parsed.

It's pointless to store the value in arch_domain for something that it's only use during building...

We have struct kernel_info which store any information related to the DOM0 during the building.

Yeah, that would be better if it could use kernel_info. But the problem is that kernel_info is firstly used in construct_dom0(), while it needs to store the cbase in domain_create() which is called before construct_dom0(). And if we pass kernel_info as parameter to domain_create(), this would introduce more changes to common codes.

Do you have any better idea to handle this?

Thanks,

Signature · 1 line
Shannon
#15 lore raw

Re: [PATCH v3 01/62] Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

In reply to Shannon Zhao
Quoted 7 lines · Shannon Zhao

Hi Julien,

Quoted 4 lines · Julien Grall

Hi Shannon,

Why do you want to revert this patch?

Quoted 7 lines

Because d->arch.vgic.cbase will be used by creating Dom0 MADT table later. See [PATCH v3 43/62].
+ gicc.base_address = d->arch.vgic.cbase;

My previous way is get this from ACPI table but someone suggest get it from struct domain and I think this way is better too since it uses the value after being parsed.

It's pointless to store the value in arch_domain for something that it's only use during building...

We have struct kernel_info which store any information related to the DOM0 during the building.

Quoted 2 lines

And sorry that I didn't notice this patch before when you send it out to list.

In any case you have to explain in the commit message why you want to revert the patch.

Regards,

Signature · 1 line
Julien Grall
#16 lore raw

Re: [PATCH v3 01/62] Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

In reply to Julien Grall

Hi Julien,

Quoted 4 lines · Julien Grall

Hi Shannon,

Why do you want to revert this patch?

Because d->arch.vgic.cbase will be used by creating Dom0 MADT table later. See [PATCH v3 43/62].
+ gicc.base_address = d->arch.vgic.cbase;

My previous way is get this from ACPI table but someone suggest get it from struct domain and I think this way is better too since it uses the value after being parsed.

And sorry that I didn't notice this patch before when you send it out to list.

Signature · 1 line
Shannon
#17 lore raw

PATCH v3 1/62 Revert "xen/arm: vgic-v2: Drop cbase from arch_domain"

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

This reverts commit 810a50db69703f715d199d6b3a5f08193155d48b.

Conflicts:

	xen/arch/arm/vgic-v2.c
---
 xen/arch/arm/vgic-v2.c       | 10 +++++-----
 xen/include/asm-arm/domain.h |  1 +
 2 files changed, 6 insertions(+), 5 deletions(-)
xen/arch/arm/vgic-v2.c +5 -5
index f7d784b..ba7ddac 100644
@@ -531,7 +531,7 @@ static int vgic_v2_vcpu_init(struct vcpu *v)
 static int vgic_v2_domain_init(struct domain *d)
 {
     int i, ret;
-    paddr_t cbase, csize;
+    paddr_t csize;
     paddr_t vbase;
 
     /*
@@ -541,6 +541,7 @@ static int vgic_v2_domain_init(struct domain *d)
     if ( is_hardware_domain(d) )
     {
         d->arch.vgic.dbase = vgic_v2_hw.dbase;
+        d->arch.vgic.cbase = vgic_v2_hw.cbase;
         /*
          * For the hardware domain, we always map the whole HW CPU
          * interface region in order to match the device tree (the "reg"
@@ -548,13 +549,13 @@ static int vgic_v2_domain_init(struct domain *d)
          * Note that we assume the size of the CPU interface is always
          * aligned to PAGE_SIZE.
          */
-        cbase = vgic_v2_hw.cbase;
         csize = vgic_v2_hw.csize;
         vbase = vgic_v2_hw.vbase;
     }
     else
     {
         d->arch.vgic.dbase = GUEST_GICD_BASE;
+        d->arch.vgic.cbase = GUEST_GICC_BASE;
         /*
          * The CPU interface exposed to the guest is always 8kB. We may
          * need to add an offset to the virtual CPU interface base
@@ -562,7 +563,6 @@ static int vgic_v2_domain_init(struct domain *d)
          * region.
          */
         BUILD_BUG_ON(GUEST_GICC_SIZE != SZ_8K);
-        cbase = GUEST_GICC_BASE;
         csize = GUEST_GICC_SIZE;
         vbase = vgic_v2_hw.vbase + vgic_v2_hw.aliased_offset;
     }
@@ -571,8 +571,8 @@ static int vgic_v2_domain_init(struct domain *d)
      * Map the gic virtual cpu interface in the gic cpu interface
      * region of the guest.
      */
-    ret = map_mmio_regions(d, paddr_to_pfn(cbase), csize / PAGE_SIZE,
-                           paddr_to_pfn(vbase));
+    ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase),
+                           csize / PAGE_SIZE, paddr_to_pfn(vbase));
     if ( ret )
         return ret;
 
xen/include/asm-arm/domain.h +1 -0
index e7e40da..1e61f30 100644
@@ -102,6 +102,7 @@ struct arch_domain
         struct pending_irq *pending_irqs;
         /* Base address for guest GIC */
         paddr_t dbase; /* Distributor base address */
+        paddr_t cbase; /* CPU base address */
 #ifdef HAS_GICV3
         /* GIC V3 addressing */
         /* List of contiguous occupied by the redistributors */
Signature · 1 line
2.1.0
#18 lore raw

PATCH v3 2/62 acpi/NUMA: Build NUMA for x86 only

In reply to shannon.zhao at linaro.org

From: Naresh Bhat <[email protected]>

NUMA is currently not supported for ARM in Xen. Add a new compilation option HAS_NUMA for NUMA. Configure and build NUMA only for x86 architecture now.

---
 xen/arch/x86/Rules.mk     | 1 +
 xen/drivers/acpi/Makefile | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)
xen/arch/x86/Rules.mk +1 -0
index 42de328..5b8eaed 100644
@@ -3,6 +3,7 @@
 
 HAS_IOPORTS := y
 HAS_ACPI := y
+HAS_NUMA := y
 HAS_VGA  := y
 HAS_VIDEO  := y
 HAS_CPUFREQ := y
xen/drivers/acpi/Makefile +1 -1
index bbb06a7..3bb626e 100644
@@ -3,7 +3,7 @@ subdir-y += utilities
 subdir-$(x86) += apei
 
 obj-bin-y += tables.init.o
-obj-y += numa.o
+obj-$(HAS_NUMA) += numa.o
 obj-y += osl.o
 obj-y += pmstat.o
 
Signature · 1 line
2.1.0
#19 lore raw

PATCH v3 2/62 acpi/NUMA: Build NUMA for x86 only

In reply to shannon.zhao at linaro.org

From: Naresh Bhat <[email protected]>

NUMA is currently not supported for ARM in Xen. Add a new compilation option HAS_NUMA for NUMA. Configure and build NUMA only for x86 architecture now.

---
 xen/arch/x86/Rules.mk     | 1 +
 xen/drivers/acpi/Makefile | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)
xen/arch/x86/Rules.mk +1 -0
index 42de328..5b8eaed 100644
@@ -3,6 +3,7 @@
 
 HAS_IOPORTS := y
 HAS_ACPI := y
+HAS_NUMA := y
 HAS_VGA  := y
 HAS_VIDEO  := y
 HAS_CPUFREQ := y
xen/drivers/acpi/Makefile +1 -1
index bbb06a7..3bb626e 100644
@@ -3,7 +3,7 @@ subdir-y += utilities
 subdir-$(x86) += apei
 
 obj-bin-y += tables.init.o
-obj-y += numa.o
+obj-$(HAS_NUMA) += numa.o
 obj-y += osl.o
 obj-y += pmstat.o
 
Signature · 1 line
2.1.0
#20 lore raw

PATCH v3 3/62 acpi/pmstat: Build pmstat for x86 only

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Pmstat is currently not supported for ARM in Xen. Configure and build pmstat for x86 architecture only.

---
 xen/common/sysctl.c       | 2 +-
 xen/drivers/acpi/Makefile | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
xen/common/sysctl.c +1 -1
index 85e853f..8273ad4 100644
@@ -171,7 +171,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
         op->u.availheap.avail_bytes <<= PAGE_SHIFT;
         break;
 
-#ifdef HAS_ACPI
+#ifdef HAS_CPUFREQ
     case XEN_SYSCTL_get_pmstat:
         ret = do_get_pm_info(&op->u.get_pmstat);
         break;
xen/drivers/acpi/Makefile +1 -1
index 3bb626e..c7d006a 100644
@@ -5,7 +5,7 @@ subdir-$(x86) += apei
 obj-bin-y += tables.init.o
 obj-$(HAS_NUMA) += numa.o
 obj-y += osl.o
-obj-y += pmstat.o
+obj-$(HAS_CPUFREQ) += pmstat.o
 
 obj-$(x86) += hwregs.o
 obj-$(x86) += reboot.o
Signature · 1 line
2.1.0
#21 lore raw

PATCH v3 3/62 acpi/pmstat: Build pmstat for x86 only

xen/common/sysctl.c long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) · line 174

Quoted 9 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/common/sysctl.c +1 -1
@@ -171,7 +171,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
         op->u.availheap.avail_bytes <<= PAGE_SHIFT;
         break;
 
-#ifdef HAS_ACPI
+#ifdef HAS_CPUFREQ

You should combine the two instead of replacing one with the other.

Jan

#22 lore raw

Re: [PATCH v3 03/62] acpi/pmstat: Build pmstat for x86 only

In reply to shannon.zhao at linaro.org

xen/common/sysctl.c long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) · line 174

Quoted 9 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/common/sysctl.c +1 -1
@@ -171,7 +171,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
         op->u.availheap.avail_bytes <<= PAGE_SHIFT;
         break;
 
-#ifdef HAS_ACPI
+#ifdef HAS_CPUFREQ

You should combine the two instead of replacing one with the other.

Jan

#23 lore raw

PATCH v3 3/62 acpi/pmstat: Build pmstat for x86 only

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Pmstat is currently not supported for ARM in Xen. Configure and build pmstat for x86 architecture only.

---
 xen/common/sysctl.c       | 2 +-
 xen/drivers/acpi/Makefile | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
xen/common/sysctl.c +1 -1
index 85e853f..8273ad4 100644
@@ -171,7 +171,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
         op->u.availheap.avail_bytes <<= PAGE_SHIFT;
         break;
 
-#ifdef HAS_ACPI
+#ifdef HAS_CPUFREQ
     case XEN_SYSCTL_get_pmstat:
         ret = do_get_pm_info(&op->u.get_pmstat);
         break;
xen/drivers/acpi/Makefile +1 -1
index 3bb626e..c7d006a 100644
@@ -5,7 +5,7 @@ subdir-$(x86) += apei
 obj-bin-y += tables.init.o
 obj-$(HAS_NUMA) += numa.o
 obj-y += osl.o
-obj-y += pmstat.o
+obj-$(HAS_CPUFREQ) += pmstat.o
 
 obj-$(x86) += hwregs.o
 obj-$(x86) += reboot.o
Signature · 1 line
2.1.0
#24 lore raw

PATCH v3 4/62 arm/acpi: Emulate io ports for arm

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Add macros to emulate x86 style ports for arm. This avoids modification in common code for acpi.

---
 xen/include/asm-arm/arm64/io.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
xen/include/asm-arm/arm64/io.h +14 -0
index 37abc47..7ad9b65 100644
@@ -20,6 +20,7 @@
 #ifndef _ARM_ARM64_IO_H
 #define _ARM_ARM64_IO_H
 
+#include <asm/system.h>
 #include <asm/byteorder.h>
 
 /*
@@ -109,4 +110,17 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 #define writel(v,c)             ({ __iowmb(); writel_relaxed((v),(c)); })
 #define writeq(v,c)             ({ __iowmb(); writeq_relaxed((v),(c)); })
 
+/*
+ * Emulate x86 io ports for arm.
+ */
+#define __armio(addr) ( (void __iomem *)addr )
+
+#define inb(c) ( readb( __armio(c) ) )
+#define inw(c) ( readw( __armio(c) ) )
+#define inl(c) ( readl( __armio(c) ) )
+
+#define outb(v, c) ( writeb(v, __armio(c) ) )
+#define outw(v, c) ( writew(v, __armio(c) ) )
+#define outl(v, c) ( writel(v, __armio(c) ) )
+
 #endif /* _ARM_ARM64_IO_H */
Signature · 1 line
2.1.0
#25 lore raw

PATCH v3 4/62 arm/acpi: Emulate io ports for arm

xen/include/asm-arm/arm64/io.h static inline u64 __raw_readq(const volatile void __iomem *addr) · line 125

Quoted 13 lines · On Tuesday 17 November 2015 17:40:03 shannon.zhao at linaro.org wrote:
xen/include/asm-arm/arm64/io.h +13 -0
+/*
+ * Emulate x86 io ports for arm.
+ */
+#define __armio(addr) ( (void __iomem *)addr )
+
+#define inb(c) ( readb( __armio(c) ) )
+#define inw(c) ( readw( __armio(c) ) )
+#define inl(c) ( readl( __armio(c) ) )
+
+#define outb(v, c) ( writeb(v, __armio(c) ) )
+#define outw(v, c) ( writew(v, __armio(c) ) )
+#define outl(v, c) ( writel(v, __armio(c) ) )
+

This is almost certainly wrong. There might be I/O port accesses, but they won't be in the same place as normal pointers.

Arnd

#26 lore raw

PATCH v3 4/62 arm/acpi: Emulate io ports for arm

Hi Arnd,

Quoted 18 lines · Arnd Bergmann

xen/include/asm-arm/arm64/io.h static inline u64 __raw_readq(const volatile void __iomem *addr) · line 125

Quoted 13 lines · On Tuesday 17 November 2015 17:40:03 shannon.zhao at linaro.org wrote:
xen/include/asm-arm/arm64/io.h +13 -0
+/*
+ * Emulate x86 io ports for arm.
+ */
+#define __armio(addr) ( (void __iomem *)addr )
+
+#define inb(c) ( readb( __armio(c) ) )
+#define inw(c) ( readw( __armio(c) ) )
+#define inl(c) ( readl( __armio(c) ) )
+
+#define outb(v, c) ( writeb(v, __armio(c) ) )
+#define outw(v, c) ( writew(v, __armio(c) ) )
+#define outl(v, c) ( writel(v, __armio(c) ) )
+

This is almost certainly wrong. There might be I/O port accesses, but they won't be in the same place as normal pointers.

Sorry, maybe I didn't get what you mean. Here it just wants emulate the in(b,w,l) and out(b,w,l) which exist on x86 while not on ARM. So it could introduce less change to the common ACPI codes, for example acpi_os_write_port().

I see there is the same thing in Linux arch/arm/include/asm/io.h

Thanks,

Signature · 1 line
Shannon
#27 lore raw

PATCH v3 4/62 arm/acpi: Emulate io ports for arm

Quoted 21 lines · On Wednesday 18 November 2015 15:01:26 Shannon Zhao wrote:

Hi Arnd,

Quoted 18 lines · Arnd Bergmann

xen/include/asm-arm/arm64/io.h static inline u64 __raw_readq(const volatile void __iomem *addr) · line 125

Quoted 13 lines · On Tuesday 17 November 2015 17:40:03 shannon.zhao at linaro.org wrote:
xen/include/asm-arm/arm64/io.h +13 -0
+/*
+ * Emulate x86 io ports for arm.
+ */
+#define __armio(addr) ( (void __iomem *)addr )
+
+#define inb(c) ( readb( __armio(c) ) )
+#define inw(c) ( readw( __armio(c) ) )
+#define inl(c) ( readl( __armio(c) ) )
+
+#define outb(v, c) ( writeb(v, __armio(c) ) )
+#define outw(v, c) ( writew(v, __armio(c) ) )
+#define outl(v, c) ( writel(v, __armio(c) ) )
+

This is almost certainly wrong. There might be I/O port accesses, but they won't be in the same place as normal pointers.

Quoted 6 lines

Sorry, maybe I didn't get what you mean. Here it just wants emulate the in(b,w,l) and out(b,w,l) which exist on x86 while not on ARM. So it could introduce less change to the common ACPI codes, for example acpi_os_write_port().

I see there is the same thing in Linux arch/arm/include/asm/io.h

The problem is that your definition of __armio() is wrong. If you want to do it right, you need to first find the PCI I/O port ranges and map them into a virtual address, and then define __armio() in a way to add the virtual address you have mapped them to.

Alternatively, define the functions so they don't try to access the pointers but instead just print a warning.

Arnd

#28 lore raw

Re: [PATCH v3 04/62] arm/acpi: Emulate io ports for arm

In reply to Shannon Zhao
Quoted 21 lines · On Wednesday 18 November 2015 15:01:26 Shannon Zhao wrote:

Hi Arnd,

Quoted 18 lines · Arnd Bergmann

xen/include/asm-arm/arm64/io.h static inline u64 __raw_readq(const volatile void __iomem *addr) · line 125

Quoted 13 lines · On Tuesday 17 November 2015 17:40:03 [email protected] wrote:
xen/include/asm-arm/arm64/io.h +13 -0
+/*
+ * Emulate x86 io ports for arm.
+ */
+#define __armio(addr) ( (void __iomem *)addr )
+
+#define inb(c) ( readb( __armio(c) ) )
+#define inw(c) ( readw( __armio(c) ) )
+#define inl(c) ( readl( __armio(c) ) )
+
+#define outb(v, c) ( writeb(v, __armio(c) ) )
+#define outw(v, c) ( writew(v, __armio(c) ) )
+#define outl(v, c) ( writel(v, __armio(c) ) )
+

This is almost certainly wrong. There might be I/O port accesses, but they won't be in the same place as normal pointers.

Quoted 6 lines

Sorry, maybe I didn't get what you mean. Here it just wants emulate the in(b,w,l) and out(b,w,l) which exist on x86 while not on ARM. So it could introduce less change to the common ACPI codes, for example acpi_os_write_port().

I see there is the same thing in Linux arch/arm/include/asm/io.h

The problem is that your definition of __armio() is wrong. If you want to do it right, you need to first find the PCI I/O port ranges and map them into a virtual address, and then define __armio() in a way to add the virtual address you have mapped them to.

Alternatively, define the functions so they don't try to access the pointers but instead just print a warning.

Arnd

#29 lore raw

Re: [PATCH v3 04/62] arm/acpi: Emulate io ports for arm

In reply to Arnd Bergmann

Hi Arnd,

Quoted 18 lines · Arnd Bergmann

xen/include/asm-arm/arm64/io.h static inline u64 __raw_readq(const volatile void __iomem *addr) · line 125

Quoted 13 lines · On Tuesday 17 November 2015 17:40:03 [email protected] wrote:
xen/include/asm-arm/arm64/io.h +13 -0
+/*
+ * Emulate x86 io ports for arm.
+ */
+#define __armio(addr) ( (void __iomem *)addr )
+
+#define inb(c) ( readb( __armio(c) ) )
+#define inw(c) ( readw( __armio(c) ) )
+#define inl(c) ( readl( __armio(c) ) )
+
+#define outb(v, c) ( writeb(v, __armio(c) ) )
+#define outw(v, c) ( writew(v, __armio(c) ) )
+#define outl(v, c) ( writel(v, __armio(c) ) )
+

This is almost certainly wrong. There might be I/O port accesses, but they won't be in the same place as normal pointers.

Sorry, maybe I didn't get what you mean. Here it just wants emulate the in(b,w,l) and out(b,w,l) which exist on x86 while not on ARM. So it could introduce less change to the common ACPI codes, for example acpi_os_write_port().

I see there is the same thing in Linux arch/arm/include/asm/io.h

Thanks,

Signature · 1 line
Shannon
#30 lore raw

PATCH v3 5/62 acpi: Don't do traditional BIOS table scan for ARM64

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

With the addition of ARM64 that does not have a traditional BIOS to scan, add a #ifdef option for x86 to do the traditional BIOS scanning for tables.

---
 xen/drivers/acpi/osl.c | 2 ++
 1 file changed, 2 insertions(+)
xen/drivers/acpi/osl.c +2 -0
index ce15470..db74a90 100644
@@ -78,7 +78,9 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
 	} else {
 		acpi_physical_address pa = 0;
 
+		#ifdef CONFIG_X86
 		acpi_find_root_pointer(&pa);
+		#endif
 		return pa;
 	}
 }
Signature · 1 line
2.1.0
#31 lore raw

PATCH v3 5/62 acpi: Don't do traditional BIOS table scan for ARM64

Quoted 16 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

With the addition of ARM64 that does not have a traditional BIOS to scan, add a #ifdef option for x86 to do the traditional BIOS scanning for tables.

---
 xen/drivers/acpi/osl.c | 2 ++
 1 file changed, 2 insertions(+)
xen/drivers/acpi/osl.c +0 -0
index ce15470..db74a90 100644

xen/drivers/acpi/osl.c acpi_physical_address __init acpi_os_get_root_pointer(void) · line 85

Quoted 8 lines
xen/drivers/acpi/osl.c +2 -0
@@ -78,7 +78,9 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
 	} else {
 		acpi_physical_address pa = 0;
 
+		#ifdef CONFIG_X86
 		acpi_find_root_pointer(&pa);
+		#endif
 		return pa;
 	}

I think it might be best to error out earlier if acpi and !efi_enabled on arm and arm64. If we do that we'll never enter this "else".

If acpi_find_root_pointer doesn't build on arm, we should move it to an x86 specific location, such as xen/arch/x86/efi.

#32 lore raw

PATCH v3 5/62 acpi: Don't do traditional BIOS table scan for ARM64

Quoted 30 lines
Quoted 1 line
Quoted 1 line · On 23.11.15 at 12:24, <[email protected]> wrote:
Quoted 16 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

With the addition of ARM64 that does not have a traditional BIOS to scan, add a #ifdef option for x86 to do the traditional BIOS scanning for tables.

---
 xen/drivers/acpi/osl.c | 2 ++
 1 file changed, 2 insertions(+)
xen/drivers/acpi/osl.c +0 -0
index ce15470..db74a90 100644

xen/drivers/acpi/osl.c acpi_physical_address __init acpi_os_get_root_pointer(void) · line 85

Quoted 8 lines
xen/drivers/acpi/osl.c +2 -0
@@ -78,7 +78,9 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
 	} else {
 		acpi_physical_address pa = 0;
 
+		#ifdef CONFIG_X86
 		acpi_find_root_pointer(&pa);
+		#endif
 		return pa;
 	}

I think it might be best to error out earlier if acpi and !efi_enabled on arm and arm64. If we do that we'll never enter this "else".

Quoted 2 lines

If acpi_find_root_pointer doesn't build on arm, we should move it to an x86 specific location, such as xen/arch/x86/efi.

No, definitely not (or if anything, then xen/arch/x86/acpi/). Instead the function itself should be stubbed out to do nothing on ARM. (And of course also the #ifdef placement is rather odd).

Jan

#33 lore raw

PATCH v3 5/62 acpi: Don't do traditional BIOS table scan for ARM64

Quoted 30 lines · Jan Beulich
Quoted 30 lines
Quoted 1 line
Quoted 1 line · On 23.11.15 at 12:24, <[email protected]> wrote:
Quoted 16 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

With the addition of ARM64 that does not have a traditional BIOS to scan, add a #ifdef option for x86 to do the traditional BIOS scanning for tables.

---
 xen/drivers/acpi/osl.c | 2 ++
 1 file changed, 2 insertions(+)
xen/drivers/acpi/osl.c +0 -0
index ce15470..db74a90 100644

xen/drivers/acpi/osl.c acpi_physical_address __init acpi_os_get_root_pointer(void) · line 85

Quoted 8 lines
xen/drivers/acpi/osl.c +2 -0
@@ -78,7 +78,9 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
 	} else {
 		acpi_physical_address pa = 0;
 
+		#ifdef CONFIG_X86
 		acpi_find_root_pointer(&pa);
+		#endif
 		return pa;
 	}

I think it might be best to error out earlier if acpi and !efi_enabled on arm and arm64. If we do that we'll never enter this "else".

Quoted 7 lines
Quoted 2 lines

If acpi_find_root_pointer doesn't build on arm, we should move it to an x86 specific location, such as xen/arch/x86/efi.

No, definitely not (or if anything, then xen/arch/x86/acpi/). Instead the function itself should be stubbed out to do nothing on ARM. (And of course also the #ifdef placement is rather odd).

How about adding a new CONFIG_ACPI_LEGACY_TABLES_LOOKUP like Linux kernel for x86?

Thanks,

Signature · 1 line
Shannon
#34 lore raw

PATCH v3 5/62 acpi: Don't do traditional BIOS table scan for ARM64

Quoted 22 lines
Quoted 1 line
Quoted 1 line · On 24.11.15 at 04:39, <[email protected]> wrote:
Quoted 20 lines · Jan Beulich
Quoted 19 lines
Quoted 1 line
Quoted 1 line · On 23.11.15 at 12:24, <[email protected]> wrote:

xen/drivers/acpi/osl.c acpi_physical_address __init acpi_os_get_root_pointer(void) · line 85

Quoted 11 lines · shannon.zhao at linaro.org
xen/drivers/acpi/osl.c +2 -0
@@ -78,7 +78,9 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
 	} else {
 		acpi_physical_address pa = 0;
 
+		#ifdef CONFIG_X86
 		acpi_find_root_pointer(&pa);
+		#endif
 		return pa;
 	}

I think it might be best to error out earlier if acpi and !efi_enabled on arm and arm64. If we do that we'll never enter this "else".

If acpi_find_root_pointer doesn't build on arm, we should move it to an x86 specific location, such as xen/arch/x86/efi.

Quoted 6 lines
Quoted 4 lines

No, definitely not (or if anything, then xen/arch/x86/acpi/). Instead the function itself should be stubbed out to do nothing on ARM. (And of course also the #ifdef placement is rather odd).

How about adding a new CONFIG_ACPI_LEGACY_TABLES_LOOKUP like Linux kernel for x86?

Unless you know of an architecture other than x86 potentially needing this, I think this would go too far. Plus the suggested name would imply "old style" lookup only, whereas per-arch customization also allows for other "modern" (or simply "alternative") mechanisms to be used.

Jan

#35 lore raw

Re: [PATCH v3 05/62] acpi: Don't do traditional BIOS table scan for ARM64

In reply to Shannon Zhao
Quoted 22 lines
Quoted 1 line
Quoted 1 line · On 24.11.15 at 04:39, <[email protected]> wrote:
Quoted 20 lines · Jan Beulich
Quoted 19 lines
Quoted 1 line
Quoted 1 line · On 23.11.15 at 12:24, <[email protected]> wrote:

xen/drivers/acpi/osl.c acpi_physical_address __init acpi_os_get_root_pointer(void) · line 85

Quoted 11 lines · On Tue, 17 Nov 2015, [email protected] wrote:
xen/drivers/acpi/osl.c +2 -0
@@ -78,7 +78,9 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
 	} else {
 		acpi_physical_address pa = 0;
 
+		#ifdef CONFIG_X86
 		acpi_find_root_pointer(&pa);
+		#endif
 		return pa;
 	}

I think it might be best to error out earlier if acpi and !efi_enabled on arm and arm64. If we do that we'll never enter this "else".

If acpi_find_root_pointer doesn't build on arm, we should move it to an x86 specific location, such as xen/arch/x86/efi.

Quoted 6 lines
Quoted 4 lines

No, definitely not (or if anything, then xen/arch/x86/acpi/). Instead the function itself should be stubbed out to do nothing on ARM. (And of course also the #ifdef placement is rather odd).

How about adding a new CONFIG_ACPI_LEGACY_TABLES_LOOKUP like Linux kernel for x86?

Unless you know of an architecture other than x86 potentially needing this, I think this would go too far. Plus the suggested name would imply "old style" lookup only, whereas per-arch customization also allows for other "modern" (or simply "alternative") mechanisms to be used.

Jan

#36 lore raw

Re: [PATCH v3 05/62] acpi: Don't do traditional BIOS table scan for ARM64

In reply to Jan Beulich
Quoted 30 lines · Jan Beulich
Quoted 30 lines
Quoted 1 line
Quoted 1 line · On 23.11.15 at 12:24, <[email protected]> wrote:
Quoted 16 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

With the addition of ARM64 that does not have a traditional BIOS to scan, add a #ifdef option for x86 to do the traditional BIOS scanning for tables.

---
 xen/drivers/acpi/osl.c | 2 ++
 1 file changed, 2 insertions(+)
xen/drivers/acpi/osl.c +0 -0
index ce15470..db74a90 100644

xen/drivers/acpi/osl.c acpi_physical_address __init acpi_os_get_root_pointer(void) · line 85

Quoted 8 lines
xen/drivers/acpi/osl.c +2 -0
@@ -78,7 +78,9 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
 	} else {
 		acpi_physical_address pa = 0;
 
+		#ifdef CONFIG_X86
 		acpi_find_root_pointer(&pa);
+		#endif
 		return pa;
 	}

I think it might be best to error out earlier if acpi and !efi_enabled on arm and arm64. If we do that we'll never enter this "else".

Quoted 7 lines
Quoted 2 lines

If acpi_find_root_pointer doesn't build on arm, we should move it to an x86 specific location, such as xen/arch/x86/efi.

No, definitely not (or if anything, then xen/arch/x86/acpi/). Instead the function itself should be stubbed out to do nothing on ARM. (And of course also the #ifdef placement is rather odd).

How about adding a new CONFIG_ACPI_LEGACY_TABLES_LOOKUP like Linux kernel for x86?

Thanks,

Signature · 1 line
Shannon
#37 lore raw

Re: [PATCH v3 05/62] acpi: Don't do traditional BIOS table scan for ARM64

In reply to Stefano Stabellini
Quoted 30 lines
Quoted 1 line
Quoted 1 line · On 23.11.15 at 12:24, <[email protected]> wrote:
Quoted 16 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

With the addition of ARM64 that does not have a traditional BIOS to scan, add a #ifdef option for x86 to do the traditional BIOS scanning for tables.

---
 xen/drivers/acpi/osl.c | 2 ++
 1 file changed, 2 insertions(+)
xen/drivers/acpi/osl.c +0 -0
index ce15470..db74a90 100644

xen/drivers/acpi/osl.c acpi_physical_address __init acpi_os_get_root_pointer(void) · line 85

Quoted 8 lines
xen/drivers/acpi/osl.c +2 -0
@@ -78,7 +78,9 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
 	} else {
 		acpi_physical_address pa = 0;
 
+		#ifdef CONFIG_X86
 		acpi_find_root_pointer(&pa);
+		#endif
 		return pa;
 	}

I think it might be best to error out earlier if acpi and !efi_enabled on arm and arm64. If we do that we'll never enter this "else".

Quoted 2 lines

If acpi_find_root_pointer doesn't build on arm, we should move it to an x86 specific location, such as xen/arch/x86/efi.

No, definitely not (or if anything, then xen/arch/x86/acpi/). Instead the function itself should be stubbed out to do nothing on ARM. (And of course also the #ifdef placement is rather odd).

Jan

#38 lore raw

PATCH v3 6/62 acpi: Refactor acpi_os_map_memory to be architecturally independent

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Current acpi_os_map_memory is specific to x86. Refactor it to be architecturally independent.

---
 xen/arch/x86/acpi/lib.c | 16 ++++++++++++++++
 xen/drivers/acpi/osl.c  | 12 +-----------
 xen/include/xen/acpi.h  |  2 ++
 3 files changed, 19 insertions(+), 11 deletions(-)
xen/arch/x86/acpi/lib.c +16 -0
index cc15ea3..1e2e124 100644
@@ -33,6 +33,22 @@ u8 __read_mostly acpi_disable_value;
 u32 __read_mostly x86_acpiid_to_apicid[MAX_MADT_ENTRIES] =
     {[0 ... MAX_MADT_ENTRIES - 1] = BAD_APICID };
 
+void __iomem *
+arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
+{
+	if (system_state >= SYS_STATE_active) {
+		mfn_t mfn = _mfn(PFN_DOWN(phys));
+		unsigned int offs = phys & (PAGE_SIZE - 1);
+
+		/* The low first Mb is always mapped. */
+		if ( !((phys + size - 1) >> 20) )
+			return __va(phys);
+		return __vmap(&mfn, PFN_UP(offs + size), 1, 1,
+			      PAGE_HYPERVISOR_NOCACHE) + offs;
+	}
+	return __acpi_map_table(phys, size);
+}
+
 /*
  * Important Safety Note:  The fixed ACPI page numbers are *subtracted*
  * from the fixed base.  That's why we start at FIX_ACPI_END and
xen/drivers/acpi/osl.c +1 -11
index db74a90..54fb0f0 100644
@@ -88,17 +88,7 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
 void __iomem *
 acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 {
-	if (system_state >= SYS_STATE_active) {
-		mfn_t mfn = _mfn(PFN_DOWN(phys));
-		unsigned int offs = phys & (PAGE_SIZE - 1);
-
-		/* The low first Mb is always mapped. */
-		if ( !((phys + size - 1) >> 20) )
-			return __va(phys);
-		return __vmap(&mfn, PFN_UP(offs + size), 1, 1,
-			      PAGE_HYPERVISOR_NOCACHE) + offs;
-	}
-	return __acpi_map_table(phys, size);
+	return arch_acpi_os_map_memory(phys, size);
 }
 
 void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
xen/include/xen/acpi.h +2 -0
index 0f1077d..48d7810 100644
@@ -54,6 +54,8 @@ typedef int (*acpi_table_handler) (struct acpi_table_header *table);
 
 typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
 
+void __iomem *
+arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size);
 unsigned int acpi_get_processor_id (unsigned int cpu);
 char * __acpi_map_table (paddr_t phys_addr, unsigned long size);
 int acpi_boot_init (void);
Signature · 1 line
2.1.0
#39 lore raw

PATCH v3 6/62 acpi: Refactor acpi_os_map_memory to be architecturally independent

Quoted 3 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>
Current acpi_os_map_memory is specific to x86. Refactor it to be architecturally independent.

I would say "Move it to an x86-specific location".

Quoted 1 line
Quoted 77 lines
 xen/arch/x86/acpi/lib.c | 16 ++++++++++++++++
 xen/drivers/acpi/osl.c  | 12 +-----------
 xen/include/xen/acpi.h  |  2 ++
 3 files changed, 19 insertions(+), 11 deletions(-)
xen/arch/x86/acpi/lib.c +16 -0
index cc15ea3..1e2e124 100644
@@ -33,6 +33,22 @@ u8 __read_mostly acpi_disable_value;
 u32 __read_mostly x86_acpiid_to_apicid[MAX_MADT_ENTRIES] =
     {[0 ... MAX_MADT_ENTRIES - 1] = BAD_APICID };
 
+void __iomem *
+arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
+{
+	if (system_state >= SYS_STATE_active) {
+		mfn_t mfn = _mfn(PFN_DOWN(phys));
+		unsigned int offs = phys & (PAGE_SIZE - 1);
+
+		/* The low first Mb is always mapped. */
+		if ( !((phys + size - 1) >> 20) )
+			return __va(phys);
+		return __vmap(&mfn, PFN_UP(offs + size), 1, 1,
+			      PAGE_HYPERVISOR_NOCACHE) + offs;
+	}
+	return __acpi_map_table(phys, size);
+}
+
 /*
  * Important Safety Note:  The fixed ACPI page numbers are *subtracted*
  * from the fixed base.  That's why we start at FIX_ACPI_END and
xen/drivers/acpi/osl.c +1 -11
index db74a90..54fb0f0 100644
@@ -88,17 +88,7 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
 void __iomem *
 acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 {
-	if (system_state >= SYS_STATE_active) {
-		mfn_t mfn = _mfn(PFN_DOWN(phys));
-		unsigned int offs = phys & (PAGE_SIZE - 1);
-
-		/* The low first Mb is always mapped. */
-		if ( !((phys + size - 1) >> 20) )
-			return __va(phys);
-		return __vmap(&mfn, PFN_UP(offs + size), 1, 1,
-			      PAGE_HYPERVISOR_NOCACHE) + offs;
-	}
-	return __acpi_map_table(phys, size);
+	return arch_acpi_os_map_memory(phys, size);
 }
 
 void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
xen/include/xen/acpi.h +2 -0
index 0f1077d..48d7810 100644
@@ -54,6 +54,8 @@ typedef int (*acpi_table_handler) (struct acpi_table_header *table);
 
 typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
 
+void __iomem *
+arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size);
 unsigned int acpi_get_processor_id (unsigned int cpu);
 char * __acpi_map_table (paddr_t phys_addr, unsigned long size);
 int acpi_boot_init (void);
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel at lists.xen.org
http://lists.xen.org/xen-devel
#40 lore raw

PATCH v3 6/62 acpi: Refactor acpi_os_map_memory to be architecturally independent

Quoted 7 lines
Quoted 1 line
Quoted 1 line · On 23.11.15 at 12:29, <[email protected]> wrote:
Quoted 3 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>
Current acpi_os_map_memory is specific to x86. Refactor it to be architecturally independent.

I would say "Move it to an x86-specific location".

But it shouldn't be moved - only the _truly_ x86-specific pieces should be factored out.

Jan

#41 lore raw

Re: [PATCH v3 06/62] acpi: Refactor acpi_os_map_memory to be architecturally independent

In reply to Stefano Stabellini
Quoted 7 lines
Quoted 1 line
Quoted 1 line · On 23.11.15 at 12:29, <[email protected]> wrote:
Quoted 3 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>
Current acpi_os_map_memory is specific to x86. Refactor it to be architecturally independent.

I would say "Move it to an x86-specific location".

But it shouldn't be moved - only the _truly_ x86-specific pieces should be factored out.

Jan

Acked-by on v3 6/62
#42 lore raw

Re: [PATCH v3 06/62] acpi: Refactor acpi_os_map_memory to be architecturally independent

In reply to shannon.zhao at linaro.org
Quoted 3 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>
Current acpi_os_map_memory is specific to x86. Refactor it to be architecturally independent.

I would say "Move it to an x86-specific location".

Quoted 1 line
Quoted 77 lines
 xen/arch/x86/acpi/lib.c | 16 ++++++++++++++++
 xen/drivers/acpi/osl.c  | 12 +-----------
 xen/include/xen/acpi.h  |  2 ++
 3 files changed, 19 insertions(+), 11 deletions(-)
xen/arch/x86/acpi/lib.c +16 -0
index cc15ea3..1e2e124 100644
@@ -33,6 +33,22 @@ u8 __read_mostly acpi_disable_value;
 u32 __read_mostly x86_acpiid_to_apicid[MAX_MADT_ENTRIES] =
     {[0 ... MAX_MADT_ENTRIES - 1] = BAD_APICID };
 
+void __iomem *
+arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
+{
+	if (system_state >= SYS_STATE_active) {
+		mfn_t mfn = _mfn(PFN_DOWN(phys));
+		unsigned int offs = phys & (PAGE_SIZE - 1);
+
+		/* The low first Mb is always mapped. */
+		if ( !((phys + size - 1) >> 20) )
+			return __va(phys);
+		return __vmap(&mfn, PFN_UP(offs + size), 1, 1,
+			      PAGE_HYPERVISOR_NOCACHE) + offs;
+	}
+	return __acpi_map_table(phys, size);
+}
+
 /*
  * Important Safety Note:  The fixed ACPI page numbers are *subtracted*
  * from the fixed base.  That's why we start at FIX_ACPI_END and
xen/drivers/acpi/osl.c +1 -11
index db74a90..54fb0f0 100644
@@ -88,17 +88,7 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
 void __iomem *
 acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 {
-	if (system_state >= SYS_STATE_active) {
-		mfn_t mfn = _mfn(PFN_DOWN(phys));
-		unsigned int offs = phys & (PAGE_SIZE - 1);
-
-		/* The low first Mb is always mapped. */
-		if ( !((phys + size - 1) >> 20) )
-			return __va(phys);
-		return __vmap(&mfn, PFN_UP(offs + size), 1, 1,
-			      PAGE_HYPERVISOR_NOCACHE) + offs;
-	}
-	return __acpi_map_table(phys, size);
+	return arch_acpi_os_map_memory(phys, size);
 }
 
 void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
xen/include/xen/acpi.h +2 -0
index 0f1077d..48d7810 100644
@@ -54,6 +54,8 @@ typedef int (*acpi_table_handler) (struct acpi_table_header *table);
 
 typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
 
+void __iomem *
+arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size);
 unsigned int acpi_get_processor_id (unsigned int cpu);
 char * __acpi_map_table (paddr_t phys_addr, unsigned long size);
 int acpi_boot_init (void);
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#43 lore raw

PATCH v3 6/62 acpi: Refactor acpi_os_map_memory to be architecturally independent

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 4 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Current acpi_os_map_memory is specific to x86. Refactor it to be architecturally independent.

The function acpi_os_unmap_memory should also be arch-independent.

Otherwise, with the implementation you did on ARM (see patch #7), you will destroy by mistake the mapping in the page table for those regions.

Regards,

Signature · 1 line
Julien Grall
#44 lore raw

Re: [PATCH v3 06/62] acpi: Refactor acpi_os_map_memory to be architecturally independent

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 4 lines · On 17/11/15 09:40, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Current acpi_os_map_memory is specific to x86. Refactor it to be architecturally independent.

The function acpi_os_unmap_memory should also be arch-independent.

Otherwise, with the implementation you did on ARM (see patch #7), you will destroy by mistake the mapping in the page table for those regions.

Regards,

Signature · 1 line
Julien Grall
#45 lore raw

PATCH v3 7/62 arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

---
 xen/arch/arm/Makefile      |  1 +
 xen/arch/arm/acpi/Makefile |  1 +
 xen/arch/arm/acpi/lib.c    | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+)
 create mode 100644 xen/arch/arm/acpi/Makefile
 create mode 100644 xen/arch/arm/acpi/lib.c
xen/arch/arm/Makefile +1 -0
index 1ef39f7..1851ae8 100644
@@ -2,6 +2,7 @@ subdir-$(arm32) += arm32
 subdir-$(arm64) += arm64
 subdir-y += platforms
 subdir-$(arm64) += efi
+subdir-$(HAS_ACPI) += acpi
 
 obj-$(EARLY_PRINTK) += early_printk.o
 obj-y += cpu.o
xen/arch/arm/acpi/Makefile new file +1 -0
new file mode 100644
index 0000000..b5be22d
@@ -0,0 +1 @@
+obj-y += lib.o
xen/arch/arm/acpi/lib.c new file +33 -0
new file mode 100644
index 0000000..b68623b
@@ -0,0 +1,33 @@
+/*
+ *  lib.c - Architecture-Specific Low-Level ACPI Support
+ *
+ *  Copyright (C) 2015, Shannon Zhao <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <xen/acpi.h>
+#include <xen/mm.h>
+#include <asm/mm.h>
+
+void __iomem *
+arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
+{
+    return __va(phys);
+}
Signature · 1 line
2.1.0
#46 lore raw

PATCH v3 7/62 arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

Quoted 1 line · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Hi Shannon,

could you please add a couple of lines to the commit message mentioning why __va(phys) is an acceptable implementation of arch_acpi_os_map_memory?

Thanks,

Stefano

Quoted 70 lines
---
 xen/arch/arm/Makefile      |  1 +
 xen/arch/arm/acpi/Makefile |  1 +
 xen/arch/arm/acpi/lib.c    | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+)
 create mode 100644 xen/arch/arm/acpi/Makefile
 create mode 100644 xen/arch/arm/acpi/lib.c
xen/arch/arm/Makefile +1 -0
index 1ef39f7..1851ae8 100644
@@ -2,6 +2,7 @@ subdir-$(arm32) += arm32
 subdir-$(arm64) += arm64
 subdir-y += platforms
 subdir-$(arm64) += efi
+subdir-$(HAS_ACPI) += acpi
 
 obj-$(EARLY_PRINTK) += early_printk.o
 obj-y += cpu.o
xen/arch/arm/acpi/Makefile new file +1 -0
new file mode 100644
index 0000000..b5be22d
@@ -0,0 +1 @@
+obj-y += lib.o
xen/arch/arm/acpi/lib.c new file +33 -0
new file mode 100644
index 0000000..b68623b
@@ -0,0 +1,33 @@
+/*
+ *  lib.c - Architecture-Specific Low-Level ACPI Support
+ *
+ *  Copyright (C) 2015, Shannon Zhao <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <xen/acpi.h>
+#include <xen/mm.h>
+#include <asm/mm.h>
+
+void __iomem *
+arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
+{
+    return __va(phys);
+}
Signature · 1 line
2.1.0
#47 lore raw

PATCH v3 7/62 arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

Hi,

Quoted 5 lines · Stefano Stabellini
Quoted 1 line · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

could you please add a couple of lines to the commit message mentioning why __va(phys) is an acceptable implementation of arch_acpi_os_map_memory?

FWIW, I already asked this question multiple time on the previous series without clear answer.

__va should only be used when the memory is direct-mapped to Xen (i.e accessible directly). On ARM64, this is only the case for the RAM. Can someone confirm the ACPI will always reside to the RAM?

Regards,

Signature · 1 line
Julien Grall
#48 lore raw

PATCH v3 7/62 arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

Hi,

Quoted 5 lines · Julien Grall

Hi,

Quoted 2 lines · Stefano Stabellini
Quoted 2 lines · shannon.zhao at linaro.org
Quoted 1 line
Quoted 1 line

From: Shannon Zhao <[email protected]>

Quoted 8 lines
Quoted 2 lines
Quoted 2 lines

could you please add a couple of lines to the commit message mentioning why __va(phys) is an acceptable implementation of arch_acpi_os_map_memory?

FWIW, I already asked this question multiple time on the previous series without clear answer.

__va should only be used when the memory is direct-mapped to Xen (i.e accessible directly). On ARM64, this is only the case for the RAM. Can someone confirm the ACPI will always reside to the RAM?

I checked this with the UEFI SPEC. It says in 2.3.6 AArch64 Platforms:
"If ACPI is supported :
? ACPI Tables loaded at boot time can be contained in memory of type EfiACPIReclaimMemory (recommended) or EfiACPIMemoryNVS."

So I think it means the ACPI tables will always reside in RAM.

Thanks,

Signature · 1 line
Shannon
#49 lore raw

PATCH v3 7/62 arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

Quoted 13 lines
Quoted 1 line
Quoted 1 line · On 07.12.15 at 09:58, <[email protected]> wrote:
Quoted 11 lines · Julien Grall
Quoted 4 lines · Stefano Stabellini
Quoted 4 lines · shannon.zhao at linaro.org
Quoted 1 line
Quoted 1 line

From: Shannon Zhao <[email protected]>

could you please add a couple of lines to the commit message mentioning why __va(phys) is an acceptable implementation of arch_acpi_os_map_memory?

FWIW, I already asked this question multiple time on the previous series without clear answer.

__va should only be used when the memory is direct-mapped to Xen (i.e accessible directly). On ARM64, this is only the case for the RAM. Can someone confirm the ACPI will always reside to the RAM?

Quoted 6 lines

I checked this with the UEFI SPEC. It says in 2.3.6 AArch64 Platforms:
"If ACPI is supported :
? ACPI Tables loaded at boot time can be contained in memory of type EfiACPIReclaimMemory (recommended) or EfiACPIMemoryNVS."

So I think it means the ACPI tables will always reside in RAM.

I think NVS doesn't necessarily mean RAM.

Jan

#50 lore raw

PATCH v3 7/62 arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

Quoted 17 lines · Jan Beulich
Quoted 17 lines
Quoted 1 line
Quoted 1 line · On 07.12.15 at 09:58, <[email protected]> wrote:
Quoted 15 lines · Julien Grall
Quoted 6 lines · Stefano Stabellini
Quoted 6 lines · shannon.zhao at linaro.org
Quoted 1 line
Quoted 1 line

From: Shannon Zhao <[email protected]>

could you please add a couple of lines to the commit message mentioning
why __va(phys) is an acceptable implementation of arch_acpi_os_map_memory?

FWIW, I already asked this question multiple time on the previous series
without clear answer.

__va should only be used when the memory is direct-mapped to Xen (i.e accessible directly). On ARM64, this is only the case for the RAM. Can
someone confirm the ACPI will always reside to the RAM?

Quoted 8 lines
Quoted 6 lines

I checked this with the UEFI SPEC. It says in 2.3.6 AArch64 Platforms:
"If ACPI is supported :
? ACPI Tables loaded at boot time can be contained in memory of type EfiACPIReclaimMemory (recommended) or EfiACPIMemoryNVS."

So I think it means the ACPI tables will always reside in RAM.

I think NVS doesn't necessarily mean RAM.

That's what I thought/expected too (sounds like it could be flash, CMOS, ROM etc), but looking at the ACPI 6.0 spec ("16.3.2 BIOS Initialization of Memory") it says:

Memory identified by the BIOS as being? reserved by the BIOS for its use.
OSPM is required to tag this memory as cacheable, and to save and
restore its image before entering an S4 state.

IOW, if I'm reading that correctly, it actually is "memory", and it is only "NV" by virtue of requiring the OSPM to save/restore it over suspend (so not at all "NV" in the usual sense).

Ian.

#51 lore raw

PATCH v3 7/62 arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

Quoted 31 lines · Ian Campbell
Quoted 17 lines · Jan Beulich
Quoted 17 lines
Quoted 1 line
Quoted 1 line · On 07.12.15 at 09:58, <[email protected]> wrote:
Quoted 15 lines · Julien Grall
Quoted 6 lines · Stefano Stabellini
Quoted 6 lines · shannon.zhao at linaro.org
Quoted 1 line
Quoted 1 line

From: Shannon Zhao <[email protected]>

could you please add a couple of lines to the commit message mentioning
why __va(phys) is an acceptable implementation of arch_acpi_os_map_memory?

FWIW, I already asked this question multiple time on the previous series
without clear answer.

__va should only be used when the memory is direct-mapped to Xen (i.e accessible directly). On ARM64, this is only the case for the RAM. Can
someone confirm the ACPI will always reside to the RAM?

Quoted 8 lines
Quoted 6 lines

I checked this with the UEFI SPEC. It says in 2.3.6 AArch64 Platforms:
"If ACPI is supported :
? ACPI Tables loaded at boot time can be contained in memory of type EfiACPIReclaimMemory (recommended) or EfiACPIMemoryNVS."

So I think it means the ACPI tables will always reside in RAM.

I think NVS doesn't necessarily mean RAM.

That's what I thought/expected too (sounds like it could be flash, CMOS, ROM etc), but looking at the ACPI 6.0 spec ("16.3.2 BIOS Initialization of Memory") it says:

Quoted 7 lines

Memory identified by the BIOS as being reserved by the BIOS for its use.
OSPM is required to tag this memory as cacheable, and to save and
restore its image before entering an S4 state.

IOW, if I'm reading that correctly, it actually is "memory", and it is only "NV" by virtue of requiring the OSPM to save/restore it over suspend (so not at all "NV" in the usual sense).

I think it would be safer to use vmap. It won't impact much Xen as the mapping are mostly used during Xen boot and DOM0 creation.

Regards,

Signature · 1 line
Julien Grall
#52 lore raw

Re: [PATCH v3 07/62] arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

Hi,

Quoted 36 lines · Julien Grall
Quoted 35 lines · Ian Campbell
Quoted 17 lines · Jan Beulich
Quoted 17 lines
Quoted 1 line
Quoted 1 line · On 07.12.15 at 09:58, <[email protected]> wrote:
Quoted 15 lines · Julien Grall
Quoted 6 lines · Stefano Stabellini
Quoted 6 lines · On Tue, 17 Nov 2015, [email protected] wrote:
Quoted 1 line
Quoted 1 line

From: Shannon Zhao <[email protected]>

could you please add a couple of lines to the commit message mentioning
why __va(phys) is an acceptable implementation of arch_acpi_os_map_memory?

FWIW, I already asked this question multiple time on the previous series
without clear answer.

__va should only be used when the memory is direct-mapped to Xen (i.e accessible directly). On ARM64, this is only the case for the RAM. Can
someone confirm the ACPI will always reside to the RAM?

Quoted 8 lines
Quoted 6 lines

I checked this with the UEFI SPEC. It says in 2.3.6 AArch64 Platforms:
"If ACPI is supported :
● ACPI Tables loaded at boot time can be contained in memory of type EfiACPIReclaimMemory (recommended) or EfiACPIMemoryNVS."

So I think it means the ACPI tables will always reside in RAM.

I think NVS doesn't necessarily mean RAM.

That's what I thought/expected too (sounds like it could be flash, CMOS, ROM etc), but looking at the ACPI 6.0 spec ("16.3.2 BIOS Initialization of Memory") it says:

Memory identified by the BIOS as being reserved by the BIOS for its use.
OSPM is required to tag this memory as cacheable, and to save and
restore its image before entering an S4 state.

Quoted 7 lines
Quoted 3 lines

IOW, if I'm reading that correctly, it actually is "memory", and it is only "NV" by virtue of requiring the OSPM to save/restore it over suspend (so not at all "NV" in the usual sense).

I think it would be safer to use vmap. It won't impact much Xen as the mapping are mostly used during Xen boot and DOM0 creation.

If it uses vmap, it needs to move acpi_boot_table_init after vm_init(), right?

I move acpi_boot_table_init after vm_init() and rewrite arch_acpi_os_map_memory like below.

void __iomem * arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size) {

-    return __va(phys);
+    mfn_t mfn = _mfn(PFN_DOWN(phys));
+    unsigned int offs = phys & (PAGE_SIZE - 1);

+
+ return __vmap(&mfn, PFN_UP(offs + size), 1, 1, PAGE_HYPERVISOR)
+ + offs;
}

But there is a weird problem. All the ACPI tables are installed correctly within acpi_boot_table_init() and it prints with below output:

(XEN) ACPI: RSDP FEC90014, 0024 (r2 LINARO)

(XEN) ACPI: XSDT FEC800E8, 0044 (r1 LINARO RTSMVEV8        0       1000013)
(XEN) ACPI: FACP FEC50000, 0114 (r6 LINARO RTSMVEV8        0 INTL 20150619)
(XEN) ACPI: DSDT FEC60000, 0248 (r2 LINARO RTSMVEV8        4 INTL 20150619)
(XEN) ACPI: APIC FEC70000, 02D4 (r3 LINARO RTSMVEV8        1 INTL 20150619)
(XEN) ACPI: GTDT FEC40000, 009C (r2 LINARO RTSMVEV8        1 INTL 20150619)
(XEN) ACPI: SPCR FEC30000, 0050 (r1 LINARO RTSMVEV8        0 INTL 20150619)

As you see, the physical address of DSDT table is FEC60000, but when I print acpi_gbl_root_table_list.tables[0].address after acpi_boot_table_init(), it becomes aafec60000. And it even becomes d6aaaaaafec60000 when it's used in acpi_map_rest_tables(see patch 49).

But others of acpi_gbl_root_table_list don't change. E.g. acpi_gbl_root_table_list.tables[2].address is always FEC50000.

Signature · 7 lines
Shannon


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#53 lore raw

Re: [PATCH v3 07/62] arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

In reply to Ian Campbell
Quoted 31 lines · Ian Campbell
Quoted 17 lines · Jan Beulich
Quoted 17 lines
Quoted 1 line
Quoted 1 line · On 07.12.15 at 09:58, <[email protected]> wrote:
Quoted 15 lines · Julien Grall
Quoted 6 lines · Stefano Stabellini
Quoted 6 lines · On Tue, 17 Nov 2015, [email protected] wrote:
Quoted 1 line
Quoted 1 line

From: Shannon Zhao <[email protected]>

could you please add a couple of lines to the commit message mentioning
why __va(phys) is an acceptable implementation of arch_acpi_os_map_memory?

FWIW, I already asked this question multiple time on the previous series
without clear answer.

__va should only be used when the memory is direct-mapped to Xen (i.e accessible directly). On ARM64, this is only the case for the RAM. Can
someone confirm the ACPI will always reside to the RAM?

Quoted 8 lines
Quoted 6 lines

I checked this with the UEFI SPEC. It says in 2.3.6 AArch64 Platforms:
"If ACPI is supported :
● ACPI Tables loaded at boot time can be contained in memory of type EfiACPIReclaimMemory (recommended) or EfiACPIMemoryNVS."

So I think it means the ACPI tables will always reside in RAM.

I think NVS doesn't necessarily mean RAM.

That's what I thought/expected too (sounds like it could be flash, CMOS, ROM etc), but looking at the ACPI 6.0 spec ("16.3.2 BIOS Initialization of Memory") it says:

Quoted 7 lines

Memory identified by the BIOS as being reserved by the BIOS for its use.
OSPM is required to tag this memory as cacheable, and to save and
restore its image before entering an S4 state.

IOW, if I'm reading that correctly, it actually is "memory", and it is only "NV" by virtue of requiring the OSPM to save/restore it over suspend (so not at all "NV" in the usual sense).

I think it would be safer to use vmap. It won't impact much Xen as the mapping are mostly used during Xen boot and DOM0 creation.

Regards,

Signature · 6 lines
Julien Grall

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#54 lore raw

Re: [PATCH v3 07/62] arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

In reply to Jan Beulich
Quoted 17 lines · Jan Beulich
Quoted 17 lines
Quoted 1 line
Quoted 1 line · On 07.12.15 at 09:58, <[email protected]> wrote:
Quoted 15 lines · Julien Grall
Quoted 6 lines · Stefano Stabellini
Quoted 6 lines · On Tue, 17 Nov 2015, [email protected] wrote:
Quoted 1 line
Quoted 1 line

From: Shannon Zhao <[email protected]>

could you please add a couple of lines to the commit message mentioning
why __va(phys) is an acceptable implementation of arch_acpi_os_map_memory?

FWIW, I already asked this question multiple time on the previous series
without clear answer.

__va should only be used when the memory is direct-mapped to Xen (i.e accessible directly). On ARM64, this is only the case for the RAM. Can
someone confirm the ACPI will always reside to the RAM?

Quoted 8 lines
Quoted 6 lines

I checked this with the UEFI SPEC. It says in 2.3.6 AArch64 Platforms:
"If ACPI is supported :
● ACPI Tables loaded at boot time can be contained in memory of type EfiACPIReclaimMemory (recommended) or EfiACPIMemoryNVS."

So I think it means the ACPI tables will always reside in RAM.

I think NVS doesn't necessarily mean RAM.

That's what I thought/expected too (sounds like it could be flash, CMOS, ROM etc), but looking at the ACPI 6.0 spec ("16.3.2 BIOS Initialization of Memory") it says:

Memory identified by the BIOS as being  reserved by the BIOS for its use.
OSPM is required to tag this memory as cacheable, and to save and
restore its image before entering an S4 state.

IOW, if I'm reading that correctly, it actually is "memory", and it is only "NV" by virtue of requiring the OSPM to save/restore it over suspend (so not at all "NV" in the usual sense).

Ian.

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#55 lore raw

Re: [PATCH v3 07/62] arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

In reply to Shannon Zhao
Quoted 13 lines
Quoted 1 line
Quoted 1 line · On 07.12.15 at 09:58, <[email protected]> wrote:
Quoted 11 lines · Julien Grall
Quoted 4 lines · Stefano Stabellini
Quoted 4 lines · On Tue, 17 Nov 2015, [email protected] wrote:
Quoted 1 line
Quoted 1 line

From: Shannon Zhao <[email protected]>

could you please add a couple of lines to the commit message mentioning why __va(phys) is an acceptable implementation of arch_acpi_os_map_memory?

FWIW, I already asked this question multiple time on the previous series without clear answer.

__va should only be used when the memory is direct-mapped to Xen (i.e accessible directly). On ARM64, this is only the case for the RAM. Can someone confirm the ACPI will always reside to the RAM?

Quoted 6 lines

I checked this with the UEFI SPEC. It says in 2.3.6 AArch64 Platforms:
"If ACPI is supported :
● ACPI Tables loaded at boot time can be contained in memory of type EfiACPIReclaimMemory (recommended) or EfiACPIMemoryNVS."

So I think it means the ACPI tables will always reside in RAM.

I think NVS doesn't necessarily mean RAM.

Jan

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#56 lore raw

Re: [PATCH v3 07/62] arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

In reply to Stefano Stabellini

Hi,

Quoted 5 lines · Stefano Stabellini
Quoted 1 line · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

could you please add a couple of lines to the commit message mentioning why __va(phys) is an acceptable implementation of arch_acpi_os_map_memory?

FWIW, I already asked this question multiple time on the previous series without clear answer.

__va should only be used when the memory is direct-mapped to Xen (i.e accessible directly). On ARM64, this is only the case for the RAM. Can someone confirm the ACPI will always reside to the RAM?

Regards,

Signature · 1 line
Julien Grall
#57 lore raw

Re: [PATCH v3 07/62] arm/acpi: Add arch_acpi_os_map_memory helper function for ARM

In reply to shannon.zhao at linaro.org
Quoted 1 line · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Hi Shannon,

could you please add a couple of lines to the commit message mentioning why __va(phys) is an acceptable implementation of arch_acpi_os_map_memory?

Thanks,

Stefano

Quoted 70 lines
---
 xen/arch/arm/Makefile      |  1 +
 xen/arch/arm/acpi/Makefile |  1 +
 xen/arch/arm/acpi/lib.c    | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+)
 create mode 100644 xen/arch/arm/acpi/Makefile
 create mode 100644 xen/arch/arm/acpi/lib.c
xen/arch/arm/Makefile +1 -0
index 1ef39f7..1851ae8 100644
@@ -2,6 +2,7 @@ subdir-$(arm32) += arm32
 subdir-$(arm64) += arm64
 subdir-y += platforms
 subdir-$(arm64) += efi
+subdir-$(HAS_ACPI) += acpi
 
 obj-$(EARLY_PRINTK) += early_printk.o
 obj-y += cpu.o
xen/arch/arm/acpi/Makefile new file +1 -0
new file mode 100644
index 0000000..b5be22d
@@ -0,0 +1 @@
+obj-y += lib.o
xen/arch/arm/acpi/lib.c new file +33 -0
new file mode 100644
index 0000000..b68623b
@@ -0,0 +1,33 @@
+/*
+ *  lib.c - Architecture-Specific Low-Level ACPI Support
+ *
+ *  Copyright (C) 2015, Shannon Zhao <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <xen/acpi.h>
+#include <xen/mm.h>
+#include <asm/mm.h>
+
+void __iomem *
+arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
+{
+    return __va(phys);
+}
Signature · 1 line
2.1.0
#58 lore raw

PATCH v3 8/62 arm/acpi: Add arm specific acpi header file

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Add architecture specific definitions and calls required for acpi in new header file.

---
 xen/arch/arm/setup.c       |  3 +++
 xen/include/asm-arm/acpi.h | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)
 create mode 100644 xen/include/asm-arm/acpi.h
xen/arch/arm/setup.c +3 -0
index e95759d..3b29904 100644
@@ -45,11 +45,14 @@
 #include <asm/procinfo.h>
 #include <asm/setup.h>
 #include <xsm/xsm.h>
+#include <asm/acpi.h>
 
 struct bootinfo __initdata bootinfo;
 
 struct cpuinfo_arm __read_mostly boot_cpu_data;
 
+bool_t __read_mostly acpi_disabled;
+
 #ifdef CONFIG_ARM_32
 static unsigned long opt_xenheap_megabytes __initdata;
 integer_param("xenheap_megabytes", opt_xenheap_megabytes);
xen/include/asm-arm/acpi.h new file +38 -0
new file mode 100644
index 0000000..e41e03b
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (C) 2015, Shannon Zhao <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#ifndef _ASM_ARM_ACPI_H
+#define _ASM_ARM_ACPI_H
+
+#include <xen/init.h>
+
+#define COMPILER_DEPENDENT_INT64   long long
+#define COMPILER_DEPENDENT_UINT64  unsigned long long
+
+extern bool_t acpi_disabled;
+/* Basic configuration for ACPI */
+static inline void disable_acpi(void)
+{
+    acpi_disabled = 1;
+}
+
+#endif /*_ASM_ARM_ACPI_H*/
Signature · 1 line
2.1.0
#59 lore raw

PATCH v3 8/62 arm/acpi: Add arm specific acpi header file

Quoted 7 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Add architecture specific definitions and calls required for acpi in new header file.

Quoted 71 lines
 xen/arch/arm/setup.c       |  3 +++
 xen/include/asm-arm/acpi.h | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)
 create mode 100644 xen/include/asm-arm/acpi.h
xen/arch/arm/setup.c +3 -0
index e95759d..3b29904 100644
@@ -45,11 +45,14 @@
 #include <asm/procinfo.h>
 #include <asm/setup.h>
 #include <xsm/xsm.h>
+#include <asm/acpi.h>
 
 struct bootinfo __initdata bootinfo;
 
 struct cpuinfo_arm __read_mostly boot_cpu_data;
 
+bool_t __read_mostly acpi_disabled;
+
 #ifdef CONFIG_ARM_32
 static unsigned long opt_xenheap_megabytes __initdata;
 integer_param("xenheap_megabytes", opt_xenheap_megabytes);
xen/include/asm-arm/acpi.h new file +38 -0
new file mode 100644
index 0000000..e41e03b
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (C) 2015, Shannon Zhao <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#ifndef _ASM_ARM_ACPI_H
+#define _ASM_ARM_ACPI_H
+
+#include <xen/init.h>
+
+#define COMPILER_DEPENDENT_INT64   long long
+#define COMPILER_DEPENDENT_UINT64  unsigned long long
+
+extern bool_t acpi_disabled;
+/* Basic configuration for ACPI */
+static inline void disable_acpi(void)
+{
+    acpi_disabled = 1;
+}
+
+#endif /*_ASM_ARM_ACPI_H*/
Signature · 1 line
2.1.0
Acked-by on v3 8/62
#60 lore raw

Re: [PATCH v3 08/62] arm/acpi: Add arm specific acpi header file

In reply to shannon.zhao at linaro.org
Quoted 7 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Add architecture specific definitions and calls required for acpi in new header file.

Quoted 71 lines
 xen/arch/arm/setup.c       |  3 +++
 xen/include/asm-arm/acpi.h | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)
 create mode 100644 xen/include/asm-arm/acpi.h
xen/arch/arm/setup.c +3 -0
index e95759d..3b29904 100644
@@ -45,11 +45,14 @@
 #include <asm/procinfo.h>
 #include <asm/setup.h>
 #include <xsm/xsm.h>
+#include <asm/acpi.h>
 
 struct bootinfo __initdata bootinfo;
 
 struct cpuinfo_arm __read_mostly boot_cpu_data;
 
+bool_t __read_mostly acpi_disabled;
+
 #ifdef CONFIG_ARM_32
 static unsigned long opt_xenheap_megabytes __initdata;
 integer_param("xenheap_megabytes", opt_xenheap_megabytes);
xen/include/asm-arm/acpi.h new file +38 -0
new file mode 100644
index 0000000..e41e03b
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (C) 2015, Shannon Zhao <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#ifndef _ASM_ARM_ACPI_H
+#define _ASM_ARM_ACPI_H
+
+#include <xen/init.h>
+
+#define COMPILER_DEPENDENT_INT64   long long
+#define COMPILER_DEPENDENT_UINT64  unsigned long long
+
+extern bool_t acpi_disabled;
+/* Basic configuration for ACPI */
+static inline void disable_acpi(void)
+{
+    acpi_disabled = 1;
+}
+
+#endif /*_ASM_ARM_ACPI_H*/
Signature · 1 line
2.1.0
#61 lore raw

PATCH v3 9/62 arm/acpi: Add basic ACPI initialization

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

acpi_boot_table_init() will be called in start_xen to get the RSDP and all the table pointers. With this patch, we can get ACPI boot-time tables from firmware on ARM64.

---
 xen/arch/arm/acpi/Makefile |  1 +
 xen/arch/arm/acpi/boot.c   | 62 ++++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/setup.c       |  4 +++
 3 files changed, 67 insertions(+)
 create mode 100644 xen/arch/arm/acpi/boot.c
xen/arch/arm/acpi/Makefile +1 -0
index b5be22d..196c40a 100644
@@ -1 +1,2 @@
 obj-y += lib.o
+obj-y += boot.o
xen/arch/arm/acpi/boot.c new file +62 -0

62 lines not on this page · raw message

xen/arch/arm/setup.c +4 -0
index 3b29904..768312f 100644
@@ -36,6 +36,7 @@
 #include <xen/pfn.h>
 #include <xen/vmap.h>
 #include <xen/libfdt/libfdt.h>
+#include <xen/acpi.h>
 #include <asm/page.h>
 #include <asm/current.h>
 #include <asm/setup.h>
@@ -753,6 +754,9 @@ void __init start_xen(unsigned long boot_phys_offset,
 
     setup_mm(fdt_paddr, fdt_size);
 
+    /* Parse the ACPI tables for possible boot-time configuration */
+    acpi_boot_table_init();
+
     vm_init();
     dt_unflatten_host_device_tree();
 
Signature · 1 line
2.1.0
#62 lore raw

PATCH v3 9/62 arm/acpi: Add basic ACPI initialization

Quoted 5 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

acpi_boot_table_init() will be called in start_xen to get the RSDP and all the table pointers. With this patch, we can get ACPI boot-time tables from firmware on ARM64.

The patch looks good, only one comment below.

Quoted 98 lines
---
 xen/arch/arm/acpi/Makefile |  1 +
 xen/arch/arm/acpi/boot.c   | 62 ++++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/setup.c       |  4 +++
 3 files changed, 67 insertions(+)
 create mode 100644 xen/arch/arm/acpi/boot.c
xen/arch/arm/acpi/Makefile +1 -0
index b5be22d..196c40a 100644
@@ -1 +1,2 @@
 obj-y += lib.o
+obj-y += boot.o
xen/arch/arm/acpi/boot.c new file +62 -0
new file mode 100644
index 0000000..ad51afc
@@ -0,0 +1,62 @@
+/*
+ *  ARM Specific Low-Level ACPI Boot Support
+ *
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <[email protected]>
+ *  Copyright (C) 2001 Jun Nakajima <[email protected]>
+ *  Copyright (C) 2014, Naresh Bhat <[email protected]>
+ *  Copyright (C) 2015, Shannon Zhao <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <xen/init.h>
+#include <xen/acpi.h>
+
+#include <asm/acpi.h>
+
+/*
+ * acpi_boot_table_init() called from setup_arch(), always.
+ *      1. find RSDP and get its address, and then find XSDT
+ *      2. extract all tables and checksums them all
+ *
+ * return value: (currently ignored)
+ *	0: success
+ *	!0: failure
+ *
+ * We can parse ACPI boot-time tables such as FADT, MADT after
+ * this function is called.
+ */
+int __init acpi_boot_table_init(void)
+{
+    int error;
+
+    /* If acpi_disabled, bail out */
+    if ( acpi_disabled )
+        return 1;
+
+    /* Initialize the ACPI boot-time table parser. */
+    error = acpi_table_init();
+    if ( error )
+    {
+        disable_acpi();
+        return error;
+    }
+
+    return 0;
+}
xen/arch/arm/setup.c +1 -0
index 3b29904..768312f 100644
@@ -36,6 +36,7 @@
 #include <xen/pfn.h>
 #include <xen/vmap.h>
 #include <xen/libfdt/libfdt.h>
+#include <xen/acpi.h>
 #include <asm/page.h>
 #include <asm/current.h>
 #include <asm/setup.h>

xen/arch/arm/setup.c void __init start_xen(unsigned long boot_phys_offset, · line 758

Quoted 5 lines
xen/arch/arm/setup.c +2 -0
@@ -753,6 +754,9 @@ void __init start_xen(unsigned long boot_phys_offset,
 
     setup_mm(fdt_paddr, fdt_size);
 
+    /* Parse the ACPI tables for possible boot-time configuration */
+    acpi_boot_table_init();

Are you sure that you need to call acpi_boot_table_init before vm_init?

Quoted 12 lines
xen/arch/arm/setup.c +0 -0
     vm_init();
     dt_unflatten_host_device_tree();
 
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel at lists.xen.org
http://lists.xen.org/xen-devel
#63 lore raw

Re: [PATCH v3 09/62] arm/acpi: Add basic ACPI initialization

In reply to shannon.zhao at linaro.org
Quoted 5 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

acpi_boot_table_init() will be called in start_xen to get the RSDP and all the table pointers. With this patch, we can get ACPI boot-time tables from firmware on ARM64.

The patch looks good, only one comment below.

Quoted 98 lines
---
 xen/arch/arm/acpi/Makefile |  1 +
 xen/arch/arm/acpi/boot.c   | 62 ++++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/setup.c       |  4 +++
 3 files changed, 67 insertions(+)
 create mode 100644 xen/arch/arm/acpi/boot.c
xen/arch/arm/acpi/Makefile +1 -0
index b5be22d..196c40a 100644
@@ -1 +1,2 @@
 obj-y += lib.o
+obj-y += boot.o
xen/arch/arm/acpi/boot.c new file +62 -0
new file mode 100644
index 0000000..ad51afc
@@ -0,0 +1,62 @@
+/*
+ *  ARM Specific Low-Level ACPI Boot Support
+ *
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <[email protected]>
+ *  Copyright (C) 2001 Jun Nakajima <[email protected]>
+ *  Copyright (C) 2014, Naresh Bhat <[email protected]>
+ *  Copyright (C) 2015, Shannon Zhao <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <xen/init.h>
+#include <xen/acpi.h>
+
+#include <asm/acpi.h>
+
+/*
+ * acpi_boot_table_init() called from setup_arch(), always.
+ *      1. find RSDP and get its address, and then find XSDT
+ *      2. extract all tables and checksums them all
+ *
+ * return value: (currently ignored)
+ *	0: success
+ *	!0: failure
+ *
+ * We can parse ACPI boot-time tables such as FADT, MADT after
+ * this function is called.
+ */
+int __init acpi_boot_table_init(void)
+{
+    int error;
+
+    /* If acpi_disabled, bail out */
+    if ( acpi_disabled )
+        return 1;
+
+    /* Initialize the ACPI boot-time table parser. */
+    error = acpi_table_init();
+    if ( error )
+    {
+        disable_acpi();
+        return error;
+    }
+
+    return 0;
+}
xen/arch/arm/setup.c +1 -0
index 3b29904..768312f 100644
@@ -36,6 +36,7 @@
 #include <xen/pfn.h>
 #include <xen/vmap.h>
 #include <xen/libfdt/libfdt.h>
+#include <xen/acpi.h>
 #include <asm/page.h>
 #include <asm/current.h>
 #include <asm/setup.h>

xen/arch/arm/setup.c void __init start_xen(unsigned long boot_phys_offset, · line 758

Quoted 5 lines
xen/arch/arm/setup.c +2 -0
@@ -753,6 +754,9 @@ void __init start_xen(unsigned long boot_phys_offset,
 
     setup_mm(fdt_paddr, fdt_size);
 
+    /* Parse the ACPI tables for possible boot-time configuration */
+    acpi_boot_table_init();

Are you sure that you need to call acpi_boot_table_init before vm_init?

Quoted 12 lines
xen/arch/arm/setup.c +0 -0
     vm_init();
     dt_unflatten_host_device_tree();
 
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#64 lore raw

PATCH v3 10/62 arm/acpi: Move end_boot_allocator after acpi_boot_table_init

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

If ACPI is initialized after the boot allocator has ended(the system state is not early boot), assert happens in acpi_os_zalloc_memory and acpi_boot_table_init will fail. So it needs to move end_boot_allocator after acpi_boot_table_init.

---
 xen/arch/arm/setup.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
xen/arch/arm/setup.c +2 -4
index 768312f..c15a09d 100644
@@ -613,8 +613,6 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size)
        allocator. */
     init_xenheap_pages(pfn_to_paddr(xenheap_mfn_start),
                        pfn_to_paddr(boot_mfn_start));
-
-    end_boot_allocator();
 }
 #else /* CONFIG_ARM_64 */
 static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size)
@@ -682,8 +680,6 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size)
 
     setup_frametable_mappings(ram_start, ram_end);
     max_page = PFN_DOWN(ram_end);
-
-    end_boot_allocator();
 }
 #endif
 
@@ -757,6 +753,8 @@ void __init start_xen(unsigned long boot_phys_offset,
     /* Parse the ACPI tables for possible boot-time configuration */
     acpi_boot_table_init();
 
+    end_boot_allocator();
+
     vm_init();
     dt_unflatten_host_device_tree();
 
Signature · 1 line
2.1.0
#65 lore raw

PATCH v3 10/62 arm/acpi: Move end_boot_allocator after acpi_boot_table_init

Quoted 9 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

If ACPI is initialized after the boot allocator has ended(the system state is not early boot), assert happens in acpi_os_zalloc_memory and acpi_boot_table_init will fail. So it needs to move end_boot_allocator after acpi_boot_table_init.

This is the reason why you are calling acpi_boot_table_init before vm_init, correct?

Quoted 37 lines
 xen/arch/arm/setup.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
xen/arch/arm/setup.c +2 -4
index 768312f..c15a09d 100644
@@ -613,8 +613,6 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size)
        allocator. */
     init_xenheap_pages(pfn_to_paddr(xenheap_mfn_start),
                        pfn_to_paddr(boot_mfn_start));
-
-    end_boot_allocator();
 }
 #else /* CONFIG_ARM_64 */
 static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size)
@@ -682,8 +680,6 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size)
 
     setup_frametable_mappings(ram_start, ram_end);
     max_page = PFN_DOWN(ram_end);
-
-    end_boot_allocator();
 }
 #endif
 
@@ -757,6 +753,8 @@ void __init start_xen(unsigned long boot_phys_offset,
     /* Parse the ACPI tables for possible boot-time configuration */
     acpi_boot_table_init();
 
+    end_boot_allocator();
+
     vm_init();
     dt_unflatten_host_device_tree();
 
Signature · 1 line
2.1.0
#66 lore raw

Re: [PATCH v3 10/62] arm/acpi: Move end_boot_allocator after acpi_boot_table_init

In reply to shannon.zhao at linaro.org
Quoted 9 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

If ACPI is initialized after the boot allocator has ended(the system state is not early boot), assert happens in acpi_os_zalloc_memory and acpi_boot_table_init will fail. So it needs to move end_boot_allocator after acpi_boot_table_init.

This is the reason why you are calling acpi_boot_table_init before vm_init, correct?

Quoted 37 lines
 xen/arch/arm/setup.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
xen/arch/arm/setup.c +2 -4
index 768312f..c15a09d 100644
@@ -613,8 +613,6 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size)
        allocator. */
     init_xenheap_pages(pfn_to_paddr(xenheap_mfn_start),
                        pfn_to_paddr(boot_mfn_start));
-
-    end_boot_allocator();
 }
 #else /* CONFIG_ARM_64 */
 static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size)
@@ -682,8 +680,6 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size)
 
     setup_frametable_mappings(ram_start, ram_end);
     max_page = PFN_DOWN(ram_end);
-
-    end_boot_allocator();
 }
 #endif
 
@@ -757,6 +753,8 @@ void __init start_xen(unsigned long boot_phys_offset,
     /* Parse the ACPI tables for possible boot-time configuration */
     acpi_boot_table_init();
 
+    end_boot_allocator();
+
     vm_init();
     dt_unflatten_host_device_tree();
 
Signature · 1 line
2.1.0
#67 lore raw

PATCH v3 11/62 arm/acpi: Introduce ARM Boot Architecture Flags in FADT

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

The Power State Coordination Interface (PSCI) defines an API that can be used to coordinate power control amongst the various supervisory systems concurrently running on a device. ACPI support for this technology would require the addition of two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set, the former signals to the OS that the hardware is PSCI compliant. The latter selects the appropriate conduit for PSCI calls by toggling between Hypervisor Calls (HVC) and Secure Monitor Calls (SMC).

An ARM Boot Architecture Flags structure to support new ARM hardware was introduced in FADT in ACPI 5.1, add the code accordingly to implement that in ACPICA core.

Since ACPI 5.1 doesn't support self defined PSCI function IDs, which means that only PSCI 0.2+ is supported in ACPI.

---
 xen/include/acpi/actbl.h | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
xen/include/acpi/actbl.h +9 -3
index 856945d..66e29c3 100644
@@ -244,7 +244,8 @@ struct acpi_table_fadt {
 	u32 flags;		/* Miscellaneous flag bits (see below for individual flags) */
 	struct acpi_generic_address reset_register;	/* 64-bit address of the Reset register */
 	u8 reset_value;		/* Value to write to the reset_register port to reset the system */
-	u8 reserved4[3];	/* Reserved, must be zero */
+	u16 arm_boot_flags;     /* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */
+	u8 minor_revision;      /* FADT Minor Revision (ACPI 5.1) */
 	u64 Xfacs;		/* 64-bit physical address of FACS */
 	u64 Xdsdt;		/* 64-bit physical address of DSDT */
 	struct acpi_generic_address xpm1a_event_block;	/* 64-bit Extended Power Mgt 1a Event Reg Blk address */
@@ -259,7 +260,7 @@ struct acpi_table_fadt {
 	struct acpi_generic_address sleep_status;	/* 64-bit Sleep Status register */
 };
 
-/* Masks for FADT Boot Architecture Flags (boot_flags) */
+/* Masks for FADT IA-PC Boot Architecture Flags (boot_flags) */
 
 #define ACPI_FADT_LEGACY_DEVICES    (1)  	/* 00: [V2] System has LPC or ISA bus devices */
 #define ACPI_FADT_8042              (1<<1)	/* 01: [V3] System has an 8042 controller on port 60/64 */
@@ -270,6 +271,11 @@ struct acpi_table_fadt {
 
 #define FADT2_REVISION_ID               3
 
+/* Masks for FADT ARM Boot Architecture Flags (arm_boot_flags) ACPI 5.1 */
+
+#define ACPI_FADT_PSCI_COMPLIANT    (1)        /* 00:  [V5+] PSCI 0.2+ is implemented */
+#define ACPI_FADT_PSCI_USE_HVC      (1<<1)     /* 01:  [V5+] HVC must be used instead of SMC as the PSCI conduit */
+
 /* Masks for FADT flags */
 
 #define ACPI_FADT_WBINVD            (1)	/* 00: [V1] The wbinvd instruction works properly */
@@ -345,7 +351,7 @@ enum acpi_prefered_pm_profiles {
  *     FADT V5  size: 0x10C
  */
 #define ACPI_FADT_V1_SIZE       (u32) (ACPI_FADT_OFFSET (flags) + 4)
-#define ACPI_FADT_V2_SIZE       (u32) (ACPI_FADT_OFFSET (reserved4[0]) + 3)
+#define ACPI_FADT_V2_SIZE       (u32) (ACPI_FADT_OFFSET (minor_revision) + 1)
 #define ACPI_FADT_V3_SIZE       (u32) (ACPI_FADT_OFFSET (sleep_control))
 #define ACPI_FADT_V5_SIZE       (u32) (sizeof (struct acpi_table_fadt))
 
Signature · 1 line
2.1.0
#68 lore raw

PATCH v3 11/62 arm/acpi: Introduce ARM Boot Architecture Flags in FADT

Quoted 15 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

The Power State Coordination Interface (PSCI) defines an API that can be used to coordinate power control amongst the various supervisory systems concurrently running on a device. ACPI support for this technology would require the addition of two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set, the former signals to the OS that the hardware is PSCI compliant. The latter selects the appropriate conduit for PSCI calls by toggling between Hypervisor Calls (HVC) and Secure Monitor Calls (SMC).

An ARM Boot Architecture Flags structure to support new ARM hardware was introduced in FADT in ACPI 5.1, add the code accordingly to implement that in ACPICA core.

Quoted 6 lines

Since ACPI 5.1 doesn't support self defined PSCI function IDs, which means that only PSCI 0.2+ is supported in ACPI.

Quoted 50 lines
 xen/include/acpi/actbl.h | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
xen/include/acpi/actbl.h +9 -3
index 856945d..66e29c3 100644
@@ -244,7 +244,8 @@ struct acpi_table_fadt {
 	u32 flags;		/* Miscellaneous flag bits (see below for individual flags) */
 	struct acpi_generic_address reset_register;	/* 64-bit address of the Reset register */
 	u8 reset_value;		/* Value to write to the reset_register port to reset the system */
-	u8 reserved4[3];	/* Reserved, must be zero */
+	u16 arm_boot_flags;     /* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */
+	u8 minor_revision;      /* FADT Minor Revision (ACPI 5.1) */
 	u64 Xfacs;		/* 64-bit physical address of FACS */
 	u64 Xdsdt;		/* 64-bit physical address of DSDT */
 	struct acpi_generic_address xpm1a_event_block;	/* 64-bit Extended Power Mgt 1a Event Reg Blk address */
@@ -259,7 +260,7 @@ struct acpi_table_fadt {
 	struct acpi_generic_address sleep_status;	/* 64-bit Sleep Status register */
 };
 
-/* Masks for FADT Boot Architecture Flags (boot_flags) */
+/* Masks for FADT IA-PC Boot Architecture Flags (boot_flags) */
 
 #define ACPI_FADT_LEGACY_DEVICES    (1)  	/* 00: [V2] System has LPC or ISA bus devices */
 #define ACPI_FADT_8042              (1<<1)	/* 01: [V3] System has an 8042 controller on port 60/64 */
@@ -270,6 +271,11 @@ struct acpi_table_fadt {
 
 #define FADT2_REVISION_ID               3
 
+/* Masks for FADT ARM Boot Architecture Flags (arm_boot_flags) ACPI 5.1 */
+
+#define ACPI_FADT_PSCI_COMPLIANT    (1)        /* 00:  [V5+] PSCI 0.2+ is implemented */
+#define ACPI_FADT_PSCI_USE_HVC      (1<<1)     /* 01:  [V5+] HVC must be used instead of SMC as the PSCI conduit */
+
 /* Masks for FADT flags */
 
 #define ACPI_FADT_WBINVD            (1)	/* 00: [V1] The wbinvd instruction works properly */
@@ -345,7 +351,7 @@ enum acpi_prefered_pm_profiles {
  *     FADT V5  size: 0x10C
  */
 #define ACPI_FADT_V1_SIZE       (u32) (ACPI_FADT_OFFSET (flags) + 4)
-#define ACPI_FADT_V2_SIZE       (u32) (ACPI_FADT_OFFSET (reserved4[0]) + 3)
+#define ACPI_FADT_V2_SIZE       (u32) (ACPI_FADT_OFFSET (minor_revision) + 1)
 #define ACPI_FADT_V3_SIZE       (u32) (ACPI_FADT_OFFSET (sleep_control))
 #define ACPI_FADT_V5_SIZE       (u32) (sizeof (struct acpi_table_fadt))
 
Signature · 1 line
2.1.0
Acked-by on v3 11/62
#69 lore raw

Re: [PATCH v3 11/62] arm/acpi: Introduce ARM Boot Architecture Flags in FADT

In reply to shannon.zhao at linaro.org
Quoted 15 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

The Power State Coordination Interface (PSCI) defines an API that can be used to coordinate power control amongst the various supervisory systems concurrently running on a device. ACPI support for this technology would require the addition of two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set, the former signals to the OS that the hardware is PSCI compliant. The latter selects the appropriate conduit for PSCI calls by toggling between Hypervisor Calls (HVC) and Secure Monitor Calls (SMC).

An ARM Boot Architecture Flags structure to support new ARM hardware was introduced in FADT in ACPI 5.1, add the code accordingly to implement that in ACPICA core.

Quoted 6 lines

Since ACPI 5.1 doesn't support self defined PSCI function IDs, which means that only PSCI 0.2+ is supported in ACPI.

Quoted 50 lines
 xen/include/acpi/actbl.h | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
xen/include/acpi/actbl.h +9 -3
index 856945d..66e29c3 100644
@@ -244,7 +244,8 @@ struct acpi_table_fadt {
 	u32 flags;		/* Miscellaneous flag bits (see below for individual flags) */
 	struct acpi_generic_address reset_register;	/* 64-bit address of the Reset register */
 	u8 reset_value;		/* Value to write to the reset_register port to reset the system */
-	u8 reserved4[3];	/* Reserved, must be zero */
+	u16 arm_boot_flags;     /* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */
+	u8 minor_revision;      /* FADT Minor Revision (ACPI 5.1) */
 	u64 Xfacs;		/* 64-bit physical address of FACS */
 	u64 Xdsdt;		/* 64-bit physical address of DSDT */
 	struct acpi_generic_address xpm1a_event_block;	/* 64-bit Extended Power Mgt 1a Event Reg Blk address */
@@ -259,7 +260,7 @@ struct acpi_table_fadt {
 	struct acpi_generic_address sleep_status;	/* 64-bit Sleep Status register */
 };
 
-/* Masks for FADT Boot Architecture Flags (boot_flags) */
+/* Masks for FADT IA-PC Boot Architecture Flags (boot_flags) */
 
 #define ACPI_FADT_LEGACY_DEVICES    (1)  	/* 00: [V2] System has LPC or ISA bus devices */
 #define ACPI_FADT_8042              (1<<1)	/* 01: [V3] System has an 8042 controller on port 60/64 */
@@ -270,6 +271,11 @@ struct acpi_table_fadt {
 
 #define FADT2_REVISION_ID               3
 
+/* Masks for FADT ARM Boot Architecture Flags (arm_boot_flags) ACPI 5.1 */
+
+#define ACPI_FADT_PSCI_COMPLIANT    (1)        /* 00:  [V5+] PSCI 0.2+ is implemented */
+#define ACPI_FADT_PSCI_USE_HVC      (1<<1)     /* 01:  [V5+] HVC must be used instead of SMC as the PSCI conduit */
+
 /* Masks for FADT flags */
 
 #define ACPI_FADT_WBINVD            (1)	/* 00: [V1] The wbinvd instruction works properly */
@@ -345,7 +351,7 @@ enum acpi_prefered_pm_profiles {
  *     FADT V5  size: 0x10C
  */
 #define ACPI_FADT_V1_SIZE       (u32) (ACPI_FADT_OFFSET (flags) + 4)
-#define ACPI_FADT_V2_SIZE       (u32) (ACPI_FADT_OFFSET (reserved4[0]) + 3)
+#define ACPI_FADT_V2_SIZE       (u32) (ACPI_FADT_OFFSET (minor_revision) + 1)
 #define ACPI_FADT_V3_SIZE       (u32) (ACPI_FADT_OFFSET (sleep_control))
 #define ACPI_FADT_V5_SIZE       (u32) (sizeof (struct acpi_table_fadt))
 
Signature · 1 line
2.1.0
#70 lore raw

PATCH v3 12/62 ACPICA: ACPI 6.0: Add changes for FADT table

In reply to shannon.zhao at linaro.org

From: Bob Moore <[email protected]>

ACPICA commit 72b0b6741990f619f6aaa915302836b7cbb41ac4

One new 64-bit field at the end of the table. FADT version is now 6.

---
 xen/include/acpi/actbl.h | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)
xen/include/acpi/actbl.h +10 -7
index 66e29c3..3079176 100644
@@ -258,6 +258,7 @@ struct acpi_table_fadt {
 	struct acpi_generic_address xgpe1_block;	/* 64-bit Extended General Purpose Event 1 Reg Blk address */
 	struct acpi_generic_address sleep_control;	/* 64-bit Sleep Control register */
 	struct acpi_generic_address sleep_status;	/* 64-bit Sleep Status register */
+	u64 hypervisor_id;      /* Hypervisor Vendor ID (ACPI 6.0) */
 };
 
 /* Masks for FADT IA-PC Boot Architecture Flags (boot_flags) */
@@ -315,7 +316,7 @@ enum acpi_prefered_pm_profiles {
 	PM_TABLET = 8
 };
 
-/* Values for sleep_status and sleep_control registers (V5 FADT) */
+/* Values for sleep_status and sleep_control registers (V5+ FADT) */
 
 #define ACPI_X_WAKE_STATUS          0x80
 #define ACPI_X_SLEEP_TYPE_MASK      0x1C
@@ -344,15 +345,17 @@ enum acpi_prefered_pm_profiles {
  * FADT is the bottom line as to what the version really is.
  *
  * For reference, the values below are as follows:
- *     FADT V1  size: 0x074
- *     FADT V2  size: 0x084
- *     FADT V3  size: 0x0F4
- *     FADT V4  size: 0x0F4
- *     FADT V5  size: 0x10C
+ *     FADT V1 size: 0x074
+ *     FADT V2 size: 0x084
+ *     FADT V3 size: 0x0F4
+ *     FADT V4 size: 0x0F4
+ *     FADT V5 size: 0x10C
+ *     FADT V6 size: 0x114
  */
 #define ACPI_FADT_V1_SIZE       (u32) (ACPI_FADT_OFFSET (flags) + 4)
 #define ACPI_FADT_V2_SIZE       (u32) (ACPI_FADT_OFFSET (minor_revision) + 1)
 #define ACPI_FADT_V3_SIZE       (u32) (ACPI_FADT_OFFSET (sleep_control))
-#define ACPI_FADT_V5_SIZE       (u32) (sizeof (struct acpi_table_fadt))
+#define ACPI_FADT_V5_SIZE       (u32) (ACPI_FADT_OFFSET (hypervisor_id))
+#define ACPI_FADT_V6_SIZE       (u32) (sizeof (struct acpi_table_fadt))
 
 #endif				/* __ACTBL_H__ */
Signature · 1 line
2.1.0
#71 lore raw

PATCH v3 12/62 ACPICA: ACPI 6.0: Add changes for FADT table

Quoted 7 lines · shannon.zhao at linaro.org

From: Bob Moore <[email protected]>

ACPICA commit 72b0b6741990f619f6aaa915302836b7cbb41ac4

One new 64-bit field at the end of the table. FADT version is now 6.

Quoted 6 lines
Quoted 51 lines
 xen/include/acpi/actbl.h | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)
xen/include/acpi/actbl.h +10 -7
index 66e29c3..3079176 100644
@@ -258,6 +258,7 @@ struct acpi_table_fadt {
 	struct acpi_generic_address xgpe1_block;	/* 64-bit Extended General Purpose Event 1 Reg Blk address */
 	struct acpi_generic_address sleep_control;	/* 64-bit Sleep Control register */
 	struct acpi_generic_address sleep_status;	/* 64-bit Sleep Status register */
+	u64 hypervisor_id;      /* Hypervisor Vendor ID (ACPI 6.0) */
 };
 
 /* Masks for FADT IA-PC Boot Architecture Flags (boot_flags) */
@@ -315,7 +316,7 @@ enum acpi_prefered_pm_profiles {
 	PM_TABLET = 8
 };
 
-/* Values for sleep_status and sleep_control registers (V5 FADT) */
+/* Values for sleep_status and sleep_control registers (V5+ FADT) */
 
 #define ACPI_X_WAKE_STATUS          0x80
 #define ACPI_X_SLEEP_TYPE_MASK      0x1C
@@ -344,15 +345,17 @@ enum acpi_prefered_pm_profiles {
  * FADT is the bottom line as to what the version really is.
  *
  * For reference, the values below are as follows:
- *     FADT V1  size: 0x074
- *     FADT V2  size: 0x084
- *     FADT V3  size: 0x0F4
- *     FADT V4  size: 0x0F4
- *     FADT V5  size: 0x10C
+ *     FADT V1 size: 0x074
+ *     FADT V2 size: 0x084
+ *     FADT V3 size: 0x0F4
+ *     FADT V4 size: 0x0F4
+ *     FADT V5 size: 0x10C
+ *     FADT V6 size: 0x114
  */
 #define ACPI_FADT_V1_SIZE       (u32) (ACPI_FADT_OFFSET (flags) + 4)
 #define ACPI_FADT_V2_SIZE       (u32) (ACPI_FADT_OFFSET (minor_revision) + 1)
 #define ACPI_FADT_V3_SIZE       (u32) (ACPI_FADT_OFFSET (sleep_control))
-#define ACPI_FADT_V5_SIZE       (u32) (sizeof (struct acpi_table_fadt))
+#define ACPI_FADT_V5_SIZE       (u32) (ACPI_FADT_OFFSET (hypervisor_id))
+#define ACPI_FADT_V6_SIZE       (u32) (sizeof (struct acpi_table_fadt))
 
 #endif				/* __ACTBL_H__ */
Signature · 1 line
2.1.0
Acked-by on v3 12/62
#72 lore raw

Re: [PATCH v3 12/62] ACPICA: ACPI 6.0: Add changes for FADT table

In reply to shannon.zhao at linaro.org
Quoted 7 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Bob Moore <[email protected]>

ACPICA commit 72b0b6741990f619f6aaa915302836b7cbb41ac4

One new 64-bit field at the end of the table. FADT version is now 6.

Quoted 6 lines
Quoted 51 lines
 xen/include/acpi/actbl.h | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)
xen/include/acpi/actbl.h +10 -7
index 66e29c3..3079176 100644
@@ -258,6 +258,7 @@ struct acpi_table_fadt {
 	struct acpi_generic_address xgpe1_block;	/* 64-bit Extended General Purpose Event 1 Reg Blk address */
 	struct acpi_generic_address sleep_control;	/* 64-bit Sleep Control register */
 	struct acpi_generic_address sleep_status;	/* 64-bit Sleep Status register */
+	u64 hypervisor_id;      /* Hypervisor Vendor ID (ACPI 6.0) */
 };
 
 /* Masks for FADT IA-PC Boot Architecture Flags (boot_flags) */
@@ -315,7 +316,7 @@ enum acpi_prefered_pm_profiles {
 	PM_TABLET = 8
 };
 
-/* Values for sleep_status and sleep_control registers (V5 FADT) */
+/* Values for sleep_status and sleep_control registers (V5+ FADT) */
 
 #define ACPI_X_WAKE_STATUS          0x80
 #define ACPI_X_SLEEP_TYPE_MASK      0x1C
@@ -344,15 +345,17 @@ enum acpi_prefered_pm_profiles {
  * FADT is the bottom line as to what the version really is.
  *
  * For reference, the values below are as follows:
- *     FADT V1  size: 0x074
- *     FADT V2  size: 0x084
- *     FADT V3  size: 0x0F4
- *     FADT V4  size: 0x0F4
- *     FADT V5  size: 0x10C
+ *     FADT V1 size: 0x074
+ *     FADT V2 size: 0x084
+ *     FADT V3 size: 0x0F4
+ *     FADT V4 size: 0x0F4
+ *     FADT V5 size: 0x10C
+ *     FADT V6 size: 0x114
  */
 #define ACPI_FADT_V1_SIZE       (u32) (ACPI_FADT_OFFSET (flags) + 4)
 #define ACPI_FADT_V2_SIZE       (u32) (ACPI_FADT_OFFSET (minor_revision) + 1)
 #define ACPI_FADT_V3_SIZE       (u32) (ACPI_FADT_OFFSET (sleep_control))
-#define ACPI_FADT_V5_SIZE       (u32) (sizeof (struct acpi_table_fadt))
+#define ACPI_FADT_V5_SIZE       (u32) (ACPI_FADT_OFFSET (hypervisor_id))
+#define ACPI_FADT_V6_SIZE       (u32) (sizeof (struct acpi_table_fadt))
 
 #endif				/* __ACTBL_H__ */
Signature · 1 line
2.1.0
#73 lore raw

PATCH v3 12/62 ACPICA: ACPI 6.0: Add changes for FADT table

In reply to shannon.zhao at linaro.org
Quoted 14 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:

From: Bob Moore <[email protected]>

ACPICA commit 72b0b6741990f619f6aaa915302836b7cbb41ac4

One new 64-bit field at the end of the table. FADT version is now 6.

Quoted 3 lines
---
 xen/include/acpi/actbl.h | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

So while I applied this one after fixing it up, I'm not going to do any further fixups to later patches I also meant to apply. I realize the fixups may have been necessary because of me applying them in other than the submitted sequence, but then again such general imports from ACPICA/Linux should have been independent of earlier changes. I.e. either earlier patches in the series wrongly touch these headers, or there's a general problem with the series.

Jan

#74 lore raw

PATCH v3 12/62 ACPICA: ACPI 6.0: Add changes for FADT table

Quoted 18 lines · Jan Beulich
Quoted 14 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:

From: Bob Moore <[email protected]>

ACPICA commit 72b0b6741990f619f6aaa915302836b7cbb41ac4

One new 64-bit field at the end of the table. FADT version is now 6.

Quoted 3 lines
---
 xen/include/acpi/actbl.h | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)
Quoted 8 lines

So while I applied this one after fixing it up, I'm not going to do any further fixups to later patches I also meant to apply. I realize the fixups may have been necessary because of me applying them in other than the submitted sequence, but then again such general imports from ACPICA/Linux should have been independent of earlier changes. I.e. either earlier patches in the series wrongly touch these headers, or there's a general problem with the series.

I will split this patch set in several parts and the first part would be the changes and updates of ACPI SPEC 5.0~6.0. So maybe you could apply them at next version.

Thanks,

Signature · 1 line
Shannon
#75 lore raw

Re: [PATCH v3 12/62] ACPICA: ACPI 6.0: Add changes for FADT table

In reply to Jan Beulich
Quoted 18 lines · Jan Beulich
Quoted 14 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:

From: Bob Moore <[email protected]>

ACPICA commit 72b0b6741990f619f6aaa915302836b7cbb41ac4

One new 64-bit field at the end of the table. FADT version is now 6.

Quoted 3 lines
---
 xen/include/acpi/actbl.h | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)
Quoted 8 lines

So while I applied this one after fixing it up, I'm not going to do any further fixups to later patches I also meant to apply. I realize the fixups may have been necessary because of me applying them in other than the submitted sequence, but then again such general imports from ACPICA/Linux should have been independent of earlier changes. I.e. either earlier patches in the series wrongly touch these headers, or there's a general problem with the series.

I will split this patch set in several parts and the first part would be the changes and updates of ACPI SPEC 5.0~6.0. So maybe you could apply them at next version.

Thanks,

Signature · 1 line
Shannon
#76 lore raw

Re: [PATCH v3 12/62] ACPICA: ACPI 6.0: Add changes for FADT table

In reply to shannon.zhao at linaro.org
Quoted 14 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:

From: Bob Moore <[email protected]>

ACPICA commit 72b0b6741990f619f6aaa915302836b7cbb41ac4

One new 64-bit field at the end of the table. FADT version is now 6.

Quoted 3 lines
---
 xen/include/acpi/actbl.h | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

So while I applied this one after fixing it up, I'm not going to do any further fixups to later patches I also meant to apply. I realize the fixups may have been necessary because of me applying them in other than the submitted sequence, but then again such general imports from ACPICA/Linux should have been independent of earlier changes. I.e. either earlier patches in the series wrongly touch these headers, or there's a general problem with the series.

Jan

#77 lore raw

PATCH v3 13/62 arm/acpi: Parse FADT table and get PSCI flags

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set, the former signals to the OS that the hardware is PSCI compliant. The latter selects the appropriate conduit for PSCI calls by toggling between Hypervisor Calls (HVC) and Secure Monitor Calls (SMC).

FADT table contains such information, parse FADT to get the flags for furture usage. At the same time, only ACPI 5.1 or higher verison supports PSCI, and FADT Major.Minor version was introduced in ACPI 5.1, but for Xen it needs FADT hypervisor_id introduced by ACPI 6.0 to tell Dom0 that it runs on Xen hypervisor, so we will check the version and only parse FADT table with version >= 6.0.

If firmware provides ACPI tables with ACPI version less than 6.0, OS will be messed up with those information, so disable ACPI if we get an FADT table with version less that 6.0.

---
 xen/arch/arm/acpi/boot.c   | 31 +++++++++++++++++++++++++++++++
 xen/arch/arm/acpi/lib.c    | 12 ++++++++++++
 xen/include/asm-arm/acpi.h |  9 +++++++++
 3 files changed, 52 insertions(+)
xen/arch/arm/acpi/boot.c +31 -0
index ad51afc..0fabe7d 100644
@@ -27,9 +27,33 @@
 
 #include <xen/init.h>
 #include <xen/acpi.h>
+#include <xen/errno.h>
+#include <acpi/actables.h>
+#include <xen/mm.h>
 
 #include <asm/acpi.h>
 
+static int __init acpi_parse_fadt(struct acpi_table_header *table)
+{
+    struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
+
+    /*
+     * Revision in table header is the FADT Major revision, and there
+     * is a minor revision of FADT which was introduced by ACPI 6.0,
+     * we only deal with ACPI 6.0 or newer revision to get GIC and SMP
+     * boot protocol configuration data, or we will disable ACPI.
+     */
+    if ( table->revision > 6
+         || (table->revision == 6 && fadt->minor_revision >= 0) )
+        return 0;
+
+    printk("Unsupported FADT revision %d.%d, should be 6.0+, will disable ACPI\n",
+            table->revision, fadt->minor_revision);
+    disable_acpi();
+
+    return -EINVAL;
+}
+
 /*
  * acpi_boot_table_init() called from setup_arch(), always.
  *      1. find RSDP and get its address, and then find XSDT
@@ -58,5 +82,12 @@ int __init acpi_boot_table_init(void)
         return error;
     }
 
+    if ( acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt) )
+    {
+        /* disable ACPI if no FADT is found */
+        disable_acpi();
+        printk("Can't find FADT\n");
+    }
+
     return 0;
 }
xen/arch/arm/acpi/lib.c +12 -0
index b68623b..d8b7635 100644
@@ -31,3 +31,15 @@ arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 {
     return __va(phys);
 }
+
+/* 1 to indicate PSCI 0.2+ is implemented */
+bool_t __init acpi_psci_present(void)
+{
+    return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT;
+}
+
+/* 1 to indicate HVC is present instead of SMC as the PSCI conduit */
+bool_t __init acpi_psci_hvc_present(void)
+{
+    return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC;
+}
xen/include/asm-arm/acpi.h +9 -0
index e41e03b..65f80b1 100644
@@ -29,6 +29,15 @@
 #define COMPILER_DEPENDENT_UINT64  unsigned long long
 
 extern bool_t acpi_disabled;
+
+#ifdef CONFIG_ACPI
+bool_t __init acpi_psci_present(void);
+bool_t __init acpi_psci_hvc_present(void);
+#else
+static inline bool_t acpi_psci_present(void) { return false; }
+static inline bool_t acpi_psci_hvc_present(void) {return false; }
+#endif /* CONFIG_ACPI */
+
 /* Basic configuration for ACPI */
 static inline void disable_acpi(void)
 {
Signature · 1 line
2.1.0
#78 lore raw

PATCH v3 13/62 arm/acpi: Parse FADT table and get PSCI flags

Quoted 50 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set, the former signals to the OS that the hardware is PSCI compliant. The latter selects the appropriate conduit for PSCI calls by toggling between Hypervisor Calls (HVC) and Secure Monitor Calls (SMC).

FADT table contains such information, parse FADT to get the flags for furture usage. At the same time, only ACPI 5.1 or higher verison supports PSCI, and FADT Major.Minor version was introduced in ACPI 5.1, but for Xen it needs FADT hypervisor_id introduced by ACPI 6.0 to tell Dom0 that it runs on Xen hypervisor, so we will check the version and only parse FADT table with version >= 6.0.

If firmware provides ACPI tables with ACPI version less than 6.0, OS will be messed up with those information, so disable ACPI if we get an FADT table with version less that 6.0.

---
 xen/arch/arm/acpi/boot.c   | 31 +++++++++++++++++++++++++++++++
 xen/arch/arm/acpi/lib.c    | 12 ++++++++++++
 xen/include/asm-arm/acpi.h |  9 +++++++++
 3 files changed, 52 insertions(+)
xen/arch/arm/acpi/boot.c +10 -0
index ad51afc..0fabe7d 100644
@@ -27,9 +27,33 @@
 
 #include <xen/init.h>
 #include <xen/acpi.h>
+#include <xen/errno.h>
+#include <acpi/actables.h>
+#include <xen/mm.h>
 
 #include <asm/acpi.h>
 
+static int __init acpi_parse_fadt(struct acpi_table_header *table)
+{
+    struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
+
+    /*
+     * Revision in table header is the FADT Major revision, and there
+     * is a minor revision of FADT which was introduced by ACPI 6.0,

xen/arch/arm/acpi/boot.c line 52

Quoted 10 lines
xen/arch/arm/acpi/boot.c +10 -0
+     * we only deal with ACPI 6.0 or newer revision to get GIC and SMP
+     * boot protocol configuration data, or we will disable ACPI.
+     */
+    if ( table->revision > 6
+         || (table->revision == 6 && fadt->minor_revision >= 0) )
+        return 0;
+
+    printk("Unsupported FADT revision %d.%d, should be 6.0+, will disable ACPI\n",
+            table->revision, fadt->minor_revision);
+    disable_acpi();

This call to disable_acpi is redundant, given the other call below

Quoted 45 lines
xen/arch/arm/acpi/boot.c +10 -0
+    return -EINVAL;
+}
+
 /*
  * acpi_boot_table_init() called from setup_arch(), always.
  *      1. find RSDP and get its address, and then find XSDT
@@ -58,5 +82,12 @@ int __init acpi_boot_table_init(void)
         return error;
     }
 
+    if ( acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt) )
+    {
+        /* disable ACPI if no FADT is found */
+        disable_acpi();
+        printk("Can't find FADT\n");
+    }
+
     return 0;
 }
xen/arch/arm/acpi/lib.c +12 -0
index b68623b..d8b7635 100644
@@ -31,3 +31,15 @@ arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 {
     return __va(phys);
 }
+
+/* 1 to indicate PSCI 0.2+ is implemented */
+bool_t __init acpi_psci_present(void)
+{
+    return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT;
+}
+
+/* 1 to indicate HVC is present instead of SMC as the PSCI conduit */
+bool_t __init acpi_psci_hvc_present(void)
+{
+    return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC;
+}
xen/include/asm-arm/acpi.h +0 -0
index e41e03b..65f80b1 100644
@@ -29,6 +29,15 @@
 #define COMPILER_DEPENDENT_UINT64  unsigned long long

xen/include/asm-arm/acpi.h line 39

Quoted 10 lines
xen/include/asm-arm/acpi.h +8 -0
 
 extern bool_t acpi_disabled;
+
+#ifdef CONFIG_ACPI
+bool_t __init acpi_psci_present(void);
+bool_t __init acpi_psci_hvc_present(void);
+#else
+static inline bool_t acpi_psci_present(void) { return false; }
+static inline bool_t acpi_psci_hvc_present(void) {return false; }
+#endif /* CONFIG_ACPI */

It doesn't look like this is necessary on x86, acpi_gbl_FADT is used in a few places, including xen/arch/x86/time.c, without checking for CONFIG_ACPI or HAS_ACPI. Is the x86 code wrong?

Quoted 6 lines
xen/include/asm-arm/acpi.h +0 -0
 /* Basic configuration for ACPI */
 static inline void disable_acpi(void)
 {
Signature · 1 line
2.1.0
#79 lore raw

Re: [PATCH v3 13/62] arm/acpi: Parse FADT table and get PSCI flags

In reply to shannon.zhao at linaro.org
Quoted 50 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set, the former signals to the OS that the hardware is PSCI compliant. The latter selects the appropriate conduit for PSCI calls by toggling between Hypervisor Calls (HVC) and Secure Monitor Calls (SMC).

FADT table contains such information, parse FADT to get the flags for furture usage. At the same time, only ACPI 5.1 or higher verison supports PSCI, and FADT Major.Minor version was introduced in ACPI 5.1, but for Xen it needs FADT hypervisor_id introduced by ACPI 6.0 to tell Dom0 that it runs on Xen hypervisor, so we will check the version and only parse FADT table with version >= 6.0.

If firmware provides ACPI tables with ACPI version less than 6.0, OS will be messed up with those information, so disable ACPI if we get an FADT table with version less that 6.0.

---
 xen/arch/arm/acpi/boot.c   | 31 +++++++++++++++++++++++++++++++
 xen/arch/arm/acpi/lib.c    | 12 ++++++++++++
 xen/include/asm-arm/acpi.h |  9 +++++++++
 3 files changed, 52 insertions(+)
xen/arch/arm/acpi/boot.c +10 -0
index ad51afc..0fabe7d 100644
@@ -27,9 +27,33 @@
 
 #include <xen/init.h>
 #include <xen/acpi.h>
+#include <xen/errno.h>
+#include <acpi/actables.h>
+#include <xen/mm.h>
 
 #include <asm/acpi.h>
 
+static int __init acpi_parse_fadt(struct acpi_table_header *table)
+{
+    struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
+
+    /*
+     * Revision in table header is the FADT Major revision, and there
+     * is a minor revision of FADT which was introduced by ACPI 6.0,

xen/arch/arm/acpi/boot.c line 52

Quoted 10 lines
xen/arch/arm/acpi/boot.c +10 -0
+     * we only deal with ACPI 6.0 or newer revision to get GIC and SMP
+     * boot protocol configuration data, or we will disable ACPI.
+     */
+    if ( table->revision > 6
+         || (table->revision == 6 && fadt->minor_revision >= 0) )
+        return 0;
+
+    printk("Unsupported FADT revision %d.%d, should be 6.0+, will disable ACPI\n",
+            table->revision, fadt->minor_revision);
+    disable_acpi();

This call to disable_acpi is redundant, given the other call below

Quoted 45 lines
xen/arch/arm/acpi/boot.c +10 -0
+    return -EINVAL;
+}
+
 /*
  * acpi_boot_table_init() called from setup_arch(), always.
  *      1. find RSDP and get its address, and then find XSDT
@@ -58,5 +82,12 @@ int __init acpi_boot_table_init(void)
         return error;
     }
 
+    if ( acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt) )
+    {
+        /* disable ACPI if no FADT is found */
+        disable_acpi();
+        printk("Can't find FADT\n");
+    }
+
     return 0;
 }
xen/arch/arm/acpi/lib.c +12 -0
index b68623b..d8b7635 100644
@@ -31,3 +31,15 @@ arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 {
     return __va(phys);
 }
+
+/* 1 to indicate PSCI 0.2+ is implemented */
+bool_t __init acpi_psci_present(void)
+{
+    return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT;
+}
+
+/* 1 to indicate HVC is present instead of SMC as the PSCI conduit */
+bool_t __init acpi_psci_hvc_present(void)
+{
+    return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC;
+}
xen/include/asm-arm/acpi.h +0 -0
index e41e03b..65f80b1 100644
@@ -29,6 +29,15 @@
 #define COMPILER_DEPENDENT_UINT64  unsigned long long

xen/include/asm-arm/acpi.h line 39

Quoted 10 lines
xen/include/asm-arm/acpi.h +8 -0
 
 extern bool_t acpi_disabled;
+
+#ifdef CONFIG_ACPI
+bool_t __init acpi_psci_present(void);
+bool_t __init acpi_psci_hvc_present(void);
+#else
+static inline bool_t acpi_psci_present(void) { return false; }
+static inline bool_t acpi_psci_hvc_present(void) {return false; }
+#endif /* CONFIG_ACPI */

It doesn't look like this is necessary on x86, acpi_gbl_FADT is used in a few places, including xen/arch/x86/time.c, without checking for CONFIG_ACPI or HAS_ACPI. Is the x86 code wrong?

Quoted 6 lines
xen/include/asm-arm/acpi.h +0 -0
 /* Basic configuration for ACPI */
 static inline void disable_acpi(void)
 {
Signature · 1 line
2.1.0
#80 lore raw

PATCH v3 14/62 arm/acpi: Add Generic Interrupt and Distributor struct

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Add Generic Interrupt and Distributor (ACPI 5.0) structure. Add new features for MADT introduced by ACPI 5.1. Comment on the GIC ID field of the GIC structure which is replaced by CPU Interface Number.
Add new fields: Redistributor Base Address, GICV, GICH, and MPIDR. Add new structures for GIC MSI frame and GICR.
Add flag definition for GICC flags.

---
 xen/include/acpi/actbl1.h | 69 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 2 deletions(-)
xen/include/acpi/actbl1.h +67 -2
index 9311e3a..2fb2ad7 100644
@@ -639,7 +639,11 @@ enum acpi_madt_type {
 	ACPI_MADT_TYPE_INTERRUPT_SOURCE = 8,
 	ACPI_MADT_TYPE_LOCAL_X2APIC = 9,
 	ACPI_MADT_TYPE_LOCAL_X2APIC_NMI = 10,
-	ACPI_MADT_TYPE_RESERVED = 11	/* 11 and greater are reserved */
+	ACPI_MADT_TYPE_GENERIC_INTERRUPT = 11,
+	ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR = 12,
+	ACPI_MADT_TYPE_GENERIC_MSI_FRAME = 13,
+	ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
+	ACPI_MADT_TYPE_RESERVED = 15    /* 15 and greater are reserved */
 };
 
 /*
@@ -760,11 +764,72 @@ struct acpi_madt_local_x2apic_nmi {
 	u8 reserved[3];
 };
 
+/* 11: Generic Interrupt (ACPI 5.0) */
+
+struct acpi_madt_generic_interrupt {
+	struct acpi_subtable_header header;
+	u16 reserved;           /* reserved - must be zero */
+	u32 cpu_interface_number;
+	u32 uid;
+	u32 flags;
+	u32 parking_version;
+	u32 performance_interrupt;
+	u64 parked_address;
+	u64 base_address;
+	u64 gicv_base_address;
+	u64 gich_base_address;
+	u32 vgic_interrupt;
+	u64 gicr_base_address;
+	u64 arm_mpidr;
+};
+
+/* Masks for Flags field above */
+
+/* ACPI_MADT_ENABLED                    (1)      Processor is usable if set */
+#define ACPI_MADT_PERFORMANCE_IRQ_MODE  (1<<1) /* 01: Performance Interrupt Mode */
+#define ACPI_MADT_VGIC_IRQ_MODE         (1<<2) /* 02: VGIC Maintenance Interrupt mode */
+
+/* 12: Generic Distributor (ACPI 5.0) */
+
+struct acpi_madt_generic_distributor {
+	struct acpi_subtable_header header;
+	u16 reserved;           /* reserved - must be zero */
+	u32 gic_id;
+	u64 base_address;
+	u32 global_irq_base;
+	u32 reserved2;          /* reserved - must be zero */
+};
+
+/* 13: GIC MSI Frame (ACPI 5.1) */
+
+struct acpi_madt_generic_msi_frame {
+	struct acpi_subtable_header header;
+	u16 reserved;		/* reserved - must be zero */
+	u32 msi_frame_id;
+	u64 base_address;
+	u32 flags;
+	u16 spi_count;
+	u16 spi_base;
+};
+
+/* Masks for Flags field above */
+
+#define ACPI_MADT_OVERRIDE_SPI_VALUES   (1)
+
+/* 14: GIC Redistributor (ACPI 5.1) */
+
+struct acpi_madt_generic_redistributor {
+	struct acpi_subtable_header header;
+	u16 reserved;		/* reserved - must be zero */
+	u64 base_address;
+	u32 length;
+};
+
 /*
  * Common flags fields for MADT subtables
  */
 
-/* MADT Local APIC flags (lapic_flags) */
+/* MADT Local APIC flags */
 
 #define ACPI_MADT_ENABLED           (1)	/* 00: Processor is usable if set */
 
Signature · 1 line
2.1.0
#81 lore raw

PATCH v3 14/62 arm/acpi: Add Generic Interrupt and Distributor struct

Quoted 10 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Add Generic Interrupt and Distributor (ACPI 5.0) structure. Add new features for MADT introduced by ACPI 5.1. Comment on the GIC ID field of the GIC structure which is replaced by CPU Interface Number.
Add new fields: Redistributor Base Address, GICV, GICH, and MPIDR. Add new structures for GIC MSI frame and GICR.
Add flag definition for GICC flags.

Quoted 4 lines

Would it make sense to add the changes for ACPI 6.0 compatibility too?

Quoted 97 lines
 xen/include/acpi/actbl1.h | 69 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 2 deletions(-)
xen/include/acpi/actbl1.h +67 -2
index 9311e3a..2fb2ad7 100644
@@ -639,7 +639,11 @@ enum acpi_madt_type {
 	ACPI_MADT_TYPE_INTERRUPT_SOURCE = 8,
 	ACPI_MADT_TYPE_LOCAL_X2APIC = 9,
 	ACPI_MADT_TYPE_LOCAL_X2APIC_NMI = 10,
-	ACPI_MADT_TYPE_RESERVED = 11	/* 11 and greater are reserved */
+	ACPI_MADT_TYPE_GENERIC_INTERRUPT = 11,
+	ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR = 12,
+	ACPI_MADT_TYPE_GENERIC_MSI_FRAME = 13,
+	ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
+	ACPI_MADT_TYPE_RESERVED = 15    /* 15 and greater are reserved */
 };
 
 /*
@@ -760,11 +764,72 @@ struct acpi_madt_local_x2apic_nmi {
 	u8 reserved[3];
 };
 
+/* 11: Generic Interrupt (ACPI 5.0) */
+
+struct acpi_madt_generic_interrupt {
+	struct acpi_subtable_header header;
+	u16 reserved;           /* reserved - must be zero */
+	u32 cpu_interface_number;
+	u32 uid;
+	u32 flags;
+	u32 parking_version;
+	u32 performance_interrupt;
+	u64 parked_address;
+	u64 base_address;
+	u64 gicv_base_address;
+	u64 gich_base_address;
+	u32 vgic_interrupt;
+	u64 gicr_base_address;
+	u64 arm_mpidr;
+};
+
+/* Masks for Flags field above */
+
+/* ACPI_MADT_ENABLED                    (1)      Processor is usable if set */
+#define ACPI_MADT_PERFORMANCE_IRQ_MODE  (1<<1) /* 01: Performance Interrupt Mode */
+#define ACPI_MADT_VGIC_IRQ_MODE         (1<<2) /* 02: VGIC Maintenance Interrupt mode */
+
+/* 12: Generic Distributor (ACPI 5.0) */
+
+struct acpi_madt_generic_distributor {
+	struct acpi_subtable_header header;
+	u16 reserved;           /* reserved - must be zero */
+	u32 gic_id;
+	u64 base_address;
+	u32 global_irq_base;
+	u32 reserved2;          /* reserved - must be zero */
+};
+
+/* 13: GIC MSI Frame (ACPI 5.1) */
+
+struct acpi_madt_generic_msi_frame {
+	struct acpi_subtable_header header;
+	u16 reserved;		/* reserved - must be zero */
+	u32 msi_frame_id;
+	u64 base_address;
+	u32 flags;
+	u16 spi_count;
+	u16 spi_base;
+};
+
+/* Masks for Flags field above */
+
+#define ACPI_MADT_OVERRIDE_SPI_VALUES   (1)
+
+/* 14: GIC Redistributor (ACPI 5.1) */
+
+struct acpi_madt_generic_redistributor {
+	struct acpi_subtable_header header;
+	u16 reserved;		/* reserved - must be zero */
+	u64 base_address;
+	u32 length;
+};
+
 /*
  * Common flags fields for MADT subtables
  */
 
-/* MADT Local APIC flags (lapic_flags) */
+/* MADT Local APIC flags */
 
 #define ACPI_MADT_ENABLED           (1)	/* 00: Processor is usable if set */
 
Signature · 1 line
2.1.0
Acked-by on v3 14/62
#82 lore raw

Re: [PATCH v3 14/62] arm/acpi: Add Generic Interrupt and Distributor struct

In reply to shannon.zhao at linaro.org
Quoted 10 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Add Generic Interrupt and Distributor (ACPI 5.0) structure. Add new features for MADT introduced by ACPI 5.1. Comment on the GIC ID field of the GIC structure which is replaced by CPU Interface Number.
Add new fields: Redistributor Base Address, GICV, GICH, and MPIDR. Add new structures for GIC MSI frame and GICR.
Add flag definition for GICC flags.

Quoted 4 lines

Would it make sense to add the changes for ACPI 6.0 compatibility too?

Quoted 97 lines
 xen/include/acpi/actbl1.h | 69 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 2 deletions(-)
xen/include/acpi/actbl1.h +67 -2
index 9311e3a..2fb2ad7 100644
@@ -639,7 +639,11 @@ enum acpi_madt_type {
 	ACPI_MADT_TYPE_INTERRUPT_SOURCE = 8,
 	ACPI_MADT_TYPE_LOCAL_X2APIC = 9,
 	ACPI_MADT_TYPE_LOCAL_X2APIC_NMI = 10,
-	ACPI_MADT_TYPE_RESERVED = 11	/* 11 and greater are reserved */
+	ACPI_MADT_TYPE_GENERIC_INTERRUPT = 11,
+	ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR = 12,
+	ACPI_MADT_TYPE_GENERIC_MSI_FRAME = 13,
+	ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
+	ACPI_MADT_TYPE_RESERVED = 15    /* 15 and greater are reserved */
 };
 
 /*
@@ -760,11 +764,72 @@ struct acpi_madt_local_x2apic_nmi {
 	u8 reserved[3];
 };
 
+/* 11: Generic Interrupt (ACPI 5.0) */
+
+struct acpi_madt_generic_interrupt {
+	struct acpi_subtable_header header;
+	u16 reserved;           /* reserved - must be zero */
+	u32 cpu_interface_number;
+	u32 uid;
+	u32 flags;
+	u32 parking_version;
+	u32 performance_interrupt;
+	u64 parked_address;
+	u64 base_address;
+	u64 gicv_base_address;
+	u64 gich_base_address;
+	u32 vgic_interrupt;
+	u64 gicr_base_address;
+	u64 arm_mpidr;
+};
+
+/* Masks for Flags field above */
+
+/* ACPI_MADT_ENABLED                    (1)      Processor is usable if set */
+#define ACPI_MADT_PERFORMANCE_IRQ_MODE  (1<<1) /* 01: Performance Interrupt Mode */
+#define ACPI_MADT_VGIC_IRQ_MODE         (1<<2) /* 02: VGIC Maintenance Interrupt mode */
+
+/* 12: Generic Distributor (ACPI 5.0) */
+
+struct acpi_madt_generic_distributor {
+	struct acpi_subtable_header header;
+	u16 reserved;           /* reserved - must be zero */
+	u32 gic_id;
+	u64 base_address;
+	u32 global_irq_base;
+	u32 reserved2;          /* reserved - must be zero */
+};
+
+/* 13: GIC MSI Frame (ACPI 5.1) */
+
+struct acpi_madt_generic_msi_frame {
+	struct acpi_subtable_header header;
+	u16 reserved;		/* reserved - must be zero */
+	u32 msi_frame_id;
+	u64 base_address;
+	u32 flags;
+	u16 spi_count;
+	u16 spi_base;
+};
+
+/* Masks for Flags field above */
+
+#define ACPI_MADT_OVERRIDE_SPI_VALUES   (1)
+
+/* 14: GIC Redistributor (ACPI 5.1) */
+
+struct acpi_madt_generic_redistributor {
+	struct acpi_subtable_header header;
+	u16 reserved;		/* reserved - must be zero */
+	u64 base_address;
+	u32 length;
+};
+
 /*
  * Common flags fields for MADT subtables
  */
 
-/* MADT Local APIC flags (lapic_flags) */
+/* MADT Local APIC flags */
 
 #define ACPI_MADT_ENABLED           (1)	/* 00: Processor is usable if set */
 
Signature · 1 line
2.1.0
#83 lore raw

PATCH v3 15/62 ACPICA: ACPI 6.0: Add changes for MADT table.

In reply to shannon.zhao at linaro.org

From: Bob Moore <[email protected]>

ACPICA commit 02cbb41232bccf7a91967140cab95d5f48291f21

New subtable type. Some additions to existing subtables.

---
 xen/include/acpi/actbl1.h | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)
xen/include/acpi/actbl1.h +18 -4
index 2fb2ad7..7dd6960 100644
@@ -643,7 +643,8 @@ enum acpi_madt_type {
 	ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR = 12,
 	ACPI_MADT_TYPE_GENERIC_MSI_FRAME = 13,
 	ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
-	ACPI_MADT_TYPE_RESERVED = 15    /* 15 and greater are reserved */
+	ACPI_MADT_TYPE_GENERIC_TRANSLATOR = 15,
+	ACPI_MADT_TYPE_RESERVED = 16    /* 16 and greater are reserved */
 };
 
 /*
@@ -764,7 +765,7 @@ struct acpi_madt_local_x2apic_nmi {
 	u8 reserved[3];
 };
 
-/* 11: Generic Interrupt (ACPI 5.0) */
+/* 11: Generic Interrupt (ACPI 5.0 + ACPI 6.0 changes) */
 
 struct acpi_madt_generic_interrupt {
 	struct acpi_subtable_header header;
@@ -781,6 +782,8 @@ struct acpi_madt_generic_interrupt {
 	u32 vgic_interrupt;
 	u64 gicr_base_address;
 	u64 arm_mpidr;
+	u8 efficiency_class;
+	u8 reserved2[3];
 };
 
 /* Masks for Flags field above */
@@ -789,7 +792,7 @@ struct acpi_madt_generic_interrupt {
 #define ACPI_MADT_PERFORMANCE_IRQ_MODE  (1<<1) /* 01: Performance Interrupt Mode */
 #define ACPI_MADT_VGIC_IRQ_MODE         (1<<2) /* 02: VGIC Maintenance Interrupt mode */
 
-/* 12: Generic Distributor (ACPI 5.0) */
+/* 12: Generic Distributor (ACPI 5.0 + ACPI 6.0 changes) */
 
 struct acpi_madt_generic_distributor {
 	struct acpi_subtable_header header;
@@ -797,7 +800,8 @@ struct acpi_madt_generic_distributor {
 	u32 gic_id;
 	u64 base_address;
 	u32 global_irq_base;
-	u32 reserved2;          /* reserved - must be zero */
+	u8 version;
+	u8 reserved2[3];          /* reserved - must be zero */
 };
 
 /* 13: GIC MSI Frame (ACPI 5.1) */
@@ -825,6 +829,16 @@ struct acpi_madt_generic_redistributor {
 	u32 length;
 };
 
+/* 15: Generic Translator (ACPI 6.0) */
+
+struct acpi_madt_generic_translator {
+	struct acpi_subtable_header header;
+	u16 reserved;           /* reserved - must be zero */
+	u32 translation_id;
+	u64 base_address;
+	u32 reserved2;
+};
+
 /*
  * Common flags fields for MADT subtables
  */
Signature · 1 line
2.1.0
#84 lore raw

PATCH v3 15/62 ACPICA: ACPI 6.0: Add changes for MADT table.

Quoted 4 lines · shannon.zhao at linaro.org

From: Bob Moore <[email protected]>

ACPICA commit 02cbb41232bccf7a91967140cab95d5f48291f21

Quoted 8 lines

New subtable type. Some additions to existing subtables.

These are the ACPI 6.0 changes. I am OK both with them being folded in the previous patch or kept separate.

Quoted 74 lines
 xen/include/acpi/actbl1.h | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)
xen/include/acpi/actbl1.h +18 -4
index 2fb2ad7..7dd6960 100644
@@ -643,7 +643,8 @@ enum acpi_madt_type {
 	ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR = 12,
 	ACPI_MADT_TYPE_GENERIC_MSI_FRAME = 13,
 	ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
-	ACPI_MADT_TYPE_RESERVED = 15    /* 15 and greater are reserved */
+	ACPI_MADT_TYPE_GENERIC_TRANSLATOR = 15,
+	ACPI_MADT_TYPE_RESERVED = 16    /* 16 and greater are reserved */
 };
 
 /*
@@ -764,7 +765,7 @@ struct acpi_madt_local_x2apic_nmi {
 	u8 reserved[3];
 };
 
-/* 11: Generic Interrupt (ACPI 5.0) */
+/* 11: Generic Interrupt (ACPI 5.0 + ACPI 6.0 changes) */
 
 struct acpi_madt_generic_interrupt {
 	struct acpi_subtable_header header;
@@ -781,6 +782,8 @@ struct acpi_madt_generic_interrupt {
 	u32 vgic_interrupt;
 	u64 gicr_base_address;
 	u64 arm_mpidr;
+	u8 efficiency_class;
+	u8 reserved2[3];
 };
 
 /* Masks for Flags field above */
@@ -789,7 +792,7 @@ struct acpi_madt_generic_interrupt {
 #define ACPI_MADT_PERFORMANCE_IRQ_MODE  (1<<1) /* 01: Performance Interrupt Mode */
 #define ACPI_MADT_VGIC_IRQ_MODE         (1<<2) /* 02: VGIC Maintenance Interrupt mode */
 
-/* 12: Generic Distributor (ACPI 5.0) */
+/* 12: Generic Distributor (ACPI 5.0 + ACPI 6.0 changes) */
 
 struct acpi_madt_generic_distributor {
 	struct acpi_subtable_header header;
@@ -797,7 +800,8 @@ struct acpi_madt_generic_distributor {
 	u32 gic_id;
 	u64 base_address;
 	u32 global_irq_base;
-	u32 reserved2;          /* reserved - must be zero */
+	u8 version;
+	u8 reserved2[3];          /* reserved - must be zero */
 };
 
 /* 13: GIC MSI Frame (ACPI 5.1) */
@@ -825,6 +829,16 @@ struct acpi_madt_generic_redistributor {
 	u32 length;
 };
 
+/* 15: Generic Translator (ACPI 6.0) */
+
+struct acpi_madt_generic_translator {
+	struct acpi_subtable_header header;
+	u16 reserved;           /* reserved - must be zero */
+	u32 translation_id;
+	u64 base_address;
+	u32 reserved2;
+};
+
 /*
  * Common flags fields for MADT subtables
  */
Signature · 1 line
2.1.0
Acked-by on v3 15/62
#85 lore raw

Re: [PATCH v3 15/62] ACPICA: ACPI 6.0: Add changes for MADT table.

In reply to shannon.zhao at linaro.org
Quoted 4 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Bob Moore <[email protected]>

ACPICA commit 02cbb41232bccf7a91967140cab95d5f48291f21

Quoted 8 lines

New subtable type. Some additions to existing subtables.

These are the ACPI 6.0 changes. I am OK both with them being folded in the previous patch or kept separate.

Quoted 74 lines
 xen/include/acpi/actbl1.h | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)
xen/include/acpi/actbl1.h +18 -4
index 2fb2ad7..7dd6960 100644
@@ -643,7 +643,8 @@ enum acpi_madt_type {
 	ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR = 12,
 	ACPI_MADT_TYPE_GENERIC_MSI_FRAME = 13,
 	ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
-	ACPI_MADT_TYPE_RESERVED = 15    /* 15 and greater are reserved */
+	ACPI_MADT_TYPE_GENERIC_TRANSLATOR = 15,
+	ACPI_MADT_TYPE_RESERVED = 16    /* 16 and greater are reserved */
 };
 
 /*
@@ -764,7 +765,7 @@ struct acpi_madt_local_x2apic_nmi {
 	u8 reserved[3];
 };
 
-/* 11: Generic Interrupt (ACPI 5.0) */
+/* 11: Generic Interrupt (ACPI 5.0 + ACPI 6.0 changes) */
 
 struct acpi_madt_generic_interrupt {
 	struct acpi_subtable_header header;
@@ -781,6 +782,8 @@ struct acpi_madt_generic_interrupt {
 	u32 vgic_interrupt;
 	u64 gicr_base_address;
 	u64 arm_mpidr;
+	u8 efficiency_class;
+	u8 reserved2[3];
 };
 
 /* Masks for Flags field above */
@@ -789,7 +792,7 @@ struct acpi_madt_generic_interrupt {
 #define ACPI_MADT_PERFORMANCE_IRQ_MODE  (1<<1) /* 01: Performance Interrupt Mode */
 #define ACPI_MADT_VGIC_IRQ_MODE         (1<<2) /* 02: VGIC Maintenance Interrupt mode */
 
-/* 12: Generic Distributor (ACPI 5.0) */
+/* 12: Generic Distributor (ACPI 5.0 + ACPI 6.0 changes) */
 
 struct acpi_madt_generic_distributor {
 	struct acpi_subtable_header header;
@@ -797,7 +800,8 @@ struct acpi_madt_generic_distributor {
 	u32 gic_id;
 	u64 base_address;
 	u32 global_irq_base;
-	u32 reserved2;          /* reserved - must be zero */
+	u8 version;
+	u8 reserved2[3];          /* reserved - must be zero */
 };
 
 /* 13: GIC MSI Frame (ACPI 5.1) */
@@ -825,6 +829,16 @@ struct acpi_madt_generic_redistributor {
 	u32 length;
 };
 
+/* 15: Generic Translator (ACPI 6.0) */
+
+struct acpi_madt_generic_translator {
+	struct acpi_subtable_header header;
+	u16 reserved;           /* reserved - must be zero */
+	u32 translation_id;
+	u64 base_address;
+	u32 reserved2;
+};
+
 /*
  * Common flags fields for MADT subtables
  */
Signature · 1 line
2.1.0
#86 lore raw

PATCH v3 16/62 ACPICA: ACPI 6.0: Add values for MADT GIC version field

In reply to shannon.zhao at linaro.org

From: Hanjun Guo <[email protected]>

ACPICA commit 4b100dc43e8baee8c8b4891b23bc7ad03eba6a28

Support for the new version field in the generic distributor subtable. Hanjun Guo <[email protected]>

---
 xen/include/acpi/actbl1.h | 11 +++++++++++
 1 file changed, 11 insertions(+)
xen/include/acpi/actbl1.h +11 -0
index 7dd6960..cf31837 100644
@@ -804,6 +804,17 @@ struct acpi_madt_generic_distributor {
 	u8 reserved2[3];          /* reserved - must be zero */
 };
 
+/* Values for Version field above */
+
+enum acpi_madt_gic_version {
+	ACPI_MADT_GIC_VERSION_NONE = 0,
+	ACPI_MADT_GIC_VERSION_V1 = 1,
+	ACPI_MADT_GIC_VERSION_V2 = 2,
+	ACPI_MADT_GIC_VERSION_V3 = 3,
+	ACPI_MADT_GIC_VERSION_V4 = 4,
+	ACPI_MADT_GIC_VERSION_RESERVED = 5      /* 5 and greater are reserved */
+};
+
 /* 13: GIC MSI Frame (ACPI 5.1) */
 
 struct acpi_madt_generic_msi_frame {
Signature · 1 line
2.1.0
#87 lore raw

PATCH v3 16/62 ACPICA: ACPI 6.0: Add values for MADT GIC version field

Quoted 7 lines · shannon.zhao at linaro.org

From: Hanjun Guo <[email protected]>

ACPICA commit 4b100dc43e8baee8c8b4891b23bc7ad03eba6a28

Support for the new version field in the generic distributor subtable. Hanjun Guo <[email protected]>

Quoted 7 lines
Quoted 28 lines
 xen/include/acpi/actbl1.h | 11 +++++++++++
 1 file changed, 11 insertions(+)
xen/include/acpi/actbl1.h +11 -0
index 7dd6960..cf31837 100644
@@ -804,6 +804,17 @@ struct acpi_madt_generic_distributor {
 	u8 reserved2[3];          /* reserved - must be zero */
 };
 
+/* Values for Version field above */
+
+enum acpi_madt_gic_version {
+	ACPI_MADT_GIC_VERSION_NONE = 0,
+	ACPI_MADT_GIC_VERSION_V1 = 1,
+	ACPI_MADT_GIC_VERSION_V2 = 2,
+	ACPI_MADT_GIC_VERSION_V3 = 3,
+	ACPI_MADT_GIC_VERSION_V4 = 4,
+	ACPI_MADT_GIC_VERSION_RESERVED = 5      /* 5 and greater are reserved */
+};
+
 /* 13: GIC MSI Frame (ACPI 5.1) */
 
 struct acpi_madt_generic_msi_frame {
Signature · 1 line
2.1.0
Acked-by on v3 16/62
#88 lore raw

Re: [PATCH v3 16/62] ACPICA: ACPI 6.0: Add values for MADT GIC version field

In reply to shannon.zhao at linaro.org
Quoted 7 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Hanjun Guo <[email protected]>

ACPICA commit 4b100dc43e8baee8c8b4891b23bc7ad03eba6a28

Support for the new version field in the generic distributor subtable. Hanjun Guo <[email protected]>

Quoted 7 lines
Quoted 28 lines
 xen/include/acpi/actbl1.h | 11 +++++++++++
 1 file changed, 11 insertions(+)
xen/include/acpi/actbl1.h +11 -0
index 7dd6960..cf31837 100644
@@ -804,6 +804,17 @@ struct acpi_madt_generic_distributor {
 	u8 reserved2[3];          /* reserved - must be zero */
 };
 
+/* Values for Version field above */
+
+enum acpi_madt_gic_version {
+	ACPI_MADT_GIC_VERSION_NONE = 0,
+	ACPI_MADT_GIC_VERSION_V1 = 1,
+	ACPI_MADT_GIC_VERSION_V2 = 2,
+	ACPI_MADT_GIC_VERSION_V3 = 3,
+	ACPI_MADT_GIC_VERSION_V4 = 4,
+	ACPI_MADT_GIC_VERSION_RESERVED = 5      /* 5 and greater are reserved */
+};
+
 /* 13: GIC MSI Frame (ACPI 5.1) */
 
 struct acpi_madt_generic_msi_frame {
Signature · 1 line
2.1.0
#89 lore raw

PATCH v3 17/62 arm/acpi: Print GIC information when MADT is parsed

In reply to shannon.zhao at linaro.org

From: Naresh Bhat <[email protected]>

When MADT is parsed, print GIC information to make the boot log look pretty.

---
 xen/drivers/acpi/tables.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
xen/drivers/acpi/tables.c +24 -0
index 60c4ab1..6573175 100644
@@ -189,6 +189,30 @@ void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 		}
 		break;
 
+	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+		{
+			struct acpi_madt_generic_interrupt *p =
+				(struct acpi_madt_generic_interrupt *)header;
+			printk(KERN_INFO PREFIX
+			       "GICC (acpi_id[0x%04x] address[%llx] MPIDR[0x%llx] %s)\n",
+			       p->uid, (long long unsigned int)p->base_address,
+			       (long long unsigned int)p->arm_mpidr,
+			       (p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
+
+		}
+		break;
+
+	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+		{
+			struct acpi_madt_generic_distributor *p =
+				(struct acpi_madt_generic_distributor *)header;
+			printk(KERN_INFO PREFIX
+			       "GIC Distributor (gic_id[0x%04x] address[%llx] gsi_base[%d])\n",
+			       p->gic_id, (long long unsigned int)p->base_address,
+			       p->global_irq_base);
+		}
+		break;
+
 	default:
 		printk(KERN_WARNING PREFIX
 		       "Found unsupported MADT entry (type = %#x)\n",
Signature · 1 line
2.1.0
#90 lore raw

PATCH v3 17/62 arm/acpi: Print GIC information when MADT is parsed

Quoted 20 lines · shannon.zhao at linaro.org

From: Naresh Bhat <[email protected]>

When MADT is parsed, print GIC information to make the boot log look pretty.

---
 xen/drivers/acpi/tables.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
xen/drivers/acpi/tables.c +0 -0
index 60c4ab1..6573175 100644
@@ -189,6 +189,30 @@ void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 		}
 		break;

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 200

Quoted 10 lines
xen/drivers/acpi/tables.c +9 -0
 
+	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+		{
+			struct acpi_madt_generic_interrupt *p =
+				(struct acpi_madt_generic_interrupt *)header;
+			printk(KERN_INFO PREFIX
+			       "GICC (acpi_id[0x%04x] address[%llx] MPIDR[0x%llx] %s)\n",
+			       p->uid, (long long unsigned int)p->base_address,
+			       (long long unsigned int)p->arm_mpidr,
+			       (p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");

PRIx64?

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 212

Quoted 11 lines
xen/drivers/acpi/tables.c +11 -0
+		}
+		break;
+
+	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+		{
+			struct acpi_madt_generic_distributor *p =
+				(struct acpi_madt_generic_distributor *)header;
+			printk(KERN_INFO PREFIX
+			       "GIC Distributor (gic_id[0x%04x] address[%llx] gsi_base[%d])\n",
+			       p->gic_id, (long long unsigned int)p->base_address,
+			       p->global_irq_base);

ditto

Quoted 9 lines
xen/drivers/acpi/tables.c +3 -0
+		}
+		break;
+
 	default:
 		printk(KERN_WARNING PREFIX
 		       "Found unsupported MADT entry (type = %#x)\n",
Signature · 1 line
2.1.0
#91 lore raw

Re: [PATCH v3 17/62] arm/acpi: Print GIC information when MADT is parsed

In reply to shannon.zhao at linaro.org
Quoted 20 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Naresh Bhat <[email protected]>

When MADT is parsed, print GIC information to make the boot log look pretty.

---
 xen/drivers/acpi/tables.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
xen/drivers/acpi/tables.c +0 -0
index 60c4ab1..6573175 100644
@@ -189,6 +189,30 @@ void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 		}
 		break;

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 200

Quoted 10 lines
xen/drivers/acpi/tables.c +9 -0
 
+	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+		{
+			struct acpi_madt_generic_interrupt *p =
+				(struct acpi_madt_generic_interrupt *)header;
+			printk(KERN_INFO PREFIX
+			       "GICC (acpi_id[0x%04x] address[%llx] MPIDR[0x%llx] %s)\n",
+			       p->uid, (long long unsigned int)p->base_address,
+			       (long long unsigned int)p->arm_mpidr,
+			       (p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");

PRIx64?

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 212

Quoted 11 lines
xen/drivers/acpi/tables.c +11 -0
+		}
+		break;
+
+	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+		{
+			struct acpi_madt_generic_distributor *p =
+				(struct acpi_madt_generic_distributor *)header;
+			printk(KERN_INFO PREFIX
+			       "GIC Distributor (gic_id[0x%04x] address[%llx] gsi_base[%d])\n",
+			       p->gic_id, (long long unsigned int)p->base_address,
+			       p->global_irq_base);

ditto

Quoted 9 lines
xen/drivers/acpi/tables.c +3 -0
+		}
+		break;
+
 	default:
 		printk(KERN_WARNING PREFIX
 		       "Found unsupported MADT entry (type = %#x)\n",
Signature · 1 line
2.1.0
#92 lore raw

PATCH v3 18/62 arm/acpi: Parse MADT to map logical cpu to MPIDR and get cpu_possible_map

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

MADT contains the information for MPIDR which is essential for SMP initialization, parse the GIC cpu interface structures to get the MPIDR value and map it to cpu_logical_map(), and add enabled cpu with valid MPIDR into cpu_possible_map.

---
 xen/arch/arm/acpi/boot.c   | 121 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/acpi.h |   2 +
 xen/include/xen/acpi.h     |   4 ++
 3 files changed, 127 insertions(+)
xen/arch/arm/acpi/boot.c +121 -0
index 0fabe7d..913d2a5 100644
@@ -32,6 +32,127 @@
 #include <xen/mm.h>
 
 #include <asm/acpi.h>
+#include <asm/smp.h>
+
+/* Processors with enabled flag and sane MPIDR */
+static int enabled_cpus;
+
+/* Boot CPU is valid or not in MADT */
+static bool_t __initdata bootcpu_valid;
+
+/* total number of cpus in this system */
+static unsigned int __initdata total_cpus = 0;
+
+/*
+ * acpi_map_gic_cpu_interface - generates a logical cpu number
+ * and map to MPIDR represented by GICC structure
+ */
+static void __init
+acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
+{
+    int i;
+    u64 mpidr = processor->arm_mpidr & MPIDR_HWID_MASK;
+    bool enabled = !!(processor->flags & ACPI_MADT_ENABLED);
+
+    if (mpidr == MPIDR_INVALID) {
+        printk("Skip MADT cpu entry with invalid MPIDR\n");
+        return;
+    }
+
+    total_cpus++;
+    if (!enabled)
+        return;
+
+    if (enabled_cpus >=  NR_CPUS) {
+        printk("NR_CPUS limit of %d reached, Processor %d/0x%"PRIx64" ignored.\n",
+               NR_CPUS, total_cpus, mpidr);
+        return;
+    }
+
+    /* Check if GICC structure of boot CPU is available in the MADT */
+    if (cpu_logical_map(0) == mpidr) {
+        if (bootcpu_valid) {
+            printk("Firmware bug, duplicate CPU MPIDR: 0x%"PRIx64" in MADT\n",
+                   mpidr);
+            return;
+        }
+
+        bootcpu_valid = true;
+    }
+
+    /*
+     * Duplicate MPIDRs are a recipe for disaster. Scan
+     * all initialized entries and check for
+     * duplicates. If any is found just ignore the CPU.
+     */
+    for (i = 1; i < enabled_cpus; i++) {
+        if (cpu_logical_map(i) == mpidr) {
+            printk("Firmware bug, duplicate CPU MPIDR: 0x%"PRIx64" in MADT\n",
+                   mpidr);
+            return;
+        }
+    }
+
+    if (!acpi_psci_present())
+        return;
+
+    /* CPU 0 was already initialized */
+    if (enabled_cpus) {
+        if (arch_cpu_init(enabled_cpus, NULL) < 0)
+            return;
+
+        /* map the logical cpu id to cpu MPIDR */
+        cpu_logical_map(enabled_cpus) = mpidr;
+    }
+
+    enabled_cpus++;
+}
+
+static int __init
+acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header,
+                             const unsigned long end)
+{
+    struct acpi_madt_generic_interrupt *processor;
+
+    processor = (struct acpi_madt_generic_interrupt *)header;
+
+    if (BAD_MADT_ENTRY(processor, end))
+        return -EINVAL;
+
+    acpi_table_print_madt_entry(header);
+    acpi_map_gic_cpu_interface(processor);
+    return 0;
+}
+
+/* Parse GIC cpu interface entries in MADT for SMP init */
+void __init acpi_smp_init_cpus(void)
+{
+    int count, i;
+
+    /*
+     * do a partial walk of MADT to determine how many CPUs
+     * we have including disabled CPUs, and get information
+     * we need for SMP init
+     */
+    count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+                    acpi_parse_gic_cpu_interface, 0);
+
+    if (count <= 0) {
+        printk("Error parsing GIC CPU interface entry\n");
+        return;
+    }
+
+    if (!bootcpu_valid) {
+        printk("MADT missing boot CPU MPIDR, not enabling secondaries\n");
+        return;
+    }
+
+    for (i = 0; i < enabled_cpus; i++)
+        cpumask_set_cpu(i, &cpu_possible_map);
+
+    /* Make boot-up look pretty */
+    printk("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus);
+}
 
 static int __init acpi_parse_fadt(struct acpi_table_header *table)
 {
xen/include/asm-arm/acpi.h +2 -0
index 65f80b1..1efa29d 100644
@@ -33,9 +33,11 @@ extern bool_t acpi_disabled;
 #ifdef CONFIG_ACPI
 bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
+void __init acpi_smp_init_cpus(void);
 #else
 static inline bool_t acpi_psci_present(void) { return false; }
 static inline bool_t acpi_psci_hvc_present(void) {return false; }
+static inline void acpi_smp_init_cpus(void) { }
 #endif /* CONFIG_ACPI */
 
 /* Basic configuration for ACPI */
xen/include/xen/acpi.h +4 -0
index 48d7810..723ece8 100644
@@ -39,6 +39,10 @@
 #define ACPI_MADT_GET_POLARITY(inti)	ACPI_MADT_GET_(POLARITY, inti)
 #define ACPI_MADT_GET_TRIGGER(inti)	ACPI_MADT_GET_(TRIGGER, inti)
 
+#define BAD_MADT_ENTRY(entry, end) (                                        \
+                (!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
+                ((struct acpi_subtable_header *)entry)->length < sizeof(*entry))
+
 #ifdef CONFIG_ACPI_BOOT
 
 enum acpi_interrupt_id {
Signature · 1 line
2.1.0
#93 lore raw

PATCH v3 18/62 arm/acpi: Parse MADT to map logical cpu to MPIDR and get cpu_possible_map

Quoted 23 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

MADT contains the information for MPIDR which is essential for SMP initialization, parse the GIC cpu interface structures to get the MPIDR value and map it to cpu_logical_map(), and add enabled cpu with valid MPIDR into cpu_possible_map.

---
 xen/arch/arm/acpi/boot.c   | 121 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/acpi.h |   2 +
 xen/include/xen/acpi.h     |   4 ++
 3 files changed, 127 insertions(+)
xen/arch/arm/acpi/boot.c +0 -0
index 0fabe7d..913d2a5 100644

xen/arch/arm/acpi/boot.c line 38

Quoted 7 lines
xen/arch/arm/acpi/boot.c +4 -0
@@ -32,6 +32,127 @@
 #include <xen/mm.h>
 
 #include <asm/acpi.h>
+#include <asm/smp.h>
+
+/* Processors with enabled flag and sane MPIDR */
+static int enabled_cpus;

unsigned int

xen/arch/arm/acpi/boot.c line 44

Quoted 5 lines
xen/arch/arm/acpi/boot.c +5 -0
+/* Boot CPU is valid or not in MADT */
+static bool_t __initdata bootcpu_valid;
+
+/* total number of cpus in this system */
+static unsigned int __initdata total_cpus = 0;

no need to explicitly initialize to 0

xen/arch/arm/acpi/boot.c line 55

Quoted 10 lines
xen/arch/arm/acpi/boot.c +10 -0
+/*
+ * acpi_map_gic_cpu_interface - generates a logical cpu number
+ * and map to MPIDR represented by GICC structure
+ */
+static void __init
+acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
+{
+    int i;
+    u64 mpidr = processor->arm_mpidr & MPIDR_HWID_MASK;
+    bool enabled = !!(processor->flags & ACPI_MADT_ENABLED);

bool_t

xen/arch/arm/acpi/boot.c line 60

Quoted 4 lines
xen/arch/arm/acpi/boot.c +4 -0
+    if (mpidr == MPIDR_INVALID) {
+        printk("Skip MADT cpu entry with invalid MPIDR\n");
+        return;
+    }

I am not sure which coding style we are supposed to follow in this file. This is the Linux coding style, not the Xen coding style.

xen/arch/arm/acpi/boot.c line 66

Quoted 5 lines
xen/arch/arm/acpi/boot.c +5 -0
+    total_cpus++;
+    if (!enabled)
+        return;
+
+    if (enabled_cpus >=  NR_CPUS) {

unnecessary space

Quoted 18 lines
xen/arch/arm/acpi/boot.c +18 -0
+        printk("NR_CPUS limit of %d reached, Processor %d/0x%"PRIx64" ignored.\n",
+               NR_CPUS, total_cpus, mpidr);
+        return;
+    }
+
+    /* Check if GICC structure of boot CPU is available in the MADT */
+    if (cpu_logical_map(0) == mpidr) {
+        if (bootcpu_valid) {
+            printk("Firmware bug, duplicate CPU MPIDR: 0x%"PRIx64" in MADT\n",
+                   mpidr);
+            return;
+        }
+
+        bootcpu_valid = true;
+    }
+
+    /*
+     * Duplicate MPIDRs are a recipe for disaster. Scan

xen/arch/arm/acpi/boot.c line 94

Quoted 10 lines
xen/arch/arm/acpi/boot.c +10 -0
+     * all initialized entries and check for
+     * duplicates. If any is found just ignore the CPU.
+     */
+    for (i = 1; i < enabled_cpus; i++) {
+        if (cpu_logical_map(i) == mpidr) {
+            printk("Firmware bug, duplicate CPU MPIDR: 0x%"PRIx64" in MADT\n",
+                   mpidr);
+            return;
+        }
+    }

I would merge this loop with the previous if statement and just add one cpu_logical_map(0) check to set bootcpu_valid.

Quoted 12 lines
xen/arch/arm/acpi/boot.c +12 -0
+    if (!acpi_psci_present())
+        return;
+
+    /* CPU 0 was already initialized */
+    if (enabled_cpus) {
+        if (arch_cpu_init(enabled_cpus, NULL) < 0)
+            return;
+
+        /* map the logical cpu id to cpu MPIDR */
+        cpu_logical_map(enabled_cpus) = mpidr;
+    }
+

xen/arch/arm/acpi/boot.c line 117

Quoted 10 lines
xen/arch/arm/acpi/boot.c +10 -0
+    enabled_cpus++;
+}
+
+static int __init
+acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header,
+                             const unsigned long end)
+{
+    struct acpi_madt_generic_interrupt *processor;
+
+    processor = (struct acpi_madt_generic_interrupt *)header;

struct acpi_madt_generic_interrupt *processor =

		container_of(header, struct acpi_madt_generic_interrupt, header);
Quoted 74 lines
xen/arch/arm/acpi/boot.c +37 -0
+    if (BAD_MADT_ENTRY(processor, end))
+        return -EINVAL;
+
+    acpi_table_print_madt_entry(header);
+    acpi_map_gic_cpu_interface(processor);
+    return 0;
+}
+
+/* Parse GIC cpu interface entries in MADT for SMP init */
+void __init acpi_smp_init_cpus(void)
+{
+    int count, i;
+
+    /*
+     * do a partial walk of MADT to determine how many CPUs
+     * we have including disabled CPUs, and get information
+     * we need for SMP init
+     */
+    count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+                    acpi_parse_gic_cpu_interface, 0);
+
+    if (count <= 0) {
+        printk("Error parsing GIC CPU interface entry\n");
+        return;
+    }
+
+    if (!bootcpu_valid) {
+        printk("MADT missing boot CPU MPIDR, not enabling secondaries\n");
+        return;
+    }
+
+    for (i = 0; i < enabled_cpus; i++)
+        cpumask_set_cpu(i, &cpu_possible_map);
+
+    /* Make boot-up look pretty */
+    printk("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus);
+}
 
 static int __init acpi_parse_fadt(struct acpi_table_header *table)
 {
xen/include/asm-arm/acpi.h +2 -0
index 65f80b1..1efa29d 100644
@@ -33,9 +33,11 @@ extern bool_t acpi_disabled;
 #ifdef CONFIG_ACPI
 bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
+void __init acpi_smp_init_cpus(void);
 #else
 static inline bool_t acpi_psci_present(void) { return false; }
 static inline bool_t acpi_psci_hvc_present(void) {return false; }
+static inline void acpi_smp_init_cpus(void) { }
 #endif /* CONFIG_ACPI */
 
 /* Basic configuration for ACPI */
xen/include/xen/acpi.h +4 -0
index 48d7810..723ece8 100644
@@ -39,6 +39,10 @@
 #define ACPI_MADT_GET_POLARITY(inti)	ACPI_MADT_GET_(POLARITY, inti)
 #define ACPI_MADT_GET_TRIGGER(inti)	ACPI_MADT_GET_(TRIGGER, inti)
 
+#define BAD_MADT_ENTRY(entry, end) (                                        \
+                (!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
+                ((struct acpi_subtable_header *)entry)->length < sizeof(*entry))
+
 #ifdef CONFIG_ACPI_BOOT
 
 enum acpi_interrupt_id {
Signature · 1 line
2.1.0
#94 lore raw

PATCH v3 19/62 arm/smpboot: Move dt specific code in smp to seperate functions

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Partition smp initialization functions into generic and dt specific parts, this will be useful when introducing new functions for smp initialization based on acpi.

---
 xen/arch/arm/arm64/smpboot.c |  7 ++++++-
 xen/arch/arm/smpboot.c       | 29 ++++++++++++++++++-----------
 2 files changed, 24 insertions(+), 12 deletions(-)
xen/arch/arm/arm64/smpboot.c +6 -1
index 62e6abb..7928f69 100644
@@ -70,7 +70,7 @@ int __init arch_smp_init(void)
     return 0;
 }
 
-int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
+static int __init dt_arch_cpu_init(int cpu, struct dt_device_node *dn)
 {
     const char *enable_method;
 
@@ -94,6 +94,11 @@ int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
     return 0;
 }
 
+int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
+{
+    return dt_arch_cpu_init(cpu, dn);
+}
+
 int __init arch_cpu_up(int cpu)
 {
     if ( !smp_enable_ops[cpu].prepare_cpu )
xen/arch/arm/smpboot.c +18 -11
index a96cda2..d115228 100644
@@ -92,7 +92,7 @@ smp_clear_cpu_maps (void)
  * MPIDR values related to logical cpus
  * Code base on Linux arch/arm/kernel/devtree.c
  */
-void __init smp_init_cpus(void)
+static void __init dt_smp_init_cpus(void)
 {
     register_t mpidr;
     struct dt_device_node *cpus = dt_find_node_by_path("/cpus");
@@ -106,16 +106,6 @@ void __init smp_init_cpus(void)
     bool_t bootcpu_valid = 0;
     int rc;
 
-    /* scan the DTB for a PSCI node and set a global variable */
-    psci_init();
-
-    if ( (rc = arch_smp_init()) < 0 )
-    {
-        printk(XENLOG_WARNING "SMP init failed (%d)\n"
-               "Using only 1 CPU\n", rc);
-        return;
-    }
-
     mpidr = boot_cpu_data.mpidr.bits & MPIDR_HWID_MASK;
 
     if ( !cpus )
@@ -243,6 +233,23 @@ void __init smp_init_cpus(void)
     }
 }
 
+void __init smp_init_cpus(void)
+{
+    int rc;
+
+    /* initialize PSCI and set a global variable */
+    psci_init();
+
+    if ( (rc = arch_smp_init()) < 0 )
+    {
+        printk(XENLOG_WARNING "SMP init failed (%d)\n"
+               "Using only 1 CPU\n", rc);
+        return;
+    }
+
+    dt_smp_init_cpus();
+}
+
 int __init
 smp_get_max_cpus (void)
 {
Signature · 1 line
2.1.0
#95 lore raw

PATCH v3 19/62 arm/smpboot: Move dt specific code in smp to seperate functions

Quoted 8 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Partition smp initialization functions into generic and dt specific parts, this will be useful when introducing new functions for smp initialization based on acpi.

Quoted 86 lines
 xen/arch/arm/arm64/smpboot.c |  7 ++++++-
 xen/arch/arm/smpboot.c       | 29 ++++++++++++++++++-----------
 2 files changed, 24 insertions(+), 12 deletions(-)
xen/arch/arm/arm64/smpboot.c +6 -1
index 62e6abb..7928f69 100644
@@ -70,7 +70,7 @@ int __init arch_smp_init(void)
     return 0;
 }
 
-int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
+static int __init dt_arch_cpu_init(int cpu, struct dt_device_node *dn)
 {
     const char *enable_method;
 
@@ -94,6 +94,11 @@ int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
     return 0;
 }
 
+int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
+{
+    return dt_arch_cpu_init(cpu, dn);
+}
+
 int __init arch_cpu_up(int cpu)
 {
     if ( !smp_enable_ops[cpu].prepare_cpu )
xen/arch/arm/smpboot.c +18 -11
index a96cda2..d115228 100644
@@ -92,7 +92,7 @@ smp_clear_cpu_maps (void)
  * MPIDR values related to logical cpus
  * Code base on Linux arch/arm/kernel/devtree.c
  */
-void __init smp_init_cpus(void)
+static void __init dt_smp_init_cpus(void)
 {
     register_t mpidr;
     struct dt_device_node *cpus = dt_find_node_by_path("/cpus");
@@ -106,16 +106,6 @@ void __init smp_init_cpus(void)
     bool_t bootcpu_valid = 0;
     int rc;
 
-    /* scan the DTB for a PSCI node and set a global variable */
-    psci_init();
-
-    if ( (rc = arch_smp_init()) < 0 )
-    {
-        printk(XENLOG_WARNING "SMP init failed (%d)\n"
-               "Using only 1 CPU\n", rc);
-        return;
-    }
-
     mpidr = boot_cpu_data.mpidr.bits & MPIDR_HWID_MASK;
 
     if ( !cpus )
@@ -243,6 +233,23 @@ void __init smp_init_cpus(void)
     }
 }
 
+void __init smp_init_cpus(void)
+{
+    int rc;
+
+    /* initialize PSCI and set a global variable */
+    psci_init();
+
+    if ( (rc = arch_smp_init()) < 0 )
+    {
+        printk(XENLOG_WARNING "SMP init failed (%d)\n"
+               "Using only 1 CPU\n", rc);
+        return;
+    }
+
+    dt_smp_init_cpus();
+}
+
 int __init
 smp_get_max_cpus (void)
 {
Signature · 1 line
2.1.0
Acked-by on v3 19/62
#96 lore raw

Re: [PATCH v3 19/62] arm/smpboot: Move dt specific code in smp to seperate functions

In reply to shannon.zhao at linaro.org
Quoted 8 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

Partition smp initialization functions into generic and dt specific parts, this will be useful when introducing new functions for smp initialization based on acpi.

Quoted 86 lines
 xen/arch/arm/arm64/smpboot.c |  7 ++++++-
 xen/arch/arm/smpboot.c       | 29 ++++++++++++++++++-----------
 2 files changed, 24 insertions(+), 12 deletions(-)
xen/arch/arm/arm64/smpboot.c +6 -1
index 62e6abb..7928f69 100644
@@ -70,7 +70,7 @@ int __init arch_smp_init(void)
     return 0;
 }
 
-int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
+static int __init dt_arch_cpu_init(int cpu, struct dt_device_node *dn)
 {
     const char *enable_method;
 
@@ -94,6 +94,11 @@ int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
     return 0;
 }
 
+int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
+{
+    return dt_arch_cpu_init(cpu, dn);
+}
+
 int __init arch_cpu_up(int cpu)
 {
     if ( !smp_enable_ops[cpu].prepare_cpu )
xen/arch/arm/smpboot.c +18 -11
index a96cda2..d115228 100644
@@ -92,7 +92,7 @@ smp_clear_cpu_maps (void)
  * MPIDR values related to logical cpus
  * Code base on Linux arch/arm/kernel/devtree.c
  */
-void __init smp_init_cpus(void)
+static void __init dt_smp_init_cpus(void)
 {
     register_t mpidr;
     struct dt_device_node *cpus = dt_find_node_by_path("/cpus");
@@ -106,16 +106,6 @@ void __init smp_init_cpus(void)
     bool_t bootcpu_valid = 0;
     int rc;
 
-    /* scan the DTB for a PSCI node and set a global variable */
-    psci_init();
-
-    if ( (rc = arch_smp_init()) < 0 )
-    {
-        printk(XENLOG_WARNING "SMP init failed (%d)\n"
-               "Using only 1 CPU\n", rc);
-        return;
-    }
-
     mpidr = boot_cpu_data.mpidr.bits & MPIDR_HWID_MASK;
 
     if ( !cpus )
@@ -243,6 +233,23 @@ void __init smp_init_cpus(void)
     }
 }
 
+void __init smp_init_cpus(void)
+{
+    int rc;
+
+    /* initialize PSCI and set a global variable */
+    psci_init();
+
+    if ( (rc = arch_smp_init()) < 0 )
+    {
+        printk(XENLOG_WARNING "SMP init failed (%d)\n"
+               "Using only 1 CPU\n", rc);
+        return;
+    }
+
+    dt_smp_init_cpus();
+}
+
 int __init
 smp_get_max_cpus (void)
 {
Signature · 1 line
2.1.0
#97 lore raw

PATCH v3 20/62 arm/acpi: Add ACPI support for SMP initialization

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

ACPI 5.1 only has two explicit methods to boot up SMP, PSCI and Parking protocol, but the Parking protocol is only specified for ARMv7 now, so make PSCI as the only way for the SMP boot protocol before some updates for the ACPI spec or the Parking protocol spec.

---
 xen/arch/arm/arm64/smpboot.c |  7 ++++++-
 xen/arch/arm/psci.c          | 30 +++++++++++++++++++++++-------
 xen/arch/arm/smpboot.c       |  7 ++++++-
 3 files changed, 35 insertions(+), 9 deletions(-)
xen/arch/arm/arm64/smpboot.c +6 -1
index 7928f69..93cb6b3 100644
@@ -7,6 +7,7 @@
 #include <xen/vmap.h>
 #include <asm/io.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 struct smp_enable_ops {
         int             (*prepare_cpu)(int);
@@ -96,7 +97,11 @@ static int __init dt_arch_cpu_init(int cpu, struct dt_device_node *dn)
 
 int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
 {
-    return dt_arch_cpu_init(cpu, dn);
+    if( acpi_disabled )
+        return dt_arch_cpu_init(cpu, dn);
+    else
+        /* acpi only supports psci at present */
+        return smp_psci_init(cpu);
 }
 
 int __init arch_cpu_up(int cpu)
xen/arch/arm/psci.c +23 -7
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
+    if ( !acpi_disabled )
+        return -EINVAL;
+
     psci = dt_find_compatible_node(NULL, NULL, "arm,psci");
     if ( !psci )
         return -EOPNOTSUPP;
@@ -116,15 +120,24 @@ int __init psci_init_0_2(void)
         { /* sentinel */ },
     };
     int ret;
-    const struct dt_device_node *psci;
 
-    psci = dt_find_matching_node(NULL, psci_ids);
-    if ( !psci )
-        return -EOPNOTSUPP;
+    if( acpi_disabled )
+    {
+        const struct dt_device_node *psci;
 
-    ret = psci_is_smc_method(psci);
-    if ( ret )
-        return -EINVAL;
+        psci = dt_find_matching_node(NULL, psci_ids);
+        if ( !psci )
+            return -EOPNOTSUPP;
+
+        ret = psci_is_smc_method(psci);
+        if ( ret )
+            return -EINVAL;
+    }
+    else
+    {
+        if ( acpi_psci_hvc_present() )
+            return -EINVAL;
+    }
 
     psci_ver = call_smc(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
 
@@ -148,6 +161,9 @@ int __init psci_init(void)
 {
     int ret;
 
+    if( !acpi_disabled && !acpi_psci_present() )
+        return -EOPNOTSUPP;
+
     ret = psci_init_0_2();
     if ( ret )
         ret = psci_init_0_1();
xen/arch/arm/smpboot.c +6 -1
index d115228..513f1f6 100644
@@ -31,6 +31,7 @@
 #include <xen/console.h>
 #include <asm/gic.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 cpumask_t cpu_online_map;
 cpumask_t cpu_present_map;
@@ -247,7 +248,11 @@ void __init smp_init_cpus(void)
         return;
     }
 
-    dt_smp_init_cpus();
+    if ( acpi_disabled )
+        dt_smp_init_cpus();
+    else
+        acpi_smp_init_cpus();
+
 }
 
 int __init
Signature · 1 line
2.1.0
#98 lore raw

PATCH v3 20/62 arm/acpi: Add ACPI support for SMP initialization

Quoted 54 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

ACPI 5.1 only has two explicit methods to boot up SMP, PSCI and Parking protocol, but the Parking protocol is only specified for ARMv7 now, so make PSCI as the only way for the SMP boot protocol before some updates for the ACPI spec or the Parking protocol spec.

---
 xen/arch/arm/arm64/smpboot.c |  7 ++++++-
 xen/arch/arm/psci.c          | 30 +++++++++++++++++++++++-------
 xen/arch/arm/smpboot.c       |  7 ++++++-
 3 files changed, 35 insertions(+), 9 deletions(-)
xen/arch/arm/arm64/smpboot.c +6 -1
index 7928f69..93cb6b3 100644
@@ -7,6 +7,7 @@
 #include <xen/vmap.h>
 #include <asm/io.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 struct smp_enable_ops {
         int             (*prepare_cpu)(int);
@@ -96,7 +97,11 @@ static int __init dt_arch_cpu_init(int cpu, struct dt_device_node *dn)
 
 int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
 {
-    return dt_arch_cpu_init(cpu, dn);
+    if( acpi_disabled )
+        return dt_arch_cpu_init(cpu, dn);
+    else
+        /* acpi only supports psci at present */
+        return smp_psci_init(cpu);
 }
 
 int __init arch_cpu_up(int cpu)
xen/arch/arm/psci.c +1 -0
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for

xen/arch/arm/psci.c int __init psci_init_0_1(void) · line 91

Quoted 5 lines
xen/arch/arm/psci.c +2 -0
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
+    if ( !acpi_disabled )
+        return -EINVAL;

It might be worth printing an error message here

Quoted 21 lines
xen/arch/arm/psci.c +5 -7
     psci = dt_find_compatible_node(NULL, NULL, "arm,psci");
     if ( !psci )
         return -EOPNOTSUPP;
@@ -116,15 +120,24 @@ int __init psci_init_0_2(void)
         { /* sentinel */ },
     };
     int ret;
-    const struct dt_device_node *psci;
 
-    psci = dt_find_matching_node(NULL, psci_ids);
-    if ( !psci )
-        return -EOPNOTSUPP;
+    if( acpi_disabled )
+    {
+        const struct dt_device_node *psci;
 
-    ret = psci_is_smc_method(psci);
-    if ( ret )
-        return -EINVAL;
+        psci = dt_find_matching_node(NULL, psci_ids);
+        if ( !psci )

xen/arch/arm/psci.c int __init psci_init_0_2(void) · line 139

Quoted 10 lines
xen/arch/arm/psci.c +10 -0
+            return -EOPNOTSUPP;
+
+        ret = psci_is_smc_method(psci);
+        if ( ret )
+            return -EINVAL;
+    }
+    else
+    {
+        if ( acpi_psci_hvc_present() )
+            return -EINVAL;

and also here

Quoted 42 lines
xen/arch/arm/psci.c +4 -0
+    }
 
     psci_ver = call_smc(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
 
@@ -148,6 +161,9 @@ int __init psci_init(void)
 {
     int ret;
 
+    if( !acpi_disabled && !acpi_psci_present() )
+        return -EOPNOTSUPP;
+
     ret = psci_init_0_2();
     if ( ret )
         ret = psci_init_0_1();
xen/arch/arm/smpboot.c +6 -1
index d115228..513f1f6 100644
@@ -31,6 +31,7 @@
 #include <xen/console.h>
 #include <asm/gic.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 cpumask_t cpu_online_map;
 cpumask_t cpu_present_map;
@@ -247,7 +248,11 @@ void __init smp_init_cpus(void)
         return;
     }
 
-    dt_smp_init_cpus();
+    if ( acpi_disabled )
+        dt_smp_init_cpus();
+    else
+        acpi_smp_init_cpus();
+
 }
 
 int __init
Signature · 1 line
2.1.0
#99 lore raw

Re: [PATCH v3 20/62] arm/acpi: Add ACPI support for SMP initialization

In reply to shannon.zhao at linaro.org
Quoted 54 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

ACPI 5.1 only has two explicit methods to boot up SMP, PSCI and Parking protocol, but the Parking protocol is only specified for ARMv7 now, so make PSCI as the only way for the SMP boot protocol before some updates for the ACPI spec or the Parking protocol spec.

---
 xen/arch/arm/arm64/smpboot.c |  7 ++++++-
 xen/arch/arm/psci.c          | 30 +++++++++++++++++++++++-------
 xen/arch/arm/smpboot.c       |  7 ++++++-
 3 files changed, 35 insertions(+), 9 deletions(-)
xen/arch/arm/arm64/smpboot.c +6 -1
index 7928f69..93cb6b3 100644
@@ -7,6 +7,7 @@
 #include <xen/vmap.h>
 #include <asm/io.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 struct smp_enable_ops {
         int             (*prepare_cpu)(int);
@@ -96,7 +97,11 @@ static int __init dt_arch_cpu_init(int cpu, struct dt_device_node *dn)
 
 int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
 {
-    return dt_arch_cpu_init(cpu, dn);
+    if( acpi_disabled )
+        return dt_arch_cpu_init(cpu, dn);
+    else
+        /* acpi only supports psci at present */
+        return smp_psci_init(cpu);
 }
 
 int __init arch_cpu_up(int cpu)
xen/arch/arm/psci.c +1 -0
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for

xen/arch/arm/psci.c int __init psci_init_0_1(void) · line 91

Quoted 5 lines
xen/arch/arm/psci.c +2 -0
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
+    if ( !acpi_disabled )
+        return -EINVAL;

It might be worth printing an error message here

Quoted 21 lines
xen/arch/arm/psci.c +5 -7
     psci = dt_find_compatible_node(NULL, NULL, "arm,psci");
     if ( !psci )
         return -EOPNOTSUPP;
@@ -116,15 +120,24 @@ int __init psci_init_0_2(void)
         { /* sentinel */ },
     };
     int ret;
-    const struct dt_device_node *psci;
 
-    psci = dt_find_matching_node(NULL, psci_ids);
-    if ( !psci )
-        return -EOPNOTSUPP;
+    if( acpi_disabled )
+    {
+        const struct dt_device_node *psci;
 
-    ret = psci_is_smc_method(psci);
-    if ( ret )
-        return -EINVAL;
+        psci = dt_find_matching_node(NULL, psci_ids);
+        if ( !psci )

xen/arch/arm/psci.c int __init psci_init_0_2(void) · line 139

Quoted 10 lines
xen/arch/arm/psci.c +10 -0
+            return -EOPNOTSUPP;
+
+        ret = psci_is_smc_method(psci);
+        if ( ret )
+            return -EINVAL;
+    }
+    else
+    {
+        if ( acpi_psci_hvc_present() )
+            return -EINVAL;

and also here

Quoted 42 lines
xen/arch/arm/psci.c +4 -0
+    }
 
     psci_ver = call_smc(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
 
@@ -148,6 +161,9 @@ int __init psci_init(void)
 {
     int ret;
 
+    if( !acpi_disabled && !acpi_psci_present() )
+        return -EOPNOTSUPP;
+
     ret = psci_init_0_2();
     if ( ret )
         ret = psci_init_0_1();
xen/arch/arm/smpboot.c +6 -1
index d115228..513f1f6 100644
@@ -31,6 +31,7 @@
 #include <xen/console.h>
 #include <asm/gic.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 cpumask_t cpu_online_map;
 cpumask_t cpu_present_map;
@@ -247,7 +248,11 @@ void __init smp_init_cpus(void)
         return;
     }
 
-    dt_smp_init_cpus();
+    if ( acpi_disabled )
+        dt_smp_init_cpus();
+    else
+        acpi_smp_init_cpus();
+
 }
 
 int __init
Signature · 1 line
2.1.0
#100 lore raw

PATCH v3 20/62 arm/acpi: Add ACPI support for SMP initialization

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 13 lines · shannon.zhao at linaro.org
xen/arch/arm/psci.c +1 -0
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for

xen/arch/arm/psci.c int __init psci_init_0_1(void) · line 91

Quoted 5 lines
xen/arch/arm/psci.c +2 -0
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
+    if ( !acpi_disabled )
+        return -EINVAL;

Please explain in the commit message why PSCI 0.1 is not supported on ACPI.

Regards,

Signature · 1 line
Julien Grall
#101 lore raw

PATCH v3 20/62 arm/acpi: Add ACPI support for SMP initialization

Quoted 19 lines · Julien Grall

Hi Shannon,

Quoted 16 lines · shannon.zhao at linaro.org
Quoted 16 lines
xen/arch/arm/psci.c +1 -0
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
Quoted 3 lines
Quoted 2 lines

xen/arch/arm/psci.c int __init psci_init_0_1(void) · line 91

Quoted 2 lines
xen/arch/arm/psci.c +2 -0
+    if ( !acpi_disabled )
+        return -EINVAL;

Please explain in the commit message why PSCI 0.1 is not supported on ACPI.

Hi,

I check this again. There are not limitations of supporting PSCI version in ACPI SPEC. It should support PSCI 0.1 as well. But look at the code of linux kernel, it says it only supports PSCI 0.2+.

#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is
implemented */

So does it need to be consistent with Linux or support PSCI 0.1 in Xen as well?

Thanks,

Signature · 1 line
Shannon
#102 lore raw

PATCH v3 20/62 arm/acpi: Add ACPI support for SMP initialization

Quoted 30 lines · Shannon Zhao
Quoted 19 lines · Julien Grall

Hi Shannon,

Quoted 16 lines · shannon.zhao at linaro.org
Quoted 16 lines
xen/arch/arm/psci.c +1 -0
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
Quoted 3 lines
Quoted 2 lines

xen/arch/arm/psci.c int __init psci_init_0_1(void) · line 91

Quoted 2 lines
xen/arch/arm/psci.c +2 -0
+    if ( !acpi_disabled )
+        return -EINVAL;

Please explain in the commit message why PSCI 0.1 is not supported on ACPI.

Hi,

I check this again. There are not limitations of supporting PSCI version in ACPI SPEC. It should support PSCI 0.1 as well. But look at the code of linux kernel, it says it only supports PSCI 0.2+.

Quoted 5 lines

#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is
implemented */

So does it need to be consistent with Linux or support PSCI 0.1 in Xen as well?

I don't think it needs to be consistent with Linux. I would support PSCI 0.1 too.

#103 lore raw

PATCH v3 20/62 arm/acpi: Add ACPI support for SMP initialization

Quoted 31 lines · Stefano Stabellini
Quoted 30 lines · Shannon Zhao
Quoted 19 lines · Julien Grall

Hi Shannon,

Quoted 16 lines · shannon.zhao at linaro.org
Quoted 16 lines
xen/arch/arm/psci.c +1 -0
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
Quoted 3 lines
Quoted 2 lines

xen/arch/arm/psci.c int __init psci_init_0_1(void) · line 91

Quoted 2 lines
xen/arch/arm/psci.c +2 -0
+    if ( !acpi_disabled )
+        return -EINVAL;

Please explain in the commit message why PSCI 0.1 is not supported on ACPI.

Hi,

I check this again. There are not limitations of supporting PSCI version in ACPI SPEC. It should support PSCI 0.1 as well. But look at the code of linux kernel, it says it only supports PSCI 0.2+.

Quoted 8 lines
Quoted 5 lines

#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is
implemented */

So does it need to be consistent with Linux or support PSCI 0.1 in Xen as well?

I don't think it needs to be consistent with Linux. I would support PSCI 0.1 too.

That's not possible, so I don't follow. Prior to 0.2 the function IDs are not defined.

The FADT has a single bit which describes PSCI 0.2+ being implemented, and does not describe function IDs.

You must assume PSCI 0.2+ in order to have a set of function IDs to use.

You should also assume the presence of the rest of the mandatory portions of PSCI 0.2, as these are also required per the combination of the PSCI spec and the ACPI spec.

Mark.

#104 lore raw

PATCH v3 20/62 arm/acpi: Add ACPI support for SMP initialization

Quoted 12 lines · Mark Rutland
Quoted 11 lines · Stefano Stabellini
Quoted 9 lines · Shannon Zhao

I check this again. There are not limitations of supporting PSCI version in ACPI SPEC. It should support PSCI 0.1 as well. But look at the code of linux kernel, it says it only supports PSCI 0.2+.

#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is
implemented */

So does it need to be consistent with Linux or support PSCI 0.1 in Xen as well?

Quoted 8 lines
Quoted 2 lines

I don't think it needs to be consistent with Linux. I would support PSCI 0.1 too.

That's not possible, so I don't follow. Prior to 0.2 the function IDs are not defined.

The FADT has a single bit which describes PSCI 0.2+ being implemented, and does not describe function IDs.

I've now spotted that this wording is indeed missing from the ACPI documentation. I believe this is a documentation bug, as the intent was always for the bit to imply PSCI 0.2+.

Mark.

#105 lore raw

Re: [PATCH v3 20/62] arm/acpi: Add ACPI support for SMP initialization

In reply to Mark Rutland
Quoted 12 lines · Mark Rutland
Quoted 11 lines · Stefano Stabellini
Quoted 9 lines · Shannon Zhao

I check this again. There are not limitations of supporting PSCI version in ACPI SPEC. It should support PSCI 0.1 as well. But look at the code of linux kernel, it says it only supports PSCI 0.2+.

#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is
implemented */

So does it need to be consistent with Linux or support PSCI 0.1 in Xen as well?

Quoted 8 lines
Quoted 2 lines

I don't think it needs to be consistent with Linux. I would support PSCI 0.1 too.

That's not possible, so I don't follow. Prior to 0.2 the function IDs are not defined.

The FADT has a single bit which describes PSCI 0.2+ being implemented, and does not describe function IDs.

I've now spotted that this wording is indeed missing from the ACPI documentation. I believe this is a documentation bug, as the intent was always for the bit to imply PSCI 0.2+.

Mark.

#106 lore raw

Re: [PATCH v3 20/62] arm/acpi: Add ACPI support for SMP initialization

In reply to Stefano Stabellini
Quoted 31 lines · Stefano Stabellini
Quoted 30 lines · Shannon Zhao
Quoted 19 lines · Julien Grall

Hi Shannon,

Quoted 16 lines · On 17/11/15 09:40, [email protected] wrote:
Quoted 16 lines
xen/arch/arm/psci.c +1 -0
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
Quoted 3 lines
Quoted 2 lines

xen/arch/arm/psci.c int __init psci_init_0_1(void) · line 91

Quoted 2 lines
xen/arch/arm/psci.c +2 -0
+    if ( !acpi_disabled )
+        return -EINVAL;

Please explain in the commit message why PSCI 0.1 is not supported on ACPI.

Hi,

I check this again. There are not limitations of supporting PSCI version in ACPI SPEC. It should support PSCI 0.1 as well. But look at the code of linux kernel, it says it only supports PSCI 0.2+.

Quoted 8 lines
Quoted 5 lines

#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is
implemented */

So does it need to be consistent with Linux or support PSCI 0.1 in Xen as well?

I don't think it needs to be consistent with Linux. I would support PSCI 0.1 too.

That's not possible, so I don't follow. Prior to 0.2 the function IDs are not defined.

The FADT has a single bit which describes PSCI 0.2+ being implemented, and does not describe function IDs.

You must assume PSCI 0.2+ in order to have a set of function IDs to use.

You should also assume the presence of the rest of the mandatory portions of PSCI 0.2, as these are also required per the combination of the PSCI spec and the ACPI spec.

Mark.

#107 lore raw

Re: [PATCH v3 20/62] arm/acpi: Add ACPI support for SMP initialization

In reply to Shannon Zhao
Quoted 30 lines · Shannon Zhao
Quoted 19 lines · Julien Grall

Hi Shannon,

Quoted 16 lines · On 17/11/15 09:40, [email protected] wrote:
Quoted 16 lines
xen/arch/arm/psci.c +1 -0
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
Quoted 3 lines
Quoted 2 lines

xen/arch/arm/psci.c int __init psci_init_0_1(void) · line 91

Quoted 2 lines
xen/arch/arm/psci.c +2 -0
+    if ( !acpi_disabled )
+        return -EINVAL;

Please explain in the commit message why PSCI 0.1 is not supported on ACPI.

Hi,

I check this again. There are not limitations of supporting PSCI version in ACPI SPEC. It should support PSCI 0.1 as well. But look at the code of linux kernel, it says it only supports PSCI 0.2+.

Quoted 5 lines

#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is
implemented */

So does it need to be consistent with Linux or support PSCI 0.1 in Xen as well?

I don't think it needs to be consistent with Linux. I would support PSCI 0.1 too.

#108 lore raw

PATCH v3 20/62 arm/acpi: Add ACPI support for SMP initialization

In reply to Shannon Zhao
Quoted 22 lines · Shannon Zhao
Quoted 19 lines · Julien Grall

Hi Shannon,

Quoted 16 lines · shannon.zhao at linaro.org
Quoted 16 lines
xen/arch/arm/psci.c +1 -0
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
Quoted 8 lines
Quoted 3 lines
Quoted 2 lines

xen/arch/arm/psci.c int __init psci_init_0_1(void) · line 91

Quoted 2 lines
xen/arch/arm/psci.c +2 -0
+    if ( !acpi_disabled )
+        return -EINVAL;

Please explain in the commit message why PSCI 0.1 is not supported on ACPI.

Hi,

I check this again. There are not limitations of supporting PSCI version in ACPI SPEC. It should support PSCI 0.1 as well.

I believe that's an oversight in the ACPI documentation, which should state 0.2+.

There was a deliberate decision that the FADT PSCI flag implied PSCI 0.2+, since prior to PSCI 0.2 function IDs were not well-defined, and functions crticial for some uses cases did not exist (e.g. AFFINITY_INFO for kexec-type things).

I don't know why that did not make it into the documentation.

Charles, thoughts?

Mark.

#109 lore raw

Re: [PATCH v3 20/62] arm/acpi: Add ACPI support for SMP initialization

In reply to Shannon Zhao
Quoted 22 lines · Shannon Zhao
Quoted 19 lines · Julien Grall

Hi Shannon,

Quoted 16 lines · On 17/11/15 09:40, [email protected] wrote:
Quoted 16 lines
xen/arch/arm/psci.c +1 -0
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
Quoted 8 lines
Quoted 3 lines
Quoted 2 lines

xen/arch/arm/psci.c int __init psci_init_0_1(void) · line 91

Quoted 2 lines
xen/arch/arm/psci.c +2 -0
+    if ( !acpi_disabled )
+        return -EINVAL;

Please explain in the commit message why PSCI 0.1 is not supported on ACPI.

Hi,

I check this again. There are not limitations of supporting PSCI version in ACPI SPEC. It should support PSCI 0.1 as well.

I believe that's an oversight in the ACPI documentation, which should state 0.2+.

There was a deliberate decision that the FADT PSCI flag implied PSCI 0.2+, since prior to PSCI 0.2 function IDs were not well-defined, and functions crticial for some uses cases did not exist (e.g. AFFINITY_INFO for kexec-type things).

I don't know why that did not make it into the documentation.

Charles, thoughts?

Mark.

#110 lore raw

Re: [PATCH v3 20/62] arm/acpi: Add ACPI support for SMP initialization

In reply to Julien Grall
Quoted 19 lines · Julien Grall

Hi Shannon,

Quoted 16 lines · On 17/11/15 09:40, [email protected] wrote:
Quoted 16 lines
xen/arch/arm/psci.c +1 -0
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
Quoted 3 lines
Quoted 2 lines

xen/arch/arm/psci.c int __init psci_init_0_1(void) · line 91

Quoted 2 lines
xen/arch/arm/psci.c +2 -0
+    if ( !acpi_disabled )
+        return -EINVAL;

Please explain in the commit message why PSCI 0.1 is not supported on ACPI.

Hi,

I check this again. There are not limitations of supporting PSCI version in ACPI SPEC. It should support PSCI 0.1 as well. But look at the code of linux kernel, it says it only supports PSCI 0.2+.

#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is
implemented */

So does it need to be consistent with Linux or support PSCI 0.1 in Xen as well?

Thanks,

Signature · 1 line
Shannon
#111 lore raw

Re: [PATCH v3 20/62] arm/acpi: Add ACPI support for SMP initialization

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 13 lines · On 17/11/15 09:40, [email protected] wrote:
xen/arch/arm/psci.c +1 -0
index d800cb6..dede0e1 100644
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/smp.h>
 #include <asm/psci.h>
+#include <asm/acpi.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for

xen/arch/arm/psci.c int __init psci_init_0_1(void) · line 91

Quoted 5 lines
xen/arch/arm/psci.c +2 -0
@@ -86,6 +87,9 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
+    if ( !acpi_disabled )
+        return -EINVAL;

Please explain in the commit message why PSCI 0.1 is not supported on ACPI.

Regards,

Signature · 1 line
Julien Grall
#112 lore raw

PATCH v3 21/62 arm/gic-v2: Refactor gicv2_init into generic and dt specific parts

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Refactor gic-v2 related functions into dt and generic parts. This will be helpful when adding acpi support for gic.

---
 xen/arch/arm/gic-v2.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)
xen/arch/arm/gic-v2.c +14 -7
index 01e36b5..e31d38e 100644
@@ -628,13 +628,12 @@ static bool_t gicv2_is_aliased(paddr_t cbase, paddr_t csize)
     return ((val_low & 0xfff0fff) == 0x0202043B && val_low == val_high);
 }
 
-static int __init gicv2_init(void)
+static paddr_t __initdata hbase, dbase, cbase, csize, vbase;
+
+static void __init dt_gicv2_init(void)
 {
     int res;
-    paddr_t hbase, dbase;
-    paddr_t cbase, csize;
-    paddr_t vbase, vsize;
-    uint32_t aliased_offset = 0;
+    paddr_t vsize;
     const struct dt_device_node *node = gicv2_info.node;
 
     res = dt_device_get_address(node, 0, &dbase, NULL);
@@ -680,6 +679,13 @@ static int __init gicv2_init(void)
     if ( csize != vsize )
         panic("GICv2: Sizes of GICC (%#"PRIpaddr") and GICV (%#"PRIpaddr") don't match\n",
                csize, vsize);
+}
+
+static int __init gicv2_init(void)
+{
+    uint32_t aliased_offset = 0;
+
+    dt_gicv2_init();
 
     printk("GICv2 initialization:\n"
               "        gic_dist_addr=%"PRIpaddr"\n"
@@ -765,7 +771,8 @@ const static struct gic_hw_operations gicv2_ops = {
 };
 
 /* Set up the GIC */
-static int __init gicv2_preinit(struct dt_device_node *node, const void *data)
+static int __init dt_gicv2_preinit(struct dt_device_node *node,
+                                   const void *data)
 {
     gicv2_info.hw_version = GIC_V2;
     gicv2_info.node = node;
@@ -783,7 +790,7 @@ static const struct dt_device_match gicv2_dt_match[] __initconst =
 
 DT_DEVICE_START(gicv2, "GICv2", DEVICE_GIC)
         .dt_match = gicv2_dt_match,
-        .init = gicv2_preinit,
+        .init = dt_gicv2_preinit,
 DT_DEVICE_END
 
 /*
Signature · 1 line
2.1.0
#113 lore raw

PATCH v3 21/62 arm/gic-v2: Refactor gicv2_init into generic and dt specific parts

Quoted 58 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Refactor gic-v2 related functions into dt and generic parts. This will be helpful when adding acpi support for gic.

---
 xen/arch/arm/gic-v2.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)
xen/arch/arm/gic-v2.c +13 -6
index 01e36b5..e31d38e 100644
@@ -628,13 +628,12 @@ static bool_t gicv2_is_aliased(paddr_t cbase, paddr_t csize)
     return ((val_low & 0xfff0fff) == 0x0202043B && val_low == val_high);
 }
 
-static int __init gicv2_init(void)
+static paddr_t __initdata hbase, dbase, cbase, csize, vbase;
+
+static void __init dt_gicv2_init(void)
 {
     int res;
-    paddr_t hbase, dbase;
-    paddr_t cbase, csize;
-    paddr_t vbase, vsize;
-    uint32_t aliased_offset = 0;
+    paddr_t vsize;
     const struct dt_device_node *node = gicv2_info.node;
 
     res = dt_device_get_address(node, 0, &dbase, NULL);
@@ -680,6 +679,13 @@ static int __init gicv2_init(void)
     if ( csize != vsize )
         panic("GICv2: Sizes of GICC (%#"PRIpaddr") and GICV (%#"PRIpaddr") don't match\n",
                csize, vsize);
+}
+
+static int __init gicv2_init(void)
+{
+    uint32_t aliased_offset = 0;
+
+    dt_gicv2_init();
 
     printk("GICv2 initialization:\n"
               "        gic_dist_addr=%"PRIpaddr"\n"
@@ -765,7 +771,8 @@ const static struct gic_hw_operations gicv2_ops = {
 };
 
 /* Set up the GIC */
-static int __init gicv2_preinit(struct dt_device_node *node, const void *data)
+static int __init dt_gicv2_preinit(struct dt_device_node *node,
+                                   const void *data)
 {
     gicv2_info.hw_version = GIC_V2;
     gicv2_info.node = node;

xen/arch/arm/gic-v2.c static const struct dt_device_match gicv2_dt_match[] __initconst = · line 793

Quoted 5 lines
xen/arch/arm/gic-v2.c +1 -1
@@ -783,7 +790,7 @@ static const struct dt_device_match gicv2_dt_match[] __initconst =
 
 DT_DEVICE_START(gicv2, "GICv2", DEVICE_GIC)
         .dt_match = gicv2_dt_match,
-        .init = gicv2_preinit,
+        .init = dt_gicv2_preinit,

Maybe it would make sense to call this gicv2_dt_preinit for consistency, nonetheless

Quoted 6 lines
xen/arch/arm/gic-v2.c +0 -0
 DT_DEVICE_END
 
 /*
Signature · 1 line
2.1.0
Acked-by on v3 21/62
#114 lore raw

Re: [PATCH v3 21/62] arm/gic-v2: Refactor gicv2_init into generic and dt specific parts

In reply to shannon.zhao at linaro.org
Quoted 58 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Refactor gic-v2 related functions into dt and generic parts. This will be helpful when adding acpi support for gic.

---
 xen/arch/arm/gic-v2.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)
xen/arch/arm/gic-v2.c +13 -6
index 01e36b5..e31d38e 100644
@@ -628,13 +628,12 @@ static bool_t gicv2_is_aliased(paddr_t cbase, paddr_t csize)
     return ((val_low & 0xfff0fff) == 0x0202043B && val_low == val_high);
 }
 
-static int __init gicv2_init(void)
+static paddr_t __initdata hbase, dbase, cbase, csize, vbase;
+
+static void __init dt_gicv2_init(void)
 {
     int res;
-    paddr_t hbase, dbase;
-    paddr_t cbase, csize;
-    paddr_t vbase, vsize;
-    uint32_t aliased_offset = 0;
+    paddr_t vsize;
     const struct dt_device_node *node = gicv2_info.node;
 
     res = dt_device_get_address(node, 0, &dbase, NULL);
@@ -680,6 +679,13 @@ static int __init gicv2_init(void)
     if ( csize != vsize )
         panic("GICv2: Sizes of GICC (%#"PRIpaddr") and GICV (%#"PRIpaddr") don't match\n",
                csize, vsize);
+}
+
+static int __init gicv2_init(void)
+{
+    uint32_t aliased_offset = 0;
+
+    dt_gicv2_init();
 
     printk("GICv2 initialization:\n"
               "        gic_dist_addr=%"PRIpaddr"\n"
@@ -765,7 +771,8 @@ const static struct gic_hw_operations gicv2_ops = {
 };
 
 /* Set up the GIC */
-static int __init gicv2_preinit(struct dt_device_node *node, const void *data)
+static int __init dt_gicv2_preinit(struct dt_device_node *node,
+                                   const void *data)
 {
     gicv2_info.hw_version = GIC_V2;
     gicv2_info.node = node;

xen/arch/arm/gic-v2.c static const struct dt_device_match gicv2_dt_match[] __initconst = · line 793

Quoted 5 lines
xen/arch/arm/gic-v2.c +1 -1
@@ -783,7 +790,7 @@ static const struct dt_device_match gicv2_dt_match[] __initconst =
 
 DT_DEVICE_START(gicv2, "GICv2", DEVICE_GIC)
         .dt_match = gicv2_dt_match,
-        .init = gicv2_preinit,
+        .init = dt_gicv2_preinit,

Maybe it would make sense to call this gicv2_dt_preinit for consistency, nonetheless

Quoted 6 lines
xen/arch/arm/gic-v2.c +0 -0
 DT_DEVICE_END
 
 /*
Signature · 1 line
2.1.0
#115 lore raw

PATCH v3 22/62 arm/gic-v3: Refactor gicv3_init into generic and dt specific parts

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Refactor gic-v3 related functions into dt and generic parts. This will be helpful when adding acpi support for gic-v3.

---
 xen/arch/arm/gic-v3.c | 95 +++++++++++++++++++++++++++------------------------
 1 file changed, 51 insertions(+), 44 deletions(-)
xen/arch/arm/gic-v3.c +51 -44
index 4fe0c37..bd13010 100644
@@ -1138,62 +1138,27 @@ static int __init cmp_rdist(const void *a, const void *b)
     return ( l->base < r->base) ? -1 : 0;
 }
 
+static paddr_t __initdata dbase = 0, cbase = 0, csize = 0, vbase = 0;
+
 /* If the GICv3 supports GICv2, initialize it */
-static void __init gicv3_init_v2(const struct dt_device_node *node,
-                                 paddr_t dbase)
+static void __init gicv3_init_v2(void)
 {
-    int res;
-    paddr_t cbase, csize;
-    paddr_t vbase, vsize;
-
-    /*
-     * For GICv3 supporting GICv2, GICC and GICV base address will be
-     * provided.
-     */
-    res = dt_device_get_address(node, 1 + gicv3.rdist_count,
-                                &cbase, &csize);
-    if ( res )
+    if ( cbase == 0 || vbase == 0 )
         return;
 
-    res = dt_device_get_address(node, 1 + gicv3.rdist_count + 2,
-                                &vbase, &vsize);
-    if ( res )
-        return;
-
-    /*
-     * We emulate a vGICv2 using a GIC CPU interface of GUEST_GICC_SIZE.
-     * So only support GICv2 on GICv3 when the virtual CPU interface is
-     * at least GUEST_GICC_SIZE.
-     */
-    if ( vsize < GUEST_GICC_SIZE )
-    {
-        printk(XENLOG_WARNING
-               "GICv3: WARNING: Not enabling support for GICv2 compat mode.\n"
-               "Size of GICV (%#"PRIpaddr") must at least be %#llx.\n",
-               vsize, GUEST_GICC_SIZE);
-        return;
-    }
-
     printk("GICv3 compatible with GICv2 cbase %#"PRIpaddr" vbase %#"PRIpaddr"\n",
            cbase, vbase);
 
     vgic_v2_setup_hw(dbase, cbase, csize, vbase, 0);
 }
 
-/* Set up the GIC */
-static int __init gicv3_init(void)
+static void __init dt_gicv3_init(void)
 {
     struct rdist_region *rdist_regs;
     int res, i;
     uint32_t reg;
     const struct dt_device_node *node = gicv3_info.node;
-    paddr_t dbase;
-
-    if ( !cpu_has_gicv3 )
-    {
-        dprintk(XENLOG_ERR, "GICv3: driver requires system register support\n");
-        return -ENODEV;
-    }
+    paddr_t vsize;
 
     res = dt_device_get_address(node, 0, &dbase, NULL);
     if ( res )
@@ -1248,6 +1213,48 @@ static int __init gicv3_init(void)
         panic("GICv3: Cannot find the maintenance IRQ");
     gicv3_info.maintenance_irq = res;
 
+    /*
+     * For GICv3 supporting GICv2, GICC and GICV base address will be
+     * provided.
+     */
+    res = dt_device_get_address(node, 1 + gicv3.rdist_count,
+                                &cbase, &csize);
+    if ( res )
+        return;
+
+    res = dt_device_get_address(node, 1 + gicv3.rdist_count + 2,
+                                &vbase, &vsize);
+    if ( res )
+        return;
+
+    /*
+     * We emulate a vGICv2 using a GIC CPU interface of GUEST_GICC_SIZE.
+     * So only support GICv2 on GICv3 when the virtual CPU interface is
+     * at least GUEST_GICC_SIZE.
+     */
+    if ( vsize < GUEST_GICC_SIZE )
+    {
+        printk(XENLOG_WARNING
+               "GICv3: WARNING: Not enabling support for GICv2 compat mode.\n"
+               "Size of GICV (%#"PRIpaddr") must@least be %#llx.\n",
+               vsize, GUEST_GICC_SIZE);
+        return;
+    }
+}
+
+/* Set up the GIC */
+static int __init gicv3_init(void)
+{
+    int res, i;
+
+    if ( !cpu_has_gicv3 )
+    {
+        dprintk(XENLOG_ERR, "GICv3: driver requires system register support\n");
+        return -ENODEV;
+    }
+
+    dt_gicv3_init();
+
     for ( i = 0; i < gicv3.rdist_count; i++ )
     {
         /* map dbase & rdist regions */
@@ -1277,7 +1284,7 @@ static int __init gicv3_init(void)
 
     vgic_v3_setup_hw(dbase, gicv3.rdist_count, gicv3.rdist_regions,
                      gicv3.rdist_stride);
-    gicv3_init_v2(node, dbase);
+    gicv3_init_v2();
 
     spin_lock_init(&gicv3.lock);
 
@@ -1317,7 +1324,7 @@ static const struct gic_hw_operations gicv3_ops = {
     .make_hwdom_dt_node  = gicv3_make_hwdom_dt_node,
 };
 
-static int __init gicv3_preinit(struct dt_device_node *node, const void *data)
+static int __init dt_gicv3_preinit(struct dt_device_node *node, const void *data)
 {
     gicv3_info.hw_version = GIC_V3;
     gicv3_info.node = node;
@@ -1335,7 +1342,7 @@ static const struct dt_device_match gicv3_dt_match[] __initconst =
 
 DT_DEVICE_START(gicv3, "GICv3", DEVICE_GIC)
         .dt_match = gicv3_dt_match,
-        .init = gicv3_preinit,
+        .init = dt_gicv3_preinit,
 DT_DEVICE_END
 
 /*
Signature · 1 line
2.1.0
#116 lore raw

PATCH v3 22/62 arm/gic-v3: Refactor gicv3_init into generic and dt specific parts

Quoted 15 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Refactor gic-v3 related functions into dt and generic parts. This will be helpful when adding acpi support for gic-v3.

---
 xen/arch/arm/gic-v3.c | 95 +++++++++++++++++++++++++++------------------------
 1 file changed, 51 insertions(+), 44 deletions(-)
xen/arch/arm/gic-v3.c +0 -0
index 4fe0c37..bd13010 100644

xen/arch/arm/gic-v3.c static int __init cmp_rdist(const void *a, const void *b) · line 1141

Quoted 4 lines
xen/arch/arm/gic-v3.c +1 -0
@@ -1138,62 +1138,27 @@ static int __init cmp_rdist(const void *a, const void *b)
     return ( l->base < r->base) ? -1 : 0;
 }
 
+static paddr_t __initdata dbase = 0, cbase = 0, csize = 0, vbase = 0;

It might be best to initialize them to something like INVALID_PADDR rather then 0, which is actually a possible address value.

Quoted 98 lines
xen/arch/arm/gic-v3.c +35 -41
 /* If the GICv3 supports GICv2, initialize it */
-static void __init gicv3_init_v2(const struct dt_device_node *node,
-                                 paddr_t dbase)
+static void __init gicv3_init_v2(void)
 {
-    int res;
-    paddr_t cbase, csize;
-    paddr_t vbase, vsize;
-
-    /*
-     * For GICv3 supporting GICv2, GICC and GICV base address will be
-     * provided.
-     */
-    res = dt_device_get_address(node, 1 + gicv3.rdist_count,
-                                &cbase, &csize);
-    if ( res )
+    if ( cbase == 0 || vbase == 0 )
         return;
 
-    res = dt_device_get_address(node, 1 + gicv3.rdist_count + 2,
-                                &vbase, &vsize);
-    if ( res )
-        return;
-
-    /*
-     * We emulate a vGICv2 using a GIC CPU interface of GUEST_GICC_SIZE.
-     * So only support GICv2 on GICv3 when the virtual CPU interface is
-     * at least GUEST_GICC_SIZE.
-     */
-    if ( vsize < GUEST_GICC_SIZE )
-    {
-        printk(XENLOG_WARNING
-               "GICv3: WARNING: Not enabling support for GICv2 compat mode.\n"
-               "Size of GICV (%#"PRIpaddr") must at least be %#llx.\n",
-               vsize, GUEST_GICC_SIZE);
-        return;
-    }
-
     printk("GICv3 compatible with GICv2 cbase %#"PRIpaddr" vbase %#"PRIpaddr"\n",
            cbase, vbase);
 
     vgic_v2_setup_hw(dbase, cbase, csize, vbase, 0);
 }
 
-/* Set up the GIC */
-static int __init gicv3_init(void)
+static void __init dt_gicv3_init(void)
 {
     struct rdist_region *rdist_regs;
     int res, i;
     uint32_t reg;
     const struct dt_device_node *node = gicv3_info.node;
-    paddr_t dbase;
-
-    if ( !cpu_has_gicv3 )
-    {
-        dprintk(XENLOG_ERR, "GICv3: driver requires system register support\n");
-        return -ENODEV;
-    }
+    paddr_t vsize;
 
     res = dt_device_get_address(node, 0, &dbase, NULL);
     if ( res )
@@ -1248,6 +1213,48 @@ static int __init gicv3_init(void)
         panic("GICv3: Cannot find the maintenance IRQ");
     gicv3_info.maintenance_irq = res;
 
+    /*
+     * For GICv3 supporting GICv2, GICC and GICV base address will be
+     * provided.
+     */
+    res = dt_device_get_address(node, 1 + gicv3.rdist_count,
+                                &cbase, &csize);
+    if ( res )
+        return;
+
+    res = dt_device_get_address(node, 1 + gicv3.rdist_count + 2,
+                                &vbase, &vsize);
+    if ( res )
+        return;
+
+    /*
+     * We emulate a vGICv2 using a GIC CPU interface of GUEST_GICC_SIZE.
+     * So only support GICv2 on GICv3 when the virtual CPU interface is
+     * at least GUEST_GICC_SIZE.
+     */
+    if ( vsize < GUEST_GICC_SIZE )
+    {
+        printk(XENLOG_WARNING
+               "GICv3: WARNING: Not enabling support for GICv2 compat mode.\n"
+               "Size of GICV (%#"PRIpaddr") must at least be %#llx.\n",
+               vsize, GUEST_GICC_SIZE);
+        return;
+    }
+}
+
+/* Set up the GIC */
+static int __init gicv3_init(void)

xen/arch/arm/gic-v3.c static int __init gicv3_init(void) · line 1256

Quoted 10 lines
xen/arch/arm/gic-v3.c +10 -0
+{
+    int res, i;
+
+    if ( !cpu_has_gicv3 )
+    {
+        dprintk(XENLOG_ERR, "GICv3: driver requires system register support\n");
+        return -ENODEV;
+    }
+
+    dt_gicv3_init();

I think it would be best if we kept iall the ioremap calls here in the common function, instead of duplicating them in the acpi and dt specific init functions.

The GICD_PIDR2 check should common too.

Quoted 30 lines
xen/arch/arm/gic-v3.c +3 -3
     for ( i = 0; i < gicv3.rdist_count; i++ )
     {
         /* map dbase & rdist regions */
@@ -1277,7 +1284,7 @@ static int __init gicv3_init(void)
 
     vgic_v3_setup_hw(dbase, gicv3.rdist_count, gicv3.rdist_regions,
                      gicv3.rdist_stride);
-    gicv3_init_v2(node, dbase);
+    gicv3_init_v2();
 
     spin_lock_init(&gicv3.lock);
 
@@ -1317,7 +1324,7 @@ static const struct gic_hw_operations gicv3_ops = {
     .make_hwdom_dt_node  = gicv3_make_hwdom_dt_node,
 };
 
-static int __init gicv3_preinit(struct dt_device_node *node, const void *data)
+static int __init dt_gicv3_preinit(struct dt_device_node *node, const void *data)
 {
     gicv3_info.hw_version = GIC_V3;
     gicv3_info.node = node;
@@ -1335,7 +1342,7 @@ static const struct dt_device_match gicv3_dt_match[] __initconst =
 
 DT_DEVICE_START(gicv3, "GICv3", DEVICE_GIC)
         .dt_match = gicv3_dt_match,
-        .init = gicv3_preinit,
+        .init = dt_gicv3_preinit,
 DT_DEVICE_END
 
 /*
#117 lore raw

PATCH v3 22/62 arm/gic-v3: Refactor gicv3_init into generic and dt specific parts

Quoted 19 lines · Stefano Stabellini
Quoted 18 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Refactor gic-v3 related functions into dt and generic parts. This will be helpful when adding acpi support for gic-v3.

---
 xen/arch/arm/gic-v3.c | 95 +++++++++++++++++++++++++++------------------------
 1 file changed, 51 insertions(+), 44 deletions(-)
xen/arch/arm/gic-v3.c +0 -0
index 4fe0c37..bd13010 100644
@@ -1138,62 +1138,27 @@ static int __init cmp_rdist(const void *a, const void *b)
     return ( l->base < r->base) ? -1 : 0;
 }
 
Quoted 4 lines

xen/arch/arm/gic-v3.c static int __init cmp_rdist(const void *a, const void *b) · line 1141

Quoted 1 line
xen/arch/arm/gic-v3.c +1 -0
+static paddr_t __initdata dbase = 0, cbase = 0, csize = 0, vbase = 0;

It might be best to initialize them to something like INVALID_PADDR rather then 0, which is actually a possible address value.

It's even mandatory, we had a patch [1] to allow base address to be 0 and there is no point to re-introduce this restriction.

Regards,

[1] c1fde0dcd4ecb78378ffe8b3e263d28dc3b9c0eb "xen/arm: gic: Allow the base address to be 0"

Signature · 1 line
Julien Grall
#118 lore raw

Re: [PATCH v3 22/62] arm/gic-v3: Refactor gicv3_init into generic and dt specific parts

In reply to Stefano Stabellini
Quoted 19 lines · Stefano Stabellini
Quoted 18 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Refactor gic-v3 related functions into dt and generic parts. This will be helpful when adding acpi support for gic-v3.

---
 xen/arch/arm/gic-v3.c | 95 +++++++++++++++++++++++++++------------------------
 1 file changed, 51 insertions(+), 44 deletions(-)
xen/arch/arm/gic-v3.c +0 -0
index 4fe0c37..bd13010 100644
@@ -1138,62 +1138,27 @@ static int __init cmp_rdist(const void *a, const void *b)
     return ( l->base < r->base) ? -1 : 0;
 }
 
Quoted 4 lines

xen/arch/arm/gic-v3.c static int __init cmp_rdist(const void *a, const void *b) · line 1141

Quoted 1 line
xen/arch/arm/gic-v3.c +1 -0
+static paddr_t __initdata dbase = 0, cbase = 0, csize = 0, vbase = 0;

It might be best to initialize them to something like INVALID_PADDR rather then 0, which is actually a possible address value.

It's even mandatory, we had a patch [1] to allow base address to be 0 and there is no point to re-introduce this restriction.

Regards,

[1] c1fde0dcd4ecb78378ffe8b3e263d28dc3b9c0eb "xen/arm: gic: Allow the base address to be 0"

Signature · 1 line
Julien Grall
#119 lore raw

Re: [PATCH v3 22/62] arm/gic-v3: Refactor gicv3_init into generic and dt specific parts

In reply to shannon.zhao at linaro.org
Quoted 15 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Refactor gic-v3 related functions into dt and generic parts. This will be helpful when adding acpi support for gic-v3.

---
 xen/arch/arm/gic-v3.c | 95 +++++++++++++++++++++++++++------------------------
 1 file changed, 51 insertions(+), 44 deletions(-)
xen/arch/arm/gic-v3.c +0 -0
index 4fe0c37..bd13010 100644

xen/arch/arm/gic-v3.c static int __init cmp_rdist(const void *a, const void *b) · line 1141

Quoted 4 lines
xen/arch/arm/gic-v3.c +1 -0
@@ -1138,62 +1138,27 @@ static int __init cmp_rdist(const void *a, const void *b)
     return ( l->base < r->base) ? -1 : 0;
 }
 
+static paddr_t __initdata dbase = 0, cbase = 0, csize = 0, vbase = 0;

It might be best to initialize them to something like INVALID_PADDR rather then 0, which is actually a possible address value.

Quoted 98 lines
xen/arch/arm/gic-v3.c +35 -41
 /* If the GICv3 supports GICv2, initialize it */
-static void __init gicv3_init_v2(const struct dt_device_node *node,
-                                 paddr_t dbase)
+static void __init gicv3_init_v2(void)
 {
-    int res;
-    paddr_t cbase, csize;
-    paddr_t vbase, vsize;
-
-    /*
-     * For GICv3 supporting GICv2, GICC and GICV base address will be
-     * provided.
-     */
-    res = dt_device_get_address(node, 1 + gicv3.rdist_count,
-                                &cbase, &csize);
-    if ( res )
+    if ( cbase == 0 || vbase == 0 )
         return;
 
-    res = dt_device_get_address(node, 1 + gicv3.rdist_count + 2,
-                                &vbase, &vsize);
-    if ( res )
-        return;
-
-    /*
-     * We emulate a vGICv2 using a GIC CPU interface of GUEST_GICC_SIZE.
-     * So only support GICv2 on GICv3 when the virtual CPU interface is
-     * at least GUEST_GICC_SIZE.
-     */
-    if ( vsize < GUEST_GICC_SIZE )
-    {
-        printk(XENLOG_WARNING
-               "GICv3: WARNING: Not enabling support for GICv2 compat mode.\n"
-               "Size of GICV (%#"PRIpaddr") must at least be %#llx.\n",
-               vsize, GUEST_GICC_SIZE);
-        return;
-    }
-
     printk("GICv3 compatible with GICv2 cbase %#"PRIpaddr" vbase %#"PRIpaddr"\n",
            cbase, vbase);
 
     vgic_v2_setup_hw(dbase, cbase, csize, vbase, 0);
 }
 
-/* Set up the GIC */
-static int __init gicv3_init(void)
+static void __init dt_gicv3_init(void)
 {
     struct rdist_region *rdist_regs;
     int res, i;
     uint32_t reg;
     const struct dt_device_node *node = gicv3_info.node;
-    paddr_t dbase;
-
-    if ( !cpu_has_gicv3 )
-    {
-        dprintk(XENLOG_ERR, "GICv3: driver requires system register support\n");
-        return -ENODEV;
-    }
+    paddr_t vsize;
 
     res = dt_device_get_address(node, 0, &dbase, NULL);
     if ( res )
@@ -1248,6 +1213,48 @@ static int __init gicv3_init(void)
         panic("GICv3: Cannot find the maintenance IRQ");
     gicv3_info.maintenance_irq = res;
 
+    /*
+     * For GICv3 supporting GICv2, GICC and GICV base address will be
+     * provided.
+     */
+    res = dt_device_get_address(node, 1 + gicv3.rdist_count,
+                                &cbase, &csize);
+    if ( res )
+        return;
+
+    res = dt_device_get_address(node, 1 + gicv3.rdist_count + 2,
+                                &vbase, &vsize);
+    if ( res )
+        return;
+
+    /*
+     * We emulate a vGICv2 using a GIC CPU interface of GUEST_GICC_SIZE.
+     * So only support GICv2 on GICv3 when the virtual CPU interface is
+     * at least GUEST_GICC_SIZE.
+     */
+    if ( vsize < GUEST_GICC_SIZE )
+    {
+        printk(XENLOG_WARNING
+               "GICv3: WARNING: Not enabling support for GICv2 compat mode.\n"
+               "Size of GICV (%#"PRIpaddr") must at least be %#llx.\n",
+               vsize, GUEST_GICC_SIZE);
+        return;
+    }
+}
+
+/* Set up the GIC */
+static int __init gicv3_init(void)

xen/arch/arm/gic-v3.c static int __init gicv3_init(void) · line 1256

Quoted 10 lines
xen/arch/arm/gic-v3.c +10 -0
+{
+    int res, i;
+
+    if ( !cpu_has_gicv3 )
+    {
+        dprintk(XENLOG_ERR, "GICv3: driver requires system register support\n");
+        return -ENODEV;
+    }
+
+    dt_gicv3_init();

I think it would be best if we kept iall the ioremap calls here in the common function, instead of duplicating them in the acpi and dt specific init functions.

The GICD_PIDR2 check should common too.

Quoted 30 lines
xen/arch/arm/gic-v3.c +3 -3
     for ( i = 0; i < gicv3.rdist_count; i++ )
     {
         /* map dbase & rdist regions */
@@ -1277,7 +1284,7 @@ static int __init gicv3_init(void)
 
     vgic_v3_setup_hw(dbase, gicv3.rdist_count, gicv3.rdist_regions,
                      gicv3.rdist_stride);
-    gicv3_init_v2(node, dbase);
+    gicv3_init_v2();
 
     spin_lock_init(&gicv3.lock);
 
@@ -1317,7 +1324,7 @@ static const struct gic_hw_operations gicv3_ops = {
     .make_hwdom_dt_node  = gicv3_make_hwdom_dt_node,
 };
 
-static int __init gicv3_preinit(struct dt_device_node *node, const void *data)
+static int __init dt_gicv3_preinit(struct dt_device_node *node, const void *data)
 {
     gicv3_info.hw_version = GIC_V3;
     gicv3_info.node = node;
@@ -1335,7 +1342,7 @@ static const struct dt_device_match gicv3_dt_match[] __initconst =
 
 DT_DEVICE_START(gicv3, "GICv3", DEVICE_GIC)
         .dt_match = gicv3_dt_match,
-        .init = gicv3_preinit,
+        .init = dt_gicv3_preinit,
 DT_DEVICE_END
 
 /*
#120 lore raw

PATCH v3 23/62 acpi/table: Introduce acpi_parse_entries

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Add new function acpi_parse_entries which takes acpi table as argument. This will avoid fetching table everytime in acpi_table_parse_entries. This function will be used in acpi_gicv2_init within another patch.

---
 xen/drivers/acpi/tables.c | 53 ++++++++++++++++++++++++++++++++++-------------
 xen/include/xen/acpi.h    |  3 +++
 2 files changed, 42 insertions(+), 14 deletions(-)
xen/drivers/acpi/tables.c +39 -14
index 6573175..2fba206 100644
@@ -221,29 +221,27 @@ void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	}
 }
 
-
 int __init
-acpi_table_parse_entries(char *id,
-			     unsigned long table_size,
-			     int entry_id,
-			     acpi_table_entry_handler handler,
-			     unsigned int max_entries)
+acpi_parse_entries(char *id,
+		      unsigned long table_size,
+		      acpi_table_entry_handler handler,
+		      struct acpi_table_header *table_header,
+		      int entry_id,
+		      unsigned int max_entries)
 {
-	struct acpi_table_header *table_header = NULL;
 	struct acpi_subtable_header *entry;
 	unsigned int count = 0;
 	unsigned long table_end;
 
-	if (!handler)
+	if ( !handler )
 		return -EINVAL;
 
-	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
-		acpi_get_table(id, acpi_apic_instance, &table_header);
-	else
-		acpi_get_table(id, 0, &table_header);
+	if ( !table_size )
+		return -EINVAL;
 
-	if (!table_header) {
-		printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
+	if ( !table_header )
+	{
+		printk("Table header not present\n");
 		return -ENODEV;
 	}
 
@@ -279,6 +277,33 @@ acpi_table_parse_entries(char *id,
 	}
 
 	return count;
+
+}
+
+int __init
+acpi_table_parse_entries(char *id,
+			     unsigned long table_size,
+			     int entry_id,
+			     acpi_table_entry_handler handler,
+			     unsigned int max_entries)
+{
+	struct acpi_table_header *table_header = NULL;
+
+	if (!handler)
+		return -EINVAL;
+
+	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
+		acpi_get_table(id, acpi_apic_instance, &table_header);
+	else
+		acpi_get_table(id, 0, &table_header);
+
+	if (!table_header) {
+		printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
+		return -ENODEV;
+	}
+
+	return acpi_parse_entries(id, table_size, handler, table_header,
+				  entry_id, max_entries);
 }
 
 int __init
xen/include/xen/acpi.h +3 -0
index 723ece8..23f8261 100644
@@ -72,6 +72,9 @@ int acpi_table_init (void);
 int acpi_table_parse(char *id, acpi_table_handler handler);
 int acpi_table_parse_entries(char *id, unsigned long table_size,
 	int entry_id, acpi_table_entry_handler handler, unsigned int max_entries);
+int acpi_parse_entries(char *id, unsigned long table_size,
+	acpi_table_entry_handler handler, struct acpi_table_header *table_header,
+	int entry_id, unsigned int max_entries);
 int acpi_table_parse_madt(enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries);
 int acpi_table_parse_srat(int id, acpi_madt_entry_handler handler,
 	unsigned int max_entries);
Signature · 1 line
2.1.0
#121 lore raw

PATCH v3 23/62 acpi/table: Introduce acpi_parse_entries

Quoted 10 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:

From: Parth Dixit <[email protected]>

Add new function acpi_parse_entries which takes acpi table as argument. This will avoid fetching table everytime in acpi_table_parse_entries. This function will be used in acpi_gicv2_init within another patch.

Please clarify authorship: From and first S-o-b aren't really in line.

Quoted 12 lines
xen/drivers/acpi/tables.c +0 -4
@@ -221,29 +221,27 @@ void __init acpi_table_print_madt_entry(struct 
 acpi_subtable_header *header)
 	}
 }
 
-
 int __init
-acpi_table_parse_entries(char *id,
-			     unsigned long table_size,
-			     int entry_id,

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct · line 233

Quoted 10 lines
xen/drivers/acpi/tables.c +6 -3
-			     acpi_table_entry_handler handler,
-			     unsigned int max_entries)
+acpi_parse_entries(char *id,
+		      unsigned long table_size,
+		      acpi_table_entry_handler handler,
+		      struct acpi_table_header *table_header,
+		      int entry_id,
+		      unsigned int max_entries)
 {
-	struct acpi_table_header *table_header = NULL;

Looks like Linux has gained similar functionality. Can't you simply pull in one or more Linux commits?

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 236

Quoted 2 lines
xen/drivers/acpi/tables.c +1 -1
-	if (!handler)
+	if ( !handler )

But in any event please don't change the file's coding style.

Jan

#122 lore raw

Re: [PATCH v3 23/62] acpi/table: Introduce acpi_parse_entries

In reply to shannon.zhao at linaro.org
Quoted 10 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:

From: Parth Dixit <[email protected]>

Add new function acpi_parse_entries which takes acpi table as argument. This will avoid fetching table everytime in acpi_table_parse_entries. This function will be used in acpi_gicv2_init within another patch.

Please clarify authorship: From and first S-o-b aren't really in line.

Quoted 12 lines
xen/drivers/acpi/tables.c +0 -4
@@ -221,29 +221,27 @@ void __init acpi_table_print_madt_entry(struct 
 acpi_subtable_header *header)
 	}
 }
 
-
 int __init
-acpi_table_parse_entries(char *id,
-			     unsigned long table_size,
-			     int entry_id,

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct · line 233

Quoted 10 lines
xen/drivers/acpi/tables.c +6 -3
-			     acpi_table_entry_handler handler,
-			     unsigned int max_entries)
+acpi_parse_entries(char *id,
+		      unsigned long table_size,
+		      acpi_table_entry_handler handler,
+		      struct acpi_table_header *table_header,
+		      int entry_id,
+		      unsigned int max_entries)
 {
-	struct acpi_table_header *table_header = NULL;

Looks like Linux has gained similar functionality. Can't you simply pull in one or more Linux commits?

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 236

Quoted 2 lines
xen/drivers/acpi/tables.c +1 -1
-	if (!handler)
+	if ( !handler )

But in any event please don't change the file's coding style.

Jan

#123 lore raw

PATCH v3 24/62 arm: Introduce a generic way to use a device from acpi

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Add generic way to use device from acpi similar to the way it is supported in device tree.

---
 xen/arch/arm/device.c        | 19 +++++++++++++++++++
 xen/arch/arm/xen.lds.S       |  7 +++++++
 xen/include/asm-arm/device.h | 30 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)
xen/arch/arm/device.c +19 -0
index 0b53f6a..5494de0 100644
@@ -22,6 +22,7 @@
 #include <xen/lib.h>
 
 extern const struct device_desc _sdevice[], _edevice[];
+extern const struct acpi_device_desc _asdevice[], _aedevice[];
 
 int __init device_init(struct dt_device_node *dev, enum device_class class,
                        const void *data)
@@ -50,6 +51,24 @@ int __init device_init(struct dt_device_node *dev, enum device_class class,
     return -EBADF;
 }
 
+int __init acpi_device_init(enum device_class class, const void *data, int class_type)
+{
+    const struct acpi_device_desc *desc;
+
+    for ( desc = _asdevice; desc != _aedevice; desc++ )
+    {
+        if ( ( desc->class != class ) && ( desc->class_type != class_type ) )
+            continue;
+
+
+        ASSERT(desc->init != NULL);
+
+        return desc->init(data);
+    }
+
+    return -EBADF;
+}
+
 enum device_class device_get_class(const struct dt_device_node *dev)
 {
     const struct device_desc *desc;
xen/arch/arm/xen.lds.S +7 -0
index 0488f37..60802f6 100644
@@ -100,6 +100,13 @@ SECTIONS
       _edevice = .;
   } :text
 
+  . = ALIGN(8);
+  .adev.info : {
+      _asdevice = .;
+      *(.adev.info)
+      _aedevice = .;
+  } :text
+
   . = ALIGN(PAGE_SIZE);             /* Init code and data */
   __init_begin = .;
   .init.text : {
xen/include/asm-arm/device.h +30 -0
index 5d0a4cd..085f221 100644
@@ -50,6 +50,27 @@ struct device_desc {
     int (*init)(struct dt_device_node *dev, const void *data);
 };
 
+struct acpi_device_desc {
+    /* Device name */
+    const char *name;
+    /* Device class */
+    enum device_class class;
+    /* type of device supported by the driver */
+    const int class_type;
+    /* Device initialization */
+    int (*init)(const void *data);
+};
+
+/**
+ *  acpi_device_init - Initialize a device
+ *  @class: class of the device (serial, network...)
+ *  @data: specific data for initializing the device
+ *
+ *  Return 0 on success.
+ */
+int __init acpi_device_init(enum device_class class,
+                            const void *data, int class_type);
+
 /**
  *  device_init - Initialize a device
  *  @dev: device to initialize
@@ -78,6 +99,15 @@ __section(".dev.info") = {                                          \
 #define DT_DEVICE_END                                               \
 };
 
+#define ACPI_DEVICE_START(_name, _namestr, _class)                    \
+static const struct acpi_device_desc __dev_desc_##_name __used           \
+__attribute__((__section__(".adev.info"))) = {                       \
+    .name = _namestr,                                               \
+    .class = _class,                                                \
+
+#define ACPI_DEVICE_END                                               \
+};
+
 #endif /* __ASM_ARM_DEVICE_H */
 
 /*
Signature · 1 line
2.1.0
#124 lore raw

PATCH v3 24/62 arm: Introduce a generic way to use a device from acpi

Hi Shannon,

Quoted 26 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Add generic way to use device from acpi similar to the way it is supported in device tree.

---
 xen/arch/arm/device.c        | 19 +++++++++++++++++++
 xen/arch/arm/xen.lds.S       |  7 +++++++
 xen/include/asm-arm/device.h | 30 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)
xen/arch/arm/device.c +1 -0
index 0b53f6a..5494de0 100644
@@ -22,6 +22,7 @@
 #include <xen/lib.h>
 
 extern const struct device_desc _sdevice[], _edevice[];
+extern const struct acpi_device_desc _asdevice[], _aedevice[];
 
 int __init device_init(struct dt_device_node *dev, enum device_class class,
                        const void *data)

xen/arch/arm/device.c int __init device_init(struct dt_device_node *dev, enum device_class class, · line 54

Quoted 4 lines
xen/arch/arm/device.c +1 -0
@@ -50,6 +51,24 @@ int __init device_init(struct dt_device_node *dev, enum device_class class,
     return -EBADF;
 }
 
+int __init acpi_device_init(enum device_class class, const void *data, int class_type)

As said on a previous version, please explain what means class_type and how this will fit with every
ACPI device tables.

AFAICT, it does only works for SPCR table used for UART device. For the GIC you've hardcoded the value and I can't find any version number in the table.

You may need to introduce another way to find the device such as a callback taking the table in parameter.

Regards,

Signature · 1 line
Julien Grall
#125 lore raw

PATCH v3 24/62 arm: Introduce a generic way to use a device from acpi

Quoted 38 lines · Julien Grall

Hi Shannon,

Quoted 26 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Add generic way to use device from acpi similar to the way it is supported in device tree.

---
 xen/arch/arm/device.c        | 19 +++++++++++++++++++
 xen/arch/arm/xen.lds.S       |  7 +++++++
 xen/include/asm-arm/device.h | 30 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)
xen/arch/arm/device.c +1 -0
index 0b53f6a..5494de0 100644
@@ -22,6 +22,7 @@
 #include <xen/lib.h>
 
 extern const struct device_desc _sdevice[], _edevice[];
+extern const struct acpi_device_desc _asdevice[], _aedevice[];
 
 int __init device_init(struct dt_device_node *dev, enum device_class class,
                        const void *data)

xen/arch/arm/device.c int __init device_init(struct dt_device_node *dev, enum device_class class, · line 54

Quoted 4 lines
xen/arch/arm/device.c +1 -0
@@ -50,6 +51,24 @@ int __init device_init(struct dt_device_node *dev, enum device_class class,
     return -EBADF;
 }
 
+int __init acpi_device_init(enum device_class class, const void *data, int class_type)

As said on a previous version, please explain what means class_type and how this will fit with every
ACPI device tables.

Quoted 4 lines

AFAICT, it does only works for SPCR table used for UART device. For the GIC you've hardcoded the value and I can't find any version number in the table.

No, I didn't hardcode the GIC version. Since ACPI 6.0 introduces GIC version in generic distributor table, it could get the version from that. Please see [PATCH v3 28/62].

Quoted 3 lines

You may need to introduce another way to find the device such as a callback taking the table in parameter.

Signature · 1 line
Shannon
#126 lore raw

PATCH v3 24/62 arm: Introduce a generic way to use a device from acpi

Quoted 7 lines · Shannon Zhao
Quoted 4 lines

AFAICT, it does only works for SPCR table used for UART device. For the GIC you've hardcoded the value and I can't find any version number in the table.

No, I didn't hardcode the GIC version. Since ACPI 6.0 introduces GIC version in generic distributor table, it could get the version from that. Please see [PATCH v3 28/62].

+ if ( dist->version == ACPI_MADT_GIC_VERSION_V2 )
+ rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V2);
+ else if ( dist->version == ACPI_MADT_GIC_VERSION_V3 )
+ rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V3);

Every single time a new GIC version will be added, we will had to add another else if. I'm sorry but it's what I call hardcoding.

Regards,

Signature · 1 line
Julien Grall
#127 lore raw

PATCH v3 24/62 arm: Introduce a generic way to use a device from acpi

Quoted 14 lines · Julien Grall
Quoted 7 lines · Shannon Zhao
Quoted 4 lines

AFAICT, it does only works for SPCR table used for UART device. For the GIC you've hardcoded the value and I can't find any version number in the table.

No, I didn't hardcode the GIC version. Since ACPI 6.0 introduces GIC version in generic distributor table, it could get the version from that. Please see [PATCH v3 28/62].

(quoted diff) +4 -0
+    if ( dist->version == ACPI_MADT_GIC_VERSION_V2 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V2);
+    else if ( dist->version == ACPI_MADT_GIC_VERSION_V3 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V3);
Quoted 3 lines

Every single time a new GIC version will be added, we will had to add another else if. I'm sorry but it's what I call hardcoding.

Oh, I see. If it uses the enum acpi_madt_gic_version for ACPI GIC not the enum gic_version, it could match 1:1. Something like below:

It uses ACPI_MADT_GIC_VERSION_V2 for GICv2.

ACPI_DEVICE_START(agicv2, "GICv2", DEVICE_GIC)
.class_type = ACPI_MADT_GIC_VERSION_V2,
.init = acpi_gicv2_preinit,
ACPI_DEVICE_END

Then get the GIC version from MADT table and call

acpi_device_init(DEVICE_GIC, NULL, dist->version);

How about this way?

Thanks,

Signature · 1 line
Shannon
#128 lore raw

PATCH v3 24/62 arm: Introduce a generic way to use a device from acpi

Quoted 31 lines · Shannon Zhao
Quoted 14 lines · Julien Grall
Quoted 7 lines · Shannon Zhao
Quoted 4 lines

AFAICT, it does only works for SPCR table used for UART device. For the GIC you've hardcoded the value and I can't find any version number in the table.

No, I didn't hardcode the GIC version. Since ACPI 6.0 introduces GIC version in generic distributor table, it could get the version from that. Please see [PATCH v3 28/62].

(quoted diff) +4 -0
+    if ( dist->version == ACPI_MADT_GIC_VERSION_V2 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V2);
+    else if ( dist->version == ACPI_MADT_GIC_VERSION_V3 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V3);
Quoted 3 lines

Every single time a new GIC version will be added, we will had to add another else if. I'm sorry but it's what I call hardcoding.

Oh, I see. If it uses the enum acpi_madt_gic_version for ACPI GIC not the enum gic_version, it could match 1:1. Something like below:

It uses ACPI_MADT_GIC_VERSION_V2 for GICv2.

ACPI_DEVICE_START(agicv2, "GICv2", DEVICE_GIC)
.class_type = ACPI_MADT_GIC_VERSION_V2,
.init = acpi_gicv2_preinit,
ACPI_DEVICE_END

Quoted 5 lines

Then get the GIC version from MADT table and call

acpi_device_init(DEVICE_GIC, NULL, dist->version);

How about this way?

That would be better. We want the common mode as agnostic as possible from the GIC version.

Regards,

Signature · 1 line
Julien Grall
#129 lore raw

Re: [PATCH v3 24/62] arm: Introduce a generic way to use a device from acpi

In reply to Shannon Zhao
Quoted 31 lines · Shannon Zhao
Quoted 14 lines · Julien Grall
Quoted 7 lines · Shannon Zhao
Quoted 4 lines

AFAICT, it does only works for SPCR table used for UART device. For the GIC you've hardcoded the value and I can't find any version number in the table.

No, I didn't hardcode the GIC version. Since ACPI 6.0 introduces GIC version in generic distributor table, it could get the version from that. Please see [PATCH v3 28/62].

(quoted diff) +4 -0
+    if ( dist->version == ACPI_MADT_GIC_VERSION_V2 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V2);
+    else if ( dist->version == ACPI_MADT_GIC_VERSION_V3 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V3);
Quoted 3 lines

Every single time a new GIC version will be added, we will had to add another else if. I'm sorry but it's what I call hardcoding.

Oh, I see. If it uses the enum acpi_madt_gic_version for ACPI GIC not the enum gic_version, it could match 1:1. Something like below:

It uses ACPI_MADT_GIC_VERSION_V2 for GICv2.

ACPI_DEVICE_START(agicv2, "GICv2", DEVICE_GIC)
.class_type = ACPI_MADT_GIC_VERSION_V2,
.init = acpi_gicv2_preinit,
ACPI_DEVICE_END

Quoted 5 lines

Then get the GIC version from MADT table and call

acpi_device_init(DEVICE_GIC, NULL, dist->version);

How about this way?

That would be better. We want the common mode as agnostic as possible from the GIC version.

Regards,

Signature · 1 line
Julien Grall
#130 lore raw

Re: [PATCH v3 24/62] arm: Introduce a generic way to use a device from acpi

In reply to Julien Grall
Quoted 14 lines · Julien Grall
Quoted 7 lines · Shannon Zhao
Quoted 4 lines

AFAICT, it does only works for SPCR table used for UART device. For the GIC you've hardcoded the value and I can't find any version number in the table.

No, I didn't hardcode the GIC version. Since ACPI 6.0 introduces GIC version in generic distributor table, it could get the version from that. Please see [PATCH v3 28/62].

(quoted diff) +4 -0
+    if ( dist->version == ACPI_MADT_GIC_VERSION_V2 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V2);
+    else if ( dist->version == ACPI_MADT_GIC_VERSION_V3 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V3);
Quoted 3 lines

Every single time a new GIC version will be added, we will had to add another else if. I'm sorry but it's what I call hardcoding.

Oh, I see. If it uses the enum acpi_madt_gic_version for ACPI GIC not the enum gic_version, it could match 1:1. Something like below:

It uses ACPI_MADT_GIC_VERSION_V2 for GICv2.

ACPI_DEVICE_START(agicv2, "GICv2", DEVICE_GIC)
.class_type = ACPI_MADT_GIC_VERSION_V2,
.init = acpi_gicv2_preinit,
ACPI_DEVICE_END

Then get the GIC version from MADT table and call

acpi_device_init(DEVICE_GIC, NULL, dist->version);

How about this way?

Thanks,

Signature · 1 line
Shannon
#131 lore raw

Re: [PATCH v3 24/62] arm: Introduce a generic way to use a device from acpi

In reply to Shannon Zhao
Quoted 7 lines · Shannon Zhao
Quoted 4 lines

AFAICT, it does only works for SPCR table used for UART device. For the GIC you've hardcoded the value and I can't find any version number in the table.

No, I didn't hardcode the GIC version. Since ACPI 6.0 introduces GIC version in generic distributor table, it could get the version from that. Please see [PATCH v3 28/62].

+ if ( dist->version == ACPI_MADT_GIC_VERSION_V2 )
+ rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V2);
+ else if ( dist->version == ACPI_MADT_GIC_VERSION_V3 )
+ rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V3);

Every single time a new GIC version will be added, we will had to add another else if. I'm sorry but it's what I call hardcoding.

Regards,

Signature · 1 line
Julien Grall
#132 lore raw

Re: [PATCH v3 24/62] arm: Introduce a generic way to use a device from acpi

In reply to Julien Grall
Quoted 38 lines · Julien Grall

Hi Shannon,

Quoted 26 lines · On 17/11/15 09:40, [email protected] wrote:

From: Parth Dixit <[email protected]>

Add generic way to use device from acpi similar to the way it is supported in device tree.

---
 xen/arch/arm/device.c        | 19 +++++++++++++++++++
 xen/arch/arm/xen.lds.S       |  7 +++++++
 xen/include/asm-arm/device.h | 30 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)
xen/arch/arm/device.c +1 -0
index 0b53f6a..5494de0 100644
@@ -22,6 +22,7 @@
 #include <xen/lib.h>
 
 extern const struct device_desc _sdevice[], _edevice[];
+extern const struct acpi_device_desc _asdevice[], _aedevice[];
 
 int __init device_init(struct dt_device_node *dev, enum device_class class,
                        const void *data)

xen/arch/arm/device.c int __init device_init(struct dt_device_node *dev, enum device_class class, · line 54

Quoted 4 lines
xen/arch/arm/device.c +1 -0
@@ -50,6 +51,24 @@ int __init device_init(struct dt_device_node *dev, enum device_class class,
     return -EBADF;
 }
 
+int __init acpi_device_init(enum device_class class, const void *data, int class_type)

As said on a previous version, please explain what means class_type and how this will fit with every
ACPI device tables.

Quoted 4 lines

AFAICT, it does only works for SPCR table used for UART device. For the GIC you've hardcoded the value and I can't find any version number in the table.

No, I didn't hardcode the GIC version. Since ACPI 6.0 introduces GIC version in generic distributor table, it could get the version from that. Please see [PATCH v3 28/62].

Quoted 3 lines

You may need to introduce another way to find the device such as a callback taking the table in parameter.

Signature · 1 line
Shannon
#133 lore raw

Re: [PATCH v3 24/62] arm: Introduce a generic way to use a device from acpi

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 26 lines · On 17/11/15 09:40, [email protected] wrote:

From: Parth Dixit <[email protected]>

Add generic way to use device from acpi similar to the way it is supported in device tree.

---
 xen/arch/arm/device.c        | 19 +++++++++++++++++++
 xen/arch/arm/xen.lds.S       |  7 +++++++
 xen/include/asm-arm/device.h | 30 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)
xen/arch/arm/device.c +1 -0
index 0b53f6a..5494de0 100644
@@ -22,6 +22,7 @@
 #include <xen/lib.h>
 
 extern const struct device_desc _sdevice[], _edevice[];
+extern const struct acpi_device_desc _asdevice[], _aedevice[];
 
 int __init device_init(struct dt_device_node *dev, enum device_class class,
                        const void *data)

xen/arch/arm/device.c int __init device_init(struct dt_device_node *dev, enum device_class class, · line 54

Quoted 4 lines
xen/arch/arm/device.c +1 -0
@@ -50,6 +51,24 @@ int __init device_init(struct dt_device_node *dev, enum device_class class,
     return -EBADF;
 }
 
+int __init acpi_device_init(enum device_class class, const void *data, int class_type)

As said on a previous version, please explain what means class_type and how this will fit with every
ACPI device tables.

AFAICT, it does only works for SPCR table used for UART device. For the GIC you've hardcoded the value and I can't find any version number in the table.

You may need to introduce another way to find the device such as a callback taking the table in parameter.

Regards,

Signature · 1 line
Julien Grall
#134 lore raw

PATCH v3 24/62 arm: Introduce a generic way to use a device from acpi

In reply to shannon.zhao at linaro.org
Quoted 27 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Add generic way to use device from acpi similar to the way it is supported in device tree.

---
 xen/arch/arm/device.c        | 19 +++++++++++++++++++
 xen/arch/arm/xen.lds.S       |  7 +++++++
 xen/include/asm-arm/device.h | 30 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)
xen/arch/arm/device.c +1 -0
index 0b53f6a..5494de0 100644
@@ -22,6 +22,7 @@
 #include <xen/lib.h>
 
 extern const struct device_desc _sdevice[], _edevice[];
+extern const struct acpi_device_desc _asdevice[], _aedevice[];
 
 int __init device_init(struct dt_device_node *dev, enum device_class class,
                        const void *data)
@@ -50,6 +51,24 @@ int __init device_init(struct dt_device_node *dev, enum device_class class,
     return -EBADF;

xen/arch/arm/device.c int __init device_init(struct dt_device_node *dev, enum device_class class, · line 61

Quoted 10 lines
xen/arch/arm/device.c +8 -0
 }
 
+int __init acpi_device_init(enum device_class class, const void *data, int class_type)
+{
+    const struct acpi_device_desc *desc;
+
+    for ( desc = _asdevice; desc != _aedevice; desc++ )
+    {
+        if ( ( desc->class != class ) && ( desc->class_type != class_type ) )
+            continue;

Shouldn't this be

  if ( ( desc->class != class ) || ( desc->class_type != class_type ) )

?

Quoted 63 lines
xen/arch/arm/device.c +9 -0
+
+        ASSERT(desc->init != NULL);
+
+        return desc->init(data);
+    }
+
+    return -EBADF;
+}
+
 enum device_class device_get_class(const struct dt_device_node *dev)
 {
     const struct device_desc *desc;
xen/arch/arm/xen.lds.S +7 -0
index 0488f37..60802f6 100644
@@ -100,6 +100,13 @@ SECTIONS
       _edevice = .;
   } :text
 
+  . = ALIGN(8);
+  .adev.info : {
+      _asdevice = .;
+      *(.adev.info)
+      _aedevice = .;
+  } :text
+
   . = ALIGN(PAGE_SIZE);             /* Init code and data */
   __init_begin = .;
   .init.text : {
xen/include/asm-arm/device.h +21 -0
index 5d0a4cd..085f221 100644
@@ -50,6 +50,27 @@ struct device_desc {
     int (*init)(struct dt_device_node *dev, const void *data);
 };
 
+struct acpi_device_desc {
+    /* Device name */
+    const char *name;
+    /* Device class */
+    enum device_class class;
+    /* type of device supported by the driver */
+    const int class_type;
+    /* Device initialization */
+    int (*init)(const void *data);
+};
+
+/**
+ *  acpi_device_init - Initialize a device
+ *  @class: class of the device (serial, network...)
+ *  @data: specific data for initializing the device
+ *
+ *  Return 0 on success.
+ */
+int __init acpi_device_init(enum device_class class,
+                            const void *data, int class_type);
+
 /**
  *  device_init - Initialize a device
  *  @dev: device to initialize

xen/include/asm-arm/device.h __section(".dev.info") = { \ · line 104

Quoted 6 lines
xen/include/asm-arm/device.h +3 -0
@@ -78,6 +99,15 @@ __section(".dev.info") = {                                          \
 #define DT_DEVICE_END                                               \
 };
 
+#define ACPI_DEVICE_START(_name, _namestr, _class)                    \
+static const struct acpi_device_desc __dev_desc_##_name __used           \
+__attribute__((__section__(".adev.info"))) = {                       \

why __attribute__?

Quoted 18 lines
xen/include/asm-arm/device.h +6 -0
+    .name = _namestr,                                               \
+    .class = _class,                                                \
+
+#define ACPI_DEVICE_END                                               \
+};
+
 #endif /* __ASM_ARM_DEVICE_H */
 
 /*
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel at lists.xen.org
http://lists.xen.org/xen-devel
#135 lore raw

Re: [PATCH v3 24/62] arm: Introduce a generic way to use a device from acpi

In reply to shannon.zhao at linaro.org
Quoted 27 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

Add generic way to use device from acpi similar to the way it is supported in device tree.

---
 xen/arch/arm/device.c        | 19 +++++++++++++++++++
 xen/arch/arm/xen.lds.S       |  7 +++++++
 xen/include/asm-arm/device.h | 30 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)
xen/arch/arm/device.c +1 -0
index 0b53f6a..5494de0 100644
@@ -22,6 +22,7 @@
 #include <xen/lib.h>
 
 extern const struct device_desc _sdevice[], _edevice[];
+extern const struct acpi_device_desc _asdevice[], _aedevice[];
 
 int __init device_init(struct dt_device_node *dev, enum device_class class,
                        const void *data)
@@ -50,6 +51,24 @@ int __init device_init(struct dt_device_node *dev, enum device_class class,
     return -EBADF;

xen/arch/arm/device.c int __init device_init(struct dt_device_node *dev, enum device_class class, · line 61

Quoted 10 lines
xen/arch/arm/device.c +8 -0
 }
 
+int __init acpi_device_init(enum device_class class, const void *data, int class_type)
+{
+    const struct acpi_device_desc *desc;
+
+    for ( desc = _asdevice; desc != _aedevice; desc++ )
+    {
+        if ( ( desc->class != class ) && ( desc->class_type != class_type ) )
+            continue;

Shouldn't this be

  if ( ( desc->class != class ) || ( desc->class_type != class_type ) )

?

Quoted 63 lines
xen/arch/arm/device.c +9 -0
+
+        ASSERT(desc->init != NULL);
+
+        return desc->init(data);
+    }
+
+    return -EBADF;
+}
+
 enum device_class device_get_class(const struct dt_device_node *dev)
 {
     const struct device_desc *desc;
xen/arch/arm/xen.lds.S +7 -0
index 0488f37..60802f6 100644
@@ -100,6 +100,13 @@ SECTIONS
       _edevice = .;
   } :text
 
+  . = ALIGN(8);
+  .adev.info : {
+      _asdevice = .;
+      *(.adev.info)
+      _aedevice = .;
+  } :text
+
   . = ALIGN(PAGE_SIZE);             /* Init code and data */
   __init_begin = .;
   .init.text : {
xen/include/asm-arm/device.h +21 -0
index 5d0a4cd..085f221 100644
@@ -50,6 +50,27 @@ struct device_desc {
     int (*init)(struct dt_device_node *dev, const void *data);
 };
 
+struct acpi_device_desc {
+    /* Device name */
+    const char *name;
+    /* Device class */
+    enum device_class class;
+    /* type of device supported by the driver */
+    const int class_type;
+    /* Device initialization */
+    int (*init)(const void *data);
+};
+
+/**
+ *  acpi_device_init - Initialize a device
+ *  @class: class of the device (serial, network...)
+ *  @data: specific data for initializing the device
+ *
+ *  Return 0 on success.
+ */
+int __init acpi_device_init(enum device_class class,
+                            const void *data, int class_type);
+
 /**
  *  device_init - Initialize a device
  *  @dev: device to initialize

xen/include/asm-arm/device.h __section(".dev.info") = { \ · line 104

Quoted 6 lines
xen/include/asm-arm/device.h +3 -0
@@ -78,6 +99,15 @@ __section(".dev.info") = {                                          \
 #define DT_DEVICE_END                                               \
 };
 
+#define ACPI_DEVICE_START(_name, _namestr, _class)                    \
+static const struct acpi_device_desc __dev_desc_##_name __used           \
+__attribute__((__section__(".adev.info"))) = {                       \

why __attribute__?

Quoted 18 lines
xen/include/asm-arm/device.h +6 -0
+    .name = _namestr,                                               \
+    .class = _class,                                                \
+
+#define ACPI_DEVICE_END                                               \
+};
+
 #endif /* __ASM_ARM_DEVICE_H */
 
 /*
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#136 lore raw

PATCH v3 25/62 acpi/table: Introduce acpi_get_entry to get specified entry

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

When constructing MADT table for Dom0, it needs to create GICC subtable according to the dom0_max_vcpus. This function could be used for get the specified entry.

---
 xen/drivers/acpi/tables.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/xen/acpi.h    |  4 ++++
 2 files changed, 49 insertions(+)
xen/drivers/acpi/tables.c +45 -0
index 2fba206..3ba8bad 100644
@@ -221,6 +221,51 @@ void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	}
 }
 
+struct acpi_subtable_header * __init
+acpi_get_entry(char *id, unsigned long table_size,
+	       struct acpi_table_header *table_header, int entry_id,
+	       unsigned int entry_index)
+{
+	struct acpi_subtable_header *entry;
+	unsigned int count = 0;
+	unsigned long table_end;
+
+	if ( !table_size )
+		return NULL;
+
+	if ( !table_header )
+	{
+		printk("Table header not present\n");
+		return NULL;
+	}
+
+	table_end = (unsigned long)table_header + table_header->length;
+
+	/* Parse all entries looking for a match. */
+	entry = (struct acpi_subtable_header *)
+	    ((unsigned long)table_header + table_size);
+
+	while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
+	       table_end) {
+		if (entry->length < sizeof(*entry)) {
+			printk(KERN_ERR PREFIX "[%4.4s:%#x] Invalid length\n",
+			       id, entry_id);
+			return NULL;
+		}
+
+		if (entry->type == entry_id) {
+			if (count == entry_index)
+				return entry;
+			count++;
+		}
+
+		entry = (struct acpi_subtable_header *)
+		    ((unsigned long)entry + entry->length);
+	}
+
+	return NULL;
+}
+
 int __init
 acpi_parse_entries(char *id,
 		      unsigned long table_size,
xen/include/xen/acpi.h +4 -0
index 23f8261..3339374 100644
@@ -72,6 +72,10 @@ int acpi_table_init (void);
 int acpi_table_parse(char *id, acpi_table_handler handler);
 int acpi_table_parse_entries(char *id, unsigned long table_size,
 	int entry_id, acpi_table_entry_handler handler, unsigned int max_entries);
+struct acpi_subtable_header *
+acpi_get_entry(char *id, unsigned long table_size,
+	       struct acpi_table_header *table_header, int entry_id,
+	       unsigned int entry_index);
 int acpi_parse_entries(char *id, unsigned long table_size,
 	acpi_table_entry_handler handler, struct acpi_table_header *table_header,
 	int entry_id, unsigned int max_entries);
Signature · 1 line
2.1.0
#137 lore raw

PATCH v3 25/62 acpi/table: Introduce acpi_get_entry to get specified entry

Quoted 7 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/drivers/acpi/tables.c +0 -0
@@ -221,6 +221,51 @@ void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	}
 }
 

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 233

Quoted 10 lines
xen/drivers/acpi/tables.c +10 -0
+struct acpi_subtable_header * __init
+acpi_get_entry(char *id, unsigned long table_size,
+	       struct acpi_table_header *table_header, int entry_id,
+	       unsigned int entry_index)
+{
+	struct acpi_subtable_header *entry;
+	unsigned int count = 0;
+	unsigned long table_end;
+
+	if ( !table_size )

Linux coding style please in this file.

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 242

Quoted 9 lines
xen/drivers/acpi/tables.c +9 -0
+		return NULL;
+
+	if ( !table_header )
+	{
+		printk("Table header not present\n");
+		return NULL;
+	}
+
+	table_end = (unsigned long)table_header + table_header->length;

So here you use ->length, ...

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 246

Quoted 3 lines
xen/drivers/acpi/tables.c +3 -0
+	/* Parse all entries looking for a match. */
+	entry = (struct acpi_subtable_header *)
+	    ((unsigned long)table_header + table_size);

... but here table_size. Why?

Jan

#138 lore raw

PATCH v3 25/62 acpi/table: Introduce acpi_get_entry to get specified entry

Quoted 7 lines · Jan Beulich
Quoted 7 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/drivers/acpi/tables.c +0 -0
@@ -221,6 +221,51 @@ void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	}
 }
 
Quoted 13 lines

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 233

Quoted 10 lines
xen/drivers/acpi/tables.c +10 -0
+struct acpi_subtable_header * __init
+acpi_get_entry(char *id, unsigned long table_size,
+	       struct acpi_table_header *table_header, int entry_id,
+	       unsigned int entry_index)
+{
+	struct acpi_subtable_header *entry;
+	unsigned int count = 0;
+	unsigned long table_end;
+
+	if ( !table_size )

Linux coding style please in this file.

Sure.

Quoted 12 lines

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 242

Quoted 9 lines
xen/drivers/acpi/tables.c +9 -0
+		return NULL;
+
+	if ( !table_header )
+	{
+		printk("Table header not present\n");
+		return NULL;
+	}
+
+	table_end = (unsigned long)table_header + table_header->length;

So here you use ->length, ...

Quoted 6 lines

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 246

Quoted 3 lines
xen/drivers/acpi/tables.c +3 -0
+	/* Parse all entries looking for a match. */
+	entry = (struct acpi_subtable_header *)
+	    ((unsigned long)table_header + table_size);

... but here table_size. Why?

Here it just skips the main table size at the beginning. Then it could point to the start of sub-table.
For example, to MADT table, the table_size is sizeof(struct acpi_table_madt).

Thanks,

Signature · 1 line
Shannon
#139 lore raw

PATCH v3 25/62 acpi/table: Introduce acpi_get_entry to get specified entry

Quoted 19 lines
Quoted 1 line
Quoted 1 line · On 24.11.15 at 04:08, <[email protected]> wrote:
Quoted 11 lines · Jan Beulich

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 242

Quoted 8 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/drivers/acpi/tables.c +7 -0
+	if ( !table_header )
+	{
+		printk("Table header not present\n");
+		return NULL;
+	}
+
+	table_end = (unsigned long)table_header + table_header->length;

So here you use ->length, ...

Quoted 6 lines

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 246

Quoted 3 lines
xen/drivers/acpi/tables.c +3 -0
+	/* Parse all entries looking for a match. */
+	entry = (struct acpi_subtable_header *)
+	    ((unsigned long)table_header + table_size);

... but here table_size. Why?

Quoted 4 lines

Here it just skips the main table size at the beginning. Then it could point to the start of sub-table.
For example, to MADT table, the table_size is sizeof(struct acpi_table_madt).

Well, but for one then the parameter name is kind of wrong, and second - is it really reasonable for the caller to tell the function?

Jan

#140 lore raw

PATCH v3 25/62 acpi/table: Introduce acpi_get_entry to get specified entry

Quoted 19 lines · Jan Beulich
Quoted 19 lines
Quoted 1 line
Quoted 1 line · On 24.11.15 at 04:08, <[email protected]> wrote:
Quoted 17 lines · Jan Beulich

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 242

Quoted 8 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/drivers/acpi/tables.c +7 -0
+	if ( !table_header )
+	{
+		printk("Table header not present\n");
+		return NULL;
+	}
+
+	table_end = (unsigned long)table_header + table_header->length;

So here you use ->length, ...

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 246

Quoted 3 lines
xen/drivers/acpi/tables.c +3 -0
+	/* Parse all entries looking for a match. */
+	entry = (struct acpi_subtable_header *)
+	    ((unsigned long)table_header + table_size);

... but here table_size. Why?

Quoted 8 lines
Quoted 4 lines

Here it just skips the main table size at the beginning. Then it could point to the start of sub-table.
For example, to MADT table, the table_size is sizeof(struct acpi_table_madt).

Well, but for one then the parameter name is kind of wrong, and second - is it really reasonable for the caller to tell the function?

I think the caller knows which table it wants to parse and could calculate the size. But within this function, there is no clue to get the main table size.

Thanks,

Signature · 1 line
Shannon
#141 lore raw

PATCH v3 25/62 acpi/table: Introduce acpi_get_entry to get specified entry

Quoted 26 lines
Quoted 1 line
Quoted 1 line · On 24.11.15 at 08:48, <[email protected]> wrote:
Quoted 24 lines · Jan Beulich
Quoted 23 lines
Quoted 1 line
Quoted 1 line · On 24.11.15 at 04:08, <[email protected]> wrote:
Quoted 11 lines · Jan Beulich

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 242

Quoted 8 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/drivers/acpi/tables.c +7 -0
+	if ( !table_header )
+	{
+		printk("Table header not present\n");
+		return NULL;
+	}
+
+	table_end = (unsigned long)table_header + table_header->length;

So here you use ->length, ...

Quoted 6 lines

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 246

Quoted 3 lines
xen/drivers/acpi/tables.c +3 -0
+	/* Parse all entries looking for a match. */
+	entry = (struct acpi_subtable_header *)
+	    ((unsigned long)table_header + table_size);

... but here table_size. Why?

Here it just skips the main table size at the beginning. Then it could point to the start of sub-table.
For example, to MADT table, the table_size is sizeof(struct acpi_table_madt).

Quoted 6 lines
Quoted 3 lines

Well, but for one then the parameter name is kind of wrong, and second - is it really reasonable for the caller to tell the function?

I think the caller knows which table it wants to parse and could calculate the size. But within this function, there is no clue to get the main table size.

Well, yes and no: acpi_table_parse_entries() also gets table_size passed in, but all its callers live under xen/drivers/acpi/. Hence it's basically an internal ACPI interface with its declaration misplaced. Thus the question is where the callers of the new interface you add will end up living. If this is going to be a similarly internal interface, then I'm fine. If you mean to add callers under xen/arch/arm/, then I'm afraid I'm going to NAK this patch.

(And yes, I'd welcome a patch to introduce an internal header under xen/drivers/acpi/ to hold declarations and definitions which aren't supposed to be used outside that sub-tree.)

Jan

#142 lore raw

Re: [PATCH v3 25/62] acpi/table: Introduce acpi_get_entry to get specified entry

In reply to Shannon Zhao
Quoted 26 lines
Quoted 1 line
Quoted 1 line · On 24.11.15 at 08:48, <[email protected]> wrote:
Quoted 24 lines · Jan Beulich
Quoted 23 lines
Quoted 1 line
Quoted 1 line · On 24.11.15 at 04:08, <[email protected]> wrote:
Quoted 11 lines · Jan Beulich

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 242

Quoted 8 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/drivers/acpi/tables.c +7 -0
+	if ( !table_header )
+	{
+		printk("Table header not present\n");
+		return NULL;
+	}
+
+	table_end = (unsigned long)table_header + table_header->length;

So here you use ->length, ...

Quoted 6 lines

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 246

Quoted 3 lines
xen/drivers/acpi/tables.c +3 -0
+	/* Parse all entries looking for a match. */
+	entry = (struct acpi_subtable_header *)
+	    ((unsigned long)table_header + table_size);

... but here table_size. Why?

Here it just skips the main table size at the beginning. Then it could point to the start of sub-table.
For example, to MADT table, the table_size is sizeof(struct acpi_table_madt).

Quoted 6 lines
Quoted 3 lines

Well, but for one then the parameter name is kind of wrong, and second - is it really reasonable for the caller to tell the function?

I think the caller knows which table it wants to parse and could calculate the size. But within this function, there is no clue to get the main table size.

Well, yes and no: acpi_table_parse_entries() also gets table_size passed in, but all its callers live under xen/drivers/acpi/. Hence it's basically an internal ACPI interface with its declaration misplaced. Thus the question is where the callers of the new interface you add will end up living. If this is going to be a similarly internal interface, then I'm fine. If you mean to add callers under xen/arch/arm/, then I'm afraid I'm going to NAK this patch.

(And yes, I'd welcome a patch to introduce an internal header under xen/drivers/acpi/ to hold declarations and definitions which aren't supposed to be used outside that sub-tree.)

Jan

#143 lore raw

Re: [PATCH v3 25/62] acpi/table: Introduce acpi_get_entry to get specified entry

In reply to Jan Beulich
Quoted 19 lines · Jan Beulich
Quoted 19 lines
Quoted 1 line
Quoted 1 line · On 24.11.15 at 04:08, <[email protected]> wrote:
Quoted 17 lines · Jan Beulich

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 242

Quoted 8 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/drivers/acpi/tables.c +7 -0
+	if ( !table_header )
+	{
+		printk("Table header not present\n");
+		return NULL;
+	}
+
+	table_end = (unsigned long)table_header + table_header->length;

So here you use ->length, ...

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 246

Quoted 3 lines
xen/drivers/acpi/tables.c +3 -0
+	/* Parse all entries looking for a match. */
+	entry = (struct acpi_subtable_header *)
+	    ((unsigned long)table_header + table_size);

... but here table_size. Why?

Quoted 8 lines
Quoted 4 lines

Here it just skips the main table size at the beginning. Then it could point to the start of sub-table.
For example, to MADT table, the table_size is sizeof(struct acpi_table_madt).

Well, but for one then the parameter name is kind of wrong, and second - is it really reasonable for the caller to tell the function?

I think the caller knows which table it wants to parse and could calculate the size. But within this function, there is no clue to get the main table size.

Thanks,

Signature · 1 line
Shannon
#144 lore raw

Re: [PATCH v3 25/62] acpi/table: Introduce acpi_get_entry to get specified entry

In reply to Shannon Zhao
Quoted 19 lines
Quoted 1 line
Quoted 1 line · On 24.11.15 at 04:08, <[email protected]> wrote:
Quoted 11 lines · Jan Beulich

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 242

Quoted 8 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/drivers/acpi/tables.c +7 -0
+	if ( !table_header )
+	{
+		printk("Table header not present\n");
+		return NULL;
+	}
+
+	table_end = (unsigned long)table_header + table_header->length;

So here you use ->length, ...

Quoted 6 lines

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 246

Quoted 3 lines
xen/drivers/acpi/tables.c +3 -0
+	/* Parse all entries looking for a match. */
+	entry = (struct acpi_subtable_header *)
+	    ((unsigned long)table_header + table_size);

... but here table_size. Why?

Quoted 4 lines

Here it just skips the main table size at the beginning. Then it could point to the start of sub-table.
For example, to MADT table, the table_size is sizeof(struct acpi_table_madt).

Well, but for one then the parameter name is kind of wrong, and second - is it really reasonable for the caller to tell the function?

Jan

#145 lore raw

Re: [PATCH v3 25/62] acpi/table: Introduce acpi_get_entry to get specified entry

In reply to Jan Beulich
Quoted 7 lines · Jan Beulich
Quoted 7 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/drivers/acpi/tables.c +0 -0
@@ -221,6 +221,51 @@ void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	}
 }
 
Quoted 13 lines

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 233

Quoted 10 lines
xen/drivers/acpi/tables.c +10 -0
+struct acpi_subtable_header * __init
+acpi_get_entry(char *id, unsigned long table_size,
+	       struct acpi_table_header *table_header, int entry_id,
+	       unsigned int entry_index)
+{
+	struct acpi_subtable_header *entry;
+	unsigned int count = 0;
+	unsigned long table_end;
+
+	if ( !table_size )

Linux coding style please in this file.

Sure.

Quoted 12 lines

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 242

Quoted 9 lines
xen/drivers/acpi/tables.c +9 -0
+		return NULL;
+
+	if ( !table_header )
+	{
+		printk("Table header not present\n");
+		return NULL;
+	}
+
+	table_end = (unsigned long)table_header + table_header->length;

So here you use ->length, ...

Quoted 6 lines

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 246

Quoted 3 lines
xen/drivers/acpi/tables.c +3 -0
+	/* Parse all entries looking for a match. */
+	entry = (struct acpi_subtable_header *)
+	    ((unsigned long)table_header + table_size);

... but here table_size. Why?

Here it just skips the main table size at the beginning. Then it could point to the start of sub-table.
For example, to MADT table, the table_size is sizeof(struct acpi_table_madt).

Thanks,

Signature · 1 line
Shannon
#146 lore raw

Re: [PATCH v3 25/62] acpi/table: Introduce acpi_get_entry to get specified entry

In reply to shannon.zhao at linaro.org
Quoted 7 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/drivers/acpi/tables.c +0 -0
@@ -221,6 +221,51 @@ void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	}
 }
 

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 233

Quoted 10 lines
xen/drivers/acpi/tables.c +10 -0
+struct acpi_subtable_header * __init
+acpi_get_entry(char *id, unsigned long table_size,
+	       struct acpi_table_header *table_header, int entry_id,
+	       unsigned int entry_index)
+{
+	struct acpi_subtable_header *entry;
+	unsigned int count = 0;
+	unsigned long table_end;
+
+	if ( !table_size )

Linux coding style please in this file.

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 242

Quoted 9 lines
xen/drivers/acpi/tables.c +9 -0
+		return NULL;
+
+	if ( !table_header )
+	{
+		printk("Table header not present\n");
+		return NULL;
+	}
+
+	table_end = (unsigned long)table_header + table_header->length;

So here you use ->length, ...

xen/drivers/acpi/tables.c void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header) · line 246

Quoted 3 lines
xen/drivers/acpi/tables.c +3 -0
+	/* Parse all entries looking for a match. */
+	entry = (struct acpi_subtable_header *)
+	    ((unsigned long)table_header + table_size);

... but here table_size. Why?

Jan

#147 lore raw

PATCH v3 26/62 arm/gic-v2: Add ACPI boot support for GICv2

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

ACPI on Xen hypervisor uses MADT table for proper GIC initialization. First get the GIC version from GIC Distributor. Then parse GIC related subtables, collect CPU interface and distributor addresses and call driver initialization function (which is hardware abstraction agnostic). In a similar way, FDT initialize GICv2.

---
 xen/arch/arm/gic-v2.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 121 insertions(+), 1 deletion(-)
xen/arch/arm/gic-v2.c +121 -1
index e31d38e..9a9fcd5 100644
@@ -29,6 +29,8 @@
 #include <xen/device_tree.h>
 #include <xen/libfdt/libfdt.h>
 #include <xen/sizes.h>
+#include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <asm/p2m.h>
 #include <asm/domain.h>
 #include <asm/platform.h>
@@ -36,6 +38,7 @@
 
 #include <asm/io.h>
 #include <asm/gic.h>
+#include <asm/acpi.h>
 
 /*
  * LR register definitions are GIC v2 specific.
@@ -681,11 +684,113 @@ static void __init dt_gicv2_init(void)
                csize, vsize);
 }
 
+#ifdef CONFIG_ACPI
+static int __init
+gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
+                        const unsigned long end)
+{
+    static int cpu_base_assigned = 0;
+    struct acpi_madt_generic_interrupt *processor;
+
+    processor = (struct acpi_madt_generic_interrupt *)header;
+
+    if ( BAD_MADT_ENTRY(processor, end) )
+        return -EINVAL;
+
+    /* Read from APIC table and fill up the GIC variables */
+    if ( cpu_base_assigned == 0 )
+    {
+        cbase = processor->base_address;
+        csize = SZ_8K;
+        hbase = processor->gich_base_address;
+        vbase = processor->gicv_base_address;
+        gicv2_info.maintenance_irq = processor->vgic_interrupt;
+
+        if( processor->flags & ACPI_MADT_VGIC_IRQ_MODE )
+            irq_set_type(gicv2_info.maintenance_irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+        else
+            irq_set_type(gicv2_info.maintenance_irq, ACPI_IRQ_TYPE_LEVEL_MASK);
+
+	cpu_base_assigned = 1;
+    }
+    else
+    {
+        if ( cbase != processor->base_address
+             || hbase != processor->gich_base_address
+             || vbase != processor->gicv_base_address
+             || gicv2_info.maintenance_irq != processor->vgic_interrupt )
+        {
+	    printk("GICv2: GICC entries are not same in MADT table\n");
+	    return -EINVAL;
+        }
+    }
+
+    return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
+                                const unsigned long end)
+{
+    struct acpi_madt_generic_distributor *dist;
+
+    dist = (struct acpi_madt_generic_distributor *)header;
+
+    if ( BAD_MADT_ENTRY(dist, end) )
+        return -EINVAL;
+
+    dbase = dist->base_address;
+
+    return 0;
+}
+
+static void __init acpi_gicv2_init(void)
+{
+    acpi_status status;
+    struct acpi_table_header *table;
+    int count;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        panic("GICv2: Failed to get MADT table, %s", msg);
+    }
+
+    /* Collect CPU base addresses */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_parse_madt_cpu, table,
+                               ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
+    if ( count <= 0 )
+        panic("GICv2: No valid GICC entries exists");
+
+    /*
+     * Find distributor base address. We expect one distributor entry since
+     * ACPI 5.0 spec neither support multi-GIC instances nor GIC cascade.
+     */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_parse_madt_distributor, table,
+                               ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+    if ( count <= 0 )
+        panic("GICv2: No valid GICD entries exists");
+}
+#else
+static void __init acpi_gicv2_init(void)
+{
+/* Should never reach here */
+}
+#endif
+
 static int __init gicv2_init(void)
 {
     uint32_t aliased_offset = 0;
 
-    dt_gicv2_init();
+    if( acpi_disabled )
+        dt_gicv2_init();
+    else
+        acpi_gicv2_init();
 
     printk("GICv2 initialization:\n"
               "        gic_dist_addr=%"PRIpaddr"\n"
@@ -793,6 +898,21 @@ DT_DEVICE_START(gicv2, "GICv2", DEVICE_GIC)
         .init = dt_gicv2_preinit,
 DT_DEVICE_END
 
+#ifdef CONFIG_ACPI
+/* Set up the GIC */
+static int __init acpi_gicv2_preinit(const void *data)
+{
+    gicv2_info.hw_version = GIC_V2;
+    register_gic_ops(&gicv2_ops);
+
+    return 0;
+}
+
+ACPI_DEVICE_START(agicv2, "GICv2", DEVICE_GIC)
+        .class_type = GIC_V2,
+        .init = acpi_gicv2_preinit,
+ACPI_DEVICE_END
+#endif
 /*
  * Local variables:
  * mode: C
Signature · 1 line
2.1.0
#148 lore raw

PATCH v3 26/62 arm/gic-v2: Add ACPI boot support for GICv2

Quoted 41 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

ACPI on Xen hypervisor uses MADT table for proper GIC initialization. First get the GIC version from GIC Distributor. Then parse GIC related subtables, collect CPU interface and distributor addresses and call driver initialization function (which is hardware abstraction agnostic). In a similar way, FDT initialize GICv2.

---
 xen/arch/arm/gic-v2.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 121 insertions(+), 1 deletion(-)
xen/arch/arm/gic-v2.c +3 -0
index e31d38e..9a9fcd5 100644
@@ -29,6 +29,8 @@
 #include <xen/device_tree.h>
 #include <xen/libfdt/libfdt.h>
 #include <xen/sizes.h>
+#include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <asm/p2m.h>
 #include <asm/domain.h>
 #include <asm/platform.h>
@@ -36,6 +38,7 @@
 
 #include <asm/io.h>
 #include <asm/gic.h>
+#include <asm/acpi.h>
 
 /*
  * LR register definitions are GIC v2 specific.
@@ -681,11 +684,113 @@ static void __init dt_gicv2_init(void)
                csize, vsize);
 }

xen/arch/arm/gic-v2.c static void __init dt_gicv2_init(void) · line 695

Quoted 10 lines
xen/arch/arm/gic-v2.c +9 -0
 
+#ifdef CONFIG_ACPI
+static int __init
+gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
+                        const unsigned long end)
+{
+    static int cpu_base_assigned = 0;
+    struct acpi_madt_generic_interrupt *processor;
+
+    processor = (struct acpi_madt_generic_interrupt *)header;

Use container_of to cast

Quoted 8 lines
xen/arch/arm/gic-v2.c +8 -0
+    if ( BAD_MADT_ENTRY(processor, end) )
+        return -EINVAL;
+
+    /* Read from APIC table and fill up the GIC variables */
+    if ( cpu_base_assigned == 0 )
+    {
+        cbase = processor->base_address;
+        csize = SZ_8K;

xen/arch/arm/gic-v2.c static void __init dt_gicv2_init(void) · line 714

Quoted 10 lines
xen/arch/arm/gic-v2.c +10 -0
+        hbase = processor->gich_base_address;
+        vbase = processor->gicv_base_address;
+        gicv2_info.maintenance_irq = processor->vgic_interrupt;
+
+        if( processor->flags & ACPI_MADT_VGIC_IRQ_MODE )
+            irq_set_type(gicv2_info.maintenance_irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+        else
+            irq_set_type(gicv2_info.maintenance_irq, ACPI_IRQ_TYPE_LEVEL_MASK);
+
+	cpu_base_assigned = 1;

coding style

xen/arch/arm/gic-v2.c static void __init dt_gicv2_init(void) · line 724

Quoted 10 lines
xen/arch/arm/gic-v2.c +10 -0
+    }
+    else
+    {
+        if ( cbase != processor->base_address
+             || hbase != processor->gich_base_address
+             || vbase != processor->gicv_base_address
+             || gicv2_info.maintenance_irq != processor->vgic_interrupt )
+        {
+	    printk("GICv2: GICC entries are not same in MADT table\n");
+	    return -EINVAL;

coding style

xen/arch/arm/gic-v2.c static void __init dt_gicv2_init(void) · line 737

Quoted 13 lines
xen/arch/arm/gic-v2.c +13 -0
+        }
+    }
+
+    return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
+                                const unsigned long end)
+{
+    struct acpi_madt_generic_distributor *dist;
+
+    dist = (struct acpi_madt_generic_distributor *)header;

Same here.

It looks OK aside from these few things.

Quoted 81 lines
xen/arch/arm/gic-v2.c +66 -1
+    if ( BAD_MADT_ENTRY(dist, end) )
+        return -EINVAL;
+
+    dbase = dist->base_address;
+
+    return 0;
+}
+
+static void __init acpi_gicv2_init(void)
+{
+    acpi_status status;
+    struct acpi_table_header *table;
+    int count;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        panic("GICv2: Failed to get MADT table, %s", msg);
+    }
+
+    /* Collect CPU base addresses */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_parse_madt_cpu, table,
+                               ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
+    if ( count <= 0 )
+        panic("GICv2: No valid GICC entries exists");
+
+    /*
+     * Find distributor base address. We expect one distributor entry since
+     * ACPI 5.0 spec neither support multi-GIC instances nor GIC cascade.
+     */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_parse_madt_distributor, table,
+                               ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+    if ( count <= 0 )
+        panic("GICv2: No valid GICD entries exists");
+}
+#else
+static void __init acpi_gicv2_init(void)
+{
+/* Should never reach here */
+}
+#endif
+
 static int __init gicv2_init(void)
 {
     uint32_t aliased_offset = 0;
 
-    dt_gicv2_init();
+    if( acpi_disabled )
+        dt_gicv2_init();
+    else
+        acpi_gicv2_init();
 
     printk("GICv2 initialization:\n"
               "        gic_dist_addr=%"PRIpaddr"\n"
@@ -793,6 +898,21 @@ DT_DEVICE_START(gicv2, "GICv2", DEVICE_GIC)
         .init = dt_gicv2_preinit,
 DT_DEVICE_END
 
+#ifdef CONFIG_ACPI
+/* Set up the GIC */
+static int __init acpi_gicv2_preinit(const void *data)
+{
+    gicv2_info.hw_version = GIC_V2;
+    register_gic_ops(&gicv2_ops);
+
+    return 0;
+}
+
+ACPI_DEVICE_START(agicv2, "GICv2", DEVICE_GIC)
+        .class_type = GIC_V2,
+        .init = acpi_gicv2_preinit,
+ACPI_DEVICE_END
+#endif
 /*
  * Local variables:
  * mode: C
#149 lore raw

Re: [PATCH v3 26/62] arm/gic-v2: Add ACPI boot support for GICv2

In reply to shannon.zhao at linaro.org
Quoted 41 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

ACPI on Xen hypervisor uses MADT table for proper GIC initialization. First get the GIC version from GIC Distributor. Then parse GIC related subtables, collect CPU interface and distributor addresses and call driver initialization function (which is hardware abstraction agnostic). In a similar way, FDT initialize GICv2.

---
 xen/arch/arm/gic-v2.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 121 insertions(+), 1 deletion(-)
xen/arch/arm/gic-v2.c +3 -0
index e31d38e..9a9fcd5 100644
@@ -29,6 +29,8 @@
 #include <xen/device_tree.h>
 #include <xen/libfdt/libfdt.h>
 #include <xen/sizes.h>
+#include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <asm/p2m.h>
 #include <asm/domain.h>
 #include <asm/platform.h>
@@ -36,6 +38,7 @@
 
 #include <asm/io.h>
 #include <asm/gic.h>
+#include <asm/acpi.h>
 
 /*
  * LR register definitions are GIC v2 specific.
@@ -681,11 +684,113 @@ static void __init dt_gicv2_init(void)
                csize, vsize);
 }

xen/arch/arm/gic-v2.c static void __init dt_gicv2_init(void) · line 695

Quoted 10 lines
xen/arch/arm/gic-v2.c +9 -0
 
+#ifdef CONFIG_ACPI
+static int __init
+gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
+                        const unsigned long end)
+{
+    static int cpu_base_assigned = 0;
+    struct acpi_madt_generic_interrupt *processor;
+
+    processor = (struct acpi_madt_generic_interrupt *)header;

Use container_of to cast

Quoted 8 lines
xen/arch/arm/gic-v2.c +8 -0
+    if ( BAD_MADT_ENTRY(processor, end) )
+        return -EINVAL;
+
+    /* Read from APIC table and fill up the GIC variables */
+    if ( cpu_base_assigned == 0 )
+    {
+        cbase = processor->base_address;
+        csize = SZ_8K;

xen/arch/arm/gic-v2.c static void __init dt_gicv2_init(void) · line 714

Quoted 10 lines
xen/arch/arm/gic-v2.c +10 -0
+        hbase = processor->gich_base_address;
+        vbase = processor->gicv_base_address;
+        gicv2_info.maintenance_irq = processor->vgic_interrupt;
+
+        if( processor->flags & ACPI_MADT_VGIC_IRQ_MODE )
+            irq_set_type(gicv2_info.maintenance_irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+        else
+            irq_set_type(gicv2_info.maintenance_irq, ACPI_IRQ_TYPE_LEVEL_MASK);
+
+	cpu_base_assigned = 1;

coding style

xen/arch/arm/gic-v2.c static void __init dt_gicv2_init(void) · line 724

Quoted 10 lines
xen/arch/arm/gic-v2.c +10 -0
+    }
+    else
+    {
+        if ( cbase != processor->base_address
+             || hbase != processor->gich_base_address
+             || vbase != processor->gicv_base_address
+             || gicv2_info.maintenance_irq != processor->vgic_interrupt )
+        {
+	    printk("GICv2: GICC entries are not same in MADT table\n");
+	    return -EINVAL;

coding style

xen/arch/arm/gic-v2.c static void __init dt_gicv2_init(void) · line 737

Quoted 13 lines
xen/arch/arm/gic-v2.c +13 -0
+        }
+    }
+
+    return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
+                                const unsigned long end)
+{
+    struct acpi_madt_generic_distributor *dist;
+
+    dist = (struct acpi_madt_generic_distributor *)header;

Same here.

It looks OK aside from these few things.

Quoted 81 lines
xen/arch/arm/gic-v2.c +66 -1
+    if ( BAD_MADT_ENTRY(dist, end) )
+        return -EINVAL;
+
+    dbase = dist->base_address;
+
+    return 0;
+}
+
+static void __init acpi_gicv2_init(void)
+{
+    acpi_status status;
+    struct acpi_table_header *table;
+    int count;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        panic("GICv2: Failed to get MADT table, %s", msg);
+    }
+
+    /* Collect CPU base addresses */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_parse_madt_cpu, table,
+                               ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
+    if ( count <= 0 )
+        panic("GICv2: No valid GICC entries exists");
+
+    /*
+     * Find distributor base address. We expect one distributor entry since
+     * ACPI 5.0 spec neither support multi-GIC instances nor GIC cascade.
+     */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_parse_madt_distributor, table,
+                               ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+    if ( count <= 0 )
+        panic("GICv2: No valid GICD entries exists");
+}
+#else
+static void __init acpi_gicv2_init(void)
+{
+/* Should never reach here */
+}
+#endif
+
 static int __init gicv2_init(void)
 {
     uint32_t aliased_offset = 0;
 
-    dt_gicv2_init();
+    if( acpi_disabled )
+        dt_gicv2_init();
+    else
+        acpi_gicv2_init();
 
     printk("GICv2 initialization:\n"
               "        gic_dist_addr=%"PRIpaddr"\n"
@@ -793,6 +898,21 @@ DT_DEVICE_START(gicv2, "GICv2", DEVICE_GIC)
         .init = dt_gicv2_preinit,
 DT_DEVICE_END
 
+#ifdef CONFIG_ACPI
+/* Set up the GIC */
+static int __init acpi_gicv2_preinit(const void *data)
+{
+    gicv2_info.hw_version = GIC_V2;
+    register_gic_ops(&gicv2_ops);
+
+    return 0;
+}
+
+ACPI_DEVICE_START(agicv2, "GICv2", DEVICE_GIC)
+        .class_type = GIC_V2,
+        .init = acpi_gicv2_preinit,
+ACPI_DEVICE_END
+#endif
 /*
  * Local variables:
  * mode: C
#150 lore raw

PATCH v3 27/62 arm/gic-v3: Add ACPI boot support for GICv3

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Like GICv2, ACPI on Xen hypervisor uses MADT table for proper GICv3 initialization. Parse GIC distributor subtable, redistributor subtable and interrupt subtable.

---
 xen/arch/arm/gic-v3.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 181 insertions(+), 1 deletion(-)
xen/arch/arm/gic-v3.c +181 -1
index bd13010..fa732d7 100644
@@ -34,6 +34,8 @@
 #include <xen/sizes.h>
 #include <xen/libfdt/libfdt.h>
 #include <xen/sort.h>
+#include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <asm/p2m.h>
 #include <asm/domain.h>
 #include <asm/io.h>
@@ -41,6 +43,7 @@
 #include <asm/gic.h>
 #include <asm/gic_v3_defs.h>
 #include <asm/cpufeature.h>
+#include <asm/acpi.h>
 
 /* Global state */
 static struct {
@@ -1242,6 +1245,164 @@ static void __init dt_gicv3_init(void)
     }
 }
 
+#ifdef CONFIG_ACPI
+static int __init
+gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
+                        const unsigned long end)
+{
+    static bool cpu_base_assigned = false;
+    struct acpi_madt_generic_interrupt *processor;
+
+    processor = (struct acpi_madt_generic_interrupt *)header;
+
+    if ( BAD_MADT_ENTRY(processor, end) )
+        return -EINVAL;
+
+    /* Read from APIC table and fill up the GIC variables */
+    if ( !cpu_base_assigned )
+    {
+        cbase = processor->base_address;
+        csize = SZ_8K;
+        vbase = processor->gicv_base_address;
+        gicv3_info.maintenance_irq = processor->vgic_interrupt;
+
+        if( processor->flags & ACPI_MADT_VGIC_IRQ_MODE )
+            irq_set_type(gicv3_info.maintenance_irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+        else
+            irq_set_type(gicv3_info.maintenance_irq, ACPI_IRQ_TYPE_LEVEL_MASK);
+
+	cpu_base_assigned = true;
+    }
+    else
+    {
+        if ( cbase != processor->base_address
+             || vbase != processor->gicv_base_address
+             || gicv3_info.maintenance_irq != processor->vgic_interrupt )
+        {
+	    printk("GICv3: GICC entries are not same in MADT table\n");
+	    return -EINVAL;
+        }
+    }
+
+    return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
+                                const unsigned long end)
+{
+    struct acpi_madt_generic_distributor *dist;
+
+    dist = (struct acpi_madt_generic_distributor *)header;
+
+    if ( BAD_MADT_ENTRY(dist, end) )
+        return -EINVAL;
+
+    dbase = dist->base_address;
+
+    return 0;
+}
+static int __init
+gic_acpi_get_madt_redistributor_num(struct acpi_subtable_header *header,
+                                    const unsigned long end)
+{
+    return 0;
+}
+
+static void __init acpi_gicv3_init(void)
+{
+    struct acpi_table_header *table;
+    struct rdist_region *rdist_regs;
+    acpi_status status;
+    int count, i;
+    uint32_t reg;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        panic("GICv3: Failed to get MADT table, %s", msg);
+    }
+
+    /*
+     * Find distributor base address. We expect one distributor entry since
+     * ACPI 5.0 spec neither support multi-GIC instances nor GIC cascade.
+     */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_parse_madt_distributor, table,
+                               ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+
+    if ( count <= 0 )
+        panic("GICv3: No valid GICD entries exists");
+
+    if ( (dbase & ~PAGE_MASK) )
+        panic("GICv3: Found unaligned distributor address %"PRIpaddr"",
+              dbase);
+
+    gicv3.map_dbase = ioremap_nocache(dbase, SZ_64K);
+    if ( !gicv3.map_dbase )
+        panic("GICv3: Failed to ioremap for GIC distributor\n");
+
+    reg = readl_relaxed(GICD + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
+    if ( reg != GIC_PIDR2_ARCH_GICv3 )
+         panic("GICv3: no distributor detected\n");
+
+    /* Get number of redistributor */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_get_madt_redistributor_num, table,
+                               ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
+    if ( count <= 0 )
+        panic("GICv3: No valid GICR entries exists");
+
+    gicv3.rdist_count = count;
+
+    if ( gicv3.rdist_count > MAX_RDIST_COUNT )
+        panic("GICv3: Number of redistributor regions is more than"
+              "%d (Increase MAX_RDIST_COUNT!!)\n", MAX_RDIST_COUNT);
+
+    rdist_regs = xzalloc_array(struct rdist_region, gicv3.rdist_count);
+    if ( !rdist_regs )
+        panic("GICv3: Failed to allocate memory for rdist regions\n");
+
+    for ( i = 0; i < gicv3.rdist_count; i++ )
+    {
+        struct acpi_subtable_header *subtable;
+        struct acpi_madt_generic_redistributor *gic_rdist;
+
+        subtable = acpi_get_entry(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                                  table, ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
+                                  i);
+        if ( !subtable )
+            panic("GICv3: Can't get GICR entry");
+
+	gic_rdist = (struct acpi_madt_generic_redistributor *)subtable;
+        rdist_regs[i].base = gic_rdist->base_address;
+        rdist_regs[i].size = gic_rdist->length;
+    }
+
+    /* The vGIC code requires the region to be sorted */
+    sort(rdist_regs, gicv3.rdist_count, sizeof(*rdist_regs), cmp_rdist, NULL);
+
+    gicv3.rdist_regions= rdist_regs;
+
+    /* Collect CPU base addresses */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_parse_madt_cpu, table,
+                               ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
+    if ( count <= 0 )
+        panic("GICv3: No valid GICC entries exists");
+
+    gicv3.rdist_stride = 0;
+}
+#else
+static void __init acpi_gicv3_init(void)
+{
+/* Should never reach here */
+}
+#endif
+
 /* Set up the GIC */
 static int __init gicv3_init(void)
 {
@@ -1253,7 +1414,10 @@ static int __init gicv3_init(void)
         return -ENODEV;
     }
 
-    dt_gicv3_init();
+    if( acpi_disabled )
+        dt_gicv3_init();
+    else
+        acpi_gicv3_init();
 
     for ( i = 0; i < gicv3.rdist_count; i++ )
     {
@@ -1345,6 +1509,22 @@ DT_DEVICE_START(gicv3, "GICv3", DEVICE_GIC)
         .init = dt_gicv3_preinit,
 DT_DEVICE_END
 
+#ifdef CONFIG_ACPI
+/* Set up the GIC */
+static int __init acpi_gicv3_preinit(const void *data)
+{
+    gicv3_info.hw_version = GIC_V3;
+    register_gic_ops(&gicv3_ops);
+
+    return 0;
+}
+
+ACPI_DEVICE_START(agicv3, "GICv3", DEVICE_GIC)
+        .class_type = GIC_V3,
+        .init = acpi_gicv3_preinit,
+ACPI_DEVICE_END
+#endif
+
 /*
  * Local variables:
  * mode: C
Signature · 1 line
2.1.0
#151 lore raw

PATCH v3 27/62 arm/gic-v3: Add ACPI boot support for GICv3

Quoted 53 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Like GICv2, ACPI on Xen hypervisor uses MADT table for proper GICv3 initialization. Parse GIC distributor subtable, redistributor subtable and interrupt subtable.

---
 xen/arch/arm/gic-v3.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 181 insertions(+), 1 deletion(-)
xen/arch/arm/gic-v3.c +20 -0
index bd13010..fa732d7 100644
@@ -34,6 +34,8 @@
 #include <xen/sizes.h>
 #include <xen/libfdt/libfdt.h>
 #include <xen/sort.h>
+#include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <asm/p2m.h>
 #include <asm/domain.h>
 #include <asm/io.h>
@@ -41,6 +43,7 @@
 #include <asm/gic.h>
 #include <asm/gic_v3_defs.h>
 #include <asm/cpufeature.h>
+#include <asm/acpi.h>
 
 /* Global state */
 static struct {
@@ -1242,6 +1245,164 @@ static void __init dt_gicv3_init(void)
     }
 }
 
+#ifdef CONFIG_ACPI
+static int __init
+gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
+                        const unsigned long end)
+{
+    static bool cpu_base_assigned = false;
+    struct acpi_madt_generic_interrupt *processor;
+
+    processor = (struct acpi_madt_generic_interrupt *)header;
+
+    if ( BAD_MADT_ENTRY(processor, end) )
+        return -EINVAL;
+
+    /* Read from APIC table and fill up the GIC variables */
+    if ( !cpu_base_assigned )
+    {
+        cbase = processor->base_address;

xen/arch/arm/gic-v3.c static void __init dt_gicv3_init(void) · line 1274

Quoted 10 lines
xen/arch/arm/gic-v3.c +10 -0
+        csize = SZ_8K;
+        vbase = processor->gicv_base_address;
+        gicv3_info.maintenance_irq = processor->vgic_interrupt;
+
+        if( processor->flags & ACPI_MADT_VGIC_IRQ_MODE )
+            irq_set_type(gicv3_info.maintenance_irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+        else
+            irq_set_type(gicv3_info.maintenance_irq, ACPI_IRQ_TYPE_LEVEL_MASK);
+
+	cpu_base_assigned = true;

coding style

xen/arch/arm/gic-v3.c static void __init dt_gicv3_init(void) · line 1283

Quoted 9 lines
xen/arch/arm/gic-v3.c +9 -0
+    }
+    else
+    {
+        if ( cbase != processor->base_address
+             || vbase != processor->gicv_base_address
+             || gicv3_info.maintenance_irq != processor->vgic_interrupt )
+        {
+	    printk("GICv3: GICC entries are not same in MADT table\n");
+	    return -EINVAL;

coding style

Quoted 16 lines
xen/arch/arm/gic-v3.c +16 -0
+        }
+    }
+
+    return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
+                                const unsigned long end)
+{
+    struct acpi_madt_generic_distributor *dist;
+
+    dist = (struct acpi_madt_generic_distributor *)header;
+
+    if ( BAD_MADT_ENTRY(dist, end) )
+        return -EINVAL;

xen/arch/arm/gic-v3.c static void __init dt_gicv3_init(void) · line 1309

Quoted 10 lines
xen/arch/arm/gic-v3.c +10 -0
+
+    dbase = dist->base_address;
+
+    return 0;
+}
+static int __init
+gic_acpi_get_madt_redistributor_num(struct acpi_subtable_header *header,
+                                    const unsigned long end)
+{
+    return 0;

I think you should at least add a comment here to explain why we just return 0 in this case

Quoted 31 lines
xen/arch/arm/gic-v3.c +31 -0
+}
+
+static void __init acpi_gicv3_init(void)
+{
+    struct acpi_table_header *table;
+    struct rdist_region *rdist_regs;
+    acpi_status status;
+    int count, i;
+    uint32_t reg;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        panic("GICv3: Failed to get MADT table, %s", msg);
+    }
+
+    /*
+     * Find distributor base address. We expect one distributor entry since
+     * ACPI 5.0 spec neither support multi-GIC instances nor GIC cascade.
+     */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_parse_madt_distributor, table,
+                               ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+
+    if ( count <= 0 )
+        panic("GICv3: No valid GICD entries exists");
+
+    if ( (dbase & ~PAGE_MASK) )

xen/arch/arm/gic-v3.c static void __init dt_gicv3_init(void) · line 1350

Quoted 10 lines
xen/arch/arm/gic-v3.c +10 -0
+        panic("GICv3: Found unaligned distributor address %"PRIpaddr"",
+              dbase);
+
+    gicv3.map_dbase = ioremap_nocache(dbase, SZ_64K);
+    if ( !gicv3.map_dbase )
+        panic("GICv3: Failed to ioremap for GIC distributor\n");
+
+    reg = readl_relaxed(GICD + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
+    if ( reg != GIC_PIDR2_ARCH_GICv3 )
+         panic("GICv3: no distributor detected\n");

I think these should be moved to a common init function

Quoted 19 lines
xen/arch/arm/gic-v3.c +19 -0
+    /* Get number of redistributor */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_get_madt_redistributor_num, table,
+                               ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
+    if ( count <= 0 )
+        panic("GICv3: No valid GICR entries exists");
+
+    gicv3.rdist_count = count;
+
+    if ( gicv3.rdist_count > MAX_RDIST_COUNT )
+        panic("GICv3: Number of redistributor regions is more than"
+              "%d (Increase MAX_RDIST_COUNT!!)\n", MAX_RDIST_COUNT);
+
+    rdist_regs = xzalloc_array(struct rdist_region, gicv3.rdist_count);
+    if ( !rdist_regs )
+        panic("GICv3: Failed to allocate memory for rdist regions\n");
+
+    for ( i = 0; i < gicv3.rdist_count; i++ )
+    {

xen/arch/arm/gic-v3.c static void __init dt_gicv3_init(void) · line 1380

Quoted 10 lines
xen/arch/arm/gic-v3.c +10 -0
+        struct acpi_subtable_header *subtable;
+        struct acpi_madt_generic_redistributor *gic_rdist;
+
+        subtable = acpi_get_entry(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                                  table, ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
+                                  i);
+        if ( !subtable )
+            panic("GICv3: Can't get GICR entry");
+
+	gic_rdist = (struct acpi_madt_generic_redistributor *)subtable;

coding style

Quoted 72 lines
xen/arch/arm/gic-v3.c +45 -1
+        rdist_regs[i].base = gic_rdist->base_address;
+        rdist_regs[i].size = gic_rdist->length;
+    }
+
+    /* The vGIC code requires the region to be sorted */
+    sort(rdist_regs, gicv3.rdist_count, sizeof(*rdist_regs), cmp_rdist, NULL);
+
+    gicv3.rdist_regions= rdist_regs;
+
+    /* Collect CPU base addresses */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_parse_madt_cpu, table,
+                               ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
+    if ( count <= 0 )
+        panic("GICv3: No valid GICC entries exists");
+
+    gicv3.rdist_stride = 0;
+}
+#else
+static void __init acpi_gicv3_init(void)
+{
+/* Should never reach here */
+}
+#endif
+
 /* Set up the GIC */
 static int __init gicv3_init(void)
 {
@@ -1253,7 +1414,10 @@ static int __init gicv3_init(void)
         return -ENODEV;
     }
 
-    dt_gicv3_init();
+    if( acpi_disabled )
+        dt_gicv3_init();
+    else
+        acpi_gicv3_init();
 
     for ( i = 0; i < gicv3.rdist_count; i++ )
     {
@@ -1345,6 +1509,22 @@ DT_DEVICE_START(gicv3, "GICv3", DEVICE_GIC)
         .init = dt_gicv3_preinit,
 DT_DEVICE_END
 
+#ifdef CONFIG_ACPI
+/* Set up the GIC */
+static int __init acpi_gicv3_preinit(const void *data)
+{
+    gicv3_info.hw_version = GIC_V3;
+    register_gic_ops(&gicv3_ops);
+
+    return 0;
+}
+
+ACPI_DEVICE_START(agicv3, "GICv3", DEVICE_GIC)
+        .class_type = GIC_V3,
+        .init = acpi_gicv3_preinit,
+ACPI_DEVICE_END
+#endif
+
 /*
  * Local variables:
  * mode: C
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel at lists.xen.org
http://lists.xen.org/xen-devel
#152 lore raw

Re: [PATCH v3 27/62] arm/gic-v3: Add ACPI boot support for GICv3

In reply to shannon.zhao at linaro.org
Quoted 53 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Like GICv2, ACPI on Xen hypervisor uses MADT table for proper GICv3 initialization. Parse GIC distributor subtable, redistributor subtable and interrupt subtable.

---
 xen/arch/arm/gic-v3.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 181 insertions(+), 1 deletion(-)
xen/arch/arm/gic-v3.c +20 -0
index bd13010..fa732d7 100644
@@ -34,6 +34,8 @@
 #include <xen/sizes.h>
 #include <xen/libfdt/libfdt.h>
 #include <xen/sort.h>
+#include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <asm/p2m.h>
 #include <asm/domain.h>
 #include <asm/io.h>
@@ -41,6 +43,7 @@
 #include <asm/gic.h>
 #include <asm/gic_v3_defs.h>
 #include <asm/cpufeature.h>
+#include <asm/acpi.h>
 
 /* Global state */
 static struct {
@@ -1242,6 +1245,164 @@ static void __init dt_gicv3_init(void)
     }
 }
 
+#ifdef CONFIG_ACPI
+static int __init
+gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
+                        const unsigned long end)
+{
+    static bool cpu_base_assigned = false;
+    struct acpi_madt_generic_interrupt *processor;
+
+    processor = (struct acpi_madt_generic_interrupt *)header;
+
+    if ( BAD_MADT_ENTRY(processor, end) )
+        return -EINVAL;
+
+    /* Read from APIC table and fill up the GIC variables */
+    if ( !cpu_base_assigned )
+    {
+        cbase = processor->base_address;

xen/arch/arm/gic-v3.c static void __init dt_gicv3_init(void) · line 1274

Quoted 10 lines
xen/arch/arm/gic-v3.c +10 -0
+        csize = SZ_8K;
+        vbase = processor->gicv_base_address;
+        gicv3_info.maintenance_irq = processor->vgic_interrupt;
+
+        if( processor->flags & ACPI_MADT_VGIC_IRQ_MODE )
+            irq_set_type(gicv3_info.maintenance_irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+        else
+            irq_set_type(gicv3_info.maintenance_irq, ACPI_IRQ_TYPE_LEVEL_MASK);
+
+	cpu_base_assigned = true;

coding style

xen/arch/arm/gic-v3.c static void __init dt_gicv3_init(void) · line 1283

Quoted 9 lines
xen/arch/arm/gic-v3.c +9 -0
+    }
+    else
+    {
+        if ( cbase != processor->base_address
+             || vbase != processor->gicv_base_address
+             || gicv3_info.maintenance_irq != processor->vgic_interrupt )
+        {
+	    printk("GICv3: GICC entries are not same in MADT table\n");
+	    return -EINVAL;

coding style

Quoted 16 lines
xen/arch/arm/gic-v3.c +16 -0
+        }
+    }
+
+    return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
+                                const unsigned long end)
+{
+    struct acpi_madt_generic_distributor *dist;
+
+    dist = (struct acpi_madt_generic_distributor *)header;
+
+    if ( BAD_MADT_ENTRY(dist, end) )
+        return -EINVAL;

xen/arch/arm/gic-v3.c static void __init dt_gicv3_init(void) · line 1309

Quoted 10 lines
xen/arch/arm/gic-v3.c +10 -0
+
+    dbase = dist->base_address;
+
+    return 0;
+}
+static int __init
+gic_acpi_get_madt_redistributor_num(struct acpi_subtable_header *header,
+                                    const unsigned long end)
+{
+    return 0;

I think you should at least add a comment here to explain why we just return 0 in this case

Quoted 31 lines
xen/arch/arm/gic-v3.c +31 -0
+}
+
+static void __init acpi_gicv3_init(void)
+{
+    struct acpi_table_header *table;
+    struct rdist_region *rdist_regs;
+    acpi_status status;
+    int count, i;
+    uint32_t reg;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        panic("GICv3: Failed to get MADT table, %s", msg);
+    }
+
+    /*
+     * Find distributor base address. We expect one distributor entry since
+     * ACPI 5.0 spec neither support multi-GIC instances nor GIC cascade.
+     */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_parse_madt_distributor, table,
+                               ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+
+    if ( count <= 0 )
+        panic("GICv3: No valid GICD entries exists");
+
+    if ( (dbase & ~PAGE_MASK) )

xen/arch/arm/gic-v3.c static void __init dt_gicv3_init(void) · line 1350

Quoted 10 lines
xen/arch/arm/gic-v3.c +10 -0
+        panic("GICv3: Found unaligned distributor address %"PRIpaddr"",
+              dbase);
+
+    gicv3.map_dbase = ioremap_nocache(dbase, SZ_64K);
+    if ( !gicv3.map_dbase )
+        panic("GICv3: Failed to ioremap for GIC distributor\n");
+
+    reg = readl_relaxed(GICD + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
+    if ( reg != GIC_PIDR2_ARCH_GICv3 )
+         panic("GICv3: no distributor detected\n");

I think these should be moved to a common init function

Quoted 19 lines
xen/arch/arm/gic-v3.c +19 -0
+    /* Get number of redistributor */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_get_madt_redistributor_num, table,
+                               ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
+    if ( count <= 0 )
+        panic("GICv3: No valid GICR entries exists");
+
+    gicv3.rdist_count = count;
+
+    if ( gicv3.rdist_count > MAX_RDIST_COUNT )
+        panic("GICv3: Number of redistributor regions is more than"
+              "%d (Increase MAX_RDIST_COUNT!!)\n", MAX_RDIST_COUNT);
+
+    rdist_regs = xzalloc_array(struct rdist_region, gicv3.rdist_count);
+    if ( !rdist_regs )
+        panic("GICv3: Failed to allocate memory for rdist regions\n");
+
+    for ( i = 0; i < gicv3.rdist_count; i++ )
+    {

xen/arch/arm/gic-v3.c static void __init dt_gicv3_init(void) · line 1380

Quoted 10 lines
xen/arch/arm/gic-v3.c +10 -0
+        struct acpi_subtable_header *subtable;
+        struct acpi_madt_generic_redistributor *gic_rdist;
+
+        subtable = acpi_get_entry(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                                  table, ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
+                                  i);
+        if ( !subtable )
+            panic("GICv3: Can't get GICR entry");
+
+	gic_rdist = (struct acpi_madt_generic_redistributor *)subtable;

coding style

Quoted 72 lines
xen/arch/arm/gic-v3.c +45 -1
+        rdist_regs[i].base = gic_rdist->base_address;
+        rdist_regs[i].size = gic_rdist->length;
+    }
+
+    /* The vGIC code requires the region to be sorted */
+    sort(rdist_regs, gicv3.rdist_count, sizeof(*rdist_regs), cmp_rdist, NULL);
+
+    gicv3.rdist_regions= rdist_regs;
+
+    /* Collect CPU base addresses */
+    count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                               gic_acpi_parse_madt_cpu, table,
+                               ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
+    if ( count <= 0 )
+        panic("GICv3: No valid GICC entries exists");
+
+    gicv3.rdist_stride = 0;
+}
+#else
+static void __init acpi_gicv3_init(void)
+{
+/* Should never reach here */
+}
+#endif
+
 /* Set up the GIC */
 static int __init gicv3_init(void)
 {
@@ -1253,7 +1414,10 @@ static int __init gicv3_init(void)
         return -ENODEV;
     }
 
-    dt_gicv3_init();
+    if( acpi_disabled )
+        dt_gicv3_init();
+    else
+        acpi_gicv3_init();
 
     for ( i = 0; i < gicv3.rdist_count; i++ )
     {
@@ -1345,6 +1509,22 @@ DT_DEVICE_START(gicv3, "GICv3", DEVICE_GIC)
         .init = dt_gicv3_preinit,
 DT_DEVICE_END
 
+#ifdef CONFIG_ACPI
+/* Set up the GIC */
+static int __init acpi_gicv3_preinit(const void *data)
+{
+    gicv3_info.hw_version = GIC_V3;
+    register_gic_ops(&gicv3_ops);
+
+    return 0;
+}
+
+ACPI_DEVICE_START(agicv3, "GICv3", DEVICE_GIC)
+        .class_type = GIC_V3,
+        .init = acpi_gicv3_preinit,
+ACPI_DEVICE_END
+#endif
+
 /*
  * Local variables:
  * mode: C
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#153 lore raw

PATCH v3 28/62 arm/gic: Add ACPI support for GIC preinit

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Since ACPI 6.0 defines that GIC Distributor Structure contains the GIC version filed, it could get GIC version from that. According to the version, call different preinit functions.

---
 xen/arch/arm/gic.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 4 deletions(-)
xen/arch/arm/gic.c +51 -4
index 1e1e5ba..ac82588 100644
@@ -27,6 +27,7 @@
 #include <xen/softirq.h>
 #include <xen/list.h>
 #include <xen/device_tree.h>
+#include <xen/acpi.h>
 #include <asm/p2m.h>
 #include <asm/domain.h>
 #include <asm/platform.h>
@@ -34,6 +35,7 @@
 #include <asm/io.h>
 #include <asm/gic.h>
 #include <asm/vgic.h>
+#include <asm/acpi.h>
 
 static void gic_restore_pending_irqs(struct vcpu *v);
 
@@ -228,10 +230,7 @@ int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
     return 0;
 }
 
-/* Find the interrupt controller and set up the callback to translate
- * device tree IRQ.
- */
-void __init gic_preinit(void)
+void __init dt_gic_preinit(void)
 {
     int rc;
     struct dt_device_node *node;
@@ -261,6 +260,54 @@ void __init gic_preinit(void)
     dt_device_set_used_by(node, DOMID_XEN);
 }
 
+#ifdef CONFIG_ACPI
+static void __init acpi_gic_preinit(void)
+{
+    int rc = 0;
+    acpi_status status;
+    struct acpi_table_header *table;
+    struct acpi_subtable_header * subtable;
+    struct acpi_madt_generic_distributor *dist;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        panic("Failed to get MADT table, %s", msg);
+    }
+
+    subtable = acpi_get_entry(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+                              table, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+    if ( !subtable )
+        panic("No valid GICD entries exists");
+
+    dist = (struct acpi_madt_generic_distributor *)subtable;
+
+    if ( dist->version == ACPI_MADT_GIC_VERSION_V2 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V2);
+    else if ( dist->version == ACPI_MADT_GIC_VERSION_V3 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V3);
+    else
+        panic("Wrong GIC version or unsupported GIC");
+    if ( rc )
+        panic("Unable to find compatible GIC in the ACPI table");
+}
+#else
+static void __init acpi_gic_preinit(void) {}
+#endif
+
+/* Find the interrupt controller and set up the callback to translate
+ * device tree IRQ.
+ */
+void __init gic_preinit(void)
+{
+    if( acpi_disabled )
+        dt_gic_preinit();
+    else
+        acpi_gic_preinit();
+}
+
 /* Set up the GIC */
 void __init gic_init(void)
 {
Signature · 1 line
2.1.0
#154 lore raw

PATCH v3 28/62 arm/gic: Add ACPI support for GIC preinit

Quoted 65 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Since ACPI 6.0 defines that GIC Distributor Structure contains the GIC version filed, it could get GIC version from that. According to the version, call different preinit functions.

---
 xen/arch/arm/gic.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 4 deletions(-)
xen/arch/arm/gic.c +21 -4
index 1e1e5ba..ac82588 100644
@@ -27,6 +27,7 @@
 #include <xen/softirq.h>
 #include <xen/list.h>
 #include <xen/device_tree.h>
+#include <xen/acpi.h>
 #include <asm/p2m.h>
 #include <asm/domain.h>
 #include <asm/platform.h>
@@ -34,6 +35,7 @@
 #include <asm/io.h>
 #include <asm/gic.h>
 #include <asm/vgic.h>
+#include <asm/acpi.h>
 
 static void gic_restore_pending_irqs(struct vcpu *v);
 
@@ -228,10 +230,7 @@ int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
     return 0;
 }
 
-/* Find the interrupt controller and set up the callback to translate
- * device tree IRQ.
- */
-void __init gic_preinit(void)
+void __init dt_gic_preinit(void)
 {
     int rc;
     struct dt_device_node *node;
@@ -261,6 +260,54 @@ void __init gic_preinit(void)
     dt_device_set_used_by(node, DOMID_XEN);
 }
 
+#ifdef CONFIG_ACPI
+static void __init acpi_gic_preinit(void)
+{
+    int rc = 0;
+    acpi_status status;
+    struct acpi_table_header *table;
+    struct acpi_subtable_header * subtable;
+    struct acpi_madt_generic_distributor *dist;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        panic("Failed to get MADT table, %s", msg);
+    }
+
+    subtable = acpi_get_entry(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),

xen/arch/arm/gic.c void __init gic_preinit(void) · line 290

Quoted 10 lines
xen/arch/arm/gic.c +10 -0
+                              table, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+    if ( !subtable )
+        panic("No valid GICD entries exists");
+
+    dist = (struct acpi_madt_generic_distributor *)subtable;
+
+    if ( dist->version == ACPI_MADT_GIC_VERSION_V2 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V2);
+    else if ( dist->version == ACPI_MADT_GIC_VERSION_V3 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V3);

I agree with your suggestion and Julien's previous comment. Something like:

ACPI_DEVICE_START(agicv2, "GICv2", DEVICE_GIC)
.class_type = ACPI_MADT_GIC_VERSION_V2,
.init = acpi_gicv2_preinit,
ACPI_DEVICE_END

would be better.

Quoted 5 lines
xen/arch/arm/gic.c +5 -0
+    else
+        panic("Wrong GIC version or unsupported GIC");
+    if ( rc )
+        panic("Unable to find compatible GIC in the ACPI table");
+}

xen/arch/arm/gic.c void __init gic_preinit(void) · line 305

Quoted 10 lines
xen/arch/arm/gic.c +10 -0
+#else
+static void __init acpi_gic_preinit(void) {}
+#endif
+
+/* Find the interrupt controller and set up the callback to translate
+ * device tree IRQ.
+ */
+void __init gic_preinit(void)
+{
+    if( acpi_disabled )

coding style

Quoted 11 lines
xen/arch/arm/gic.c +5 -0
+        dt_gic_preinit();
+    else
+        acpi_gic_preinit();
+}
+
 /* Set up the GIC */
 void __init gic_init(void)
 {
Signature · 1 line
2.1.0
#155 lore raw

Re: [PATCH v3 28/62] arm/gic: Add ACPI support for GIC preinit

In reply to shannon.zhao at linaro.org
Quoted 65 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Since ACPI 6.0 defines that GIC Distributor Structure contains the GIC version filed, it could get GIC version from that. According to the version, call different preinit functions.

---
 xen/arch/arm/gic.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 4 deletions(-)
xen/arch/arm/gic.c +21 -4
index 1e1e5ba..ac82588 100644
@@ -27,6 +27,7 @@
 #include <xen/softirq.h>
 #include <xen/list.h>
 #include <xen/device_tree.h>
+#include <xen/acpi.h>
 #include <asm/p2m.h>
 #include <asm/domain.h>
 #include <asm/platform.h>
@@ -34,6 +35,7 @@
 #include <asm/io.h>
 #include <asm/gic.h>
 #include <asm/vgic.h>
+#include <asm/acpi.h>
 
 static void gic_restore_pending_irqs(struct vcpu *v);
 
@@ -228,10 +230,7 @@ int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
     return 0;
 }
 
-/* Find the interrupt controller and set up the callback to translate
- * device tree IRQ.
- */
-void __init gic_preinit(void)
+void __init dt_gic_preinit(void)
 {
     int rc;
     struct dt_device_node *node;
@@ -261,6 +260,54 @@ void __init gic_preinit(void)
     dt_device_set_used_by(node, DOMID_XEN);
 }
 
+#ifdef CONFIG_ACPI
+static void __init acpi_gic_preinit(void)
+{
+    int rc = 0;
+    acpi_status status;
+    struct acpi_table_header *table;
+    struct acpi_subtable_header * subtable;
+    struct acpi_madt_generic_distributor *dist;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        panic("Failed to get MADT table, %s", msg);
+    }
+
+    subtable = acpi_get_entry(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),

xen/arch/arm/gic.c void __init gic_preinit(void) · line 290

Quoted 10 lines
xen/arch/arm/gic.c +10 -0
+                              table, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+    if ( !subtable )
+        panic("No valid GICD entries exists");
+
+    dist = (struct acpi_madt_generic_distributor *)subtable;
+
+    if ( dist->version == ACPI_MADT_GIC_VERSION_V2 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V2);
+    else if ( dist->version == ACPI_MADT_GIC_VERSION_V3 )
+        rc = acpi_device_init(DEVICE_GIC, NULL, GIC_V3);

I agree with your suggestion and Julien's previous comment. Something like:

ACPI_DEVICE_START(agicv2, "GICv2", DEVICE_GIC)
.class_type = ACPI_MADT_GIC_VERSION_V2,
.init = acpi_gicv2_preinit,
ACPI_DEVICE_END

would be better.

Quoted 5 lines
xen/arch/arm/gic.c +5 -0
+    else
+        panic("Wrong GIC version or unsupported GIC");
+    if ( rc )
+        panic("Unable to find compatible GIC in the ACPI table");
+}

xen/arch/arm/gic.c void __init gic_preinit(void) · line 305

Quoted 10 lines
xen/arch/arm/gic.c +10 -0
+#else
+static void __init acpi_gic_preinit(void) {}
+#endif
+
+/* Find the interrupt controller and set up the callback to translate
+ * device tree IRQ.
+ */
+void __init gic_preinit(void)
+{
+    if( acpi_disabled )

coding style

Quoted 11 lines
xen/arch/arm/gic.c +5 -0
+        dt_gic_preinit();
+    else
+        acpi_gic_preinit();
+}
+
 /* Set up the GIC */
 void __init gic_init(void)
 {
Signature · 1 line
2.1.0
#156 lore raw

PATCH v3 29/62 arm/acpi: Add GTDT support updated by ACPI 5.1

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

With ACPI 5.0, we got per-processor timer support in GTDT, and ACPI 5.1 introduced the support for platform (memory-mapped)
timers: GT Block and SBSA watchdog timer, add the code needed for the spec change.

---
 xen/include/acpi/actbl3.h  | 98 +++++++++++++++++++++++++++++++++++++++-------
 xen/include/asm-arm/acpi.h |  2 +
 2 files changed, 85 insertions(+), 15 deletions(-)
xen/include/acpi/actbl3.h +83 -15
index 8c61b5f..fc96963 100644
@@ -241,33 +241,101 @@ struct acpi_s3pt_suspend {
 
 /*******************************************************************************
  *
- * GTDT - Generic Timer Description Table (ACPI 5.0)
- *        Version 1
+ * GTDT - Generic Timer Description Table (ACPI 5.1)
+ *        Version 2
  *
  ******************************************************************************/
 
 struct acpi_table_gtdt {
 	struct acpi_table_header header;	/* Common ACPI table header */
-	u64 address;
-	u32 flags;
-	u32 secure_pl1_interrupt;
-	u32 secure_pl1_flags;
-	u32 non_secure_pl1_interrupt;
-	u32 non_secure_pl1_flags;
+	u64 counter_block_addresss;
+	u32 reserved;
+	u32 secure_el1_interrupt;
+	u32 secure_el1_flags;
+	u32 non_secure_el1_interrupt;
+	u32 non_secure_el1_flags;
 	u32 virtual_timer_interrupt;
 	u32 virtual_timer_flags;
-	u32 non_secure_pl2_interrupt;
-	u32 non_secure_pl2_flags;
+	u32 non_secure_el2_interrupt;
+	u32 non_secure_el2_flags;
+	u64 counter_read_block_address;
+	u32 platform_timer_count;
+	u32 platform_timer_offset;
 };
 
-/* Values for Flags field above */
+/* Flag Definitions: Timer Block Physical Timers and Virtual timers */
+
+#define ACPI_GTDT_INTERRUPT_MODE        (1)
+#define ACPI_GTDT_INTERRUPT_POLARITY    (1<<1)
+#define ACPI_GTDT_ALWAYS_ON             (1<<2)
+
+/* Common GTDT subtable header */
+
+struct acpi_gtdt_header {
+	u8 type;
+	u16 length;
+};
+
+/* Values for GTDT subtable type above */
+
+enum acpi_gtdt_type {
+	ACPI_GTDT_TYPE_TIMER_BLOCK = 0,
+	ACPI_GTDT_TYPE_WATCHDOG = 1,
+	ACPI_GTDT_TYPE_RESERVED = 2	/* 2 and greater are reserved */
+};
+
+/* GTDT Subtables, correspond to Type in struct acpi_gtdt_header */
 
-#define ACPI_GTDT_MAPPED_BLOCK_PRESENT      1
+/* 0: Generic Timer Block */
+
+struct acpi_gtdt_timer_block {
+	struct acpi_gtdt_header header;
+	u8 reserved;
+	u64 block_address;
+	u32 timer_count;
+	u32 timer_offset;
+};
+
+/* Timer Sub-Structure, one per timer */
+
+struct acpi_gtdt_timer_entry {
+	u8 frame_number;
+	u8 reserved[3];
+	u64 base_address;
+	u64 el0_base_address;
+	u32 timer_interrupt;
+	u32 timer_flags;
+	u32 virtual_timer_interrupt;
+	u32 virtual_timer_flags;
+	u32 common_flags;
+};
+
+/* Flag Definitions: timer_flags and virtual_timer_flags above */
+
+#define ACPI_GTDT_GT_IRQ_MODE               (1)
+#define ACPI_GTDT_GT_IRQ_POLARITY           (1<<1)
+
+/* Flag Definitions: common_flags above */
+
+#define ACPI_GTDT_GT_IS_SECURE_TIMER        (1)
+#define ACPI_GTDT_GT_ALWAYS_ON              (1<<1)
+
+/* 1: SBSA Generic Watchdog Structure */
+
+struct acpi_gtdt_watchdog {
+	struct acpi_gtdt_header header;
+	u8 reserved;
+	u64 refresh_frame_address;
+	u64 control_frame_address;
+	u32 timer_interrupt;
+	u32 timer_flags;
+};
 
-/* Values for all "TimerFlags" fields above */
+/* Flag Definitions: timer_flags above */
 
-#define ACPI_GTDT_INTERRUPT_MODE            1
-#define ACPI_GTDT_INTERRUPT_POLARITY        2
+#define ACPI_GTDT_WATCHDOG_IRQ_MODE         (1)
+#define ACPI_GTDT_WATCHDOG_IRQ_POLARITY     (1<<1)
+#define ACPI_GTDT_WATCHDOG_SECURE           (1<<2)
 
 /*******************************************************************************
  *
xen/include/asm-arm/acpi.h +2 -0
index 1efa29d..714e596 100644
@@ -46,4 +46,6 @@ static inline void disable_acpi(void)
     acpi_disabled = 1;
 }
 
+#define ACPI_GTDT_INTR_MASK ( ACPI_GTDT_INTERRUPT_MODE | ACPI_GTDT_INTERRUPT_POLARITY )
+
 #endif /*_ASM_ARM_ACPI_H*/
Signature · 1 line
2.1.0
#157 lore raw

PATCH v3 29/62 arm/acpi: Add GTDT support updated by ACPI 5.1

Quoted 11 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

With ACPI 5.0, we got per-processor timer support in GTDT, and ACPI 5.1 introduced the support for platform (memory-mapped)
timers: GT Block and SBSA watchdog timer, add the code needed for the spec change.

Quoted 145 lines
 xen/include/acpi/actbl3.h  | 98 +++++++++++++++++++++++++++++++++++++++-------
 xen/include/asm-arm/acpi.h |  2 +
 2 files changed, 85 insertions(+), 15 deletions(-)
xen/include/acpi/actbl3.h +83 -15
index 8c61b5f..fc96963 100644
@@ -241,33 +241,101 @@ struct acpi_s3pt_suspend {
 
 /*******************************************************************************
  *
- * GTDT - Generic Timer Description Table (ACPI 5.0)
- *        Version 1
+ * GTDT - Generic Timer Description Table (ACPI 5.1)
+ *        Version 2
  *
  ******************************************************************************/
 
 struct acpi_table_gtdt {
 	struct acpi_table_header header;	/* Common ACPI table header */
-	u64 address;
-	u32 flags;
-	u32 secure_pl1_interrupt;
-	u32 secure_pl1_flags;
-	u32 non_secure_pl1_interrupt;
-	u32 non_secure_pl1_flags;
+	u64 counter_block_addresss;
+	u32 reserved;
+	u32 secure_el1_interrupt;
+	u32 secure_el1_flags;
+	u32 non_secure_el1_interrupt;
+	u32 non_secure_el1_flags;
 	u32 virtual_timer_interrupt;
 	u32 virtual_timer_flags;
-	u32 non_secure_pl2_interrupt;
-	u32 non_secure_pl2_flags;
+	u32 non_secure_el2_interrupt;
+	u32 non_secure_el2_flags;
+	u64 counter_read_block_address;
+	u32 platform_timer_count;
+	u32 platform_timer_offset;
 };
 
-/* Values for Flags field above */
+/* Flag Definitions: Timer Block Physical Timers and Virtual timers */
+
+#define ACPI_GTDT_INTERRUPT_MODE        (1)
+#define ACPI_GTDT_INTERRUPT_POLARITY    (1<<1)
+#define ACPI_GTDT_ALWAYS_ON             (1<<2)
+
+/* Common GTDT subtable header */
+
+struct acpi_gtdt_header {
+	u8 type;
+	u16 length;
+};
+
+/* Values for GTDT subtable type above */
+
+enum acpi_gtdt_type {
+	ACPI_GTDT_TYPE_TIMER_BLOCK = 0,
+	ACPI_GTDT_TYPE_WATCHDOG = 1,
+	ACPI_GTDT_TYPE_RESERVED = 2	/* 2 and greater are reserved */
+};
+
+/* GTDT Subtables, correspond to Type in struct acpi_gtdt_header */
 
-#define ACPI_GTDT_MAPPED_BLOCK_PRESENT      1
+/* 0: Generic Timer Block */
+
+struct acpi_gtdt_timer_block {
+	struct acpi_gtdt_header header;
+	u8 reserved;
+	u64 block_address;
+	u32 timer_count;
+	u32 timer_offset;
+};
+
+/* Timer Sub-Structure, one per timer */
+
+struct acpi_gtdt_timer_entry {
+	u8 frame_number;
+	u8 reserved[3];
+	u64 base_address;
+	u64 el0_base_address;
+	u32 timer_interrupt;
+	u32 timer_flags;
+	u32 virtual_timer_interrupt;
+	u32 virtual_timer_flags;
+	u32 common_flags;
+};
+
+/* Flag Definitions: timer_flags and virtual_timer_flags above */
+
+#define ACPI_GTDT_GT_IRQ_MODE               (1)
+#define ACPI_GTDT_GT_IRQ_POLARITY           (1<<1)
+
+/* Flag Definitions: common_flags above */
+
+#define ACPI_GTDT_GT_IS_SECURE_TIMER        (1)
+#define ACPI_GTDT_GT_ALWAYS_ON              (1<<1)
+
+/* 1: SBSA Generic Watchdog Structure */
+
+struct acpi_gtdt_watchdog {
+	struct acpi_gtdt_header header;
+	u8 reserved;
+	u64 refresh_frame_address;
+	u64 control_frame_address;
+	u32 timer_interrupt;
+	u32 timer_flags;
+};
 
-/* Values for all "TimerFlags" fields above */
+/* Flag Definitions: timer_flags above */
 
-#define ACPI_GTDT_INTERRUPT_MODE            1
-#define ACPI_GTDT_INTERRUPT_POLARITY        2
+#define ACPI_GTDT_WATCHDOG_IRQ_MODE         (1)
+#define ACPI_GTDT_WATCHDOG_IRQ_POLARITY     (1<<1)
+#define ACPI_GTDT_WATCHDOG_SECURE           (1<<2)
 
 /*******************************************************************************
  *
xen/include/asm-arm/acpi.h +2 -0
index 1efa29d..714e596 100644
@@ -46,4 +46,6 @@ static inline void disable_acpi(void)
     acpi_disabled = 1;
 }
 
+#define ACPI_GTDT_INTR_MASK ( ACPI_GTDT_INTERRUPT_MODE | ACPI_GTDT_INTERRUPT_POLARITY )
+
 #endif /*_ASM_ARM_ACPI_H*/
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel at lists.xen.org
http://lists.xen.org/xen-devel
Acked-by on v3 29/62
#158 lore raw

Re: [PATCH v3 29/62] arm/acpi: Add GTDT support updated by ACPI 5.1

In reply to shannon.zhao at linaro.org
Quoted 11 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

With ACPI 5.0, we got per-processor timer support in GTDT, and ACPI 5.1 introduced the support for platform (memory-mapped)
timers: GT Block and SBSA watchdog timer, add the code needed for the spec change.

Quoted 145 lines
 xen/include/acpi/actbl3.h  | 98 +++++++++++++++++++++++++++++++++++++++-------
 xen/include/asm-arm/acpi.h |  2 +
 2 files changed, 85 insertions(+), 15 deletions(-)
xen/include/acpi/actbl3.h +83 -15
index 8c61b5f..fc96963 100644
@@ -241,33 +241,101 @@ struct acpi_s3pt_suspend {
 
 /*******************************************************************************
  *
- * GTDT - Generic Timer Description Table (ACPI 5.0)
- *        Version 1
+ * GTDT - Generic Timer Description Table (ACPI 5.1)
+ *        Version 2
  *
  ******************************************************************************/
 
 struct acpi_table_gtdt {
 	struct acpi_table_header header;	/* Common ACPI table header */
-	u64 address;
-	u32 flags;
-	u32 secure_pl1_interrupt;
-	u32 secure_pl1_flags;
-	u32 non_secure_pl1_interrupt;
-	u32 non_secure_pl1_flags;
+	u64 counter_block_addresss;
+	u32 reserved;
+	u32 secure_el1_interrupt;
+	u32 secure_el1_flags;
+	u32 non_secure_el1_interrupt;
+	u32 non_secure_el1_flags;
 	u32 virtual_timer_interrupt;
 	u32 virtual_timer_flags;
-	u32 non_secure_pl2_interrupt;
-	u32 non_secure_pl2_flags;
+	u32 non_secure_el2_interrupt;
+	u32 non_secure_el2_flags;
+	u64 counter_read_block_address;
+	u32 platform_timer_count;
+	u32 platform_timer_offset;
 };
 
-/* Values for Flags field above */
+/* Flag Definitions: Timer Block Physical Timers and Virtual timers */
+
+#define ACPI_GTDT_INTERRUPT_MODE        (1)
+#define ACPI_GTDT_INTERRUPT_POLARITY    (1<<1)
+#define ACPI_GTDT_ALWAYS_ON             (1<<2)
+
+/* Common GTDT subtable header */
+
+struct acpi_gtdt_header {
+	u8 type;
+	u16 length;
+};
+
+/* Values for GTDT subtable type above */
+
+enum acpi_gtdt_type {
+	ACPI_GTDT_TYPE_TIMER_BLOCK = 0,
+	ACPI_GTDT_TYPE_WATCHDOG = 1,
+	ACPI_GTDT_TYPE_RESERVED = 2	/* 2 and greater are reserved */
+};
+
+/* GTDT Subtables, correspond to Type in struct acpi_gtdt_header */
 
-#define ACPI_GTDT_MAPPED_BLOCK_PRESENT      1
+/* 0: Generic Timer Block */
+
+struct acpi_gtdt_timer_block {
+	struct acpi_gtdt_header header;
+	u8 reserved;
+	u64 block_address;
+	u32 timer_count;
+	u32 timer_offset;
+};
+
+/* Timer Sub-Structure, one per timer */
+
+struct acpi_gtdt_timer_entry {
+	u8 frame_number;
+	u8 reserved[3];
+	u64 base_address;
+	u64 el0_base_address;
+	u32 timer_interrupt;
+	u32 timer_flags;
+	u32 virtual_timer_interrupt;
+	u32 virtual_timer_flags;
+	u32 common_flags;
+};
+
+/* Flag Definitions: timer_flags and virtual_timer_flags above */
+
+#define ACPI_GTDT_GT_IRQ_MODE               (1)
+#define ACPI_GTDT_GT_IRQ_POLARITY           (1<<1)
+
+/* Flag Definitions: common_flags above */
+
+#define ACPI_GTDT_GT_IS_SECURE_TIMER        (1)
+#define ACPI_GTDT_GT_ALWAYS_ON              (1<<1)
+
+/* 1: SBSA Generic Watchdog Structure */
+
+struct acpi_gtdt_watchdog {
+	struct acpi_gtdt_header header;
+	u8 reserved;
+	u64 refresh_frame_address;
+	u64 control_frame_address;
+	u32 timer_interrupt;
+	u32 timer_flags;
+};
 
-/* Values for all "TimerFlags" fields above */
+/* Flag Definitions: timer_flags above */
 
-#define ACPI_GTDT_INTERRUPT_MODE            1
-#define ACPI_GTDT_INTERRUPT_POLARITY        2
+#define ACPI_GTDT_WATCHDOG_IRQ_MODE         (1)
+#define ACPI_GTDT_WATCHDOG_IRQ_POLARITY     (1<<1)
+#define ACPI_GTDT_WATCHDOG_SECURE           (1<<2)
 
 /*******************************************************************************
  *
xen/include/asm-arm/acpi.h +2 -0
index 1efa29d..714e596 100644
@@ -46,4 +46,6 @@ static inline void disable_acpi(void)
     acpi_disabled = 1;
 }
 
+#define ACPI_GTDT_INTR_MASK ( ACPI_GTDT_INTERRUPT_MODE | ACPI_GTDT_INTERRUPT_POLARITY )
+
 #endif /*_ASM_ARM_ACPI_H*/
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#159 lore raw

PATCH v3 30/62 arm/irq: Add helper function for setting interrupt type

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Add a helper function to set edge/level type information for an interrupt.

---
 xen/arch/arm/irq.c        | 22 +++++++++++++++-------
 xen/include/asm-arm/irq.h |  2 ++
 2 files changed, 17 insertions(+), 7 deletions(-)
xen/arch/arm/irq.c +15 -7
index 1f38605..90b6e58 100644
@@ -655,6 +655,19 @@ unlock:
     return ret;
 }
 
+int irq_set_type(unsigned int irq, unsigned int type)
+{
+    int res;
+
+    /* Setup the IRQ type */
+    if ( irq < NR_LOCAL_IRQS )
+        res = irq_local_set_type(irq, type);
+    else
+        res = irq_set_spi_type(irq, type);
+
+    return res;
+}
+
 int platform_get_irq(const struct dt_device_node *device, int index)
 {
     struct dt_irq dt_irq;
@@ -668,14 +681,9 @@ int platform_get_irq(const struct dt_device_node *device, int index)
     irq = dt_irq.irq;
     type = dt_irq.type;
 
-    /* Setup the IRQ type */
-    if ( irq < NR_LOCAL_IRQS )
-        res = irq_local_set_type(irq, type);
-    else
-        res = irq_set_spi_type(irq, type);
-
+    res = irq_set_type(irq, type);
     if ( res )
-            return -1;
+        return -1;
 
     return irq;
 }
xen/include/asm-arm/irq.h +2 -0
index f33c331..493773c 100644
@@ -52,6 +52,8 @@ void arch_move_irqs(struct vcpu *v);
 /* Set IRQ type for an SPI */
 int irq_set_spi_type(unsigned int spi, unsigned int type);
 
+int irq_set_type(unsigned int irq, unsigned int type);
+
 int platform_get_irq(const struct dt_device_node *device, int index);
 
 void irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask);
Signature · 1 line
2.1.0
#160 lore raw

PATCH v3 30/62 arm/irq: Add helper function for setting interrupt type

Quoted 40 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Add a helper function to set edge/level type information for an interrupt.

---
 xen/arch/arm/irq.c        | 22 +++++++++++++++-------
 xen/include/asm-arm/irq.h |  2 ++
 2 files changed, 17 insertions(+), 7 deletions(-)
xen/arch/arm/irq.c +13 -0
index 1f38605..90b6e58 100644
@@ -655,6 +655,19 @@ unlock:
     return ret;
 }
 
+int irq_set_type(unsigned int irq, unsigned int type)
+{
+    int res;
+
+    /* Setup the IRQ type */
+    if ( irq < NR_LOCAL_IRQS )
+        res = irq_local_set_type(irq, type);
+    else
+        res = irq_set_spi_type(irq, type);
+
+    return res;
+}
+
 int platform_get_irq(const struct dt_device_node *device, int index)
 {
     struct dt_irq dt_irq;
@@ -668,14 +681,9 @@ int platform_get_irq(const struct dt_device_node *device, int index)
     irq = dt_irq.irq;
     type = dt_irq.type;
 

xen/arch/arm/irq.c int platform_get_irq(const struct dt_device_node *device, int index) · line 686

Quoted 10 lines
xen/arch/arm/irq.c +2 -7
-    /* Setup the IRQ type */
-    if ( irq < NR_LOCAL_IRQS )
-        res = irq_local_set_type(irq, type);
-    else
-        res = irq_set_spi_type(irq, type);
-
+    res = irq_set_type(irq, type);
     if ( res )
-            return -1;
+        return -1;

I would just as well do:

if ( irq_set_type(irq, type) )

    return -1;

and remove res.

In any case:

Quoted 18 lines
xen/arch/arm/irq.c +0 -0
     return irq;
 }
xen/include/asm-arm/irq.h +2 -0
index f33c331..493773c 100644
@@ -52,6 +52,8 @@ void arch_move_irqs(struct vcpu *v);
 /* Set IRQ type for an SPI */
 int irq_set_spi_type(unsigned int spi, unsigned int type);
 
+int irq_set_type(unsigned int irq, unsigned int type);
+
 int platform_get_irq(const struct dt_device_node *device, int index);
 
 void irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask);
Signature · 1 line
2.1.0
Acked-by on v3 30/62
#161 lore raw

Re: [PATCH v3 30/62] arm/irq: Add helper function for setting interrupt type

In reply to shannon.zhao at linaro.org
Quoted 40 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

Add a helper function to set edge/level type information for an interrupt.

---
 xen/arch/arm/irq.c        | 22 +++++++++++++++-------
 xen/include/asm-arm/irq.h |  2 ++
 2 files changed, 17 insertions(+), 7 deletions(-)
xen/arch/arm/irq.c +13 -0
index 1f38605..90b6e58 100644
@@ -655,6 +655,19 @@ unlock:
     return ret;
 }
 
+int irq_set_type(unsigned int irq, unsigned int type)
+{
+    int res;
+
+    /* Setup the IRQ type */
+    if ( irq < NR_LOCAL_IRQS )
+        res = irq_local_set_type(irq, type);
+    else
+        res = irq_set_spi_type(irq, type);
+
+    return res;
+}
+
 int platform_get_irq(const struct dt_device_node *device, int index)
 {
     struct dt_irq dt_irq;
@@ -668,14 +681,9 @@ int platform_get_irq(const struct dt_device_node *device, int index)
     irq = dt_irq.irq;
     type = dt_irq.type;
 

xen/arch/arm/irq.c int platform_get_irq(const struct dt_device_node *device, int index) · line 686

Quoted 10 lines
xen/arch/arm/irq.c +2 -7
-    /* Setup the IRQ type */
-    if ( irq < NR_LOCAL_IRQS )
-        res = irq_local_set_type(irq, type);
-    else
-        res = irq_set_spi_type(irq, type);
-
+    res = irq_set_type(irq, type);
     if ( res )
-            return -1;
+        return -1;

I would just as well do:

if ( irq_set_type(irq, type) )

    return -1;

and remove res.

In any case:

Quoted 18 lines
xen/arch/arm/irq.c +0 -0
     return irq;
 }
xen/include/asm-arm/irq.h +2 -0
index f33c331..493773c 100644
@@ -52,6 +52,8 @@ void arch_move_irqs(struct vcpu *v);
 /* Set IRQ type for an SPI */
 int irq_set_spi_type(unsigned int spi, unsigned int type);
 
+int irq_set_type(unsigned int irq, unsigned int type);
+
 int platform_get_irq(const struct dt_device_node *device, int index);
 
 void irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask);
Signature · 1 line
2.1.0
#162 lore raw

PATCH v3 31/62 arm/acpi: Add a helper function to get interrupt type

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Add a helper funtion to get the type of interrupts in ACPI table.

---
 xen/arch/arm/acpi/lib.c    | 27 +++++++++++++++++++++++++++
 xen/include/asm-arm/acpi.h | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)
xen/arch/arm/acpi/lib.c +27 -0
index d8b7635..47f4c6a 100644
@@ -43,3 +43,30 @@ bool_t __init acpi_psci_hvc_present(void)
 {
     return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC;
 }
+
+unsigned int acpi_get_irq_type(u32 flags)
+{
+    int trigger, polarity;
+
+    trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE
+               : ACPI_LEVEL_SENSITIVE;
+
+    polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW
+                : ACPI_ACTIVE_HIGH;
+
+    switch (polarity) {
+    case ACPI_ACTIVE_LOW:
+        return trigger == ACPI_EDGE_SENSITIVE ?
+            ACPI_IRQ_TYPE_EDGE_FALLING :
+            ACPI_IRQ_TYPE_LEVEL_LOW;
+    case ACPI_ACTIVE_HIGH:
+        return trigger == ACPI_EDGE_SENSITIVE ?
+            ACPI_IRQ_TYPE_EDGE_RISING :
+            ACPI_IRQ_TYPE_LEVEL_HIGH;
+    case ACPI_ACTIVE_BOTH:
+        if (trigger == ACPI_EDGE_SENSITIVE)
+            return ACPI_IRQ_TYPE_EDGE_BOTH;
+    default:
+        return ACPI_IRQ_TYPE_NONE;
+    }
+}
xen/include/asm-arm/acpi.h +39 -0
index 714e596..214fc4e 100644
@@ -34,10 +34,12 @@ extern bool_t acpi_disabled;
 bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
 void __init acpi_smp_init_cpus(void);
+unsigned int acpi_get_irq_type(u32 flags);
 #else
 static inline bool_t acpi_psci_present(void) { return false; }
 static inline bool_t acpi_psci_hvc_present(void) {return false; }
 static inline void acpi_smp_init_cpus(void) { }
+static inline unsigned int acpi_get_irq_type(u32 flags) { return 0; }
 #endif /* CONFIG_ACPI */
 
 /* Basic configuration for ACPI */
@@ -48,4 +50,41 @@ static inline void disable_acpi(void)
 
 #define ACPI_GTDT_INTR_MASK ( ACPI_GTDT_INTERRUPT_MODE | ACPI_GTDT_INTERRUPT_POLARITY )
 
+/* Triggering */
+
+#define ACPI_LEVEL_SENSITIVE            (u8) 0x00
+#define ACPI_EDGE_SENSITIVE             (u8) 0x01
+
+/* Polarity */
+
+#define ACPI_ACTIVE_HIGH                (u8) 0x00
+#define ACPI_ACTIVE_LOW                 (u8) 0x01
+#define ACPI_ACTIVE_BOTH                (u8) 0x02
+
+/**
+ * IRQ line type.
+ *
+ * ACPI_IRQ_TYPE_NONE            - default, unspecified type
+ * ACPI_IRQ_TYPE_EDGE_RISING     - rising edge triggered
+ * ACPI_IRQ_TYPE_EDGE_FALLING    - falling edge triggered
+ * ACPI_IRQ_TYPE_EDGE_BOTH       - rising and falling edge triggered
+ * ACPI_IRQ_TYPE_LEVEL_HIGH      - high level triggered
+ * ACPI_IRQ_TYPE_LEVEL_LOW       - low level triggered
+ * ACPI_IRQ_TYPE_LEVEL_MASK      - Mask to filter out the level bits
+ * ACPI_IRQ_TYPE_SENSE_MASK      - Mask for all the above bits
+ * ACPI_IRQ_TYPE_INVALID         - Use to initialize the type
+ */
+#define ACPI_IRQ_TYPE_NONE           0x00000000
+#define ACPI_IRQ_TYPE_EDGE_RISING    0x00000001
+#define ACPI_IRQ_TYPE_EDGE_FALLING   0x00000002
+#define ACPI_IRQ_TYPE_EDGE_BOTH                           \
+    (ACPI_IRQ_TYPE_EDGE_FALLING | ACPI_IRQ_TYPE_EDGE_RISING)
+#define ACPI_IRQ_TYPE_LEVEL_HIGH     0x00000004
+#define ACPI_IRQ_TYPE_LEVEL_LOW      0x00000008
+#define ACPI_IRQ_TYPE_LEVEL_MASK                          \
+    (ACPI_IRQ_TYPE_LEVEL_LOW | ACPI_IRQ_TYPE_LEVEL_HIGH)
+#define ACPI_IRQ_TYPE_SENSE_MASK     0x0000000f
+
+#define ACPI_IRQ_TYPE_INVALID        0x00000010
+
 #endif /*_ASM_ARM_ACPI_H*/
Signature · 1 line
2.1.0
#163 lore raw

PATCH v3 31/62 arm/acpi: Add a helper function to get interrupt type

Quoted 16 lines · shannon.zhao at linaro.org
xen/include/asm-arm/acpi.h +16 -0
+/**
+ * IRQ line type.
+ *
+ * ACPI_IRQ_TYPE_NONE            - default, unspecified type
+ * ACPI_IRQ_TYPE_EDGE_RISING     - rising edge triggered
+ * ACPI_IRQ_TYPE_EDGE_FALLING    - falling edge triggered
+ * ACPI_IRQ_TYPE_EDGE_BOTH       - rising and falling edge triggered
+ * ACPI_IRQ_TYPE_LEVEL_HIGH      - high level triggered
+ * ACPI_IRQ_TYPE_LEVEL_LOW       - low level triggered
+ * ACPI_IRQ_TYPE_LEVEL_MASK      - Mask to filter out the level bits
+ * ACPI_IRQ_TYPE_SENSE_MASK      - Mask for all the above bits
+ * ACPI_IRQ_TYPE_INVALID         - Use to initialize the type
+ */
+#define ACPI_IRQ_TYPE_NONE           0x00000000
+#define ACPI_IRQ_TYPE_EDGE_RISING    0x00000001
+#define ACPI_IRQ_TYPE_EDGE_FALLING   0x00000002

xen/include/asm-arm/acpi.h static inline void disable_acpi(void) · line 89

Quoted 10 lines
xen/include/asm-arm/acpi.h +10 -0
+#define ACPI_IRQ_TYPE_EDGE_BOTH                           \
+    (ACPI_IRQ_TYPE_EDGE_FALLING | ACPI_IRQ_TYPE_EDGE_RISING)
+#define ACPI_IRQ_TYPE_LEVEL_HIGH     0x00000004
+#define ACPI_IRQ_TYPE_LEVEL_LOW      0x00000008
+#define ACPI_IRQ_TYPE_LEVEL_MASK                          \
+    (ACPI_IRQ_TYPE_LEVEL_LOW | ACPI_IRQ_TYPE_LEVEL_HIGH)
+#define ACPI_IRQ_TYPE_SENSE_MASK     0x0000000f
+
+#define ACPI_IRQ_TYPE_INVALID        0x00000010
+

Using a separate set of *IRQ_TYPE for ACPI and mixing the DT one is wrong.

Today in Xen we only care about edge vs level, so there is no need to define so many things.

However, if you really want to keep all these types. It should be firmware agnostic.

Quoted 2 lines

#endif /*_ASM_ARM_ACPI_H*/

Regards,

Signature · 1 line
Julien Grall
#164 lore raw

Re: [PATCH v3 31/62] arm/acpi: Add a helper function to get interrupt type

In reply to shannon.zhao at linaro.org
Quoted 16 lines · On 17/11/15 09:40, [email protected] wrote:
xen/include/asm-arm/acpi.h +16 -0
+/**
+ * IRQ line type.
+ *
+ * ACPI_IRQ_TYPE_NONE            - default, unspecified type
+ * ACPI_IRQ_TYPE_EDGE_RISING     - rising edge triggered
+ * ACPI_IRQ_TYPE_EDGE_FALLING    - falling edge triggered
+ * ACPI_IRQ_TYPE_EDGE_BOTH       - rising and falling edge triggered
+ * ACPI_IRQ_TYPE_LEVEL_HIGH      - high level triggered
+ * ACPI_IRQ_TYPE_LEVEL_LOW       - low level triggered
+ * ACPI_IRQ_TYPE_LEVEL_MASK      - Mask to filter out the level bits
+ * ACPI_IRQ_TYPE_SENSE_MASK      - Mask for all the above bits
+ * ACPI_IRQ_TYPE_INVALID         - Use to initialize the type
+ */
+#define ACPI_IRQ_TYPE_NONE           0x00000000
+#define ACPI_IRQ_TYPE_EDGE_RISING    0x00000001
+#define ACPI_IRQ_TYPE_EDGE_FALLING   0x00000002

xen/include/asm-arm/acpi.h static inline void disable_acpi(void) · line 89

Quoted 10 lines
xen/include/asm-arm/acpi.h +10 -0
+#define ACPI_IRQ_TYPE_EDGE_BOTH                           \
+    (ACPI_IRQ_TYPE_EDGE_FALLING | ACPI_IRQ_TYPE_EDGE_RISING)
+#define ACPI_IRQ_TYPE_LEVEL_HIGH     0x00000004
+#define ACPI_IRQ_TYPE_LEVEL_LOW      0x00000008
+#define ACPI_IRQ_TYPE_LEVEL_MASK                          \
+    (ACPI_IRQ_TYPE_LEVEL_LOW | ACPI_IRQ_TYPE_LEVEL_HIGH)
+#define ACPI_IRQ_TYPE_SENSE_MASK     0x0000000f
+
+#define ACPI_IRQ_TYPE_INVALID        0x00000010
+

Using a separate set of *IRQ_TYPE for ACPI and mixing the DT one is wrong.

Today in Xen we only care about edge vs level, so there is no need to define so many things.

However, if you really want to keep all these types. It should be firmware agnostic.

Quoted 2 lines

#endif /*_ASM_ARM_ACPI_H*/

Regards,

Signature · 1 line
Julien Grall
#165 lore raw

PATCH v3 31/62 arm/acpi: Add a helper function to get interrupt type

In reply to shannon.zhao at linaro.org
Quoted 15 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Add a helper funtion to get the type of interrupts in ACPI table.

---
 xen/arch/arm/acpi/lib.c    | 27 +++++++++++++++++++++++++++
 xen/include/asm-arm/acpi.h | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)
xen/arch/arm/acpi/lib.c +0 -0
index d8b7635..47f4c6a 100644

xen/arch/arm/acpi/lib.c bool_t __init acpi_psci_hvc_present(void) · line 51

Quoted 9 lines
xen/arch/arm/acpi/lib.c +6 -0
@@ -43,3 +43,30 @@ bool_t __init acpi_psci_hvc_present(void)
 {
     return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC;
 }
+
+unsigned int acpi_get_irq_type(u32 flags)
+{
+    int trigger, polarity;
+
+    trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE

^ GTDT? This is not specific to the GTDT table, right?

xen/arch/arm/acpi/lib.c bool_t __init acpi_psci_hvc_present(void) · line 54

Quoted 3 lines
xen/arch/arm/acpi/lib.c +3 -0
+               : ACPI_LEVEL_SENSITIVE;
+
+    polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW

same here

Quoted 65 lines
xen/arch/arm/acpi/lib.c +18 -0
+                : ACPI_ACTIVE_HIGH;
+
+    switch (polarity) {
+    case ACPI_ACTIVE_LOW:
+        return trigger == ACPI_EDGE_SENSITIVE ?
+            ACPI_IRQ_TYPE_EDGE_FALLING :
+            ACPI_IRQ_TYPE_LEVEL_LOW;
+    case ACPI_ACTIVE_HIGH:
+        return trigger == ACPI_EDGE_SENSITIVE ?
+            ACPI_IRQ_TYPE_EDGE_RISING :
+            ACPI_IRQ_TYPE_LEVEL_HIGH;
+    case ACPI_ACTIVE_BOTH:
+        if (trigger == ACPI_EDGE_SENSITIVE)
+            return ACPI_IRQ_TYPE_EDGE_BOTH;
+    default:
+        return ACPI_IRQ_TYPE_NONE;
+    }
+}
xen/include/asm-arm/acpi.h +28 -0
index 714e596..214fc4e 100644
@@ -34,10 +34,12 @@ extern bool_t acpi_disabled;
 bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
 void __init acpi_smp_init_cpus(void);
+unsigned int acpi_get_irq_type(u32 flags);
 #else
 static inline bool_t acpi_psci_present(void) { return false; }
 static inline bool_t acpi_psci_hvc_present(void) {return false; }
 static inline void acpi_smp_init_cpus(void) { }
+static inline unsigned int acpi_get_irq_type(u32 flags) { return 0; }
 #endif /* CONFIG_ACPI */
 
 /* Basic configuration for ACPI */
@@ -48,4 +50,41 @@ static inline void disable_acpi(void)
 
 #define ACPI_GTDT_INTR_MASK ( ACPI_GTDT_INTERRUPT_MODE | ACPI_GTDT_INTERRUPT_POLARITY )
 
+/* Triggering */
+
+#define ACPI_LEVEL_SENSITIVE            (u8) 0x00
+#define ACPI_EDGE_SENSITIVE             (u8) 0x01
+
+/* Polarity */
+
+#define ACPI_ACTIVE_HIGH                (u8) 0x00
+#define ACPI_ACTIVE_LOW                 (u8) 0x01
+#define ACPI_ACTIVE_BOTH                (u8) 0x02
+
+/**
+ * IRQ line type.
+ *
+ * ACPI_IRQ_TYPE_NONE            - default, unspecified type
+ * ACPI_IRQ_TYPE_EDGE_RISING     - rising edge triggered
+ * ACPI_IRQ_TYPE_EDGE_FALLING    - falling edge triggered
+ * ACPI_IRQ_TYPE_EDGE_BOTH       - rising and falling edge triggered
+ * ACPI_IRQ_TYPE_LEVEL_HIGH      - high level triggered
+ * ACPI_IRQ_TYPE_LEVEL_LOW       - low level triggered
+ * ACPI_IRQ_TYPE_LEVEL_MASK      - Mask to filter out the level bits
+ * ACPI_IRQ_TYPE_SENSE_MASK      - Mask for all the above bits
+ * ACPI_IRQ_TYPE_INVALID         - Use to initialize the type
+ */
+#define ACPI_IRQ_TYPE_NONE           0x00000000
+#define ACPI_IRQ_TYPE_EDGE_RISING    0x00000001

xen/include/asm-arm/acpi.h static inline void disable_acpi(void) · line 88

Quoted 10 lines
xen/include/asm-arm/acpi.h +10 -0
+#define ACPI_IRQ_TYPE_EDGE_FALLING   0x00000002
+#define ACPI_IRQ_TYPE_EDGE_BOTH                           \
+    (ACPI_IRQ_TYPE_EDGE_FALLING | ACPI_IRQ_TYPE_EDGE_RISING)
+#define ACPI_IRQ_TYPE_LEVEL_HIGH     0x00000004
+#define ACPI_IRQ_TYPE_LEVEL_LOW      0x00000008
+#define ACPI_IRQ_TYPE_LEVEL_MASK                          \
+    (ACPI_IRQ_TYPE_LEVEL_LOW | ACPI_IRQ_TYPE_LEVEL_HIGH)
+#define ACPI_IRQ_TYPE_SENSE_MASK     0x0000000f
+
+#define ACPI_IRQ_TYPE_INVALID        0x00000010

Given that these are actually physical irq properties, they don't really depend on ACPI or DT, in fact I believe these are taken from the device tree definitions and renamed.

Instead of duplicating the irq types, I would make the device tree irq types generic.

#166 lore raw

Re: [PATCH v3 31/62] arm/acpi: Add a helper function to get interrupt type

In reply to shannon.zhao at linaro.org
Quoted 15 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Add a helper funtion to get the type of interrupts in ACPI table.

---
 xen/arch/arm/acpi/lib.c    | 27 +++++++++++++++++++++++++++
 xen/include/asm-arm/acpi.h | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)
xen/arch/arm/acpi/lib.c +0 -0
index d8b7635..47f4c6a 100644

xen/arch/arm/acpi/lib.c bool_t __init acpi_psci_hvc_present(void) · line 51

Quoted 9 lines
xen/arch/arm/acpi/lib.c +6 -0
@@ -43,3 +43,30 @@ bool_t __init acpi_psci_hvc_present(void)
 {
     return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC;
 }
+
+unsigned int acpi_get_irq_type(u32 flags)
+{
+    int trigger, polarity;
+
+    trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE

^ GTDT? This is not specific to the GTDT table, right?

xen/arch/arm/acpi/lib.c bool_t __init acpi_psci_hvc_present(void) · line 54

Quoted 3 lines
xen/arch/arm/acpi/lib.c +3 -0
+               : ACPI_LEVEL_SENSITIVE;
+
+    polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW

same here

Quoted 65 lines
xen/arch/arm/acpi/lib.c +18 -0
+                : ACPI_ACTIVE_HIGH;
+
+    switch (polarity) {
+    case ACPI_ACTIVE_LOW:
+        return trigger == ACPI_EDGE_SENSITIVE ?
+            ACPI_IRQ_TYPE_EDGE_FALLING :
+            ACPI_IRQ_TYPE_LEVEL_LOW;
+    case ACPI_ACTIVE_HIGH:
+        return trigger == ACPI_EDGE_SENSITIVE ?
+            ACPI_IRQ_TYPE_EDGE_RISING :
+            ACPI_IRQ_TYPE_LEVEL_HIGH;
+    case ACPI_ACTIVE_BOTH:
+        if (trigger == ACPI_EDGE_SENSITIVE)
+            return ACPI_IRQ_TYPE_EDGE_BOTH;
+    default:
+        return ACPI_IRQ_TYPE_NONE;
+    }
+}
xen/include/asm-arm/acpi.h +28 -0
index 714e596..214fc4e 100644
@@ -34,10 +34,12 @@ extern bool_t acpi_disabled;
 bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
 void __init acpi_smp_init_cpus(void);
+unsigned int acpi_get_irq_type(u32 flags);
 #else
 static inline bool_t acpi_psci_present(void) { return false; }
 static inline bool_t acpi_psci_hvc_present(void) {return false; }
 static inline void acpi_smp_init_cpus(void) { }
+static inline unsigned int acpi_get_irq_type(u32 flags) { return 0; }
 #endif /* CONFIG_ACPI */
 
 /* Basic configuration for ACPI */
@@ -48,4 +50,41 @@ static inline void disable_acpi(void)
 
 #define ACPI_GTDT_INTR_MASK ( ACPI_GTDT_INTERRUPT_MODE | ACPI_GTDT_INTERRUPT_POLARITY )
 
+/* Triggering */
+
+#define ACPI_LEVEL_SENSITIVE            (u8) 0x00
+#define ACPI_EDGE_SENSITIVE             (u8) 0x01
+
+/* Polarity */
+
+#define ACPI_ACTIVE_HIGH                (u8) 0x00
+#define ACPI_ACTIVE_LOW                 (u8) 0x01
+#define ACPI_ACTIVE_BOTH                (u8) 0x02
+
+/**
+ * IRQ line type.
+ *
+ * ACPI_IRQ_TYPE_NONE            - default, unspecified type
+ * ACPI_IRQ_TYPE_EDGE_RISING     - rising edge triggered
+ * ACPI_IRQ_TYPE_EDGE_FALLING    - falling edge triggered
+ * ACPI_IRQ_TYPE_EDGE_BOTH       - rising and falling edge triggered
+ * ACPI_IRQ_TYPE_LEVEL_HIGH      - high level triggered
+ * ACPI_IRQ_TYPE_LEVEL_LOW       - low level triggered
+ * ACPI_IRQ_TYPE_LEVEL_MASK      - Mask to filter out the level bits
+ * ACPI_IRQ_TYPE_SENSE_MASK      - Mask for all the above bits
+ * ACPI_IRQ_TYPE_INVALID         - Use to initialize the type
+ */
+#define ACPI_IRQ_TYPE_NONE           0x00000000
+#define ACPI_IRQ_TYPE_EDGE_RISING    0x00000001

xen/include/asm-arm/acpi.h static inline void disable_acpi(void) · line 88

Quoted 10 lines
xen/include/asm-arm/acpi.h +10 -0
+#define ACPI_IRQ_TYPE_EDGE_FALLING   0x00000002
+#define ACPI_IRQ_TYPE_EDGE_BOTH                           \
+    (ACPI_IRQ_TYPE_EDGE_FALLING | ACPI_IRQ_TYPE_EDGE_RISING)
+#define ACPI_IRQ_TYPE_LEVEL_HIGH     0x00000004
+#define ACPI_IRQ_TYPE_LEVEL_LOW      0x00000008
+#define ACPI_IRQ_TYPE_LEVEL_MASK                          \
+    (ACPI_IRQ_TYPE_LEVEL_LOW | ACPI_IRQ_TYPE_LEVEL_HIGH)
+#define ACPI_IRQ_TYPE_SENSE_MASK     0x0000000f
+
+#define ACPI_IRQ_TYPE_INVALID        0x00000010

Given that these are actually physical irq properties, they don't really depend on ACPI or DT, in fact I believe these are taken from the device tree definitions and renamed.

Instead of duplicating the irq types, I would make the device tree irq types generic.

#167 lore raw

PATCH v3 32/62 arm/acpi: Parse GTDT to initialize timer

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Parse GTDT (Generic Timer Descriptor Table) to initialize timer. Using the information presented by GTDT to initialize the arch timer (not memory-mapped).

---
 xen/arch/arm/time.c | 73 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 62 insertions(+), 11 deletions(-)
xen/arch/arm/time.c +62 -11
index 5ded30c..adbfc2a 100644
@@ -29,6 +29,7 @@
 #include <xen/time.h>
 #include <xen/sched.h>
 #include <xen/event.h>
+#include <xen/acpi.h>
 #include <asm/system.h>
 #include <asm/time.h>
 #include <asm/gic.h>
@@ -65,8 +66,45 @@ unsigned int timer_get_irq(enum timer_ppi ppi)
 
 static __initdata struct dt_device_node *timer;
 
+#ifdef CONFIG_ACPI
+/* Initialize per-processor generic timer */
+static int __init arch_timer_acpi_init(struct acpi_table_header *table)
+{
+    unsigned int irq_type;
+    struct acpi_table_gtdt *gtdt;
+
+    gtdt = container_of(table, struct acpi_table_gtdt, header);
+
+    /* Initialize all the generic timer IRQ variable from GTDT table */
+    irq_type = acpi_get_irq_type(gtdt->non_secure_el1_flags);
+    irq_set_type(gtdt->non_secure_el1_interrupt, irq_type);
+    timer_irq[TIMER_PHYS_NONSECURE_PPI] = gtdt->non_secure_el1_interrupt;
+
+    irq_type = acpi_get_irq_type(gtdt->secure_el1_flags);
+    irq_set_type(gtdt->secure_el1_interrupt, irq_type);
+    timer_irq[TIMER_PHYS_SECURE_PPI] = gtdt->secure_el1_interrupt;
+
+    irq_type = acpi_get_irq_type(gtdt->virtual_timer_flags);
+    irq_set_type(gtdt->virtual_timer_interrupt, irq_type);
+    timer_irq[TIMER_VIRT_PPI] = gtdt->virtual_timer_interrupt;
+
+    irq_type = acpi_get_irq_type(gtdt->non_secure_el2_flags);
+    irq_set_type(gtdt->non_secure_el2_interrupt, irq_type);
+    timer_irq[TIMER_HYP_PPI] = gtdt->non_secure_el2_interrupt;
+
+    return 0;
+}
+
+void __init acpi_preinit_xen_time(void)
+{
+	acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
+}
+#else
+static inline void acpi_preinit_xen_time(void) { }
+#endif
+
 /* Set up the timer on the boot CPU (early init function) */
-void __init preinit_xen_time(void)
+static void __init dt_preinit_xen_time(void)
 {
     static const struct dt_device_match timer_ids[] __initconst =
     {
@@ -74,7 +112,6 @@ void __init preinit_xen_time(void)
         { /* sentinel */ },
     };
     int res;
-    u32 rate;
 
     timer = dt_find_matching_node(NULL, timer_ids);
     if ( !timer )
@@ -86,8 +123,19 @@ void __init preinit_xen_time(void)
     if ( res )
         panic("Timer: Cannot initialize platform timer");
 
-    res = dt_property_read_u32(timer, "clock-frequency", &rate);
-    if ( res )
+}
+
+void __init preinit_xen_time(void)
+{
+    u32 rate;
+
+    /* Initialize all the generic timers presented in GTDT */
+    if ( acpi_disabled )
+        dt_preinit_xen_time();
+    else
+        acpi_preinit_xen_time();
+
+    if( acpi_disabled && dt_property_read_u32(timer, "clock-frequency", &rate) )
     {
         cpu_khz = rate / 1000;
         timer_dt_clock_frequency = rate;
@@ -104,14 +152,17 @@ int __init init_xen_time(void)
     int res;
     unsigned int i;
 
-    /* Retrieve all IRQs for the timer */
-    for ( i = TIMER_PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++ )
+    if( acpi_disabled )
     {
-        res = platform_get_irq(timer, i);
-
-        if ( res < 0 )
-            panic("Timer: Unable to retrieve IRQ %u from the device tree", i);
-        timer_irq[i] = res;
+        /* Retrieve all IRQs for the timer */
+        for ( i = TIMER_PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++ )
+        {
+            res = platform_get_irq(timer, i);
+
+            if ( res < 0 )
+                panic("Timer: Unable to retrieve IRQ %u from the device tree", i);
+            timer_irq[i] = res;
+        }
     }
 
     /* Check that this CPU supports the Generic Timer interface */
Signature · 1 line
2.1.0
#168 lore raw

PATCH v3 32/62 arm/acpi: Parse GTDT to initialize timer

Quoted 49 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Parse GTDT (Generic Timer Descriptor Table) to initialize timer. Using the information presented by GTDT to initialize the arch timer (not memory-mapped).

---
 xen/arch/arm/time.c | 73 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 62 insertions(+), 11 deletions(-)
xen/arch/arm/time.c +21 -0
index 5ded30c..adbfc2a 100644
@@ -29,6 +29,7 @@
 #include <xen/time.h>
 #include <xen/sched.h>
 #include <xen/event.h>
+#include <xen/acpi.h>
 #include <asm/system.h>
 #include <asm/time.h>
 #include <asm/gic.h>
@@ -65,8 +66,45 @@ unsigned int timer_get_irq(enum timer_ppi ppi)
 
 static __initdata struct dt_device_node *timer;
 
+#ifdef CONFIG_ACPI
+/* Initialize per-processor generic timer */
+static int __init arch_timer_acpi_init(struct acpi_table_header *table)
+{
+    unsigned int irq_type;
+    struct acpi_table_gtdt *gtdt;
+
+    gtdt = container_of(table, struct acpi_table_gtdt, header);
+
+    /* Initialize all the generic timer IRQ variable from GTDT table */
+    irq_type = acpi_get_irq_type(gtdt->non_secure_el1_flags);
+    irq_set_type(gtdt->non_secure_el1_interrupt, irq_type);
+    timer_irq[TIMER_PHYS_NONSECURE_PPI] = gtdt->non_secure_el1_interrupt;
+
+    irq_type = acpi_get_irq_type(gtdt->secure_el1_flags);
+    irq_set_type(gtdt->secure_el1_interrupt, irq_type);
+    timer_irq[TIMER_PHYS_SECURE_PPI] = gtdt->secure_el1_interrupt;
+
+    irq_type = acpi_get_irq_type(gtdt->virtual_timer_flags);
+    irq_set_type(gtdt->virtual_timer_interrupt, irq_type);

xen/arch/arm/time.c unsigned int timer_get_irq(enum timer_ppi ppi) · line 98

Quoted 10 lines
xen/arch/arm/time.c +10 -0
+    timer_irq[TIMER_VIRT_PPI] = gtdt->virtual_timer_interrupt;
+
+    irq_type = acpi_get_irq_type(gtdt->non_secure_el2_flags);
+    irq_set_type(gtdt->non_secure_el2_interrupt, irq_type);
+    timer_irq[TIMER_HYP_PPI] = gtdt->non_secure_el2_interrupt;
+
+    return 0;
+}
+
+void __init acpi_preinit_xen_time(void)

static?

Quoted 22 lines
xen/arch/arm/time.c +8 -2
+{
+	acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
+}
+#else
+static inline void acpi_preinit_xen_time(void) { }
+#endif
+
 /* Set up the timer on the boot CPU (early init function) */
-void __init preinit_xen_time(void)
+static void __init dt_preinit_xen_time(void)
 {
     static const struct dt_device_match timer_ids[] __initconst =
     {
@@ -74,7 +112,6 @@ void __init preinit_xen_time(void)
         { /* sentinel */ },
     };
     int res;
-    u32 rate;
 
     timer = dt_find_matching_node(NULL, timer_ids);
     if ( !timer )

xen/arch/arm/time.c void __init preinit_xen_time(void) · line 124

Quoted 2 lines
xen/arch/arm/time.c +0 -0
@@ -86,8 +123,19 @@ void __init preinit_xen_time(void)
     if ( res )
         panic("Timer: Cannot initialize platform timer");

Don't we want to call platform_init_time on ARM too? It doesn't look like something DT specific. I guess we should move the call to the generic init function?

xen/arch/arm/time.c void __init preinit_xen_time(void) · line 90

Quoted 2 lines
xen/arch/arm/time.c +0 -2
-    res = dt_property_read_u32(timer, "clock-frequency", &rate);
-    if ( res )

I think we should keep the clock-frequency DT read in dt_preinit_xen_time.

Quoted 6 lines
xen/arch/arm/time.c +6 -0
+}
+
+void __init preinit_xen_time(void)
+{
+    u32 rate;
+

xen/arch/arm/time.c void __init preinit_xen_time(void) · line 141

Quoted 10 lines
xen/arch/arm/time.c +7 -0
+    /* Initialize all the generic timers presented in GTDT */
+    if ( acpi_disabled )
+        dt_preinit_xen_time();
+    else
+        acpi_preinit_xen_time();
+
+    if( acpi_disabled && dt_property_read_u32(timer, "clock-frequency", &rate) )
     {
         cpu_khz = rate / 1000;
         timer_dt_clock_frequency = rate;

I don't think we want to read a DT property from a generic initialization function.

Quoted 13 lines
xen/arch/arm/time.c +1 -7
@@ -104,14 +152,17 @@ int __init init_xen_time(void)
     int res;
     unsigned int i;
 
-    /* Retrieve all IRQs for the timer */
-    for ( i = TIMER_PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++ )
+    if( acpi_disabled )
     {
-        res = platform_get_irq(timer, i);
-
-        if ( res < 0 )
-            panic("Timer: Unable to retrieve IRQ %u from the device tree", i);
-        timer_irq[i] = res;

xen/arch/arm/time.c int __init init_xen_time(void) · line 166

Quoted 10 lines
xen/arch/arm/time.c +9 -0
+        /* Retrieve all IRQs for the timer */
+        for ( i = TIMER_PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++ )
+        {
+            res = platform_get_irq(timer, i);
+
+            if ( res < 0 )
+                panic("Timer: Unable to retrieve IRQ %u from the device tree", i);
+            timer_irq[i] = res;
+        }
     }

Can't be just move this into the DT specific init function?

Quoted 11 lines
xen/arch/arm/time.c +0 -0
     /* Check that this CPU supports the Generic Timer interface */
Signature · 7 lines
2.1.0


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