xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64
@ 2016-03-02  7:34 Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 01/17] arm/acpi: Add __acpi_map_table function for ARM Shannon Zhao
                   ` (16 more replies)
  0 siblings, 17 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel
  Cc: zhaoshenglong, stefano.stabellini, ian.campbell, Jan Beulich,
	shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

These patches are Part 3 of the previous patch set I sent which adds
ACPI support for arm64 on Xen[1]. Split them as an individual set for
convenient reviewing.

These patches mostly add ACPI support for Xen itself(not yet for Dom0)
on ARM64. It makes Xen could parse physical ACPI tables and initialize
hardwares it uses. But so far it doesn't enable ACPI since it doesn't
add support for Dom0.

This series are rebased on branch staging. See individual patch for
changes.

Thanks,
Shannon
[1] http://lists.xenproject.org/archives/html/xen-devel/2015-11/msg01831.html

Cc: Jan Beulich <jbeulich@suse.com>

Parth Dixit (4):
  arm/acpi: Parse MADT to map logical cpu to MPIDR and get
    cpu_possible_map
  arm: Introduce a generic way to use a device from acpi
  arm/gic-v2: Add ACPI boot support for GICv2
  arm/irq: Add helper function for setting interrupt type

Shannon Zhao (13):
  arm/acpi: Add __acpi_map_table function for ARM
  arm/acpi: Add basic ACPI initialization
  arm/acpi: Move end_boot_allocator after acpi_boot_table_init
  arm/acpi: Parse FADT table and get PSCI flags
  arm/acpi: Add ACPI support for SMP initialization
  acpi/table: Introduce acpi_table_get_entry_madt to get specified entry
  arm/irq: Drop the DT prefix of the irq line type
  arm/gic-v3: Add ACPI boot support for GICv3
  arm/gic: Add ACPI support for GIC preinit
  arm/acpi: Parse GTDT to initialize timer
  arm/acpi: Add a new ACPI initialized function for UART
  arm/fdt: Export device_tree_for_each_node
  arm/acpi: Add acpi parameter to enable/disable acpi

 xen/arch/arm/Makefile         |   1 +
 xen/arch/arm/acpi/Makefile    |   2 +
 xen/arch/arm/acpi/boot.c      | 261 ++++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/acpi/lib.c       |  62 ++++++++++
 xen/arch/arm/arm64/smpboot.c  |   7 +-
 xen/arch/arm/bootfdt.c        |   6 +-
 xen/arch/arm/device.c         |  18 +++
 xen/arch/arm/domain_build.c   |  10 +-
 xen/arch/arm/gic-v2.c         | 127 +++++++++++++++++++-
 xen/arch/arm/gic-v3.c         | 179 ++++++++++++++++++++++++++++-
 xen/arch/arm/gic.c            |  41 ++++++-
 xen/arch/arm/irq.c            |  35 +++---
 xen/arch/arm/psci.c           |  35 ++++--
 xen/arch/arm/setup.c          |  12 +-
 xen/arch/arm/smpboot.c        |   7 +-
 xen/arch/arm/time.c           |  88 +++++++++++---
 xen/arch/arm/xen.lds.S        |   7 ++
 xen/arch/x86/acpi/boot.c      |   4 -
 xen/drivers/acpi/tables.c     |  59 ++++++++++
 xen/drivers/char/arm-uart.c   |  37 +++++-
 xen/include/asm-arm/acpi.h    |   4 +
 xen/include/asm-arm/config.h  |   2 +
 xen/include/asm-arm/device.h  |  30 +++++
 xen/include/asm-arm/irq.h     |   2 +
 xen/include/asm-x86/acpi.h    |   3 -
 xen/include/asm-x86/fixmap.h  |   4 +-
 xen/include/xen/acpi.h        |  12 ++
 xen/include/xen/device_tree.h |  54 +++++----
 xen/include/xen/serial.h      |   2 +-
 29 files changed, 1003 insertions(+), 108 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

-- 
2.0.4



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

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

* [PATCH v8 01/17] arm/acpi: Add __acpi_map_table function for ARM
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02 11:41   ` Stefano Stabellini
  2016-03-02  7:34 ` [PATCH v8 02/17] arm/acpi: Add basic ACPI initialization Shannon Zhao
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel
  Cc: zhaoshenglong, stefano.stabellini, ian.campbell, Jan Beulich,
	shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

Implement __acpi_map_table function for ARM. Move FIX_ACPI_PAGES to
common place and rename it to NUM_FIXMAP_ACPI_PAGES.

Cc: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
---
v8: fix coding style and file header
---
 xen/arch/arm/Makefile        |  1 +
 xen/arch/arm/acpi/Makefile   |  1 +
 xen/arch/arm/acpi/lib.c      | 50 ++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/config.h |  2 ++
 xen/include/asm-x86/acpi.h   |  3 ---
 xen/include/asm-x86/fixmap.h |  4 ++--
 xen/include/xen/acpi.h       |  6 ++++++
 7 files changed, 62 insertions(+), 5 deletions(-)
 create mode 100644 xen/arch/arm/acpi/Makefile
 create mode 100644 xen/arch/arm/acpi/lib.c

diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 1783912..0328b50 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -2,6 +2,7 @@ subdir-$(CONFIG_ARM_32) += arm32
 subdir-$(CONFIG_ARM_64) += arm64
 subdir-y += platforms
 subdir-$(CONFIG_ARM_64) += efi
+subdir-$(CONFIG_ACPI) += acpi
 
 obj-$(EARLY_PRINTK) += early_printk.o
 obj-y += cpu.o
diff --git a/xen/arch/arm/acpi/Makefile b/xen/arch/arm/acpi/Makefile
new file mode 100644
index 0000000..b5be22d
--- /dev/null
+++ b/xen/arch/arm/acpi/Makefile
@@ -0,0 +1 @@
+obj-y += lib.o
diff --git a/xen/arch/arm/acpi/lib.c b/xen/arch/arm/acpi/lib.c
new file mode 100644
index 0000000..7996e9a
--- /dev/null
+++ b/xen/arch/arm/acpi/lib.c
@@ -0,0 +1,50 @@
+/*
+ *  lib.c - Architecture-Specific Low-Level ACPI Support
+ *
+ *  Copyright (C) 2015, Shannon Zhao <shannon.zhao@linaro.org>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  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, see <http://www.gnu.org/licenses/>.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <xen/acpi.h>
+#include <xen/mm.h>
+#include <asm/config.h>
+
+char *__acpi_map_table(paddr_t phys, unsigned long size)
+{
+    unsigned long base, offset, mapped_size;
+    int idx;
+
+    offset = phys & (PAGE_SIZE - 1);
+    mapped_size = PAGE_SIZE - offset;
+    set_fixmap(FIXMAP_ACPI_BEGIN, phys >> PAGE_SHIFT, PAGE_HYPERVISOR);
+    base = FIXMAP_ADDR(FIXMAP_ACPI_BEGIN);
+
+    /* Most cases can be covered by the below. */
+    idx = FIXMAP_ACPI_BEGIN;
+    while ( mapped_size < size )
+    {
+        if ( ++idx > FIXMAP_ACPI_END )
+            return NULL;    /* cannot handle this */
+        phys += PAGE_SIZE;
+        set_fixmap(idx, phys >> PAGE_SHIFT, PAGE_HYPERVISOR);
+        mapped_size += PAGE_SIZE;
+    }
+
+    return ((char *) base + offset);
+}
diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h
index b5d155e..7ceb5c5 100644
--- a/xen/include/asm-arm/config.h
+++ b/xen/include/asm-arm/config.h
@@ -173,6 +173,8 @@
 #define FIXMAP_GICC1    4  /* Interrupt controller: CPU registers (first page) */
 #define FIXMAP_GICC2    5  /* Interrupt controller: CPU registers (second page) */
 #define FIXMAP_GICH     6  /* Interrupt controller: virtual interface control registers */
+#define FIXMAP_ACPI_BEGIN  7  /* Start mappings of ACPI tables */
+#define FIXMAP_ACPI_END    (FIXMAP_ACPI_BEGIN + NUM_FIXMAP_ACPI_PAGES - 1)  /* End mappings of ACPI tables */
 
 #define PAGE_SHIFT              12
 
diff --git a/xen/include/asm-x86/acpi.h b/xen/include/asm-x86/acpi.h
index d532e3d..49f7e1e 100644
--- a/xen/include/asm-x86/acpi.h
+++ b/xen/include/asm-x86/acpi.h
@@ -90,9 +90,6 @@ static inline void disable_acpi(void)
 	acpi_noirq = 1;
 }
 
-/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
-#define FIX_ACPI_PAGES 4
-
 static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
 
 /* routines for saving/restoring kernel state */
diff --git a/xen/include/asm-x86/fixmap.h b/xen/include/asm-x86/fixmap.h
index 1e24b11..dc0856f 100644
--- a/xen/include/asm-x86/fixmap.h
+++ b/xen/include/asm-x86/fixmap.h
@@ -19,11 +19,11 @@
 
 #ifndef __ASSEMBLY__
 
+#include <xen/acpi.h>
 #include <xen/pfn.h>
 #include <xen/kexec.h>
 #include <xen/iommu.h>
 #include <asm/apicdef.h>
-#include <asm/acpi.h>
 #include <asm/amd-iommu.h>
 #include <asm/msi.h>
 #include <acpi/apei.h>
@@ -51,7 +51,7 @@ enum fixed_addresses {
     FIX_IO_APIC_BASE_0,
     FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
     FIX_ACPI_BEGIN,
-    FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
+    FIX_ACPI_END = FIX_ACPI_BEGIN + NUM_FIXMAP_ACPI_PAGES - 1,
     FIX_HPET_BASE,
     FIX_TBOOT_SHARED_BASE,
     FIX_MSIX_IO_RESERV_BASE,
diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h
index 65e53a6..6633414 100644
--- a/xen/include/xen/acpi.h
+++ b/xen/include/xen/acpi.h
@@ -39,6 +39,12 @@
 #define ACPI_MADT_GET_POLARITY(inti)	ACPI_MADT_GET_(POLARITY, inti)
 #define ACPI_MADT_GET_TRIGGER(inti)	ACPI_MADT_GET_(TRIGGER, inti)
 
+/*
+ * Fixmap pages to reserve for ACPI boot-time tables (see asm-x86/fixmap.h or
+ * asm-arm/config.h)
+ */
+#define NUM_FIXMAP_ACPI_PAGES  4
+
 #ifdef CONFIG_ACPI_BOOT
 
 enum acpi_interrupt_id {
-- 
2.0.4



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

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

* [PATCH v8 02/17] arm/acpi: Add basic ACPI initialization
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 01/17] arm/acpi: Add __acpi_map_table function for ARM Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 03/17] arm/acpi: Move end_boot_allocator after acpi_boot_table_init Shannon Zhao
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

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.

Signed-off-by: Naresh Bhat <naresh.bhat@linaro.org>
Signed-off-by: Parth Dixit <parth.dixit@linaro.org>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/acpi/Makefile |  1 +
 xen/arch/arm/acpi/boot.c   | 58 ++++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/setup.c       |  4 ++++
 3 files changed, 63 insertions(+)
 create mode 100644 xen/arch/arm/acpi/boot.c

diff --git a/xen/arch/arm/acpi/Makefile b/xen/arch/arm/acpi/Makefile
index b5be22d..196c40a 100644
--- a/xen/arch/arm/acpi/Makefile
+++ b/xen/arch/arm/acpi/Makefile
@@ -1 +1,2 @@
 obj-y += lib.o
+obj-y += boot.o
diff --git a/xen/arch/arm/acpi/boot.c b/xen/arch/arm/acpi/boot.c
new file mode 100644
index 0000000..1570f7e
--- /dev/null
+++ b/xen/arch/arm/acpi/boot.c
@@ -0,0 +1,58 @@
+/*
+ *  ARM Specific Low-Level ACPI Boot Support
+ *
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
+ *  Copyright (C) 2014, Naresh Bhat <naresh.bhat@linaro.org>
+ *  Copyright (C) 2015, Shannon Zhao <shannon.zhao@linaro.org>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  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;
+
+    /* Initialize the ACPI boot-time table parser. */
+    error = acpi_table_init();
+    if ( error )
+    {
+        disable_acpi();
+        return error;
+    }
+
+    return 0;
+}
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index e6b689e..fee5385 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -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>
@@ -755,6 +756,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();
 
-- 
2.0.4



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

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

* [PATCH v8 03/17] arm/acpi: Move end_boot_allocator after acpi_boot_table_init
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 01/17] arm/acpi: Add __acpi_map_table function for ARM Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 02/17] arm/acpi: Add basic ACPI initialization Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 04/17] arm/acpi: Parse FADT table and get PSCI flags Shannon Zhao
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

To support ACPI NUMA, it needs to make the ACPI initialization done
before boot_end_allocator. Also, x86 does this by the same way.

Signed-off-by: Parth Dixit <parth.dixit@linaro.org>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/setup.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index fee5385..d4261e8 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -615,8 +615,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)
@@ -684,8 +682,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
 
@@ -759,6 +755,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();
 
-- 
2.0.4



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

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

* [PATCH v8 04/17] arm/acpi: Parse FADT table and get PSCI flags
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (2 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 03/17] arm/acpi: Move end_boot_allocator after acpi_boot_table_init Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 05/17] arm/acpi: Parse MADT to map logical cpu to MPIDR and get cpu_possible_map Shannon Zhao
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

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.

Since STAO table and the GIC version are introduced by ACPI 6.0, 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 than 6.0.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Naresh Bhat <naresh.bhat@linaro.org>
Signed-off-by: Parth Dixit <parth.dixit@linaro.org>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/acpi/boot.c   | 30 ++++++++++++++++++++++++++++++
 xen/arch/arm/acpi/lib.c    | 12 ++++++++++++
 xen/include/asm-arm/acpi.h |  3 +++
 3 files changed, 45 insertions(+)

diff --git a/xen/arch/arm/acpi/boot.c b/xen/arch/arm/acpi/boot.c
index 1570f7e..6b33fbe 100644
--- a/xen/arch/arm/acpi/boot.c
+++ b/xen/arch/arm/acpi/boot.c
@@ -27,9 +27,32 @@
 
 #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);
+
+    return -EINVAL;
+}
+
 /*
  * acpi_boot_table_init() called from setup_arch(), always.
  *      1. find RSDP and get its address, and then find XSDT
@@ -54,5 +77,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;
 }
diff --git a/xen/arch/arm/acpi/lib.c b/xen/arch/arm/acpi/lib.c
index 7996e9a..db5c4d8 100644
--- a/xen/arch/arm/acpi/lib.c
+++ b/xen/arch/arm/acpi/lib.c
@@ -48,3 +48,15 @@ char *__acpi_map_table(paddr_t phys, unsigned long size)
 
     return ((char *) base + offset);
 }
+
+/* 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;
+}
diff --git a/xen/include/asm-arm/acpi.h b/xen/include/asm-arm/acpi.h
index 9849edf..48d8556 100644
--- a/xen/include/asm-arm/acpi.h
+++ b/xen/include/asm-arm/acpi.h
@@ -42,6 +42,9 @@ typedef enum {
     TBL_MMAX,
 } EFI_MEM_RES;
 
+bool_t __init acpi_psci_present(void);
+bool_t __init acpi_psci_hvc_present(void);
+
 #ifdef CONFIG_ACPI
 extern bool_t acpi_disabled;
 /* Basic configuration for ACPI */
-- 
2.0.4



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

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

* [PATCH v8 05/17] arm/acpi: Parse MADT to map logical cpu to MPIDR and get cpu_possible_map
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (3 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 04/17] arm/acpi: Parse FADT table and get PSCI flags Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 06/17] arm/acpi: Add ACPI support for SMP initialization Shannon Zhao
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel
  Cc: zhaoshenglong, stefano.stabellini, ian.campbell, Jan Beulich,
	shannon.zhao

From: Parth Dixit <parth.dixit@linaro.org>

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.

Move BAD_MADT_ENTRY to common place, parenthesize its parameters and
drop the pointer cast.

Cc: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Naresh Bhat <naresh.bhat@linaro.org>
Signed-off-by: Parth Dixit <parth.dixit@linaro.org>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/arm/acpi/boot.c   | 121 +++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/acpi/boot.c   |   4 --
 xen/include/asm-arm/acpi.h |   1 +
 xen/include/xen/acpi.h     |   4 ++
 4 files changed, 126 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/acpi/boot.c b/xen/arch/arm/acpi/boot.c
index 6b33fbe..e9321c6 100644
--- a/xen/arch/arm/acpi/boot.c
+++ b/xen/arch/arm/acpi/boot.c
@@ -32,6 +32,127 @@
 #include <xen/mm.h>
 
 #include <asm/acpi.h>
+#include <asm/smp.h>
+
+/* Processors with enabled flag and sane MPIDR */
+static unsigned int enabled_cpus;
+
+/* total number of cpus in this system */
+static unsigned int __initdata total_cpus;
+
+/*
+ * 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_t 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 ( (enabled_cpus == 0) && (cpu_logical_map(0) != mpidr) )
+    {
+        printk("Firmware bug, invalid CPU MPIDR for cpu0: 0x%"PRIx64" in MADT\n",
+               mpidr);
+        return;
+    }
+
+    /*
+     * 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 = 0; 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 =
+               container_of(header, 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 ( enabled_cpus > 1 )
+    {
+        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)
 {
diff --git a/xen/arch/x86/acpi/boot.c b/xen/arch/x86/acpi/boot.c
index fac36c6..385c0be 100644
--- a/xen/arch/x86/acpi/boot.c
+++ b/xen/arch/x86/acpi/boot.c
@@ -43,10 +43,6 @@
 #include <mach_apic.h>
 #include <mach_mpparse.h>
 
-#define BAD_MADT_ENTRY(entry, end) (					    \
-		(!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
-		((struct acpi_subtable_header *)entry)->length != sizeof(*entry))
-
 #define PREFIX			"ACPI: "
 
 bool_t __initdata acpi_noirq;	/* skip ACPI IRQ initialization */
diff --git a/xen/include/asm-arm/acpi.h b/xen/include/asm-arm/acpi.h
index 48d8556..7f59761 100644
--- a/xen/include/asm-arm/acpi.h
+++ b/xen/include/asm-arm/acpi.h
@@ -44,6 +44,7 @@ typedef enum {
 
 bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
+void __init acpi_smp_init_cpus(void);
 
 #ifdef CONFIG_ACPI
 extern bool_t acpi_disabled;
diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h
index 6633414..31a6918 100644
--- a/xen/include/xen/acpi.h
+++ b/xen/include/xen/acpi.h
@@ -45,6 +45,10 @@
  */
 #define NUM_FIXMAP_ACPI_PAGES  4
 
+#define BAD_MADT_ENTRY(entry, end) (                                        \
+                (!(entry)) || (unsigned long)(entry) + sizeof(*(entry)) > (end) ||  \
+                (entry)->header.length < sizeof(*(entry)))
+
 #ifdef CONFIG_ACPI_BOOT
 
 enum acpi_interrupt_id {
-- 
2.0.4



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

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

* [PATCH v8 06/17] arm/acpi: Add ACPI support for SMP initialization
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (4 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 05/17] arm/acpi: Parse MADT to map logical cpu to MPIDR and get cpu_possible_map Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 07/17] acpi/table: Introduce acpi_table_get_entry_madt to get specified entry Shannon Zhao
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

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.

ACPI only supports PSCI 0.2+, since prior to PSCI 0.2 function IDs are
not well-defined.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Parth Dixit <parth.dixit@linaro.org>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/arm64/smpboot.c |  7 ++++++-
 xen/arch/arm/psci.c          | 35 ++++++++++++++++++++++++++++-------
 xen/arch/arm/smpboot.c       |  7 ++++++-
 3 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/xen/arch/arm/arm64/smpboot.c b/xen/arch/arm/arm64/smpboot.c
index 7928f69..4fd0ac6 100644
--- a/xen/arch/arm/arm64/smpboot.c
+++ b/xen/arch/arm/arm64/smpboot.c
@@ -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)
diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
index d800cb6..7966b5e 100644
--- a/xen/arch/arm/psci.c
+++ b/xen/arch/arm/psci.c
@@ -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,12 @@ int __init psci_init_0_1(void)
     int ret;
     const struct dt_device_node *psci;
 
+    if ( !acpi_disabled )
+    {
+        printk("PSCI 0.1 is not supported when using ACPI\n");
+        return -EINVAL;
+    }
+
     psci = dt_find_compatible_node(NULL, NULL, "arm,psci");
     if ( !psci )
         return -EOPNOTSUPP;
@@ -116,15 +123,26 @@ 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() ) {
+            printk("PSCI conduit must be SMC, but is HVC\n");
+            return -EINVAL;
+        }
+    }
 
     psci_ver = call_smc(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
 
@@ -148,6 +166,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();
diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
index b6119d1..c5109bf 100644
--- a/xen/arch/arm/smpboot.c
+++ b/xen/arch/arm/smpboot.c
@@ -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
-- 
2.0.4



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

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

* [PATCH v8 07/17] acpi/table: Introduce acpi_table_get_entry_madt to get specified entry
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (5 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 06/17] arm/acpi: Add ACPI support for SMP initialization Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 08/17] arm: Introduce a generic way to use a device from acpi Shannon Zhao
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel
  Cc: zhaoshenglong, stefano.stabellini, ian.campbell, Jan Beulich,
	shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

This function could get the specified index entry of MADT table. This
would be useful when it needs to get the contens of the entry.

Cc: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/drivers/acpi/tables.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/xen/acpi.h    |  2 ++
 2 files changed, 61 insertions(+)

diff --git a/xen/drivers/acpi/tables.c b/xen/drivers/acpi/tables.c
index 56fa71b..dd2031f 100644
--- a/xen/drivers/acpi/tables.c
+++ b/xen/drivers/acpi/tables.c
@@ -223,6 +223,65 @@ void __init acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	}
 }
 
+static struct acpi_subtable_header * __init
+acpi_get_entry(const char *id, unsigned long table_size,
+	       const struct acpi_table_header *table_header,
+	       enum acpi_madt_type entry_id, unsigned int entry_index)
+{
+	struct acpi_subtable_header *entry;
+	int count = 0;
+	unsigned long table_end;
+
+	if (!table_size)
+		return NULL;
+
+	if (!table_header) {
+		printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
+		return NULL;
+	}
+
+	table_end = (unsigned long)table_header + table_header->length;
+
+	/* Parse all entries looking for a match. */
+	entry = (void *)table_header + table_size;
+
+	while ((unsigned long)(entry + 1) < 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 = (void *)entry + entry->length;
+	}
+
+	return NULL;
+}
+
+struct acpi_subtable_header * __init
+acpi_table_get_entry_madt(enum acpi_madt_type entry_id,
+			  unsigned int entry_index)
+{
+	struct acpi_table_header *table_header;
+	acpi_status status;
+
+	status = acpi_get_table(ACPI_SIG_MADT, acpi_apic_instance,
+				&table_header);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_WARNING PREFIX "%4.4s not present\n",
+		       ACPI_SIG_MADT);
+		return NULL;
+	}
+
+	return acpi_get_entry(ACPI_SIG_MADT, sizeof(struct acpi_table_madt),
+			      table_header, entry_id, entry_index);
+}
 
 int __init
 acpi_parse_entries(char *id, unsigned long table_size,
diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h
index 31a6918..7a5abbe 100644
--- a/xen/include/xen/acpi.h
+++ b/xen/include/xen/acpi.h
@@ -80,6 +80,8 @@ int acpi_parse_entries(char *id, unsigned long table_size,
 		       int entry_id, unsigned int max_entries);
 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_table_get_entry_madt(enum acpi_madt_type id,
+						      unsigned int entry_index);
 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);
-- 
2.0.4



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

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

* [PATCH v8 08/17] arm: Introduce a generic way to use a device from acpi
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (6 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 07/17] acpi/table: Introduce acpi_table_get_entry_madt to get specified entry Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 09/17] arm/irq: Drop the DT prefix of the irq line type Shannon Zhao
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Parth Dixit <parth.dixit@linaro.org>

Add generic way to use device from acpi similar to the way it is
supported in device tree.

Signed-off-by: Parth Dixit <parth.dixit@linaro.org>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/device.c        | 18 ++++++++++++++++++
 xen/arch/arm/xen.lds.S       |  7 +++++++
 xen/include/asm-arm/device.h | 30 ++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+)

diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
index 0b53f6a..a0072c1 100644
--- a/xen/arch/arm/device.c
+++ b/xen/arch/arm/device.c
@@ -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,23 @@ 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;
diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S
index 51a3c6f..9909595 100644
--- a/xen/arch/arm/xen.lds.S
+++ b/xen/arch/arm/xen.lds.S
@@ -105,6 +105,13 @@ SECTIONS
       _edevice = .;
   } :text
 
+  . = ALIGN(8);
+  .adev.info : {
+      _asdevice = .;
+      *(.adev.info)
+      _aedevice = .;
+  } :text
+
   . = ALIGN(PAGE_SIZE);             /* Init code and data */
   __init_begin = .;
   .init.text : {
diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h
index b455bdf..6734ae8 100644
--- a/xen/include/asm-arm/device.h
+++ b/xen/include/asm-arm/device.h
@@ -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           \
+__section(".adev.info") = {                       \
+    .name = _namestr,                                               \
+    .class = _class,                                                \
+
+#define ACPI_DEVICE_END                                               \
+};
+
 #endif /* __ASM_ARM_DEVICE_H */
 
 /*
-- 
2.0.4



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

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

* [PATCH v8 09/17] arm/irq: Drop the DT prefix of the irq line type
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (7 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 08/17] arm: Introduce a generic way to use a device from acpi Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 10/17] arm/gic-v2: Add ACPI boot support for GICv2 Shannon Zhao
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

Make these types generic to DT and ACPI. So they are can be used in ACPI
codes.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/domain_build.c   | 10 ++++-----
 xen/arch/arm/gic-v2.c         | 10 ++++-----
 xen/arch/arm/gic-v3.c         |  8 +++----
 xen/arch/arm/gic.c            |  4 ++--
 xen/arch/arm/irq.c            |  8 +++----
 xen/arch/arm/time.c           |  2 +-
 xen/include/xen/device_tree.h | 50 +++++++++++++++++++++----------------------
 7 files changed, 46 insertions(+), 46 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 0f0f53e..83676e4 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -650,7 +650,7 @@ static int make_hypervisor_node(const struct kernel_info *kinfo,
      * Placeholder for the event channel interrupt.  The values will be
      * replaced later.
      */
-    set_interrupt_ppi(intr, ~0, 0xf, DT_IRQ_TYPE_INVALID);
+    set_interrupt_ppi(intr, ~0, 0xf, IRQ_TYPE_INVALID);
     res = fdt_property_interrupts(fdt, &intr, 1);
     if ( res )
         return res;
@@ -923,15 +923,15 @@ static int make_timer_node(const struct domain *d, void *fdt,
 
     irq = timer_get_irq(TIMER_PHYS_SECURE_PPI);
     DPRINT("  Secure interrupt %u\n", irq);
-    set_interrupt_ppi(intrs[0], irq, 0xf, DT_IRQ_TYPE_LEVEL_LOW);
+    set_interrupt_ppi(intrs[0], irq, 0xf, IRQ_TYPE_LEVEL_LOW);
 
     irq = timer_get_irq(TIMER_PHYS_NONSECURE_PPI);
     DPRINT("  Non secure interrupt %u\n", irq);
-    set_interrupt_ppi(intrs[1], irq, 0xf, DT_IRQ_TYPE_LEVEL_LOW);
+    set_interrupt_ppi(intrs[1], irq, 0xf, IRQ_TYPE_LEVEL_LOW);
 
     irq = timer_get_irq(TIMER_VIRT_PPI);
     DPRINT("  Virt interrupt %u\n", irq);
-    set_interrupt_ppi(intrs[2], irq, 0xf, DT_IRQ_TYPE_LEVEL_LOW);
+    set_interrupt_ppi(intrs[2], irq, 0xf, IRQ_TYPE_LEVEL_LOW);
 
     res = fdt_property_interrupts(fdt, intrs, 3);
     if ( res )
@@ -1463,7 +1463,7 @@ static void evtchn_fixup(struct domain *d, struct kernel_info *kinfo)
      *  TODO: Handle properly the cpumask
      */
     set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf,
-                      DT_IRQ_TYPE_LEVEL_LOW);
+                      IRQ_TYPE_LEVEL_LOW);
     res = fdt_setprop_inplace(kinfo->fdt, node, "interrupts",
                               &intr, sizeof(intr));
     if ( res )
diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 3fb5823..668b863 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -209,16 +209,16 @@ static void gicv2_set_irq_properties(struct irq_desc *desc,
     unsigned int irq = desc->irq;
     unsigned int type = desc->arch.type;
 
-    ASSERT(type != DT_IRQ_TYPE_INVALID);
+    ASSERT(type != IRQ_TYPE_INVALID);
     ASSERT(spin_is_locked(&desc->lock));
 
     spin_lock(&gicv2.lock);
     /* Set edge / level */
     cfg = readl_gicd(GICD_ICFGR + (irq / 16) * 4);
     edgebit = 2u << (2 * (irq % 16));
-    if ( type & DT_IRQ_TYPE_LEVEL_MASK )
+    if ( type & IRQ_TYPE_LEVEL_MASK )
         cfg &= ~edgebit;
-    else if ( type & DT_IRQ_TYPE_EDGE_BOTH )
+    else if ( type & IRQ_TYPE_EDGE_BOTH )
         cfg |= edgebit;
     writel_gicd(cfg, GICD_ICFGR + (irq / 16) * 4);
 
@@ -232,8 +232,8 @@ static void gicv2_set_irq_properties(struct irq_desc *desc,
                cfg & edgebit ? "Edge" : "Level",
                actual & edgebit ? "Edge" : "Level");
         desc->arch.type = actual & edgebit ?
-            DT_IRQ_TYPE_EDGE_RISING :
-            DT_IRQ_TYPE_LEVEL_HIGH;
+            IRQ_TYPE_EDGE_RISING :
+            IRQ_TYPE_LEVEL_HIGH;
     }
 
     /* Set target CPU mask (RAZ/WI on uniprocessor) */
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index fa61231..a42577b 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -491,9 +491,9 @@ static void gicv3_set_irq_properties(struct irq_desc *desc,
     cfg = readl_relaxed(base);
 
     edgebit = 2u << (2 * (irq % 16));
-    if ( type & DT_IRQ_TYPE_LEVEL_MASK )
+    if ( type & IRQ_TYPE_LEVEL_MASK )
         cfg &= ~edgebit;
-    else if ( type & DT_IRQ_TYPE_EDGE_BOTH )
+    else if ( type & IRQ_TYPE_EDGE_BOTH )
         cfg |= edgebit;
 
     writel_relaxed(cfg, base);
@@ -508,8 +508,8 @@ static void gicv3_set_irq_properties(struct irq_desc *desc,
                cfg & edgebit ? "Edge" : "Level",
                actual & edgebit ? "Edge" : "Level");
         desc->arch.type = actual & edgebit ?
-            DT_IRQ_TYPE_EDGE_RISING :
-            DT_IRQ_TYPE_LEVEL_HIGH;
+            IRQ_TYPE_EDGE_RISING :
+            IRQ_TYPE_LEVEL_HIGH;
     }
 
     affinity = gicv3_mpidr_to_affinity(cpu);
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 0b3f634..43e6fa2 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -98,7 +98,7 @@ void gic_restore_state(struct vcpu *v)
  * needs to be called with a valid cpu_mask, ie each cpu in the mask has
  * already called gic_cpu_init
  * - desc.lock must be held
- * - arch.type must be valid (i.e != DT_IRQ_TYPE_INVALID)
+ * - arch.type must be valid (i.e != IRQ_TYPE_INVALID)
  */
 static void gic_set_irq_properties(struct irq_desc *desc,
                                    const cpumask_t *cpu_mask,
@@ -223,7 +223,7 @@ int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
         *out_hwirq += 16;
 
     if ( out_type )
-        *out_type = intspec[2] & DT_IRQ_TYPE_SENSE_MASK;
+        *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
 
     return 0;
 }
diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
index d409abb..0ff5cbc 100644
--- a/xen/arch/arm/irq.c
+++ b/xen/arch/arm/irq.c
@@ -66,7 +66,7 @@ irq_desc_t *__irq_to_desc(int irq)
 
 int __init arch_init_one_irq_desc(struct irq_desc *desc)
 {
-    desc->arch.type = DT_IRQ_TYPE_INVALID;
+    desc->arch.type = IRQ_TYPE_INVALID;
     return 0;
 }
 
@@ -117,7 +117,7 @@ void __init init_IRQ(void)
 
     spin_lock(&local_irqs_type_lock);
     for ( irq = 0; irq < NR_LOCAL_IRQS; irq++ )
-        local_irqs_type[irq] = DT_IRQ_TYPE_INVALID;
+        local_irqs_type[irq] = IRQ_TYPE_INVALID;
     spin_unlock(&local_irqs_type_lock);
 
     BUG_ON(init_local_irq_data() < 0);
@@ -449,7 +449,7 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
 
     spin_lock_irqsave(&desc->lock, flags);
 
-    if ( desc->arch.type == DT_IRQ_TYPE_INVALID )
+    if ( desc->arch.type == IRQ_TYPE_INVALID )
     {
         printk(XENLOG_G_ERR "IRQ %u has not been configured\n", irq);
         retval = -EIO;
@@ -591,7 +591,7 @@ void pirq_set_affinity(struct domain *d, int pirq, const cpumask_t *mask)
 
 static bool_t irq_validate_new_type(unsigned int curr, unsigned new)
 {
-    return (curr == DT_IRQ_TYPE_INVALID || curr == new );
+    return (curr == IRQ_TYPE_INVALID || curr == new );
 }
 
 int irq_set_spi_type(unsigned int spi, unsigned int type)
diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
index 40f4758..73a1a3e 100644
--- a/xen/arch/arm/time.c
+++ b/xen/arch/arm/time.c
@@ -222,7 +222,7 @@ static void check_timer_irq_cfg(unsigned int irq, const char *which)
      * The interrupt controller driver will update desc->arch.type with
      * the actual type which ended up configured in the hardware.
      */
-    if ( desc->arch.type & DT_IRQ_TYPE_LEVEL_MASK )
+    if ( desc->arch.type & IRQ_TYPE_LEVEL_MASK )
         return;
 
     printk(XENLOG_WARNING
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index 5c03f40..cf31e50 100644
--- a/xen/include/xen/device_tree.h
+++ b/xen/include/xen/device_tree.h
@@ -105,33 +105,33 @@ struct dt_phandle_args {
 /**
  * IRQ line type.
  *
- * DT_IRQ_TYPE_NONE            - default, unspecified type
- * DT_IRQ_TYPE_EDGE_RISING     - rising edge triggered
- * DT_IRQ_TYPE_EDGE_FALLING    - falling edge triggered
- * DT_IRQ_TYPE_EDGE_BOTH       - rising and falling edge triggered
- * DT_IRQ_TYPE_LEVEL_HIGH      - high level triggered
- * DT_IRQ_TYPE_LEVEL_LOW       - low level triggered
- * DT_IRQ_TYPE_LEVEL_MASK      - Mask to filter out the level bits
- * DT_IRQ_TYPE_SENSE_MASK      - Mask for all the above bits
- * DT_IRQ_TYPE_INVALID         - Use to initialize the type
- */
-#define DT_IRQ_TYPE_NONE           0x00000000
-#define DT_IRQ_TYPE_EDGE_RISING    0x00000001
-#define DT_IRQ_TYPE_EDGE_FALLING   0x00000002
-#define DT_IRQ_TYPE_EDGE_BOTH                           \
-    (DT_IRQ_TYPE_EDGE_FALLING | DT_IRQ_TYPE_EDGE_RISING)
-#define DT_IRQ_TYPE_LEVEL_HIGH     0x00000004
-#define DT_IRQ_TYPE_LEVEL_LOW      0x00000008
-#define DT_IRQ_TYPE_LEVEL_MASK                          \
-    (DT_IRQ_TYPE_LEVEL_LOW | DT_IRQ_TYPE_LEVEL_HIGH)
-#define DT_IRQ_TYPE_SENSE_MASK     0x0000000f
-
-#define DT_IRQ_TYPE_INVALID        0x00000010
+ * IRQ_TYPE_NONE            - default, unspecified type
+ * IRQ_TYPE_EDGE_RISING     - rising edge triggered
+ * IRQ_TYPE_EDGE_FALLING    - falling edge triggered
+ * IRQ_TYPE_EDGE_BOTH       - rising and falling edge triggered
+ * IRQ_TYPE_LEVEL_HIGH      - high level triggered
+ * IRQ_TYPE_LEVEL_LOW       - low level triggered
+ * IRQ_TYPE_LEVEL_MASK      - Mask to filter out the level bits
+ * IRQ_TYPE_SENSE_MASK      - Mask for all the above bits
+ * IRQ_TYPE_INVALID         - Use to initialize the type
+ */
+#define IRQ_TYPE_NONE           0x00000000
+#define IRQ_TYPE_EDGE_RISING    0x00000001
+#define IRQ_TYPE_EDGE_FALLING   0x00000002
+#define IRQ_TYPE_EDGE_BOTH                           \
+    (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
+#define IRQ_TYPE_LEVEL_HIGH     0x00000004
+#define IRQ_TYPE_LEVEL_LOW      0x00000008
+#define IRQ_TYPE_LEVEL_MASK                          \
+    (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)
+#define IRQ_TYPE_SENSE_MASK     0x0000000f
+
+#define IRQ_TYPE_INVALID        0x00000010
 
 /**
  * dt_irq - describe an IRQ in the device tree
  * @irq: IRQ number
- * @type: IRQ type (see DT_IRQ_TYPE_*)
+ * @type: IRQ type (see IRQ_TYPE_*)
  *
  * This structure is returned when an interrupt is mapped.
  */
@@ -140,12 +140,12 @@ struct dt_irq {
     unsigned int type;
 };
 
-/* If type == DT_IRQ_TYPE_NONE, assume we use level triggered */
+/* If type == IRQ_TYPE_NONE, assume we use level triggered */
 static inline bool_t dt_irq_is_level_triggered(const struct dt_irq *irq)
 {
     unsigned int type = irq->type;
 
-    return (type & DT_IRQ_TYPE_LEVEL_MASK) || (type == DT_IRQ_TYPE_NONE);
+    return (type & IRQ_TYPE_LEVEL_MASK) || (type == IRQ_TYPE_NONE);
 }
 
 /**
-- 
2.0.4



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

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

* [PATCH v8 10/17] arm/gic-v2: Add ACPI boot support for GICv2
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (8 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 09/17] arm/irq: Drop the DT prefix of the irq line type Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 11/17] arm/gic-v3: Add ACPI boot support for GICv3 Shannon Zhao
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Parth Dixit <parth.dixit@linaro.org>

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.

Signed-off-by: Parth Dixit <parth.dixit@linaro.org>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/gic-v2.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 116 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 668b863..0fcb894 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -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,108 @@ static void __init gicv2_dt_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 =
+               container_of(header, 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, IRQ_TYPE_EDGE_BOTH);
+        else
+            irq_set_type(gicv2_info.maintenance_irq, 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 =
+             container_of(header, struct acpi_madt_generic_distributor, header);
+
+    if ( BAD_MADT_ENTRY(dist, end) )
+        return -EINVAL;
+
+    dbase = dist->base_address;
+
+    return 0;
+}
+
+static void __init gicv2_acpi_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 gicv2_acpi_init(void) { }
+#endif
+
 static int __init gicv2_init(void)
 {
     uint32_t aliased_offset = 0;
 
-    gicv2_dt_init();
+    if ( acpi_disabled )
+        gicv2_dt_init();
+    else
+        gicv2_acpi_init();
 
     printk("GICv2 initialization:\n"
               "        gic_dist_addr=%"PRIpaddr"\n"
@@ -793,6 +893,21 @@ DT_DEVICE_START(gicv2, "GICv2", DEVICE_GIC)
         .init = gicv2_dt_preinit,
 DT_DEVICE_END
 
+#ifdef CONFIG_ACPI
+/* Set up the GIC */
+static int __init gicv2_acpi_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 = ACPI_MADT_GIC_VERSION_V2,
+        .init = gicv2_acpi_preinit,
+ACPI_DEVICE_END
+#endif
 /*
  * Local variables:
  * mode: C
-- 
2.0.4



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

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

* [PATCH v8 11/17] arm/gic-v3: Add ACPI boot support for GICv3
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (9 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 10/17] arm/gic-v2: Add ACPI boot support for GICv2 Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 12/17] arm/gic: Add ACPI support for GIC preinit Shannon Zhao
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

Like GICv2, ACPI on Xen hypervisor uses MADT table for proper GICv3
initialization. Parse GIC distributor subtable, redistributor subtable
and interrupt subtable.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/gic-v3.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 170 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index a42577b..f83fd88 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -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 {
@@ -1232,6 +1235,153 @@ static void __init gicv3_dt_init(void)
                           &vbase, &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 =
+               container_of(header, 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, IRQ_TYPE_EDGE_BOTH);
+        else
+            irq_set_type(gicv3_info.maintenance_irq, IRQ_TYPE_LEVEL_MASK);
+
+        cpu_base_assigned = 1;
+    }
+    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 =
+             container_of(header, 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)
+{
+    /* Nothing to do here since it only wants to get the number of GIC
+     * redistributors.
+     */
+    return 0;
+}
+
+static void __init gicv3_acpi_init(void)
+{
+    struct acpi_table_header *table;
+    struct rdist_region *rdist_regs;
+    acpi_status status;
+    int count, i;
+
+    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);
+
+    /* 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 *header;
+        struct acpi_madt_generic_redistributor *gic_rdist;
+
+        header = acpi_table_get_entry_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
+                                           i);
+        if ( !header )
+            panic("GICv3: Can't get GICR entry");
+
+        gic_rdist =
+           container_of(header, struct acpi_madt_generic_redistributor, header);
+        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 gicv3_acpi_init(void) { }
+#endif
+
 /* Set up the GIC */
 static int __init gicv3_init(void)
 {
@@ -1244,7 +1394,10 @@ static int __init gicv3_init(void)
         return -ENODEV;
     }
 
-    gicv3_dt_init();
+    if ( acpi_disabled )
+        gicv3_dt_init();
+    else
+        gicv3_acpi_init();
 
     gicv3.map_dbase = ioremap_nocache(dbase, SZ_64K);
     if ( !gicv3.map_dbase )
@@ -1344,6 +1497,22 @@ DT_DEVICE_START(gicv3, "GICv3", DEVICE_GIC)
         .init = gicv3_dt_preinit,
 DT_DEVICE_END
 
+#ifdef CONFIG_ACPI
+/* Set up the GIC */
+static int __init gicv3_acpi_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 = ACPI_MADT_GIC_VERSION_V3,
+        .init = gicv3_acpi_preinit,
+ACPI_DEVICE_END
+#endif
+
 /*
  * Local variables:
  * mode: C
-- 
2.0.4



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

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

* [PATCH v8 12/17] arm/gic: Add ACPI support for GIC preinit
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (10 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 11/17] arm/gic-v3: Add ACPI boot support for GICv3 Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 13/17] arm/irq: Add helper function for setting interrupt type Shannon Zhao
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

Since ACPI 6.0 defines that GIC Distributor Structure contains the GIC
version filed, it could get GIC version from that. Then call acpi device
initializing function to preinit GIC device.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/gic.c | 37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 43e6fa2..fbbe37f 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -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)
+static void __init gic_dt_preinit(void)
 {
     int rc;
     struct dt_device_node *node;
@@ -261,6 +260,36 @@ void __init gic_preinit(void)
     dt_device_set_used_by(node, DOMID_XEN);
 }
 
+#ifdef CONFIG_ACPI
+static void __init gic_acpi_preinit(void)
+{
+    struct acpi_subtable_header *header;
+    struct acpi_madt_generic_distributor *dist;
+
+    header = acpi_table_get_entry_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+    if ( !header )
+        panic("No valid GICD entries exists");
+
+    dist = container_of(header, struct acpi_madt_generic_distributor, header);
+
+    if ( acpi_device_init(DEVICE_GIC, NULL, dist->version) )
+        panic("Unable to find compatible GIC in the ACPI table");
+}
+#else
+static void __init gic_acpi_preinit(void) { }
+#endif
+
+/* Find the interrupt controller and set up the callback to translate
+ * device tree or ACPI IRQ.
+ */
+void __init gic_preinit(void)
+{
+    if ( acpi_disabled )
+        gic_dt_preinit();
+    else
+        gic_acpi_preinit();
+}
+
 /* Set up the GIC */
 void __init gic_init(void)
 {
-- 
2.0.4



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

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

* [PATCH v8 13/17] arm/irq: Add helper function for setting interrupt type
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (11 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 12/17] arm/gic: Add ACPI support for GIC preinit Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 14/17] arm/acpi: Parse GTDT to initialize timer Shannon Zhao
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Parth Dixit <parth.dixit@linaro.org>

Add a helper function to set edge/level type information for an
interrupt.

Signed-off-by: Parth Dixit <parth.dixit@linaro.org>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/irq.c        | 27 ++++++++++++++++-----------
 xen/include/asm-arm/irq.h |  2 ++
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
index 0ff5cbc..2f8af72 100644
--- a/xen/arch/arm/irq.c
+++ b/xen/arch/arm/irq.c
@@ -655,27 +655,32 @@ 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;
     unsigned int type, irq;
-    int res;
 
-    res = dt_device_get_irq(device, index, &dt_irq);
-    if ( res )
+    if ( dt_device_get_irq(device, index, &dt_irq) )
         return -1;
 
     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);
-
-    if ( res )
-            return -1;
+    if ( irq_set_type(irq, type) )
+        return -1;
 
     return irq;
 }
diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
index f33c331..493773c 100644
--- a/xen/include/asm-arm/irq.h
+++ b/xen/include/asm-arm/irq.h
@@ -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);
-- 
2.0.4



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

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

* [PATCH v8 14/17] arm/acpi: Parse GTDT to initialize timer
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (12 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 13/17] arm/irq: Add helper function for setting interrupt type Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 15/17] arm/acpi: Add a new ACPI initialized function for UART Shannon Zhao
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

Parse GTDT (Generic Timer Descriptor Table) to initialize timer. Using
the information presented by GTDT to initialize the arch timer (not
memory-mapped).

Signed-off-by: Parth Dixit <parth.dixit@linaro.org>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/time.c | 86 +++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 70 insertions(+), 16 deletions(-)

diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
index 73a1a3e..5f8f974 100644
--- a/xen/arch/arm/time.c
+++ b/xen/arch/arm/time.c
@@ -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,51 @@ unsigned int timer_get_irq(enum timer_ppi ppi)
 
 static __initdata struct dt_device_node *timer;
 
+#ifdef CONFIG_ACPI
+static u32 __init acpi_get_timer_irq_type(u32 flags)
+{
+    return (flags & ACPI_GTDT_INTERRUPT_MODE) ? IRQ_TYPE_EDGE_BOTH
+                                              : IRQ_TYPE_LEVEL_MASK;
+}
+
+/* Initialize per-processor generic timer */
+static int __init arch_timer_acpi_init(struct acpi_table_header *header)
+{
+    u32 irq_type;
+    struct acpi_table_gtdt *gtdt;
+
+    gtdt = container_of(header, struct acpi_table_gtdt, header);
+
+    /* Initialize all the generic timer IRQ variable from GTDT table */
+    irq_type = acpi_get_timer_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_timer_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_timer_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_timer_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;
+}
+
+static void __init preinit_acpi_xen_time(void)
+{
+    acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
+}
+#else
+static void __init preinit_acpi_xen_time(void) { }
+#endif
+
 /* Set up the timer on the boot CPU (early init function) */
-void __init preinit_xen_time(void)
+static void __init preinit_dt_xen_time(void)
 {
     static const struct dt_device_match timer_ids[] __initconst =
     {
@@ -75,6 +119,7 @@ void __init preinit_xen_time(void)
     };
     int res;
     u32 rate;
+    unsigned int i;
 
     timer = dt_find_matching_node(NULL, timer_ids);
     if ( !timer )
@@ -82,27 +127,12 @@ void __init preinit_xen_time(void)
 
     dt_device_set_used_by(timer, DOMID_XEN);
 
-    res = platform_init_time();
-    if ( res )
-        panic("Timer: Cannot initialize platform timer");
-
     res = dt_property_read_u32(timer, "clock-frequency", &rate);
     if ( res )
     {
         cpu_khz = rate / 1000;
         timer_dt_clock_frequency = rate;
     }
-    else
-        cpu_khz = READ_SYSREG32(CNTFRQ_EL0) / 1000;
-
-    boot_count = READ_SYSREG64(CNTPCT_EL0);
-}
-
-/* Set up the timer on the boot CPU (late init function) */
-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++ )
@@ -113,7 +143,31 @@ int __init init_xen_time(void)
             panic("Timer: Unable to retrieve IRQ %u from the device tree", i);
         timer_irq[i] = res;
     }
+}
+
+void __init preinit_xen_time(void)
+{
+    int res;
+
+    /* Initialize all the generic timers presented in GTDT */
+    if ( acpi_disabled )
+        preinit_dt_xen_time();
+    else
+        preinit_acpi_xen_time();
+
+    if ( !cpu_khz )
+        cpu_khz = READ_SYSREG32(CNTFRQ_EL0) / 1000;
+
+    res = platform_init_time();
+    if ( res )
+        panic("Timer: Cannot initialize platform timer");
 
+    boot_count = READ_SYSREG64(CNTPCT_EL0);
+}
+
+/* Set up the timer on the boot CPU (late init function) */
+int __init init_xen_time(void)
+{
     /* Check that this CPU supports the Generic Timer interface */
     if ( !cpu_has_gentimer )
         panic("CPU does not support the Generic Timer v1 interface");
-- 
2.0.4



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

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

* [PATCH v8 15/17] arm/acpi: Add a new ACPI initialized function for UART
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (13 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 14/17] arm/acpi: Parse GTDT to initialize timer Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 16/17] arm/fdt: Export device_tree_for_each_node Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 17/17] arm/acpi: Add acpi parameter to enable/disable acpi Shannon Zhao
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

This adds a new function to initialize UART for ACPI on ARM.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/setup.c        |  2 +-
 xen/drivers/char/arm-uart.c | 37 +++++++++++++++++++++++++++++++++++--
 xen/include/xen/serial.h    |  2 +-
 3 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index d4261e8..6d205a9 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -768,7 +768,7 @@ void __init start_xen(unsigned long boot_phys_offset,
 
     gic_preinit();
 
-    dt_uart_init();
+    arm_uart_init();
     console_init_preirq();
     console_init_ring();
 
diff --git a/xen/drivers/char/arm-uart.c b/xen/drivers/char/arm-uart.c
index 883e615..627746b 100644
--- a/xen/drivers/char/arm-uart.c
+++ b/xen/drivers/char/arm-uart.c
@@ -1,7 +1,7 @@
 /*
  * xen/drivers/char/arm-uart.c
  *
- * Generic uart retrieved via the device tree
+ * Generic uart retrieved via the device tree or ACPI
  *
  * Julien Grall <julien.grall@linaro.org>
  * Copyright (c) 2013 Linaro Limited.
@@ -23,6 +23,7 @@
 #include <xen/device_tree.h>
 #include <xen/serial.h>
 #include <xen/errno.h>
+#include <xen/acpi.h>
 
 /*
  * Configure UART port with a string:
@@ -35,7 +36,7 @@
 static char __initdata opt_dtuart[256] = "";
 string_param("dtuart", opt_dtuart);
 
-void __init dt_uart_init(void)
+static void __init dt_uart_init(void)
 {
     struct dt_device_node *dev;
     int ret;
@@ -96,6 +97,38 @@ void __init dt_uart_init(void)
         printk("Unable to initialize dtuart: %d\n", ret);
 }
 
+#ifdef CONFIG_ACPI
+static void __init acpi_uart_init(void)
+{
+    struct acpi_table_spcr *spcr = NULL;
+    int ret;
+
+    acpi_get_table(ACPI_SIG_SPCR, 0, (struct acpi_table_header **)&spcr);
+
+    if ( spcr == NULL )
+    {
+        printk("Unable to get spcr table\n");
+    }
+    else
+    {
+        ret = acpi_device_init(DEVICE_SERIAL, NULL, spcr->interface_type);
+
+        if ( ret )
+            printk("Unable to initialize acpi uart: %d\n", ret);
+    }
+}
+#else
+static void __init acpi_uart_init(void) { }
+#endif
+
+void __init arm_uart_init(void)
+{
+    if ( acpi_disabled )
+        dt_uart_init();
+    else
+        acpi_uart_init();
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h
index 71e6ade..1212a12 100644
--- a/xen/include/xen/serial.h
+++ b/xen/include/xen/serial.h
@@ -170,7 +170,7 @@ struct ns16550_defaults {
 void ns16550_init(int index, struct ns16550_defaults *defaults);
 void ehci_dbgp_init(void);
 
-void __init dt_uart_init(void);
+void arm_uart_init(void);
 
 struct physdev_dbgp_op;
 int dbgp_op(const struct physdev_dbgp_op *);
-- 
2.0.4



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

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

* [PATCH v8 16/17] arm/fdt: Export device_tree_for_each_node
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (14 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 15/17] arm/acpi: Add a new ACPI initialized function for UART Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  2016-03-02  7:34 ` [PATCH v8 17/17] arm/acpi: Add acpi parameter to enable/disable acpi Shannon Zhao
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

This function will be used by ACPI booting. Export it so that it can be
used by other files.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/bootfdt.c        | 6 +++---
 xen/include/xen/device_tree.h | 4 ++++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
index 74d208b..8a14015 100644
--- a/xen/arch/arm/bootfdt.c
+++ b/xen/arch/arm/bootfdt.c
@@ -85,9 +85,9 @@ static u32 __init device_tree_get_u32(const void *fdt, int node,
  * Returns 0 if all nodes were iterated over successfully.  If @func
  * returns a value different from 0, that value is returned immediately.
  */
-static int __init device_tree_for_each_node(const void *fdt,
-                                            device_tree_node_func func,
-                                            void *data)
+int __init device_tree_for_each_node(const void *fdt,
+                                     device_tree_node_func func,
+                                     void *data)
 {
     int node;
     int depth;
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index cf31e50..e3fe77c 100644
--- a/xen/include/xen/device_tree.h
+++ b/xen/include/xen/device_tree.h
@@ -173,6 +173,10 @@ typedef int (*device_tree_node_func)(const void *fdt,
 
 extern const void *device_tree_flattened;
 
+int device_tree_for_each_node(const void *fdt,
+                                     device_tree_node_func func,
+                                     void *data);
+
 /**
  * dt_unflatten_host_device_tree - Unflatten the host device tree
  *
-- 
2.0.4



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

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

* [PATCH v8 17/17] arm/acpi: Add acpi parameter to enable/disable acpi
  2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
                   ` (15 preceding siblings ...)
  2016-03-02  7:34 ` [PATCH v8 16/17] arm/fdt: Export device_tree_for_each_node Shannon Zhao
@ 2016-03-02  7:34 ` Shannon Zhao
  16 siblings, 0 replies; 19+ messages in thread
From: Shannon Zhao @ 2016-03-02  7:34 UTC (permalink / raw)
  To: xen-devel; +Cc: zhaoshenglong, stefano.stabellini, ian.campbell, shannon.zhao

From: Shannon Zhao <shannon.zhao@linaro.org>

Define new command line parameter "acpi" to enable/disable acpi.
This implements the following policy to decide whether ACPI should be
used to boot the system:
- acpi=off: ACPI will not be used to boot the system, even if there is
  no alternative available (e.g., device tree is empty)
- acpi=force: only ACPI will be used to boot the system; if that fails,
  there will be no fallback to alternative methods (such as device tree)
- otherwise, ACPI will be used as a fallback if the device tree turns
  out to lack a platform description; the heuristic to decide this is
  whether /chosen is the only node present at depth 1

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/acpi/boot.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/xen/arch/arm/acpi/boot.c b/xen/arch/arm/acpi/boot.c
index e9321c6..859aa86 100644
--- a/xen/arch/arm/acpi/boot.c
+++ b/xen/arch/arm/acpi/boot.c
@@ -30,9 +30,11 @@
 #include <xen/errno.h>
 #include <acpi/actables.h>
 #include <xen/mm.h>
+#include <xen/device_tree.h>
 
 #include <asm/acpi.h>
 #include <asm/smp.h>
+#include <asm/setup.h>
 
 /* Processors with enabled flag and sane MPIDR */
 static unsigned int enabled_cpus;
@@ -174,6 +176,36 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
     return -EINVAL;
 }
 
+static bool_t __initdata param_acpi_off;
+static bool_t __initdata param_acpi_force;
+
+static void __init parse_acpi_param(char *arg)
+{
+    if ( !arg )
+        return;
+
+    /* Interpret the parameter for use within Xen. */
+    if ( !parse_bool(arg) )
+        param_acpi_off = true;
+    else if ( !strcmp(arg, "force") ) /* force ACPI to be enabled */
+        param_acpi_force = true;
+}
+custom_param("acpi", parse_acpi_param);
+
+static int __init dt_scan_depth1_nodes(const void *fdt, int node,
+                                       const char *uname, int depth,
+                                       u32 address_cells, u32 size_cells,
+                                       void *data)
+{
+    /*
+     * Return 1 as soon as we encounter a node at depth 1 that is
+     * not the /chosen node.
+     */
+    if (depth == 1 && (strcmp(uname, "chosen") != 0))
+        return 1;
+    return 0;
+}
+
 /*
  * acpi_boot_table_init() called from setup_arch(), always.
  *      1. find RSDP and get its address, and then find XSDT
@@ -190,6 +222,26 @@ int __init acpi_boot_table_init(void)
 {
     int error;
 
+    /*
+     * Enable ACPI instead of device tree unless
+     * - ACPI has been disabled explicitly (acpi=off), or
+     * - the device tree is not empty (it has more than just a /chosen node)
+     *   and ACPI has not been force enabled (acpi=force)
+     */
+    if ( param_acpi_off || ( !param_acpi_force
+                             && device_tree_for_each_node(device_tree_flattened,
+                                                   dt_scan_depth1_nodes, NULL)))
+    {
+        disable_acpi();
+        return 0;
+    }
+
+    /*
+     * ACPI is disabled at this point. Enable it in order to parse
+     * the ACPI tables.
+     */
+    enable_acpi();
+
     /* Initialize the ACPI boot-time table parser. */
     error = acpi_table_init();
     if ( error )
-- 
2.0.4



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

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

* Re: [PATCH v8 01/17] arm/acpi: Add __acpi_map_table function for ARM
  2016-03-02  7:34 ` [PATCH v8 01/17] arm/acpi: Add __acpi_map_table function for ARM Shannon Zhao
@ 2016-03-02 11:41   ` Stefano Stabellini
  0 siblings, 0 replies; 19+ messages in thread
From: Stefano Stabellini @ 2016-03-02 11:41 UTC (permalink / raw)
  To: Shannon Zhao
  Cc: shannon.zhao, stefano.stabellini, ian.campbell, Jan Beulich, xen-devel

On Wed, 2 Mar 2016, Shannon Zhao wrote:
> From: Shannon Zhao <shannon.zhao@linaro.org>
> 
> Implement __acpi_map_table function for ARM. Move FIX_ACPI_PAGES to
> common place and rename it to NUM_FIXMAP_ACPI_PAGES.
> 
> Cc: Jan Beulich <jbeulich@suse.com>
> Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>

Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


> v8: fix coding style and file header
> ---
>  xen/arch/arm/Makefile        |  1 +
>  xen/arch/arm/acpi/Makefile   |  1 +
>  xen/arch/arm/acpi/lib.c      | 50 ++++++++++++++++++++++++++++++++++++++++++++
>  xen/include/asm-arm/config.h |  2 ++
>  xen/include/asm-x86/acpi.h   |  3 ---
>  xen/include/asm-x86/fixmap.h |  4 ++--
>  xen/include/xen/acpi.h       |  6 ++++++
>  7 files changed, 62 insertions(+), 5 deletions(-)
>  create mode 100644 xen/arch/arm/acpi/Makefile
>  create mode 100644 xen/arch/arm/acpi/lib.c
> 
> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
> index 1783912..0328b50 100644
> --- a/xen/arch/arm/Makefile
> +++ b/xen/arch/arm/Makefile
> @@ -2,6 +2,7 @@ subdir-$(CONFIG_ARM_32) += arm32
>  subdir-$(CONFIG_ARM_64) += arm64
>  subdir-y += platforms
>  subdir-$(CONFIG_ARM_64) += efi
> +subdir-$(CONFIG_ACPI) += acpi
>  
>  obj-$(EARLY_PRINTK) += early_printk.o
>  obj-y += cpu.o
> diff --git a/xen/arch/arm/acpi/Makefile b/xen/arch/arm/acpi/Makefile
> new file mode 100644
> index 0000000..b5be22d
> --- /dev/null
> +++ b/xen/arch/arm/acpi/Makefile
> @@ -0,0 +1 @@
> +obj-y += lib.o
> diff --git a/xen/arch/arm/acpi/lib.c b/xen/arch/arm/acpi/lib.c
> new file mode 100644
> index 0000000..7996e9a
> --- /dev/null
> +++ b/xen/arch/arm/acpi/lib.c
> @@ -0,0 +1,50 @@
> +/*
> + *  lib.c - Architecture-Specific Low-Level ACPI Support
> + *
> + *  Copyright (C) 2015, Shannon Zhao <shannon.zhao@linaro.org>
> + *
> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> + *
> + *  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, see <http://www.gnu.org/licenses/>.
> + *
> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> + */
> +
> +#include <xen/acpi.h>
> +#include <xen/mm.h>
> +#include <asm/config.h>
> +
> +char *__acpi_map_table(paddr_t phys, unsigned long size)
> +{
> +    unsigned long base, offset, mapped_size;
> +    int idx;
> +
> +    offset = phys & (PAGE_SIZE - 1);
> +    mapped_size = PAGE_SIZE - offset;
> +    set_fixmap(FIXMAP_ACPI_BEGIN, phys >> PAGE_SHIFT, PAGE_HYPERVISOR);
> +    base = FIXMAP_ADDR(FIXMAP_ACPI_BEGIN);
> +
> +    /* Most cases can be covered by the below. */
> +    idx = FIXMAP_ACPI_BEGIN;
> +    while ( mapped_size < size )
> +    {
> +        if ( ++idx > FIXMAP_ACPI_END )
> +            return NULL;    /* cannot handle this */
> +        phys += PAGE_SIZE;
> +        set_fixmap(idx, phys >> PAGE_SHIFT, PAGE_HYPERVISOR);
> +        mapped_size += PAGE_SIZE;
> +    }
> +
> +    return ((char *) base + offset);
> +}
> diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h
> index b5d155e..7ceb5c5 100644
> --- a/xen/include/asm-arm/config.h
> +++ b/xen/include/asm-arm/config.h
> @@ -173,6 +173,8 @@
>  #define FIXMAP_GICC1    4  /* Interrupt controller: CPU registers (first page) */
>  #define FIXMAP_GICC2    5  /* Interrupt controller: CPU registers (second page) */
>  #define FIXMAP_GICH     6  /* Interrupt controller: virtual interface control registers */
> +#define FIXMAP_ACPI_BEGIN  7  /* Start mappings of ACPI tables */
> +#define FIXMAP_ACPI_END    (FIXMAP_ACPI_BEGIN + NUM_FIXMAP_ACPI_PAGES - 1)  /* End mappings of ACPI tables */
>  
>  #define PAGE_SHIFT              12
>  
> diff --git a/xen/include/asm-x86/acpi.h b/xen/include/asm-x86/acpi.h
> index d532e3d..49f7e1e 100644
> --- a/xen/include/asm-x86/acpi.h
> +++ b/xen/include/asm-x86/acpi.h
> @@ -90,9 +90,6 @@ static inline void disable_acpi(void)
>  	acpi_noirq = 1;
>  }
>  
> -/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
> -#define FIX_ACPI_PAGES 4
> -
>  static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
>  
>  /* routines for saving/restoring kernel state */
> diff --git a/xen/include/asm-x86/fixmap.h b/xen/include/asm-x86/fixmap.h
> index 1e24b11..dc0856f 100644
> --- a/xen/include/asm-x86/fixmap.h
> +++ b/xen/include/asm-x86/fixmap.h
> @@ -19,11 +19,11 @@
>  
>  #ifndef __ASSEMBLY__
>  
> +#include <xen/acpi.h>
>  #include <xen/pfn.h>
>  #include <xen/kexec.h>
>  #include <xen/iommu.h>
>  #include <asm/apicdef.h>
> -#include <asm/acpi.h>
>  #include <asm/amd-iommu.h>
>  #include <asm/msi.h>
>  #include <acpi/apei.h>
> @@ -51,7 +51,7 @@ enum fixed_addresses {
>      FIX_IO_APIC_BASE_0,
>      FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
>      FIX_ACPI_BEGIN,
> -    FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
> +    FIX_ACPI_END = FIX_ACPI_BEGIN + NUM_FIXMAP_ACPI_PAGES - 1,
>      FIX_HPET_BASE,
>      FIX_TBOOT_SHARED_BASE,
>      FIX_MSIX_IO_RESERV_BASE,
> diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h
> index 65e53a6..6633414 100644
> --- a/xen/include/xen/acpi.h
> +++ b/xen/include/xen/acpi.h
> @@ -39,6 +39,12 @@
>  #define ACPI_MADT_GET_POLARITY(inti)	ACPI_MADT_GET_(POLARITY, inti)
>  #define ACPI_MADT_GET_TRIGGER(inti)	ACPI_MADT_GET_(TRIGGER, inti)
>  
> +/*
> + * Fixmap pages to reserve for ACPI boot-time tables (see asm-x86/fixmap.h or
> + * asm-arm/config.h)
> + */
> +#define NUM_FIXMAP_ACPI_PAGES  4
> +
>  #ifdef CONFIG_ACPI_BOOT
>  
>  enum acpi_interrupt_id {
> -- 
> 2.0.4
> 
> 

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

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

end of thread, other threads:[~2016-03-02 11:41 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-02  7:34 [PATCH v8 00/17] Add ACPI support for Xen itself on ARM64 Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 01/17] arm/acpi: Add __acpi_map_table function for ARM Shannon Zhao
2016-03-02 11:41   ` Stefano Stabellini
2016-03-02  7:34 ` [PATCH v8 02/17] arm/acpi: Add basic ACPI initialization Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 03/17] arm/acpi: Move end_boot_allocator after acpi_boot_table_init Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 04/17] arm/acpi: Parse FADT table and get PSCI flags Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 05/17] arm/acpi: Parse MADT to map logical cpu to MPIDR and get cpu_possible_map Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 06/17] arm/acpi: Add ACPI support for SMP initialization Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 07/17] acpi/table: Introduce acpi_table_get_entry_madt to get specified entry Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 08/17] arm: Introduce a generic way to use a device from acpi Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 09/17] arm/irq: Drop the DT prefix of the irq line type Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 10/17] arm/gic-v2: Add ACPI boot support for GICv2 Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 11/17] arm/gic-v3: Add ACPI boot support for GICv3 Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 12/17] arm/gic: Add ACPI support for GIC preinit Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 13/17] arm/irq: Add helper function for setting interrupt type Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 14/17] arm/acpi: Parse GTDT to initialize timer Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 15/17] arm/acpi: Add a new ACPI initialized function for UART Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 16/17] arm/fdt: Export device_tree_for_each_node Shannon Zhao
2016-03-02  7:34 ` [PATCH v8 17/17] arm/acpi: Add acpi parameter to enable/disable acpi Shannon Zhao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).