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

[Xen-devel] [RFC PATCH v2 06/22] xen/arm: its: Port ITS driver to xen



From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>

This patch just makes ITS driver taken from linux
compiles in xen environment.

The following changes are done
  - memory allocation apis are changed
  - raw spin lock api's changed to normal spin lock api's
  - debug prints changed to xen debug prints
  - remove msi chip functions to setup_irq and teardown_irq
  - linux irqchip functions are removed
  - updated gic_v3_defs.h file

Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
---
v2: - put unused code under #if0/endif
    - changes to redistributor is moved to separate patch
    - Fixed comments from RFC version
---
 xen/arch/arm/Makefile             |    1 +
 xen/arch/arm/gic-v3-its.c         |  337 +++++++++++++++++++++----------------
 xen/include/asm-arm/gic_v3_defs.h |  116 ++++++++++++-
 3 files changed, 304 insertions(+), 150 deletions(-)

diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 41aba2e..66ea264 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -31,6 +31,7 @@ obj-y += shutdown.o
 obj-y += traps.o
 obj-y += vgic.o vgic-v2.o
 obj-$(CONFIG_ARM_64) += vgic-v3.o
+obj-$(CONFIG_ARM_64) += gic-v3-its.o
 obj-y += vtimer.o
 obj-y += vuart.o
 obj-y += hvm.o
diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
index 596b0a9..ce7ced6 100644
--- a/xen/arch/arm/gic-v3-its.c
+++ b/xen/arch/arm/gic-v3-its.c
@@ -2,6 +2,10 @@
  * Copyright (C) 2013, 2014 ARM Limited, All Rights Reserved.
  * Author: Marc Zyngier <marc.zyngier@xxxxxxx>
  *
+ * Xen changes:
+ * Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
+ * Copyright (C) 2014, 2015 Cavium Inc.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
@@ -15,28 +19,41 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <linux/bitmap.h>
-#include <linux/cpu.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/log2.h>
-#include <linux/mm.h>
-#include <linux/msi.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/of_pci.h>
-#include <linux/of_platform.h>
-#include <linux/percpu.h>
-#include <linux/slab.h>
-
-#include <linux/irqchip/arm-gic-v3.h>
-
-#include <asm/cacheflush.h>
-#include <asm/cputype.h>
-#include <asm/exception.h>
-
-#include "irqchip.h"
+#include <xen/config.h>
+#include <xen/bitops.h>
+#include <xen/lib.h>
+#include <xen/init.h>
+#include <xen/cpu.h>
+#include <xen/mm.h>
+#include <xen/irq.h>
+#include <xen/sched.h>
+#include <xen/errno.h>
+#include <xen/delay.h>
+#include <xen/device_tree.h>
+#include <xen/libfdt/libfdt.h>
+#include <xen/xmalloc.h>
+#include <xen/list.h>
+#include <xen/sizes.h>
+#include <xen/vmap.h>
+#include <asm/p2m.h>
+#include <asm/domain.h>
+#include <asm/io.h>
+#include <asm/device.h>
+#include <asm/gic.h>
+#include <asm/gic_v3_defs.h>
+
+#define its_print(lvl, fmt, ...)                                      \
+       printk(lvl "GIC-ITS:" fmt, ## __VA_ARGS__)
+
+#define its_err(fmt, ...) its_print(XENLOG_ERR, fmt, ## __VA_ARGS__)
+
+#define its_dbg(fmt, ...)                                             \
+       its_print(XENLOG_DEBUG, fmt, ## __VA_ARGS__)
+
+#define its_info(fmt, ...)                                            \
+       its_print(XENLOG_INFO, fmt, ## __VA_ARGS__)
+
+#define its_warn(fmt, ...)                                            \
 
 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING          (1 << 0)
 
@@ -58,10 +75,8 @@ struct its_collection {
  * devices writing to it.
  */
 struct its_node {
-       raw_spinlock_t          lock;
+       spinlock_t              lock;
        struct list_head        entry;
-       struct msi_controller   msi_chip;
-       struct irq_domain       *domain;
        void __iomem            *base;
        unsigned long           phys_base;
        struct its_cmd_block    *cmd_base;
@@ -85,7 +100,7 @@ struct its_device {
        struct its_collection   *collection;
        void                    *itt;
        unsigned long           *lpi_map;
-       irq_hw_number_t         lpi_base;
+       u32                     lpi_base;
        int                     nr_lpis;
        u32                     nr_ites;
        u32                     device_id;
@@ -93,11 +108,11 @@ struct its_device {
 
 static LIST_HEAD(its_nodes);
 static DEFINE_SPINLOCK(its_lock);
-static struct device_node *gic_root_node;
-static struct rdists *gic_rdists;
+static struct dt_device_node *gic_root_node;
+static struct rdist_prop  *gic_rdists;
 
-#define gic_data_rdist()               (raw_cpu_ptr(gic_rdists->rdist))
-#define gic_data_rdist_rd_base()       (gic_data_rdist()->rd_base)
+#define gic_data_rdist()               (per_cpu(rdist, smp_processor_id()))
+#define gic_data_rdist_rd_base()       (per_cpu(rdist, 
smp_processor_id()).rbase)
 
 /*
  * ITS command descriptors - parameters to be encoded in a command
@@ -228,10 +243,10 @@ static struct its_collection *its_build_mapd_cmd(struct 
its_cmd_block *cmd,
                                                 struct its_cmd_desc *desc)
 {
        unsigned long itt_addr;
-       u8 size = ilog2(desc->its_mapd_cmd.dev->nr_ites);
+       u8 size = max(fls(desc->its_mapd_cmd.dev->nr_ites) - 1, 1);
 
-       itt_addr = virt_to_phys(desc->its_mapd_cmd.dev->itt);
-       itt_addr = ALIGN(itt_addr, ITS_ITT_ALIGN);
+       itt_addr = __pa(desc->its_mapd_cmd.dev->itt);
+        itt_addr = ROUNDUP(itt_addr, ITS_ITT_ALIGN);
 
        its_encode_cmd(cmd, GITS_CMD_MAPD);
        its_encode_devid(cmd, desc->its_mapd_cmd.dev->device_id);
@@ -348,7 +363,7 @@ static struct its_cmd_block *its_allocate_entry(struct 
its_node *its)
        while (its_queue_full(its)) {
                count--;
                if (!count) {
-                       pr_err_ratelimited("ITS queue not draining\n");
+                       its_err("ITS queue not draining\n");
                        return NULL;
                }
                cpu_relax();
@@ -380,7 +395,7 @@ static void its_flush_cmd(struct its_node *its, struct 
its_cmd_block *cmd)
         * the ITS.
         */
        if (its->flags & ITS_FLAGS_CMDQ_NEEDS_FLUSHING)
-               __flush_dcache_area(cmd, sizeof(*cmd));
+               clean_and_invalidate_dcache_va_range(cmd, sizeof(*cmd));
        else
                dsb(ishst);
 }
@@ -402,7 +417,7 @@ static void its_wait_for_range_completion(struct its_node 
*its,
 
                count--;
                if (!count) {
-                       pr_err_ratelimited("ITS queue timeout\n");
+                       its_err("ITS queue timeout\n");
                        return;
                }
                cpu_relax();
@@ -418,12 +433,12 @@ static void its_send_single_command(struct its_node *its,
        struct its_collection *sync_col;
        unsigned long flags;
 
-       raw_spin_lock_irqsave(&its->lock, flags);
+       spin_lock_irqsave(&its->lock, flags);
 
        cmd = its_allocate_entry(its);
        if (!cmd) {             /* We're soooooo screewed... */
-               pr_err_ratelimited("ITS can't allocate, dropping command\n");
-               raw_spin_unlock_irqrestore(&its->lock, flags);
+               its_err("ITS can't allocate, dropping command\n");
+               spin_unlock_irqrestore(&its->lock, flags);
                return;
        }
        sync_col = builder(cmd, desc);
@@ -432,7 +447,7 @@ static void its_send_single_command(struct its_node *its,
        if (sync_col) {
                sync_cmd = its_allocate_entry(its);
                if (!sync_cmd) {
-                       pr_err_ratelimited("ITS can't SYNC, skipping\n");
+                       its_err("ITS can't SYNC, skipping\n");
                        goto post;
                }
                its_encode_cmd(sync_cmd, GITS_CMD_SYNC);
@@ -443,12 +458,13 @@ static void its_send_single_command(struct its_node *its,
 
 post:
        next_cmd = its_post_commands(its);
-       raw_spin_unlock_irqrestore(&its->lock, flags);
+       spin_unlock_irqrestore(&its->lock, flags);
 
        its_wait_for_range_completion(its, cmd, next_cmd);
 }
 
-static void its_send_inv(struct its_device *dev, u32 event_id)
+/* TODO: Remove static for the sake of compilation */
+void its_send_inv(struct its_device *dev, u32 event_id)
 {
        struct its_cmd_desc desc;
 
@@ -479,7 +495,8 @@ static void its_send_mapc(struct its_node *its, struct 
its_collection *col,
        its_send_single_command(its, its_build_mapc_cmd, &desc);
 }
 
-static void its_send_mapvi(struct its_device *dev, u32 irq_id, u32 id)
+/* TODO: Remove static for the sake of compilation */
+void its_send_mapvi(struct its_device *dev, u32 irq_id, u32 id)
 {
        struct its_cmd_desc desc;
 
@@ -490,7 +507,8 @@ static void its_send_mapvi(struct its_device *dev, u32 
irq_id, u32 id)
        its_send_single_command(dev->its, its_build_mapvi_cmd, &desc);
 }
 
-static void its_send_movi(struct its_device *dev,
+/* TODO: Remove static for the sake of compilation */
+void its_send_movi(struct its_device *dev,
                          struct its_collection *col, u32 id)
 {
        struct its_cmd_desc desc;
@@ -502,7 +520,8 @@ static void its_send_movi(struct its_device *dev,
        its_send_single_command(dev->its, its_build_movi_cmd, &desc);
 }
 
-static void its_send_discard(struct its_device *dev, u32 id)
+/* TODO: Remove static for the sake of compilation */
+void its_send_discard(struct its_device *dev, u32 id)
 {
        struct its_cmd_desc desc;
 
@@ -522,6 +541,11 @@ static void its_send_invall(struct its_node *its, struct 
its_collection *col)
 }
 
 /*
+ * The below irqchip functions are no more required.
+ * TODO: Will be implemented as separate patch
+ */
+#if 0
+/*
  * irqchip functions - assumes MSI, mostly.
  */
 
@@ -630,6 +654,7 @@ static struct irq_chip its_msi_irq_chip = {
        .irq_eoi                = irq_chip_eoi_parent,
        .irq_write_msi_msg      = pci_msi_domain_write_msg,
 };
+#endif
 
 /*
  * How we allocate LPIs:
@@ -662,25 +687,24 @@ static int its_lpi_init(u32 id_bits)
 {
        lpi_chunks = its_lpi_to_chunk(1UL << id_bits);
 
-       lpi_bitmap = kzalloc(BITS_TO_LONGS(lpi_chunks) * sizeof(long),
-                            GFP_KERNEL);
+       lpi_bitmap = xzalloc_bytes(BITS_TO_LONGS(lpi_chunks) * sizeof(long));
        if (!lpi_bitmap) {
                lpi_chunks = 0;
                return -ENOMEM;
        }
 
-       pr_info("ITS: Allocated %d chunks for LPIs\n", (int)lpi_chunks);
+       its_info("ITS: Allocated %d chunks for LPIs\n", (int)lpi_chunks);
        return 0;
 }
 
-static unsigned long *its_lpi_alloc_chunks(int nr_irqs, int *base, int *nr_ids)
+static unsigned long *its_lpi_alloc_chunks(int nirqs, int *base, int *nr_ids)
 {
        unsigned long *bitmap = NULL;
        int chunk_id;
        int nr_chunks;
        int i;
 
-       nr_chunks = DIV_ROUND_UP(nr_irqs, IRQS_PER_CHUNK);
+       nr_chunks = DIV_ROUND_UP(nirqs, IRQS_PER_CHUNK);
 
        spin_lock(&lpi_lock);
 
@@ -696,8 +720,7 @@ static unsigned long *its_lpi_alloc_chunks(int nr_irqs, int 
*base, int *nr_ids)
        if (!nr_chunks)
                goto out;
 
-       bitmap = kzalloc(BITS_TO_LONGS(nr_chunks * IRQS_PER_CHUNK) * sizeof 
(long),
-                        GFP_ATOMIC);
+       bitmap = xzalloc_bytes(BITS_TO_LONGS(nr_chunks * IRQS_PER_CHUNK) * 
sizeof (long));
        if (!bitmap)
                goto out;
 
@@ -713,7 +736,8 @@ out:
        return bitmap;
 }
 
-static void its_lpi_free(unsigned long *bitmap, int base, int nr_ids)
+/* TODO: Remove static for the sake of compilation */
+void its_lpi_free(unsigned long *bitmap, int base, int nr_ids)
 {
        int lpi;
 
@@ -725,13 +749,13 @@ static void its_lpi_free(unsigned long *bitmap, int base, 
int nr_ids)
                if (test_bit(chunk, lpi_bitmap)) {
                        clear_bit(chunk, lpi_bitmap);
                } else {
-                       pr_err("Bad LPI chunk %d\n", chunk);
+                       its_err("Bad LPI chunk %d\n", chunk);
                }
        }
 
        spin_unlock(&lpi_lock);
 
-       kfree(bitmap);
+       xfree(bitmap);
 }
 
 /*
@@ -745,31 +769,31 @@ static void its_lpi_free(unsigned long *bitmap, int base, 
int nr_ids)
 /*
  * This is how many bits of ID we need, including the useless ones.
  */
-#define LPI_NRBITS             ilog2(LPI_PROPBASE_SZ + SZ_8K)
+#define LPI_NRBITS             fls(LPI_PROPBASE_SZ + SZ_8K) - 1
 
 #define LPI_PROP_DEFAULT_PRIO  0xa0
 
 static int __init its_alloc_lpi_tables(void)
 {
-       phys_addr_t paddr;
+       paddr_t paddr;
 
-       gic_rdists->prop_page = alloc_pages(GFP_NOWAIT,
-                                          get_order(LPI_PROPBASE_SZ));
+       gic_rdists->prop_page = 
alloc_xenheap_pages(get_order_from_bytes(LPI_PROPBASE_SZ), 0);
        if (!gic_rdists->prop_page) {
-               pr_err("Failed to allocate PROPBASE\n");
+               its_err("Failed to allocate PROPBASE\n");
                return -ENOMEM;
        }
 
-       paddr = page_to_phys(gic_rdists->prop_page);
-       pr_info("GIC: using LPI property table @%pa\n", &paddr);
+       paddr = __pa(gic_rdists->prop_page);
+       its_info("GIC: using LPI property table @%pa\n", &paddr);
 
        /* Priority 0xa0, Group-1, disabled */
-       memset(page_address(gic_rdists->prop_page),
+       memset(gic_rdists->prop_page,
               LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1,
               LPI_PROPBASE_SZ);
 
        /* Make sure the GIC will observe the written configuration */
-       __flush_dcache_area(page_address(gic_rdists->prop_page), 
LPI_PROPBASE_SZ);
+       clean_and_invalidate_dcache_va_range(gic_rdists->prop_page,
+                                            LPI_PROPBASE_SZ);
 
        return 0;
 }
@@ -790,7 +814,7 @@ static void its_free_tables(struct its_node *its)
 
        for (i = 0; i < GITS_BASER_NR_REGS; i++) {
                if (its->tables[i]) {
-                       free_page((unsigned long)its->tables[i]);
+                       xfree(its->tables[i]);
                        its->tables[i] = NULL;
                }
        }
@@ -807,7 +831,7 @@ static int its_alloc_tables(struct its_node *its)
                u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
                u64 type = GITS_BASER_TYPE(val);
                u64 entry_size = GITS_BASER_ENTRY_SIZE(val);
-               int order = get_order(psz);
+               int order = get_order_from_bytes(psz);
                int alloc_size;
                u64 tmp;
                void *base;
@@ -827,25 +851,25 @@ static int its_alloc_tables(struct its_node *its)
                        u64 typer = readq_relaxed(its->base + GITS_TYPER);
                        u32 ids = GITS_TYPER_DEVBITS(typer);
 
-                       order = get_order((1UL << ids) * entry_size);
+                       order = get_order_from_bytes((1UL << ids) * entry_size);
                        if (order >= MAX_ORDER) {
                                order = MAX_ORDER - 1;
-                               pr_warn("%s: Device Table too large, reduce its 
page order to %u\n",
-                                       its->msi_chip.of_node->full_name, 
order);
+                               its_warn("Device Table too large, reduce its 
page order to %u\n",
+                                        order);
                        }
                }
 
                alloc_size = (1 << order) * PAGE_SIZE;
-               base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
+               base = alloc_xenheap_pages(order, 0);
                if (!base) {
                        err = -ENOMEM;
                        goto out_free;
                }
-
+               memset(base, 0, alloc_size);
                its->tables[i] = base;
 
 retry_baser:
-               val = (virt_to_phys(base)                                |
+               val = (__pa(base)                                        |
                       (type << GITS_BASER_TYPE_SHIFT)                   |
                       ((entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) |
                       GITS_BASER_WaWb                                   |
@@ -897,17 +921,17 @@ retry_baser:
                }
 
                if (val != tmp) {
-                       pr_err("ITS: %s: GITS_BASER%d doesn't stick: %lx %lx\n",
-                              its->msi_chip.of_node->full_name, i,
+                       its_err("ITS: GITS_BASER%d doesn't stick: %lx %lx\n",
+                              i,
                               (unsigned long) val, (unsigned long) tmp);
                        err = -ENXIO;
                        goto out_free;
                }
 
-               pr_info("ITS: allocated %d %s @%lx (psz %dK, shr %d)\n",
+               its_info("ITS: allocated %d %s @%lx (psz %dK, shr %d)\n",
                        (int)(alloc_size / entry_size),
                        its_base_type_string[type],
-                       (unsigned long)virt_to_phys(base),
+                       (unsigned long)__pa(base),
                        psz / SZ_1K, (int)shr >> GITS_BASER_SHAREABILITY_SHIFT);
        }
 
@@ -921,8 +945,7 @@ out_free:
 
 static int its_alloc_collections(struct its_node *its)
 {
-       its->collections = kzalloc(nr_cpu_ids * sizeof(*its->collections),
-                                  GFP_KERNEL);
+       its->collections = xzalloc_array(struct its_collection, nr_cpu_ids);
        if (!its->collections)
                return -ENOMEM;
 
@@ -932,32 +955,31 @@ static int its_alloc_collections(struct its_node *its)
 static void its_cpu_init_lpis(void)
 {
        void __iomem *rbase = gic_data_rdist_rd_base();
-       struct page *pend_page;
+       void *pend_page;
        u64 val, tmp;
 
        /* If we didn't allocate the pending table yet, do it now */
-       pend_page = gic_data_rdist()->pend_page;
+       pend_page = gic_data_rdist().pend_page;
        if (!pend_page) {
-               phys_addr_t paddr;
+               paddr_t paddr;
                /*
                 * The pending pages have to be at least 64kB aligned,
                 * hence the 'max(LPI_PENDBASE_SZ, SZ_64K)' below.
                 */
-               pend_page = alloc_pages(GFP_NOWAIT | __GFP_ZERO,
-                                       get_order(max(LPI_PENDBASE_SZ, 
SZ_64K)));
+               pend_page = 
alloc_xenheap_pages(get_order_from_bytes(max(LPI_PENDBASE_SZ, SZ_64K)), 0);
                if (!pend_page) {
-                       pr_err("Failed to allocate PENDBASE for CPU%d\n",
+                       its_err("Failed to allocate PENDBASE for CPU%d\n",
                               smp_processor_id());
                        return;
                }
-
+               memset(pend_page, 0, max(LPI_PENDBASE_SZ, SZ_64K));
                /* Make sure the GIC will observe the zero-ed page */
-               __flush_dcache_area(page_address(pend_page), LPI_PENDBASE_SZ);
+               clean_and_invalidate_dcache_va_range(pend_page, 
LPI_PENDBASE_SZ);
 
-               paddr = page_to_phys(pend_page);
-               pr_info("CPU%d: using LPI pending table @%pa\n",
+               paddr = __pa(pend_page);
+               its_info("CPU%d: using LPI pending table @%pa\n",
                        smp_processor_id(), &paddr);
-               gic_data_rdist()->pend_page = pend_page;
+               gic_data_rdist().pend_page = pend_page;
        }
 
        /* Disable LPIs */
@@ -971,7 +993,7 @@ static void its_cpu_init_lpis(void)
        dsb(sy);
 
        /* set PROPBASE */
-       val = (page_to_phys(gic_rdists->prop_page) |
+       val = (__pa(gic_rdists->prop_page)   |
               GICR_PROPBASER_InnerShareable |
               GICR_PROPBASER_WaWb |
               ((LPI_NRBITS - 1) & GICR_PROPBASER_IDBITS_MASK));
@@ -980,12 +1002,12 @@ static void its_cpu_init_lpis(void)
        tmp = readq_relaxed(rbase + GICR_PROPBASER);
 
        if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
-               pr_info_once("GIC: using cache flushing for LPI property 
table\n");
+               its_info("GIC: using cache flushing for LPI property table\n");
                gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING;
        }
 
        /* set PENDBASE */
-       val = (page_to_phys(pend_page) |
+       val = (__pa(pend_page)               |
               GICR_PROPBASER_InnerShareable |
               GICR_PROPBASER_WaWb);
 
@@ -1020,7 +1042,7 @@ static void its_cpu_init_collection(void)
                         * This ITS wants the physical address of the
                         * redistributor.
                         */
-                       target = gic_data_rdist()->phys_base;
+                       target = gic_data_rdist().phys_base;
                } else {
                        /*
                         * This ITS wants a linear CPU number.
@@ -1040,12 +1062,13 @@ static void its_cpu_init_collection(void)
        spin_unlock(&its_lock);
 }
 
-static struct its_device *its_find_device(struct its_node *its, u32 dev_id)
+/* TODO: Remove static for the sake of compilation */
+struct its_device *its_find_device(struct its_node *its, u32 dev_id)
 {
        struct its_device *its_dev = NULL, *tmp;
        unsigned long flags;
 
-       raw_spin_lock_irqsave(&its->lock, flags);
+       spin_lock_irqsave(&its->lock, flags);
 
        list_for_each_entry(tmp, &its->its_device_list, entry) {
                if (tmp->device_id == dev_id) {
@@ -1054,12 +1077,13 @@ static struct its_device *its_find_device(struct 
its_node *its, u32 dev_id)
                }
        }
 
-       raw_spin_unlock_irqrestore(&its->lock, flags);
+       spin_unlock_irqrestore(&its->lock, flags);
 
        return its_dev;
 }
 
-static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
+/* TODO: Remove static for the sake of compilation */
+struct its_device *its_create_device(struct its_node *its, u32 dev_id,
                                            int nvecs)
 {
        struct its_device *dev;
@@ -1072,22 +1096,26 @@ static struct its_device *its_create_device(struct 
its_node *its, u32 dev_id,
        int cpu;
        int sz;
 
-       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       dev = xzalloc(struct its_device);
        /*
         * At least one bit of EventID is being used, hence a minimum
         * of two entries. No, the architecture doesn't let you
         * express an ITT with a single entry.
         */
-       nr_ites = max(2UL, roundup_pow_of_two(nvecs));
+        /*
+        * TODO: replace roundup_pow_of_2 with shift for now.
+        * This code is not used later
+        */
+       nr_ites = max(2UL, (1UL << (nvecs)));
        sz = nr_ites * its->ite_size;
        sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
-       itt = kzalloc(sz, GFP_KERNEL);
+       itt = xzalloc_bytes(sz);
        lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis);
 
        if (!dev || !itt || !lpi_map) {
-               kfree(dev);
-               kfree(itt);
-               kfree(lpi_map);
+               xfree(dev);
+               xfree(itt);
+               xfree(lpi_map);
                return NULL;
        }
 
@@ -1100,12 +1128,12 @@ static struct its_device *its_create_device(struct 
its_node *its, u32 dev_id,
        dev->device_id = dev_id;
        INIT_LIST_HEAD(&dev->entry);
 
-       raw_spin_lock_irqsave(&its->lock, flags);
+       spin_lock_irqsave(&its->lock, flags);
        list_add(&dev->entry, &its->its_device_list);
-       raw_spin_unlock_irqrestore(&its->lock, flags);
+       spin_unlock_irqrestore(&its->lock, flags);
 
        /* Bind the device to the first possible CPU */
-       cpu = cpumask_first(cpu_online_mask);
+       cpu = cpumask_first(&cpu_online_map);
        dev->collection = &its->collections[cpu];
 
        /* Map device to its ITT */
@@ -1114,18 +1142,20 @@ static struct its_device *its_create_device(struct 
its_node *its, u32 dev_id,
        return dev;
 }
 
-static void its_free_device(struct its_device *its_dev)
+/* TODO: Remove static for the sake of compilation */
+void its_free_device(struct its_device *its_dev)
 {
        unsigned long flags;
 
-       raw_spin_lock_irqsave(&its_dev->its->lock, flags);
+       spin_lock_irqsave(&its_dev->its->lock, flags);
        list_del(&its_dev->entry);
-       raw_spin_unlock_irqrestore(&its_dev->its->lock, flags);
-       kfree(its_dev->itt);
-       kfree(its_dev);
+       spin_unlock_irqrestore(&its_dev->its->lock, flags);
+       xfree(its_dev->itt);
+       xfree(its_dev);
 }
 
-static int its_alloc_device_irq(struct its_device *dev, irq_hw_number_t *hwirq)
+/* TODO: Remove static for the sake of compilation */
+int its_alloc_device_irq(struct its_device *dev, int *hwirq)
 {
        int idx;
 
@@ -1139,6 +1169,8 @@ static int its_alloc_device_irq(struct its_device *dev, 
irq_hw_number_t *hwirq)
        return 0;
 }
 
+/* pci and msi handling no more required here */
+#if 0
 struct its_pci_alias {
        struct pci_dev  *pdev;
        u32             dev_id;
@@ -1218,6 +1250,9 @@ static struct msi_domain_info its_pci_msi_domain_info = {
        .chip   = &its_msi_irq_chip,
 };
 
+#endif
+/* IRQ domain management is not required */
+#if 0
 static int its_irq_gic_domain_alloc(struct irq_domain *domain,
                                    unsigned int virq,
                                    irq_hw_number_t hwirq)
@@ -1319,6 +1354,7 @@ static const struct irq_domain_ops its_domain_ops = {
        .activate               = its_irq_domain_activate,
        .deactivate             = its_irq_domain_deactivate,
 };
+#endif
 
 static int its_force_quiescent(void __iomem *base)
 {
@@ -1348,58 +1384,57 @@ static int its_force_quiescent(void __iomem *base)
        }
 }
 
-static int its_probe(struct device_node *node, struct irq_domain *parent)
+static int its_probe(struct dt_device_node *node)
 {
-       struct resource res;
+       paddr_t its_addr, its_size;
        struct its_node *its;
        void __iomem *its_base;
        u32 val;
        u64 baser, tmp;
        int err;
 
-       err = of_address_to_resource(node, 0, &res);
+       err = dt_device_get_address(node, 0, &its_addr, &its_size);
        if (err) {
-               pr_warn("%s: no regs?\n", node->full_name);
+               its_warn("%s: no regs?\n", node->full_name);
                return -ENXIO;
        }
 
-       its_base = ioremap(res.start, resource_size(&res));
+       its_base = ioremap_nocache(its_addr, its_size);
        if (!its_base) {
-               pr_warn("%s: unable to map registers\n", node->full_name);
+               its_warn("%s: unable to map registers\n", node->full_name);
                return -ENOMEM;
        }
 
-       val = readl_relaxed(its_base + GITS_PIDR2) & GIC_PIDR2_ARCH_MASK;
+       val = readl_relaxed(its_base + GITS_PIDR2) & GIC_PIDR2_ARCH_REV_MASK;
        if (val != 0x30 && val != 0x40) {
-               pr_warn("%s: no ITS detected, giving up\n", node->full_name);
+               its_warn("%s: no ITS detected, giving up\n", node->full_name);
                err = -ENODEV;
                goto out_unmap;
        }
 
        err = its_force_quiescent(its_base);
        if (err) {
-               pr_warn("%s: failed to quiesce, giving up\n",
+               its_warn("%s: failed to quiesce, giving up\n",
                        node->full_name);
                goto out_unmap;
        }
 
-       pr_info("ITS: %s\n", node->full_name);
+       its_info("ITS: %s\n", node->full_name);
 
-       its = kzalloc(sizeof(*its), GFP_KERNEL);
+       its = xzalloc(struct its_node);
        if (!its) {
                err = -ENOMEM;
                goto out_unmap;
        }
 
-       raw_spin_lock_init(&its->lock);
+       spin_lock_init(&its->lock);
        INIT_LIST_HEAD(&its->entry);
        INIT_LIST_HEAD(&its->its_device_list);
        its->base = its_base;
-       its->phys_base = res.start;
-       its->msi_chip.of_node = node;
+       its->phys_base = its_addr;
        its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1;
 
-       its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL);
+       its->cmd_base = xzalloc_bytes(ITS_CMD_QUEUE_SZ);
        if (!its->cmd_base) {
                err = -ENOMEM;
                goto out_free_its;
@@ -1414,7 +1449,7 @@ static int its_probe(struct device_node *node, struct 
irq_domain *parent)
        if (err)
                goto out_free_tables;
 
-       baser = (virt_to_phys(its->cmd_base)    |
+       baser = (__pa(its->cmd_base)            |
                 GITS_CBASER_WaWb               |
                 GITS_CBASER_InnerShareable     |
                 (ITS_CMD_QUEUE_SZ / SZ_4K - 1) |
@@ -1426,10 +1461,10 @@ static int its_probe(struct device_node *node, struct 
irq_domain *parent)
        writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
 
        if ((tmp ^ baser) & GITS_BASER_SHAREABILITY_MASK) {
-               pr_info("ITS: using cache flushing for cmd queue\n");
+               its_info("ITS: using cache flushing for cmd queue\n");
                its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING;
        }
-
+#if 0
        if (of_property_read_bool(its->msi_chip.of_node, "msi-controller")) {
                its->domain = irq_domain_add_tree(NULL, &its_domain_ops, its);
                if (!its->domain) {
@@ -1451,27 +1486,28 @@ static int its_probe(struct device_node *node, struct 
irq_domain *parent)
                if (err)
                        goto out_free_domains;
        }
-
+#endif
        spin_lock(&its_lock);
        list_add(&its->entry, &its_nodes);
        spin_unlock(&its_lock);
 
        return 0;
-
+#if 0
 out_free_domains:
        if (its->msi_chip.domain)
                irq_domain_remove(its->msi_chip.domain);
        if (its->domain)
                irq_domain_remove(its->domain);
+#endif
 out_free_tables:
        its_free_tables(its);
 out_free_cmd:
-       kfree(its->cmd_base);
+       xfree(its->cmd_base);
 out_free_its:
-       kfree(its);
+       xfree(its);
 out_unmap:
        iounmap(its_base);
-       pr_err("ITS: failed probing %s (%d)\n", node->full_name, err);
+       its_err("ITS: failed probing %s (%d)\n", node->full_name, err);
        return err;
 }
 
@@ -1484,7 +1520,7 @@ int its_cpu_init(void)
 {
        if (!list_empty(&its_nodes)) {
                if (!gic_rdists_supports_plpis()) {
-                       pr_info("CPU%d: LPIs not supported\n", 
smp_processor_id());
+                       its_info("CPU%d: LPIs not supported\n", 
smp_processor_id());
                        return -ENXIO;
                }
                its_cpu_init_lpis();
@@ -1494,23 +1530,28 @@ int its_cpu_init(void)
        return 0;
 }
 
-static struct of_device_id its_device_id[] = {
-       {       .compatible     = "arm,gic-v3-its",     },
-       {},
-};
-
-int its_init(struct device_node *node, struct rdists *rdists,
-            struct irq_domain *parent_domain)
+int its_init(struct dt_device_node *node, struct rdist_prop *rdists)
 {
-       struct device_node *np;
+       struct dt_device_node *np = NULL;
+
+       static const struct dt_device_match its_device_ids[] __initconst =
+       {
+               DT_MATCH_COMPATIBLE("arm,gic-v3-its"),
+               { /* sentinel */ },
+       };
+
+       while ((np = dt_find_matching_node(np, its_device_ids)))
+       {
+               if (!dt_find_property(np, "msi-controller", NULL))
+               continue;
+       }
 
-       for (np = of_find_matching_node(node, its_device_id); np;
-            np = of_find_matching_node(np, its_device_id)) {
-               its_probe(np, parent_domain);
+       if (np) {
+               its_probe(np);
        }
 
        if (list_empty(&its_nodes)) {
-               pr_warn("ITS: No ITS available, not enabling LPIs\n");
+               its_warn("ITS: No ITS available, not enabling LPIs\n");
                return -ENXIO;
        }
 
diff --git a/xen/include/asm-arm/gic_v3_defs.h 
b/xen/include/asm-arm/gic_v3_defs.h
index 4e64b56..f8bac52 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -59,11 +59,12 @@
 #define GICR_WAKER_ProcessorSleep    (1U << 1)
 #define GICR_WAKER_ChildrenAsleep    (1U << 2)
 
-#define GICD_PIDR2_ARCH_REV_MASK     (0xf0)
+#define GIC_PIDR2_ARCH_REV_MASK      (0xf0)
+#define GICD_PIDR2_ARCH_REV_MASK     GIC_PIDR2_ARCH_REV_MASK
 #define GICD_PIDR2_ARCH_REV_SHIFT    (0x4)
 #define GICD_PIDR2_ARCH_GICV3        (0x3)
 
-#define GICR_PIDR2_ARCH_REV_MASK     GICD_PIDR2_ARCH_REV_MASK
+#define GICR_PIDR2_ARCH_REV_MASK     GIC_PIDR2_ARCH_REV_MASK
 #define GICR_PIDR2_ARCH_REV_SHIFT    GICD_PIDR2_ARCH_REV_SHIFT
 #define GICR_PIDR2_ARCH_GICV3        GICD_PIDR2_ARCH_GICV3
 
@@ -113,6 +114,23 @@
 #define GICR_ICFGR1                  (0x0C04)
 #define GICR_NSACR                   (0x0E00)
 
+#define GICR_CTLR_ENABLE_LPIS        (1UL << 0)
+#define GICR_TYPER_CPU_NUMBER(r)     (((r) >> 8) & 0xffff)
+
+#define GICR_PROPBASER_NonShareable      (0U << 10)
+#define GICR_PROPBASER_InnerShareable    (1U << 10)
+#define GICR_PROPBASER_OuterShareable    (2U << 10)
+#define GICR_PROPBASER_SHAREABILITY_MASK (3UL << 10)
+#define GICR_PROPBASER_nCnB              (0U << 7)
+#define GICR_PROPBASER_nC                (1U << 7)
+#define GICR_PROPBASER_RaWt              (2U << 7)
+#define GICR_PROPBASER_RaWb              (3U << 7)
+#define GICR_PROPBASER_WaWt              (4U << 7)
+#define GICR_PROPBASER_WaWb              (5U << 7)
+#define GICR_PROPBASER_RaWaWt            (6U << 7)
+#define GICR_PROPBASER_RaWaWb            (7U << 7)
+#define GICR_PROPBASER_IDBITS_MASK       (0x1f)
+
 #define GICR_TYPER_PLPIS             (1U << 0)
 #define GICR_TYPER_VLPIS             (1U << 1)
 #define GICR_TYPER_LAST              (1U << 4)
@@ -153,6 +171,100 @@
 #define ICH_SGI_IRQ_MASK             0xf
 #define ICH_SGI_TARGETLIST_MASK      0xffff
 
+#define LPI_PROP_GROUP1                 (1 << 1)
+#define LPI_PROP_ENABLED                (1 << 0)
+
+/*
+ * ITS registers, offsets from ITS_base
+ */
+#define GITS_CTLR                       0x0000
+#define GITS_IIDR                       0x0004
+#define GITS_TYPER                      0x0008
+#define GITS_CBASER                     0x0080
+#define GITS_CWRITER                    0x0088
+#define GITS_CREADR                     0x0090
+#define GITS_BASER                      0x0100
+#define GITS_BASERN                     0x013c
+#define GITS_PIDR0                      GICR_PIDR0
+#define GITS_PIDR1                      GICR_PIDR1
+#define GITS_PIDR2                      GICR_PIDR2
+#define GITS_PIDR3                      GICR_PIDR3
+#define GITS_PIDR4                      GICR_PIDR4
+#define GITS_PIDR5                      GICR_PIDR5
+#define GITS_PIDR7                      GICR_PIDR7
+
+#define GITS_TRANSLATER                 0x10040
+#define GITS_CTLR_QUIESCENT            (1U << 31)
+#define GITS_CTLR_ENABLE               (1U << 0)
+
+#define GITS_TYPER_DEVBITS_SHIFT       13
+#define GITS_TYPER_DEVBITS(r)          ((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 
0x1f) + 1)
+#define GITS_TYPER_PTA                  (1UL << 19)
+
+#define GITS_CBASER_VALID               (1UL << 63)
+#define GITS_CBASER_nCnB                (0UL << 59)
+#define GITS_CBASER_nC                  (1UL << 59)
+#define GITS_CBASER_RaWt                (2UL << 59)
+#define GITS_CBASER_RaWb                (3UL << 59)
+#define GITS_CBASER_WaWt                (4UL << 59)
+#define GITS_CBASER_WaWb                (5UL << 59)
+#define GITS_CBASER_RaWaWt              (6UL << 59)
+#define GITS_CBASER_RaWaWb              (7UL << 59)
+#define GITS_CBASER_NonShareable        (0UL << 10)
+#define GITS_CBASER_InnerShareable      (1UL << 10)
+#define GITS_CBASER_OuterShareable      (2UL << 10)
+#define GITS_CBASER_SHAREABILITY_MASK   (3UL << 10)
+
+#define GITS_BASER_NR_REGS              8
+
+#define GITS_BASER_VALID                (1UL << 63)
+#define GITS_BASER_nCnB                 (0UL << 59)
+#define GITS_BASER_nC                   (1UL << 59)
+#define GITS_BASER_RaWt                 (2UL << 59)
+#define GITS_BASER_RaWb                 (3UL << 59)
+#define GITS_BASER_WaWt                 (4UL << 59)
+#define GITS_BASER_WaWb                 (5UL << 59)
+#define GITS_BASER_RaWaWt               (6UL << 59)
+#define GITS_BASER_RaWaWb               (7UL << 59)
+#define GITS_BASER_TYPE_SHIFT           (56)
+#define GITS_BASER_TYPE(r)              (((r) >> GITS_BASER_TYPE_SHIFT) & 7)
+#define GITS_BASER_ENTRY_SIZE_SHIFT     (48)
+#define GITS_BASER_ENTRY_SIZE(r)        ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) 
& 0xff) + 1)
+#define GITS_BASER_NonShareable         (0UL << 10)
+#define GITS_BASER_InnerShareable       (1UL << 10)
+#define GITS_BASER_OuterShareable       (2UL << 10)
+#define GITS_BASER_SHAREABILITY_SHIFT   (10)
+#define GITS_BASER_SHAREABILITY_MASK    (3UL << GITS_BASER_SHAREABILITY_SHIFT)
+#define GITS_BASER_PAGE_SIZE_SHIFT      (8)
+#define GITS_BASER_PAGE_SIZE_4K         (0UL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGE_SIZE_16K        (1UL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGE_SIZE_64K        (2UL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGE_SIZE_MASK       (3UL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_TYPE_NONE            0
+#define GITS_BASER_TYPE_DEVICE          1
+#define GITS_BASER_TYPE_VCPU            2
+#define GITS_BASER_TYPE_CPU             3
+#define GITS_BASER_TYPE_COLLECTION      4
+#define GITS_BASER_TYPE_RESERVED5       5
+#define GITS_BASER_TYPE_RESERVED6       6
+#define GITS_BASER_TYPE_RESERVED7       7
+
+/*
+ * ITS commands
+ */
+#define GITS_CMD_MAPD                   0x08
+#define GITS_CMD_MAPC                   0x09
+#define GITS_CMD_MAPVI                  0x0a
+#define GITS_CMD_MAPI                   0x0b
+#define GITS_CMD_MOVI                   0x01
+#define GITS_CMD_DISCARD                0x0f
+#define GITS_CMD_INV                    0x0c
+#define GITS_CMD_MOVALL                 0x0e
+#define GITS_CMD_INVALL                 0x0d
+#define GITS_CMD_INT                    0x03
+#define GITS_CMD_CLEAR                  0x04
+#define GITS_CMD_SYNC                   0x05
+
 struct rdist {
     void __iomem *rbase;
     void * pend_page;
-- 
1.7.9.5


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


 


Rackspace

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