* [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform
@ 2015-02-26 12:40 Frediano Ziglio
2015-02-26 12:40 ` [PATCH v6 1/5] xen/arm: Duplicate gic-v2.c file to support hip04 platform version Frediano Ziglio
` (5 more replies)
0 siblings, 6 replies; 16+ messages in thread
From: Frediano Ziglio @ 2015-02-26 12:40 UTC (permalink / raw)
To: Ian Campbell, Stefano Stabellini, Tim Deegan, Julien Grall,
frediano.ziglio
Cc: zoltan.kiss, xen-devel
This set of patches add Xen support for hip04-d01 platform (see
https://wiki.linaro.org/Boards/D01 for details).
Changes from V5.99.1:
- removed RFC again;
- use different constants for hip04 instead of redefine standard ones;
- comment compatible string change;
- add an option to ARM to enable non standard drivers;
- rename gicv2 to hip04gic to make clear this is not a standard gic.
Changes from v5:
- do not change gic-v2.c code but use a copy.
To be considered RFC, to see if better to use copy or other techniques.
Changes from v4:
- rebased to new version;
- removed patch for computing GIC addresses as it apply to all platforms;
- removed patches to platform (cpu and system operations) as now they can
use a bootwrapper which provide them.
Changes from v3:
- change the way regs property is computed for GICv2 (Julien Grall);
- revert order of compaible names for GIC (Julien Grall).
Changes from v2:
- rewrote DTS fix patch (Ian Campbell);
- use is_hip04 macro instead of doing explicit test (Julien Grall);
- do not use quirks to distinguish this platform (Ian Cambell);
- move some GIC constants to C files instead of header (Julien Grall);
- minor changes (Julien Grall).
Changes from v1:
- style (Julien Grall);
- make gicv2_send_SGI faster (Julien Grall);
- cleanup correctly if hip04_smp_init fails (Julien Grall);
- remove quirks using compatibility (Ian Campbell);
- other minor suggestions by Julien Grall.
Frediano Ziglio (5):
xen/arm: Duplicate gic-v2.c file to support hip04 platform version
xen/arm: Add HAS_NON_STANDARD_DRIVERS build option to arm
xen/arm: Make gic-v2 code handle hip04-d01 platform
xen/arm: handle GICH register changes for hip04-d01 platform
xen/arm: Force dom0 to use normal GICv2 driver on Hip04 platform
xen/arch/arm/Makefile | 3 +
xen/arch/arm/Rules.mk | 1 +
xen/arch/arm/domain_build.c | 1 +
xen/arch/arm/gic-hip04.c | 800 ++++++++++++++++++++++++++++++++++++++++++++
xen/arch/arm/gic.c | 3 +-
xen/include/asm-arm/gic.h | 4 +
6 files changed, 811 insertions(+), 1 deletion(-)
create mode 100644 xen/arch/arm/gic-hip04.c
--
1.9.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 1/5] xen/arm: Duplicate gic-v2.c file to support hip04 platform version
2015-02-26 12:40 [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform Frediano Ziglio
@ 2015-02-26 12:40 ` Frediano Ziglio
2015-02-26 13:14 ` Julien Grall
2015-02-26 12:40 ` [PATCH v6 2/5] xen/arm: Add HAS_NON_STANDARD_DRIVERS build option to arm Frediano Ziglio
` (4 subsequent siblings)
5 siblings, 1 reply; 16+ messages in thread
From: Frediano Ziglio @ 2015-02-26 12:40 UTC (permalink / raw)
To: Ian Campbell, Stefano Stabellini, Tim Deegan, Julien Grall,
frediano.ziglio
Cc: zoltan.kiss, xen-devel
HiSilison Hip04 platform use a slightly different version.
This is just a verbatim copy of the file to workaround git
not fully supporting copy operation.
Signed-off-by: Frediano Ziglio <frediano.ziglio@huawei.com>
---
xen/arch/arm/gic-hip04.c | 788 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 788 insertions(+)
create mode 100644 xen/arch/arm/gic-hip04.c
diff --git a/xen/arch/arm/gic-hip04.c b/xen/arch/arm/gic-hip04.c
new file mode 100644
index 0000000..a401e3f
--- /dev/null
+++ b/xen/arch/arm/gic-hip04.c
@@ -0,0 +1,788 @@
+/*
+ * xen/arch/arm/gic-v2.c
+ *
+ * ARM Generic Interrupt Controller support v2
+ *
+ * Tim Deegan <tim@xen.org>
+ * Copyright (c) 2011 Citrix Systems.
+ *
+ * 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.
+ */
+
+#include <xen/config.h>
+#include <xen/lib.h>
+#include <xen/init.h>
+#include <xen/mm.h>
+#include <xen/irq.h>
+#include <xen/sched.h>
+#include <xen/errno.h>
+#include <xen/softirq.h>
+#include <xen/list.h>
+#include <xen/device_tree.h>
+#include <xen/libfdt/libfdt.h>
+#include <asm/p2m.h>
+#include <asm/domain.h>
+#include <asm/platform.h>
+#include <asm/device.h>
+
+#include <asm/io.h>
+#include <asm/gic.h>
+
+/*
+ * LR register definitions are GIC v2 specific.
+ * Moved these definitions from header file to here
+ */
+#define GICH_V2_LR_VIRTUAL_MASK 0x3ff
+#define GICH_V2_LR_VIRTUAL_SHIFT 0
+#define GICH_V2_LR_PHYSICAL_MASK 0x3ff
+#define GICH_V2_LR_PHYSICAL_SHIFT 10
+#define GICH_V2_LR_STATE_MASK 0x3
+#define GICH_V2_LR_STATE_SHIFT 28
+#define GICH_V2_LR_PRIORITY_SHIFT 23
+#define GICH_V2_LR_PRIORITY_MASK 0x1f
+#define GICH_V2_LR_HW_SHIFT 31
+#define GICH_V2_LR_HW_MASK 0x1
+#define GICH_V2_LR_GRP_SHIFT 30
+#define GICH_V2_LR_GRP_MASK 0x1
+#define GICH_V2_LR_MAINTENANCE_IRQ (1<<19)
+#define GICH_V2_LR_GRP1 (1<<30)
+#define GICH_V2_LR_HW (1<<31)
+#define GICH_V2_LR_CPUID_SHIFT 9
+#define GICH_V2_VTR_NRLRGS 0x3f
+
+#define GICH_V2_VMCR_PRIORITY_MASK 0x1f
+#define GICH_V2_VMCR_PRIORITY_SHIFT 27
+
+/* Global state */
+static struct {
+ paddr_t dbase; /* Address of distributor registers */
+ void __iomem * map_dbase; /* IO mapped Address of distributor registers */
+ paddr_t cbase; /* Address of CPU interface registers */
+ void __iomem * map_cbase[2]; /* IO mapped Address of CPU interface registers */
+ paddr_t hbase; /* Address of virtual interface registers */
+ void __iomem * map_hbase; /* IO Address of virtual interface registers */
+ paddr_t vbase; /* Address of virtual cpu interface registers */
+ spinlock_t lock;
+} gicv2;
+
+static struct gic_info gicv2_info;
+
+/* The GIC mapping of CPU interfaces does not necessarily match the
+ * logical CPU numbering. Let's use mapping as returned by the GIC
+ * itself
+ */
+static DEFINE_PER_CPU(u8, gic_cpu_id);
+
+/* Maximum cpu interface per GIC */
+#define NR_GIC_CPU_IF 8
+
+static inline void writeb_gicd(uint8_t val, unsigned int offset)
+{
+ writeb_relaxed(val, gicv2.map_dbase + offset);
+}
+
+static inline void writel_gicd(uint32_t val, unsigned int offset)
+{
+ writel_relaxed(val, gicv2.map_dbase + offset);
+}
+
+static inline uint32_t readl_gicd(unsigned int offset)
+{
+ return readl_relaxed(gicv2.map_dbase + offset);
+}
+
+static inline void writel_gicc(uint32_t val, unsigned int offset)
+{
+ unsigned int page = offset >> PAGE_SHIFT;
+ offset &= ~PAGE_MASK;
+ writel_relaxed(val, gicv2.map_cbase[page] + offset);
+}
+
+static inline uint32_t readl_gicc(unsigned int offset)
+{
+ unsigned int page = offset >> PAGE_SHIFT;
+ offset &= ~PAGE_MASK;
+ return readl_relaxed(gicv2.map_cbase[page] + offset);
+}
+
+static inline void writel_gich(uint32_t val, unsigned int offset)
+{
+ writel_relaxed(val, gicv2.map_hbase + offset);
+}
+
+static inline uint32_t readl_gich(int unsigned offset)
+{
+ return readl_relaxed(gicv2.map_hbase + offset);
+}
+
+static unsigned int gicv2_cpu_mask(const cpumask_t *cpumask)
+{
+ unsigned int cpu;
+ unsigned int mask = 0;
+ cpumask_t possible_mask;
+
+ cpumask_and(&possible_mask, cpumask, &cpu_possible_map);
+ for_each_cpu( cpu, &possible_mask )
+ {
+ ASSERT(cpu < NR_GIC_CPU_IF);
+ mask |= per_cpu(gic_cpu_id, cpu);
+ }
+
+ return mask;
+}
+
+static void gicv2_save_state(struct vcpu *v)
+{
+ int i;
+
+ /* No need for spinlocks here because interrupts are disabled around
+ * this call and it only accesses struct vcpu fields that cannot be
+ * accessed simultaneously by another pCPU.
+ */
+ for ( i = 0; i < gicv2_info.nr_lrs; i++ )
+ v->arch.gic.v2.lr[i] = readl_gich(GICH_LR + i * 4);
+
+ v->arch.gic.v2.apr = readl_gich(GICH_APR);
+ v->arch.gic.v2.vmcr = readl_gich(GICH_VMCR);
+ /* Disable until next VCPU scheduled */
+ writel_gich(0, GICH_HCR);
+}
+
+static void gicv2_restore_state(const struct vcpu *v)
+{
+ int i;
+
+ for ( i = 0; i < gicv2_info.nr_lrs; i++ )
+ writel_gich(v->arch.gic.v2.lr[i], GICH_LR + i * 4);
+
+ writel_gich(v->arch.gic.v2.apr, GICH_APR);
+ writel_gich(v->arch.gic.v2.vmcr, GICH_VMCR);
+ writel_gich(GICH_HCR_EN, GICH_HCR);
+}
+
+static void gicv2_dump_state(const struct vcpu *v)
+{
+ int i;
+
+ if ( v == current )
+ {
+ for ( i = 0; i < gicv2_info.nr_lrs; i++ )
+ printk(" HW_LR[%d]=%x\n", i,
+ readl_gich(GICH_LR + i * 4));
+ }
+ else
+ {
+ for ( i = 0; i < gicv2_info.nr_lrs; i++ )
+ printk(" VCPU_LR[%d]=%x\n", i, v->arch.gic.v2.lr[i]);
+ }
+}
+
+static void gicv2_eoi_irq(struct irq_desc *irqd)
+{
+ int irq = irqd->irq;
+ /* Lower the priority */
+ writel_gicc(irq, GICC_EOIR);
+}
+
+static void gicv2_dir_irq(struct irq_desc *irqd)
+{
+ /* Deactivate */
+ writel_gicc(irqd->irq, GICC_DIR);
+}
+
+static unsigned int gicv2_read_irq(void)
+{
+ return (readl_gicc(GICC_IAR) & GICC_IA_IRQ);
+}
+
+/*
+ * needs to be called with a valid cpu_mask, ie each cpu in the mask has
+ * already called gic_cpu_init
+ */
+static void gicv2_set_irq_properties(struct irq_desc *desc,
+ const cpumask_t *cpu_mask,
+ unsigned int priority)
+{
+ uint32_t cfg, edgebit;
+ unsigned int mask = gicv2_cpu_mask(cpu_mask);
+ unsigned int irq = desc->irq;
+ unsigned int type = desc->arch.type;
+
+ ASSERT(type != DT_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 )
+ cfg &= ~edgebit;
+ else if ( type & DT_IRQ_TYPE_EDGE_BOTH )
+ cfg |= edgebit;
+ writel_gicd(cfg, GICD_ICFGR + (irq / 16) * 4);
+
+ /* Set target CPU mask (RAZ/WI on uniprocessor) */
+ writeb_gicd(mask, GICD_ITARGETSR + irq);
+ /* Set priority */
+ writeb_gicd(priority, GICD_IPRIORITYR + irq);
+
+ spin_unlock(&gicv2.lock);
+}
+
+static void __init gicv2_dist_init(void)
+{
+ uint32_t type;
+ uint32_t cpumask;
+ uint32_t gic_cpus;
+ int i;
+
+ cpumask = readl_gicd(GICD_ITARGETSR) & 0xff;
+ cpumask |= cpumask << 8;
+ cpumask |= cpumask << 16;
+
+ /* Disable the distributor */
+ writel_gicd(0, GICD_CTLR);
+
+ type = readl_gicd(GICD_TYPER);
+ gicv2_info.nr_lines = 32 * ((type & GICD_TYPE_LINES) + 1);
+ gic_cpus = 1 + ((type & GICD_TYPE_CPUS) >> 5);
+ printk("GICv2: %d lines, %d cpu%s%s (IID %8.8x).\n",
+ gicv2_info.nr_lines, gic_cpus, (gic_cpus == 1) ? "" : "s",
+ (type & GICD_TYPE_SEC) ? ", secure" : "",
+ readl_gicd(GICD_IIDR));
+
+ /* Default all global IRQs to level, active low */
+ for ( i = 32; i < gicv2_info.nr_lines; i += 16 )
+ writel_gicd(0x0, GICD_ICFGR + (i / 16) * 4);
+
+ /* Route all global IRQs to this CPU */
+ for ( i = 32; i < gicv2_info.nr_lines; i += 4 )
+ writel_gicd(cpumask, GICD_ITARGETSR + (i / 4) * 4);
+
+ /* Default priority for global interrupts */
+ for ( i = 32; i < gicv2_info.nr_lines; i += 4 )
+ writel_gicd(GIC_PRI_IRQ << 24 | GIC_PRI_IRQ << 16 |
+ GIC_PRI_IRQ << 8 | GIC_PRI_IRQ,
+ GICD_IPRIORITYR + (i / 4) * 4);
+
+ /* Disable all global interrupts */
+ for ( i = 32; i < gicv2_info.nr_lines; i += 32 )
+ writel_gicd(~0x0, GICD_ICENABLER + (i / 32) * 4);
+
+ /* Turn on the distributor */
+ writel_gicd(GICD_CTL_ENABLE, GICD_CTLR);
+}
+
+static void __cpuinit gicv2_cpu_init(void)
+{
+ int i;
+
+ this_cpu(gic_cpu_id) = readl_gicd(GICD_ITARGETSR) & 0xff;
+
+ /* The first 32 interrupts (PPI and SGI) are banked per-cpu, so
+ * even though they are controlled with GICD registers, they must
+ * be set up here with the other per-cpu state. */
+ writel_gicd(0xffff0000, GICD_ICENABLER); /* Disable all PPI */
+ writel_gicd(0x0000ffff, GICD_ISENABLER); /* Enable all SGI */
+
+ /* Set SGI priorities */
+ for ( i = 0; i < 16; i += 4 )
+ writel_gicd(GIC_PRI_IPI << 24 | GIC_PRI_IPI << 16 |
+ GIC_PRI_IPI << 8 | GIC_PRI_IPI,
+ GICD_IPRIORITYR + (i / 4) * 4);
+
+ /* Set PPI priorities */
+ for ( i = 16; i < 32; i += 4 )
+ writel_gicd(GIC_PRI_IRQ << 24 | GIC_PRI_IRQ << 16 |
+ GIC_PRI_IRQ << 8 | GIC_PRI_IRQ,
+ GICD_IPRIORITYR + (i / 4) * 4);
+
+ /* Local settings: interface controller */
+ /* Don't mask by priority */
+ writel_gicc(0xff, GICC_PMR);
+ /* Finest granularity of priority */
+ writel_gicc(0x0, GICC_BPR);
+ /* Turn on delivery */
+ writel_gicc(GICC_CTL_ENABLE|GICC_CTL_EOI, GICC_CTLR);
+}
+
+static void gicv2_cpu_disable(void)
+{
+ writel_gicc(0x0, GICC_CTLR);
+}
+
+static void __cpuinit gicv2_hyp_init(void)
+{
+ uint32_t vtr;
+ uint8_t nr_lrs;
+
+ vtr = readl_gich(GICH_VTR);
+ nr_lrs = (vtr & GICH_V2_VTR_NRLRGS) + 1;
+ gicv2_info.nr_lrs = nr_lrs;
+
+ writel_gich(GICH_MISR_EOI, GICH_MISR);
+}
+
+static void __cpuinit gicv2_hyp_disable(void)
+{
+ writel_gich(0, GICH_HCR);
+}
+
+static int gicv2_secondary_cpu_init(void)
+{
+ spin_lock(&gicv2.lock);
+
+ gicv2_cpu_init();
+ gicv2_hyp_init();
+
+ spin_unlock(&gicv2.lock);
+
+ return 0;
+}
+
+static void gicv2_send_SGI(enum gic_sgi sgi, enum gic_sgi_mode irqmode,
+ const cpumask_t *cpu_mask)
+{
+ unsigned int mask = 0;
+ cpumask_t online_mask;
+
+ switch ( irqmode )
+ {
+ case SGI_TARGET_OTHERS:
+ writel_gicd(GICD_SGI_TARGET_OTHERS | sgi, GICD_SGIR);
+ break;
+ case SGI_TARGET_SELF:
+ writel_gicd(GICD_SGI_TARGET_SELF | sgi, GICD_SGIR);
+ break;
+ case SGI_TARGET_LIST:
+ cpumask_and(&online_mask, cpu_mask, &cpu_online_map);
+ mask = gicv2_cpu_mask(&online_mask);
+ writel_gicd(GICD_SGI_TARGET_LIST |
+ (mask << GICD_SGI_TARGET_SHIFT) | sgi,
+ GICD_SGIR);
+ break;
+ default:
+ BUG();
+ }
+}
+
+/* Shut down the per-CPU GIC interface */
+static void gicv2_disable_interface(void)
+{
+ spin_lock(&gicv2.lock);
+ gicv2_cpu_disable();
+ gicv2_hyp_disable();
+ spin_unlock(&gicv2.lock);
+}
+
+static void gicv2_update_lr(int lr, const struct pending_irq *p,
+ unsigned int state)
+{
+ uint32_t lr_reg;
+
+ BUG_ON(lr >= gicv2_info.nr_lrs);
+ BUG_ON(lr < 0);
+
+ lr_reg = (((state & GICH_V2_LR_STATE_MASK) << GICH_V2_LR_STATE_SHIFT) |
+ ((GIC_PRI_TO_GUEST(p->priority) & GICH_V2_LR_PRIORITY_MASK)
+ << GICH_V2_LR_PRIORITY_SHIFT) |
+ ((p->irq & GICH_V2_LR_VIRTUAL_MASK) << GICH_V2_LR_VIRTUAL_SHIFT));
+
+ if ( p->desc != NULL )
+ {
+ if ( platform_has_quirk(PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI) )
+ lr_reg |= GICH_V2_LR_MAINTENANCE_IRQ;
+ else
+ lr_reg |= GICH_V2_LR_HW | ((p->desc->irq & GICH_V2_LR_PHYSICAL_MASK )
+ << GICH_V2_LR_PHYSICAL_SHIFT);
+ }
+
+ writel_gich(lr_reg, GICH_LR + lr * 4);
+}
+
+static void gicv2_clear_lr(int lr)
+{
+ writel_gich(0, GICH_LR + lr * 4);
+}
+
+static int gicv2v_setup(struct domain *d)
+{
+ int ret;
+
+ /*
+ * The hardware domain gets the hardware address.
+ * Guests get the virtual platform layout.
+ */
+ if ( is_hardware_domain(d) )
+ {
+ d->arch.vgic.dbase = gicv2.dbase;
+ d->arch.vgic.cbase = gicv2.cbase;
+ }
+ else
+ {
+ d->arch.vgic.dbase = GUEST_GICD_BASE;
+ d->arch.vgic.cbase = GUEST_GICC_BASE;
+ }
+
+ /*
+ * Map the gic virtual cpu interface in the gic cpu interface
+ * region of the guest.
+ *
+ * The second page is always mapped at +4K irrespective of the
+ * GIC_64K_STRIDE quirk. The DTB passed to the guest reflects this.
+ */
+ ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase), 1,
+ paddr_to_pfn(gicv2.vbase));
+ if ( ret )
+ return ret;
+
+ if ( !platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
+ ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
+ 2, paddr_to_pfn(gicv2.vbase + PAGE_SIZE));
+ else
+ ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
+ 2, paddr_to_pfn(gicv2.vbase + 16*PAGE_SIZE));
+
+ return ret;
+}
+
+static void gicv2_read_lr(int lr, struct gic_lr *lr_reg)
+{
+ uint32_t lrv;
+
+ lrv = readl_gich(GICH_LR + lr * 4);
+ lr_reg->pirq = (lrv >> GICH_V2_LR_PHYSICAL_SHIFT) & GICH_V2_LR_PHYSICAL_MASK;
+ lr_reg->virq = (lrv >> GICH_V2_LR_VIRTUAL_SHIFT) & GICH_V2_LR_VIRTUAL_MASK;
+ lr_reg->priority = (lrv >> GICH_V2_LR_PRIORITY_SHIFT) & GICH_V2_LR_PRIORITY_MASK;
+ lr_reg->state = (lrv >> GICH_V2_LR_STATE_SHIFT) & GICH_V2_LR_STATE_MASK;
+ lr_reg->hw_status = (lrv >> GICH_V2_LR_HW_SHIFT) & GICH_V2_LR_HW_MASK;
+ lr_reg->grp = (lrv >> GICH_V2_LR_GRP_SHIFT) & GICH_V2_LR_GRP_MASK;
+}
+
+static void gicv2_write_lr(int lr, const struct gic_lr *lr_reg)
+{
+ uint32_t lrv = 0;
+
+ lrv = ( ((lr_reg->pirq & GICH_V2_LR_PHYSICAL_MASK) << GICH_V2_LR_PHYSICAL_SHIFT) |
+ ((lr_reg->virq & GICH_V2_LR_VIRTUAL_MASK) << GICH_V2_LR_VIRTUAL_SHIFT) |
+ ((uint32_t)(lr_reg->priority & GICH_V2_LR_PRIORITY_MASK)
+ << GICH_V2_LR_PRIORITY_SHIFT) |
+ ((uint32_t)(lr_reg->state & GICH_V2_LR_STATE_MASK)
+ << GICH_V2_LR_STATE_SHIFT) |
+ ((uint32_t)(lr_reg->hw_status & GICH_V2_LR_HW_MASK)
+ << GICH_V2_LR_HW_SHIFT) |
+ ((uint32_t)(lr_reg->grp & GICH_V2_LR_GRP_MASK) << GICH_V2_LR_GRP_SHIFT) );
+
+ writel_gich(lrv, GICH_LR + lr * 4);
+}
+
+static void gicv2_hcr_status(uint32_t flag, bool_t status)
+{
+ uint32_t hcr = readl_gich(GICH_HCR);
+
+ if ( status )
+ hcr |= flag;
+ else
+ hcr &= (~flag);
+
+ writel_gich(hcr, GICH_HCR);
+}
+
+static unsigned int gicv2_read_vmcr_priority(void)
+{
+ return ((readl_gich(GICH_VMCR) >> GICH_V2_VMCR_PRIORITY_SHIFT)
+ & GICH_V2_VMCR_PRIORITY_MASK);
+}
+
+static unsigned int gicv2_read_apr(int apr_reg)
+{
+ return readl_gich(GICH_APR);
+}
+
+static void gicv2_irq_enable(struct irq_desc *desc)
+{
+ unsigned long flags;
+ int irq = desc->irq;
+
+ ASSERT(spin_is_locked(&desc->lock));
+
+ spin_lock_irqsave(&gicv2.lock, flags);
+ clear_bit(_IRQ_DISABLED, &desc->status);
+ dsb(sy);
+ /* Enable routing */
+ writel_gicd((1u << (irq % 32)), GICD_ISENABLER + (irq / 32) * 4);
+ spin_unlock_irqrestore(&gicv2.lock, flags);
+}
+
+static void gicv2_irq_disable(struct irq_desc *desc)
+{
+ unsigned long flags;
+ int irq = desc->irq;
+
+ ASSERT(spin_is_locked(&desc->lock));
+
+ spin_lock_irqsave(&gicv2.lock, flags);
+ /* Disable routing */
+ writel_gicd(1u << (irq % 32), GICD_ICENABLER + (irq / 32) * 4);
+ set_bit(_IRQ_DISABLED, &desc->status);
+ spin_unlock_irqrestore(&gicv2.lock, flags);
+}
+
+static unsigned int gicv2_irq_startup(struct irq_desc *desc)
+{
+ gicv2_irq_enable(desc);
+
+ return 0;
+}
+
+static void gicv2_irq_shutdown(struct irq_desc *desc)
+{
+ gicv2_irq_disable(desc);
+}
+
+static void gicv2_irq_ack(struct irq_desc *desc)
+{
+ /* No ACK -- reading IAR has done this for us */
+}
+
+static void gicv2_host_irq_end(struct irq_desc *desc)
+{
+ /* Lower the priority */
+ gicv2_eoi_irq(desc);
+ /* Deactivate */
+ gicv2_dir_irq(desc);
+}
+
+static void gicv2_guest_irq_end(struct irq_desc *desc)
+{
+ /* Lower the priority of the IRQ */
+ gicv2_eoi_irq(desc);
+ /* Deactivation happens in maintenance interrupt / via GICV */
+}
+
+static void gicv2_irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask)
+{
+ unsigned int mask;
+
+ ASSERT(!cpumask_empty(cpu_mask));
+
+ spin_lock(&gicv2.lock);
+
+ mask = gicv2_cpu_mask(cpu_mask);
+
+ /* Set target CPU mask (RAZ/WI on uniprocessor) */
+ writeb_gicd(mask, GICD_ITARGETSR + desc->irq);
+
+ spin_unlock(&gicv2.lock);
+}
+
+static int gicv2_make_dt_node(const struct domain *d,
+ const struct dt_device_node *node, void *fdt)
+{
+ const struct dt_device_node *gic = dt_interrupt_controller;
+ const void *compatible = NULL;
+ u32 len;
+ const __be32 *regs;
+ int res = 0;
+
+ compatible = dt_get_property(gic, "compatible", &len);
+ if ( !compatible )
+ {
+ dprintk(XENLOG_ERR, "Can't find compatible property for the gic node\n");
+ return -FDT_ERR_XEN(ENOENT);
+ }
+
+ res = fdt_begin_node(fdt, "interrupt-controller");
+ if ( res )
+ return res;
+
+ res = fdt_property(fdt, "compatible", compatible, len);
+ if ( res )
+ return res;
+
+ res = fdt_property_cell(fdt, "#interrupt-cells", 3);
+ if ( res )
+ return res;
+
+ res = fdt_property(fdt, "interrupt-controller", NULL, 0);
+
+ if ( res )
+ return res;
+
+ /*
+ * DTB provides up to 4 regions to handle virtualization
+ * however dom0 just needs GICC and GICD provided by Xen.
+ */
+ regs = dt_get_property(gic, "reg", &len);
+ if ( !regs )
+ {
+ dprintk(XENLOG_ERR, "Can't find reg property for the gic node\n");
+ return -FDT_ERR_XEN(ENOENT);
+ }
+
+ len = dt_cells_to_size(dt_n_addr_cells(node) + dt_n_size_cells(node));
+ len *= 2;
+
+ res = fdt_property(fdt, "reg", regs, len);
+
+ return res;
+}
+
+/* XXX different for level vs edge */
+static hw_irq_controller gicv2_host_irq_type = {
+ .typename = "gic-v2",
+ .startup = gicv2_irq_startup,
+ .shutdown = gicv2_irq_shutdown,
+ .enable = gicv2_irq_enable,
+ .disable = gicv2_irq_disable,
+ .ack = gicv2_irq_ack,
+ .end = gicv2_host_irq_end,
+ .set_affinity = gicv2_irq_set_affinity,
+};
+
+static hw_irq_controller gicv2_guest_irq_type = {
+ .typename = "gic-v2",
+ .startup = gicv2_irq_startup,
+ .shutdown = gicv2_irq_shutdown,
+ .enable = gicv2_irq_enable,
+ .disable = gicv2_irq_disable,
+ .ack = gicv2_irq_ack,
+ .end = gicv2_guest_irq_end,
+ .set_affinity = gicv2_irq_set_affinity,
+};
+
+const static struct gic_hw_operations gicv2_ops = {
+ .info = &gicv2_info,
+ .secondary_init = gicv2_secondary_cpu_init,
+ .save_state = gicv2_save_state,
+ .restore_state = gicv2_restore_state,
+ .dump_state = gicv2_dump_state,
+ .gicv_setup = gicv2v_setup,
+ .gic_host_irq_type = &gicv2_host_irq_type,
+ .gic_guest_irq_type = &gicv2_guest_irq_type,
+ .eoi_irq = gicv2_eoi_irq,
+ .deactivate_irq = gicv2_dir_irq,
+ .read_irq = gicv2_read_irq,
+ .set_irq_properties = gicv2_set_irq_properties,
+ .send_SGI = gicv2_send_SGI,
+ .disable_interface = gicv2_disable_interface,
+ .update_lr = gicv2_update_lr,
+ .update_hcr_status = gicv2_hcr_status,
+ .clear_lr = gicv2_clear_lr,
+ .read_lr = gicv2_read_lr,
+ .write_lr = gicv2_write_lr,
+ .read_vmcr_priority = gicv2_read_vmcr_priority,
+ .read_apr = gicv2_read_apr,
+ .make_dt_node = gicv2_make_dt_node,
+};
+
+/* Set up the GIC */
+static int __init gicv2_init(struct dt_device_node *node, const void *data)
+{
+ int res;
+
+ dt_device_set_used_by(node, DOMID_XEN);
+
+ res = dt_device_get_address(node, 0, &gicv2.dbase, NULL);
+ if ( res || !gicv2.dbase || (gicv2.dbase & ~PAGE_MASK) )
+ panic("GICv2: Cannot find a valid address for the distributor");
+
+ res = dt_device_get_address(node, 1, &gicv2.cbase, NULL);
+ if ( res || !gicv2.cbase || (gicv2.cbase & ~PAGE_MASK) )
+ panic("GICv2: Cannot find a valid address for the CPU");
+
+ res = dt_device_get_address(node, 2, &gicv2.hbase, NULL);
+ if ( res || !gicv2.hbase || (gicv2.hbase & ~PAGE_MASK) )
+ panic("GICv2: Cannot find a valid address for the hypervisor");
+
+ res = dt_device_get_address(node, 3, &gicv2.vbase, NULL);
+ if ( res || !gicv2.vbase || (gicv2.vbase & ~PAGE_MASK) )
+ panic("GICv2: Cannot find a valid address for the virtual CPU");
+
+ res = platform_get_irq(node, 0);
+ if ( res < 0 )
+ panic("GICv2: Cannot find the maintenance IRQ");
+ gicv2_info.maintenance_irq = res;
+
+ /* Set the GIC as the primary interrupt controller */
+ dt_interrupt_controller = node;
+
+ /* TODO: Add check on distributor, cpu size */
+
+ printk("GICv2 initialization:\n"
+ " gic_dist_addr=%"PRIpaddr"\n"
+ " gic_cpu_addr=%"PRIpaddr"\n"
+ " gic_hyp_addr=%"PRIpaddr"\n"
+ " gic_vcpu_addr=%"PRIpaddr"\n"
+ " gic_maintenance_irq=%u\n",
+ gicv2.dbase, gicv2.cbase, gicv2.hbase, gicv2.vbase,
+ gicv2_info.maintenance_irq);
+
+ if ( (gicv2.dbase & ~PAGE_MASK) || (gicv2.cbase & ~PAGE_MASK) ||
+ (gicv2.hbase & ~PAGE_MASK) || (gicv2.vbase & ~PAGE_MASK) )
+ panic("GICv2 interfaces not page aligned");
+
+ gicv2.map_dbase = ioremap_nocache(gicv2.dbase, PAGE_SIZE);
+ if ( !gicv2.map_dbase )
+ panic("GICv2: Failed to ioremap for GIC distributor\n");
+
+ gicv2.map_cbase[0] = ioremap_nocache(gicv2.cbase, PAGE_SIZE);
+
+ if ( platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
+ gicv2.map_cbase[1] = ioremap_nocache(gicv2.cbase + PAGE_SIZE * 0x10,
+ PAGE_SIZE);
+ else
+ gicv2.map_cbase[1] = ioremap_nocache(gicv2.cbase + PAGE_SIZE, PAGE_SIZE);
+
+ if ( !gicv2.map_cbase[0] || !gicv2.map_cbase[1] )
+ panic("GICv2: Failed to ioremap for GIC CPU interface\n");
+
+ gicv2.map_hbase = ioremap_nocache(gicv2.hbase, PAGE_SIZE);
+ if ( !gicv2.map_hbase )
+ panic("GICv2: Failed to ioremap for GIC Virtual interface\n");
+
+ /* Global settings: interrupt distributor */
+ spin_lock_init(&gicv2.lock);
+ spin_lock(&gicv2.lock);
+
+ gicv2_dist_init();
+ gicv2_cpu_init();
+ gicv2_hyp_init();
+
+ spin_unlock(&gicv2.lock);
+
+ gicv2_info.hw_version = GIC_V2;
+ register_gic_ops(&gicv2_ops);
+
+ return 0;
+}
+
+static const char * const gicv2_dt_compat[] __initconst =
+{
+ DT_COMPAT_GIC_CORTEX_A15,
+ DT_COMPAT_GIC_CORTEX_A7,
+ DT_COMPAT_GIC_400,
+ NULL
+};
+
+DT_DEVICE_START(gicv2, "GICv2:", DEVICE_GIC)
+ .compatible = gicv2_dt_compat,
+ .init = gicv2_init,
+DT_DEVICE_END
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v6 2/5] xen/arm: Add HAS_NON_STANDARD_DRIVERS build option to arm
2015-02-26 12:40 [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform Frediano Ziglio
2015-02-26 12:40 ` [PATCH v6 1/5] xen/arm: Duplicate gic-v2.c file to support hip04 platform version Frediano Ziglio
@ 2015-02-26 12:40 ` Frediano Ziglio
2015-02-26 12:40 ` [PATCH v6 3/5] xen/arm: Make gic-v2 code handle hip04-d01 platform Frediano Ziglio
` (3 subsequent siblings)
5 siblings, 0 replies; 16+ messages in thread
From: Frediano Ziglio @ 2015-02-26 12:40 UTC (permalink / raw)
To: Ian Campbell, Stefano Stabellini, Tim Deegan, Julien Grall,
frediano.ziglio
Cc: zoltan.kiss, xen-devel
Allow to enable non standard drivers in Xen.
Can be override in .config file.
Signed-off-by: Frediano Ziglio <frediano.ziglio@huawei.com>
---
xen/arch/arm/Rules.mk | 1 +
1 file changed, 1 insertion(+)
diff --git a/xen/arch/arm/Rules.mk b/xen/arch/arm/Rules.mk
index c7bd227..4ed142a 100644
--- a/xen/arch/arm/Rules.mk
+++ b/xen/arch/arm/Rules.mk
@@ -11,6 +11,7 @@ HAS_VIDEO := y
HAS_ARM_HDLCD := y
HAS_PASSTHROUGH := y
HAS_PDX := y
+HAS_NON_STANDARD_DRIVERS ?= n
CFLAGS += -I$(BASEDIR)/include
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v6 3/5] xen/arm: Make gic-v2 code handle hip04-d01 platform
2015-02-26 12:40 [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform Frediano Ziglio
2015-02-26 12:40 ` [PATCH v6 1/5] xen/arm: Duplicate gic-v2.c file to support hip04 platform version Frediano Ziglio
2015-02-26 12:40 ` [PATCH v6 2/5] xen/arm: Add HAS_NON_STANDARD_DRIVERS build option to arm Frediano Ziglio
@ 2015-02-26 12:40 ` Frediano Ziglio
2015-02-26 13:23 ` Julien Grall
2015-02-26 12:40 ` [PATCH v6 4/5] xen/arm: handle GICH register changes for " Frediano Ziglio
` (2 subsequent siblings)
5 siblings, 1 reply; 16+ messages in thread
From: Frediano Ziglio @ 2015-02-26 12:40 UTC (permalink / raw)
To: Ian Campbell, Stefano Stabellini, Tim Deegan, Julien Grall,
frediano.ziglio
Cc: zoltan.kiss, xen-devel
The GIC in this platform is mainly compatible with the standard
GICv2 beside:
- ITARGET is extended to 16 bit to support 16 CPUs;
- SGI mask is extended to support 16 CPUs;
- maximum supported interrupt is 510.
Use nr_lines to check for maximum irq supported. hip04-d01 support less
interrupts due to some field restriction. Any value above this is already
an error.
Signed-off-by: Frediano Ziglio <frediano.ziglio@huawei.com>
Signed-off-by: Zoltan Kiss <zoltan.kiss@huawei.com>
---
xen/arch/arm/Makefile | 3 +
xen/arch/arm/domain_build.c | 1 +
xen/arch/arm/gic-hip04.c | 351 ++++++++++++++++++++++----------------------
xen/arch/arm/gic.c | 3 +-
xen/include/asm-arm/gic.h | 4 +
5 files changed, 188 insertions(+), 174 deletions(-)
diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 41aba2e..fad72d2 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -12,6 +12,9 @@ obj-y += domctl.o
obj-y += sysctl.o
obj-y += domain_build.o
obj-y += gic.o gic-v2.o
+ifeq (arm32,$(XEN_TARGET_ARCH))
+obj-$(HAS_NON_STANDARD_DRIVERS) += gic-hip04.o
+endif
obj-$(CONFIG_ARM_64) += gic-v3.o
obj-y += io.o
obj-y += irq.o
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index c2dcb49..0834053 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1038,6 +1038,7 @@ static int handle_node(struct domain *d, struct kernel_info *kinfo,
static const struct dt_device_match gic_matches[] __initconst =
{
DT_MATCH_GIC_V2,
+ DT_MATCH_GIC_HIP04,
DT_MATCH_GIC_V3,
{ /* sentinel */ },
};
diff --git a/xen/arch/arm/gic-hip04.c b/xen/arch/arm/gic-hip04.c
index a401e3f..84d60fd 100644
--- a/xen/arch/arm/gic-hip04.c
+++ b/xen/arch/arm/gic-hip04.c
@@ -1,7 +1,8 @@
/*
- * xen/arch/arm/gic-v2.c
+ * xen/arch/arm/gic-hip04.c
*
- * ARM Generic Interrupt Controller support v2
+ * Generic Interrupt Controller for HiSilicon Hip04 platform
+ * Based heavily from gic-v2.c
*
* Tim Deegan <tim@xen.org>
* Copyright (c) 2011 Citrix Systems.
@@ -71,59 +72,66 @@ static struct {
void __iomem * map_hbase; /* IO Address of virtual interface registers */
paddr_t vbase; /* Address of virtual cpu interface registers */
spinlock_t lock;
-} gicv2;
+} hip04gic;
-static struct gic_info gicv2_info;
+static struct gic_info hip04gic_info;
/* The GIC mapping of CPU interfaces does not necessarily match the
* logical CPU numbering. Let's use mapping as returned by the GIC
* itself
*/
-static DEFINE_PER_CPU(u8, gic_cpu_id);
+static DEFINE_PER_CPU(u16, gic_cpu_id);
/* Maximum cpu interface per GIC */
-#define NR_GIC_CPU_IF 8
+#define NR_GIC_CPU_IF 16
+
+#define HIP04_GICD_SGI_TARGET_SHIFT 8
static inline void writeb_gicd(uint8_t val, unsigned int offset)
{
- writeb_relaxed(val, gicv2.map_dbase + offset);
+ writeb_relaxed(val, hip04gic.map_dbase + offset);
+}
+
+static inline void writew_gicd(uint16_t val, unsigned int offset)
+{
+ writew_relaxed(val, hip04gic.map_dbase + offset);
}
static inline void writel_gicd(uint32_t val, unsigned int offset)
{
- writel_relaxed(val, gicv2.map_dbase + offset);
+ writel_relaxed(val, hip04gic.map_dbase + offset);
}
static inline uint32_t readl_gicd(unsigned int offset)
{
- return readl_relaxed(gicv2.map_dbase + offset);
+ return readl_relaxed(hip04gic.map_dbase + offset);
}
static inline void writel_gicc(uint32_t val, unsigned int offset)
{
unsigned int page = offset >> PAGE_SHIFT;
offset &= ~PAGE_MASK;
- writel_relaxed(val, gicv2.map_cbase[page] + offset);
+ writel_relaxed(val, hip04gic.map_cbase[page] + offset);
}
static inline uint32_t readl_gicc(unsigned int offset)
{
unsigned int page = offset >> PAGE_SHIFT;
offset &= ~PAGE_MASK;
- return readl_relaxed(gicv2.map_cbase[page] + offset);
+ return readl_relaxed(hip04gic.map_cbase[page] + offset);
}
static inline void writel_gich(uint32_t val, unsigned int offset)
{
- writel_relaxed(val, gicv2.map_hbase + offset);
+ writel_relaxed(val, hip04gic.map_hbase + offset);
}
static inline uint32_t readl_gich(int unsigned offset)
{
- return readl_relaxed(gicv2.map_hbase + offset);
+ return readl_relaxed(hip04gic.map_hbase + offset);
}
-static unsigned int gicv2_cpu_mask(const cpumask_t *cpumask)
+static unsigned int hip04gic_cpu_mask(const cpumask_t *cpumask)
{
unsigned int cpu;
unsigned int mask = 0;
@@ -139,7 +147,7 @@ static unsigned int gicv2_cpu_mask(const cpumask_t *cpumask)
return mask;
}
-static void gicv2_save_state(struct vcpu *v)
+static void hip04gic_save_state(struct vcpu *v)
{
int i;
@@ -147,7 +155,7 @@ static void gicv2_save_state(struct vcpu *v)
* this call and it only accesses struct vcpu fields that cannot be
* accessed simultaneously by another pCPU.
*/
- for ( i = 0; i < gicv2_info.nr_lrs; i++ )
+ for ( i = 0; i < hip04gic_info.nr_lrs; i++ )
v->arch.gic.v2.lr[i] = readl_gich(GICH_LR + i * 4);
v->arch.gic.v2.apr = readl_gich(GICH_APR);
@@ -156,11 +164,11 @@ static void gicv2_save_state(struct vcpu *v)
writel_gich(0, GICH_HCR);
}
-static void gicv2_restore_state(const struct vcpu *v)
+static void hip04gic_restore_state(const struct vcpu *v)
{
int i;
- for ( i = 0; i < gicv2_info.nr_lrs; i++ )
+ for ( i = 0; i < hip04gic_info.nr_lrs; i++ )
writel_gich(v->arch.gic.v2.lr[i], GICH_LR + i * 4);
writel_gich(v->arch.gic.v2.apr, GICH_APR);
@@ -168,37 +176,37 @@ static void gicv2_restore_state(const struct vcpu *v)
writel_gich(GICH_HCR_EN, GICH_HCR);
}
-static void gicv2_dump_state(const struct vcpu *v)
+static void hip04gic_dump_state(const struct vcpu *v)
{
int i;
if ( v == current )
{
- for ( i = 0; i < gicv2_info.nr_lrs; i++ )
+ for ( i = 0; i < hip04gic_info.nr_lrs; i++ )
printk(" HW_LR[%d]=%x\n", i,
readl_gich(GICH_LR + i * 4));
}
else
{
- for ( i = 0; i < gicv2_info.nr_lrs; i++ )
+ for ( i = 0; i < hip04gic_info.nr_lrs; i++ )
printk(" VCPU_LR[%d]=%x\n", i, v->arch.gic.v2.lr[i]);
}
}
-static void gicv2_eoi_irq(struct irq_desc *irqd)
+static void hip04gic_eoi_irq(struct irq_desc *irqd)
{
int irq = irqd->irq;
/* Lower the priority */
writel_gicc(irq, GICC_EOIR);
}
-static void gicv2_dir_irq(struct irq_desc *irqd)
+static void hip04gic_dir_irq(struct irq_desc *irqd)
{
/* Deactivate */
writel_gicc(irqd->irq, GICC_DIR);
}
-static unsigned int gicv2_read_irq(void)
+static unsigned int hip04gic_read_irq(void)
{
return (readl_gicc(GICC_IAR) & GICC_IA_IRQ);
}
@@ -207,19 +215,19 @@ static unsigned int gicv2_read_irq(void)
* needs to be called with a valid cpu_mask, ie each cpu in the mask has
* already called gic_cpu_init
*/
-static void gicv2_set_irq_properties(struct irq_desc *desc,
+static void hip04gic_set_irq_properties(struct irq_desc *desc,
const cpumask_t *cpu_mask,
unsigned int priority)
{
uint32_t cfg, edgebit;
- unsigned int mask = gicv2_cpu_mask(cpu_mask);
+ unsigned int mask = hip04gic_cpu_mask(cpu_mask);
unsigned int irq = desc->irq;
unsigned int type = desc->arch.type;
ASSERT(type != DT_IRQ_TYPE_INVALID);
ASSERT(spin_is_locked(&desc->lock));
- spin_lock(&gicv2.lock);
+ spin_lock(&hip04gic.lock);
/* Set edge / level */
cfg = readl_gicd(GICD_ICFGR + (irq / 16) * 4);
edgebit = 2u << (2 * (irq % 16));
@@ -230,62 +238,61 @@ static void gicv2_set_irq_properties(struct irq_desc *desc,
writel_gicd(cfg, GICD_ICFGR + (irq / 16) * 4);
/* Set target CPU mask (RAZ/WI on uniprocessor) */
- writeb_gicd(mask, GICD_ITARGETSR + irq);
+ writew_gicd(mask, GICD_ITARGETSR + irq * 2);
/* Set priority */
writeb_gicd(priority, GICD_IPRIORITYR + irq);
- spin_unlock(&gicv2.lock);
+ spin_unlock(&hip04gic.lock);
}
-static void __init gicv2_dist_init(void)
+static void __init hip04gic_dist_init(void)
{
uint32_t type;
uint32_t cpumask;
uint32_t gic_cpus;
int i;
- cpumask = readl_gicd(GICD_ITARGETSR) & 0xff;
- cpumask |= cpumask << 8;
+ cpumask = readl_gicd(GICD_ITARGETSR) & 0xffff;
cpumask |= cpumask << 16;
/* Disable the distributor */
writel_gicd(0, GICD_CTLR);
type = readl_gicd(GICD_TYPER);
- gicv2_info.nr_lines = 32 * ((type & GICD_TYPE_LINES) + 1);
- gic_cpus = 1 + ((type & GICD_TYPE_CPUS) >> 5);
+ hip04gic_info.nr_lines = 32 * ((type & GICD_TYPE_LINES) + 1);
+ gic_cpus = 16;
printk("GICv2: %d lines, %d cpu%s%s (IID %8.8x).\n",
- gicv2_info.nr_lines, gic_cpus, (gic_cpus == 1) ? "" : "s",
+ hip04gic_info.nr_lines, gic_cpus, (gic_cpus == 1) ? "" : "s",
(type & GICD_TYPE_SEC) ? ", secure" : "",
readl_gicd(GICD_IIDR));
/* Default all global IRQs to level, active low */
- for ( i = 32; i < gicv2_info.nr_lines; i += 16 )
+ for ( i = 32; i < hip04gic_info.nr_lines; i += 16 )
writel_gicd(0x0, GICD_ICFGR + (i / 16) * 4);
/* Route all global IRQs to this CPU */
- for ( i = 32; i < gicv2_info.nr_lines; i += 4 )
- writel_gicd(cpumask, GICD_ITARGETSR + (i / 4) * 4);
+ for ( i = 32; i < hip04gic_info.nr_lines; i += 2 )
+ writel_gicd(cpumask, GICD_ITARGETSR + (i / 2) * 4);
/* Default priority for global interrupts */
- for ( i = 32; i < gicv2_info.nr_lines; i += 4 )
+ for ( i = 32; i < hip04gic_info.nr_lines; i += 4 )
writel_gicd(GIC_PRI_IRQ << 24 | GIC_PRI_IRQ << 16 |
GIC_PRI_IRQ << 8 | GIC_PRI_IRQ,
GICD_IPRIORITYR + (i / 4) * 4);
/* Disable all global interrupts */
- for ( i = 32; i < gicv2_info.nr_lines; i += 32 )
+ for ( i = 32; i < hip04gic_info.nr_lines; i += 32 )
writel_gicd(~0x0, GICD_ICENABLER + (i / 32) * 4);
/* Turn on the distributor */
writel_gicd(GICD_CTL_ENABLE, GICD_CTLR);
}
-static void __cpuinit gicv2_cpu_init(void)
+static void __cpuinit hip04gic_cpu_init(void)
{
int i;
- this_cpu(gic_cpu_id) = readl_gicd(GICD_ITARGETSR) & 0xff;
+ this_cpu(gic_cpu_id) = readl_gicd(GICD_ITARGETSR) & 0xffff;
/* The first 32 interrupts (PPI and SGI) are banked per-cpu, so
* even though they are controlled with GICD registers, they must
@@ -314,41 +321,41 @@ static void __cpuinit gicv2_cpu_init(void)
writel_gicc(GICC_CTL_ENABLE|GICC_CTL_EOI, GICC_CTLR);
}
-static void gicv2_cpu_disable(void)
+static void hip04gic_cpu_disable(void)
{
writel_gicc(0x0, GICC_CTLR);
}
-static void __cpuinit gicv2_hyp_init(void)
+static void __cpuinit hip04gic_hyp_init(void)
{
uint32_t vtr;
uint8_t nr_lrs;
vtr = readl_gich(GICH_VTR);
nr_lrs = (vtr & GICH_V2_VTR_NRLRGS) + 1;
- gicv2_info.nr_lrs = nr_lrs;
+ hip04gic_info.nr_lrs = nr_lrs;
writel_gich(GICH_MISR_EOI, GICH_MISR);
}
-static void __cpuinit gicv2_hyp_disable(void)
+static void __cpuinit hip04gic_hyp_disable(void)
{
writel_gich(0, GICH_HCR);
}
-static int gicv2_secondary_cpu_init(void)
+static int hip04gic_secondary_cpu_init(void)
{
- spin_lock(&gicv2.lock);
+ spin_lock(&hip04gic.lock);
- gicv2_cpu_init();
- gicv2_hyp_init();
+ hip04gic_cpu_init();
+ hip04gic_hyp_init();
- spin_unlock(&gicv2.lock);
+ spin_unlock(&hip04gic.lock);
return 0;
}
-static void gicv2_send_SGI(enum gic_sgi sgi, enum gic_sgi_mode irqmode,
+static void hip04gic_send_SGI(enum gic_sgi sgi, enum gic_sgi_mode irqmode,
const cpumask_t *cpu_mask)
{
unsigned int mask = 0;
@@ -364,9 +371,9 @@ static void gicv2_send_SGI(enum gic_sgi sgi, enum gic_sgi_mode irqmode,
break;
case SGI_TARGET_LIST:
cpumask_and(&online_mask, cpu_mask, &cpu_online_map);
- mask = gicv2_cpu_mask(&online_mask);
+ mask = hip04gic_cpu_mask(&online_mask);
writel_gicd(GICD_SGI_TARGET_LIST |
- (mask << GICD_SGI_TARGET_SHIFT) | sgi,
+ (mask << HIP04_GICD_SGI_TARGET_SHIFT) | sgi,
GICD_SGIR);
break;
default:
@@ -375,20 +382,20 @@ static void gicv2_send_SGI(enum gic_sgi sgi, enum gic_sgi_mode irqmode,
}
/* Shut down the per-CPU GIC interface */
-static void gicv2_disable_interface(void)
+static void hip04gic_disable_interface(void)
{
- spin_lock(&gicv2.lock);
- gicv2_cpu_disable();
- gicv2_hyp_disable();
- spin_unlock(&gicv2.lock);
+ spin_lock(&hip04gic.lock);
+ hip04gic_cpu_disable();
+ hip04gic_hyp_disable();
+ spin_unlock(&hip04gic.lock);
}
-static void gicv2_update_lr(int lr, const struct pending_irq *p,
+static void hip04gic_update_lr(int lr, const struct pending_irq *p,
unsigned int state)
{
uint32_t lr_reg;
- BUG_ON(lr >= gicv2_info.nr_lrs);
+ BUG_ON(lr >= hip04gic_info.nr_lrs);
BUG_ON(lr < 0);
lr_reg = (((state & GICH_V2_LR_STATE_MASK) << GICH_V2_LR_STATE_SHIFT) |
@@ -408,12 +415,12 @@ static void gicv2_update_lr(int lr, const struct pending_irq *p,
writel_gich(lr_reg, GICH_LR + lr * 4);
}
-static void gicv2_clear_lr(int lr)
+static void hip04gic_clear_lr(int lr)
{
writel_gich(0, GICH_LR + lr * 4);
}
-static int gicv2v_setup(struct domain *d)
+static int hip04gicv_setup(struct domain *d)
{
int ret;
@@ -423,8 +430,8 @@ static int gicv2v_setup(struct domain *d)
*/
if ( is_hardware_domain(d) )
{
- d->arch.vgic.dbase = gicv2.dbase;
- d->arch.vgic.cbase = gicv2.cbase;
+ d->arch.vgic.dbase = hip04gic.dbase;
+ d->arch.vgic.cbase = hip04gic.cbase;
}
else
{
@@ -440,21 +447,21 @@ static int gicv2v_setup(struct domain *d)
* GIC_64K_STRIDE quirk. The DTB passed to the guest reflects this.
*/
ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase), 1,
- paddr_to_pfn(gicv2.vbase));
+ paddr_to_pfn(hip04gic.vbase));
if ( ret )
return ret;
if ( !platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
- 2, paddr_to_pfn(gicv2.vbase + PAGE_SIZE));
+ 2, paddr_to_pfn(hip04gic.vbase + PAGE_SIZE));
else
ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
- 2, paddr_to_pfn(gicv2.vbase + 16*PAGE_SIZE));
+ 2, paddr_to_pfn(hip04gic.vbase + 16*PAGE_SIZE));
return ret;
}
-static void gicv2_read_lr(int lr, struct gic_lr *lr_reg)
+static void hip04gic_read_lr(int lr, struct gic_lr *lr_reg)
{
uint32_t lrv;
@@ -467,7 +474,7 @@ static void gicv2_read_lr(int lr, struct gic_lr *lr_reg)
lr_reg->grp = (lrv >> GICH_V2_LR_GRP_SHIFT) & GICH_V2_LR_GRP_MASK;
}
-static void gicv2_write_lr(int lr, const struct gic_lr *lr_reg)
+static void hip04gic_write_lr(int lr, const struct gic_lr *lr_reg)
{
uint32_t lrv = 0;
@@ -484,7 +491,7 @@ static void gicv2_write_lr(int lr, const struct gic_lr *lr_reg)
writel_gich(lrv, GICH_LR + lr * 4);
}
-static void gicv2_hcr_status(uint32_t flag, bool_t status)
+static void hip04gic_hcr_status(uint32_t flag, bool_t status)
{
uint32_t hcr = readl_gich(GICH_HCR);
@@ -496,95 +503,95 @@ static void gicv2_hcr_status(uint32_t flag, bool_t status)
writel_gich(hcr, GICH_HCR);
}
-static unsigned int gicv2_read_vmcr_priority(void)
+static unsigned int hip04gic_read_vmcr_priority(void)
{
return ((readl_gich(GICH_VMCR) >> GICH_V2_VMCR_PRIORITY_SHIFT)
& GICH_V2_VMCR_PRIORITY_MASK);
}
-static unsigned int gicv2_read_apr(int apr_reg)
+static unsigned int hip04gic_read_apr(int apr_reg)
{
return readl_gich(GICH_APR);
}
-static void gicv2_irq_enable(struct irq_desc *desc)
+static void hip04gic_irq_enable(struct irq_desc *desc)
{
unsigned long flags;
int irq = desc->irq;
ASSERT(spin_is_locked(&desc->lock));
- spin_lock_irqsave(&gicv2.lock, flags);
+ spin_lock_irqsave(&hip04gic.lock, flags);
clear_bit(_IRQ_DISABLED, &desc->status);
dsb(sy);
/* Enable routing */
writel_gicd((1u << (irq % 32)), GICD_ISENABLER + (irq / 32) * 4);
- spin_unlock_irqrestore(&gicv2.lock, flags);
+ spin_unlock_irqrestore(&hip04gic.lock, flags);
}
-static void gicv2_irq_disable(struct irq_desc *desc)
+static void hip04gic_irq_disable(struct irq_desc *desc)
{
unsigned long flags;
int irq = desc->irq;
ASSERT(spin_is_locked(&desc->lock));
- spin_lock_irqsave(&gicv2.lock, flags);
+ spin_lock_irqsave(&hip04gic.lock, flags);
/* Disable routing */
writel_gicd(1u << (irq % 32), GICD_ICENABLER + (irq / 32) * 4);
set_bit(_IRQ_DISABLED, &desc->status);
- spin_unlock_irqrestore(&gicv2.lock, flags);
+ spin_unlock_irqrestore(&hip04gic.lock, flags);
}
-static unsigned int gicv2_irq_startup(struct irq_desc *desc)
+static unsigned int hip04gic_irq_startup(struct irq_desc *desc)
{
- gicv2_irq_enable(desc);
+ hip04gic_irq_enable(desc);
return 0;
}
-static void gicv2_irq_shutdown(struct irq_desc *desc)
+static void hip04gic_irq_shutdown(struct irq_desc *desc)
{
- gicv2_irq_disable(desc);
+ hip04gic_irq_disable(desc);
}
-static void gicv2_irq_ack(struct irq_desc *desc)
+static void hip04gic_irq_ack(struct irq_desc *desc)
{
/* No ACK -- reading IAR has done this for us */
}
-static void gicv2_host_irq_end(struct irq_desc *desc)
+static void hip04gic_host_irq_end(struct irq_desc *desc)
{
/* Lower the priority */
- gicv2_eoi_irq(desc);
+ hip04gic_eoi_irq(desc);
/* Deactivate */
- gicv2_dir_irq(desc);
+ hip04gic_dir_irq(desc);
}
-static void gicv2_guest_irq_end(struct irq_desc *desc)
+static void hip04gic_guest_irq_end(struct irq_desc *desc)
{
/* Lower the priority of the IRQ */
- gicv2_eoi_irq(desc);
+ hip04gic_eoi_irq(desc);
/* Deactivation happens in maintenance interrupt / via GICV */
}
-static void gicv2_irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask)
+static void hip04gic_irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask)
{
unsigned int mask;
ASSERT(!cpumask_empty(cpu_mask));
- spin_lock(&gicv2.lock);
+ spin_lock(&hip04gic.lock);
- mask = gicv2_cpu_mask(cpu_mask);
+ mask = hip04gic_cpu_mask(cpu_mask);
/* Set target CPU mask (RAZ/WI on uniprocessor) */
- writeb_gicd(mask, GICD_ITARGETSR + desc->irq);
+ writew_gicd(mask, GICD_ITARGETSR + desc->irq * 2);
- spin_unlock(&gicv2.lock);
+ spin_unlock(&hip04gic.lock);
}
-static int gicv2_make_dt_node(const struct domain *d,
+static int hip04gic_make_dt_node(const struct domain *d,
const struct dt_device_node *node, void *fdt)
{
const struct dt_device_node *gic = dt_interrupt_controller;
@@ -637,80 +644,80 @@ static int gicv2_make_dt_node(const struct domain *d,
}
/* XXX different for level vs edge */
-static hw_irq_controller gicv2_host_irq_type = {
- .typename = "gic-v2",
- .startup = gicv2_irq_startup,
- .shutdown = gicv2_irq_shutdown,
- .enable = gicv2_irq_enable,
- .disable = gicv2_irq_disable,
- .ack = gicv2_irq_ack,
- .end = gicv2_host_irq_end,
- .set_affinity = gicv2_irq_set_affinity,
+static hw_irq_controller hip04gic_host_irq_type = {
+ .typename = "gic-hip04",
+ .startup = hip04gic_irq_startup,
+ .shutdown = hip04gic_irq_shutdown,
+ .enable = hip04gic_irq_enable,
+ .disable = hip04gic_irq_disable,
+ .ack = hip04gic_irq_ack,
+ .end = hip04gic_host_irq_end,
+ .set_affinity = hip04gic_irq_set_affinity,
};
-static hw_irq_controller gicv2_guest_irq_type = {
- .typename = "gic-v2",
- .startup = gicv2_irq_startup,
- .shutdown = gicv2_irq_shutdown,
- .enable = gicv2_irq_enable,
- .disable = gicv2_irq_disable,
- .ack = gicv2_irq_ack,
- .end = gicv2_guest_irq_end,
- .set_affinity = gicv2_irq_set_affinity,
+static hw_irq_controller hip04gic_guest_irq_type = {
+ .typename = "gic-hip04",
+ .startup = hip04gic_irq_startup,
+ .shutdown = hip04gic_irq_shutdown,
+ .enable = hip04gic_irq_enable,
+ .disable = hip04gic_irq_disable,
+ .ack = hip04gic_irq_ack,
+ .end = hip04gic_guest_irq_end,
+ .set_affinity = hip04gic_irq_set_affinity,
};
-const static struct gic_hw_operations gicv2_ops = {
- .info = &gicv2_info,
- .secondary_init = gicv2_secondary_cpu_init,
- .save_state = gicv2_save_state,
- .restore_state = gicv2_restore_state,
- .dump_state = gicv2_dump_state,
- .gicv_setup = gicv2v_setup,
- .gic_host_irq_type = &gicv2_host_irq_type,
- .gic_guest_irq_type = &gicv2_guest_irq_type,
- .eoi_irq = gicv2_eoi_irq,
- .deactivate_irq = gicv2_dir_irq,
- .read_irq = gicv2_read_irq,
- .set_irq_properties = gicv2_set_irq_properties,
- .send_SGI = gicv2_send_SGI,
- .disable_interface = gicv2_disable_interface,
- .update_lr = gicv2_update_lr,
- .update_hcr_status = gicv2_hcr_status,
- .clear_lr = gicv2_clear_lr,
- .read_lr = gicv2_read_lr,
- .write_lr = gicv2_write_lr,
- .read_vmcr_priority = gicv2_read_vmcr_priority,
- .read_apr = gicv2_read_apr,
- .make_dt_node = gicv2_make_dt_node,
+const static struct gic_hw_operations hip04gic_ops = {
+ .info = &hip04gic_info,
+ .secondary_init = hip04gic_secondary_cpu_init,
+ .save_state = hip04gic_save_state,
+ .restore_state = hip04gic_restore_state,
+ .dump_state = hip04gic_dump_state,
+ .gicv_setup = hip04gicv_setup,
+ .gic_host_irq_type = &hip04gic_host_irq_type,
+ .gic_guest_irq_type = &hip04gic_guest_irq_type,
+ .eoi_irq = hip04gic_eoi_irq,
+ .deactivate_irq = hip04gic_dir_irq,
+ .read_irq = hip04gic_read_irq,
+ .set_irq_properties = hip04gic_set_irq_properties,
+ .send_SGI = hip04gic_send_SGI,
+ .disable_interface = hip04gic_disable_interface,
+ .update_lr = hip04gic_update_lr,
+ .update_hcr_status = hip04gic_hcr_status,
+ .clear_lr = hip04gic_clear_lr,
+ .read_lr = hip04gic_read_lr,
+ .write_lr = hip04gic_write_lr,
+ .read_vmcr_priority = hip04gic_read_vmcr_priority,
+ .read_apr = hip04gic_read_apr,
+ .make_dt_node = hip04gic_make_dt_node,
};
/* Set up the GIC */
-static int __init gicv2_init(struct dt_device_node *node, const void *data)
+static int __init hip04gic_init(struct dt_device_node *node, const void *data)
{
int res;
dt_device_set_used_by(node, DOMID_XEN);
- res = dt_device_get_address(node, 0, &gicv2.dbase, NULL);
- if ( res || !gicv2.dbase || (gicv2.dbase & ~PAGE_MASK) )
+ res = dt_device_get_address(node, 0, &hip04gic.dbase, NULL);
+ if ( res || !hip04gic.dbase || (hip04gic.dbase & ~PAGE_MASK) )
panic("GICv2: Cannot find a valid address for the distributor");
- res = dt_device_get_address(node, 1, &gicv2.cbase, NULL);
- if ( res || !gicv2.cbase || (gicv2.cbase & ~PAGE_MASK) )
+ res = dt_device_get_address(node, 1, &hip04gic.cbase, NULL);
+ if ( res || !hip04gic.cbase || (hip04gic.cbase & ~PAGE_MASK) )
panic("GICv2: Cannot find a valid address for the CPU");
- res = dt_device_get_address(node, 2, &gicv2.hbase, NULL);
- if ( res || !gicv2.hbase || (gicv2.hbase & ~PAGE_MASK) )
+ res = dt_device_get_address(node, 2, &hip04gic.hbase, NULL);
+ if ( res || !hip04gic.hbase || (hip04gic.hbase & ~PAGE_MASK) )
panic("GICv2: Cannot find a valid address for the hypervisor");
- res = dt_device_get_address(node, 3, &gicv2.vbase, NULL);
- if ( res || !gicv2.vbase || (gicv2.vbase & ~PAGE_MASK) )
+ res = dt_device_get_address(node, 3, &hip04gic.vbase, NULL);
+ if ( res || !hip04gic.vbase || (hip04gic.vbase & ~PAGE_MASK) )
panic("GICv2: Cannot find a valid address for the virtual CPU");
res = platform_get_irq(node, 0);
if ( res < 0 )
panic("GICv2: Cannot find the maintenance IRQ");
- gicv2_info.maintenance_irq = res;
+ hip04gic_info.maintenance_irq = res;
/* Set the GIC as the primary interrupt controller */
dt_interrupt_controller = node;
@@ -723,59 +730,57 @@ static int __init gicv2_init(struct dt_device_node *node, const void *data)
" gic_hyp_addr=%"PRIpaddr"\n"
" gic_vcpu_addr=%"PRIpaddr"\n"
" gic_maintenance_irq=%u\n",
- gicv2.dbase, gicv2.cbase, gicv2.hbase, gicv2.vbase,
- gicv2_info.maintenance_irq);
+ hip04gic.dbase, hip04gic.cbase, hip04gic.hbase, hip04gic.vbase,
+ hip04gic_info.maintenance_irq);
- if ( (gicv2.dbase & ~PAGE_MASK) || (gicv2.cbase & ~PAGE_MASK) ||
- (gicv2.hbase & ~PAGE_MASK) || (gicv2.vbase & ~PAGE_MASK) )
+ if ( (hip04gic.dbase & ~PAGE_MASK) || (hip04gic.cbase & ~PAGE_MASK) ||
+ (hip04gic.hbase & ~PAGE_MASK) || (hip04gic.vbase & ~PAGE_MASK) )
panic("GICv2 interfaces not page aligned");
- gicv2.map_dbase = ioremap_nocache(gicv2.dbase, PAGE_SIZE);
- if ( !gicv2.map_dbase )
+ hip04gic.map_dbase = ioremap_nocache(hip04gic.dbase, PAGE_SIZE);
+ if ( !hip04gic.map_dbase )
panic("GICv2: Failed to ioremap for GIC distributor\n");
- gicv2.map_cbase[0] = ioremap_nocache(gicv2.cbase, PAGE_SIZE);
+ hip04gic.map_cbase[0] = ioremap_nocache(hip04gic.cbase, PAGE_SIZE);
if ( platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
- gicv2.map_cbase[1] = ioremap_nocache(gicv2.cbase + PAGE_SIZE * 0x10,
+ hip04gic.map_cbase[1] = ioremap_nocache(hip04gic.cbase + PAGE_SIZE * 0x10,
PAGE_SIZE);
else
- gicv2.map_cbase[1] = ioremap_nocache(gicv2.cbase + PAGE_SIZE, PAGE_SIZE);
+ hip04gic.map_cbase[1] = ioremap_nocache(hip04gic.cbase + PAGE_SIZE, PAGE_SIZE);
- if ( !gicv2.map_cbase[0] || !gicv2.map_cbase[1] )
+ if ( !hip04gic.map_cbase[0] || !hip04gic.map_cbase[1] )
panic("GICv2: Failed to ioremap for GIC CPU interface\n");
- gicv2.map_hbase = ioremap_nocache(gicv2.hbase, PAGE_SIZE);
- if ( !gicv2.map_hbase )
+ hip04gic.map_hbase = ioremap_nocache(hip04gic.hbase, PAGE_SIZE);
+ if ( !hip04gic.map_hbase )
panic("GICv2: Failed to ioremap for GIC Virtual interface\n");
/* Global settings: interrupt distributor */
- spin_lock_init(&gicv2.lock);
- spin_lock(&gicv2.lock);
+ spin_lock_init(&hip04gic.lock);
+ spin_lock(&hip04gic.lock);
- gicv2_dist_init();
- gicv2_cpu_init();
- gicv2_hyp_init();
+ hip04gic_dist_init();
+ hip04gic_cpu_init();
+ hip04gic_hyp_init();
- spin_unlock(&gicv2.lock);
+ spin_unlock(&hip04gic.lock);
- gicv2_info.hw_version = GIC_V2;
- register_gic_ops(&gicv2_ops);
+ hip04gic_info.hw_version = GIC_V2;
+ register_gic_ops(&hip04gic_ops);
return 0;
}
-static const char * const gicv2_dt_compat[] __initconst =
+static const char * const hip04gic_dt_compat[] __initconst =
{
- DT_COMPAT_GIC_CORTEX_A15,
- DT_COMPAT_GIC_CORTEX_A7,
- DT_COMPAT_GIC_400,
+ DT_COMPAT_GIC_HIP04,
NULL
};
-DT_DEVICE_START(gicv2, "GICv2:", DEVICE_GIC)
- .compatible = gicv2_dt_compat,
- .init = gicv2_init,
+DT_DEVICE_START(hip04gic, "GIC-HIP04:", DEVICE_GIC)
+ .compatible = hip04gic_dt_compat,
+ .init = hip04gic_init,
DT_DEVICE_END
/*
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 390c8b0..e4512a8 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -565,12 +565,13 @@ static void do_sgi(struct cpu_user_regs *regs, enum gic_sgi sgi)
void gic_interrupt(struct cpu_user_regs *regs, int is_fiq)
{
unsigned int irq;
+ unsigned int max_irq = gic_hw_ops->info->nr_lines;
do {
/* Reading IRQ will ACK it */
irq = gic_hw_ops->read_irq();
- if ( likely(irq >= 16 && irq < 1021) )
+ if ( likely(irq >= 16 && irq < max_irq) )
{
local_irq_enable();
do_IRQ(regs, irq, is_fiq);
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index 187dc46..a36f486 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -160,6 +160,10 @@
DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_CORTEX_A7), \
DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_400)
+#define DT_COMPAT_GIC_HIP04 "hisilicon,hip04-intc"
+
+#define DT_MATCH_GIC_HIP04 DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_HIP04)
+
#define DT_COMPAT_GIC_V3 "arm,gic-v3"
#define DT_MATCH_GIC_V3 DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_V3)
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v6 4/5] xen/arm: handle GICH register changes for hip04-d01 platform
2015-02-26 12:40 [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform Frediano Ziglio
` (2 preceding siblings ...)
2015-02-26 12:40 ` [PATCH v6 3/5] xen/arm: Make gic-v2 code handle hip04-d01 platform Frediano Ziglio
@ 2015-02-26 12:40 ` Frediano Ziglio
2015-02-26 12:40 ` [PATCH v6 5/5] xen/arm: Force dom0 to use normal GICv2 driver on Hip04 platform Frediano Ziglio
2015-02-26 13:24 ` [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform Julien Grall
5 siblings, 0 replies; 16+ messages in thread
From: Frediano Ziglio @ 2015-02-26 12:40 UTC (permalink / raw)
To: Ian Campbell, Stefano Stabellini, Tim Deegan, Julien Grall,
frediano.ziglio
Cc: zoltan.kiss, xen-devel
The GICH in this platform is mainly compatible with the standard
GICv2 beside APR and LR register offsets.
Signed-off-by: Frediano Ziglio <frediano.ziglio@huawei.com>
---
xen/arch/arm/gic-hip04.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/xen/arch/arm/gic-hip04.c b/xen/arch/arm/gic-hip04.c
index 84d60fd..d96a29e 100644
--- a/xen/arch/arm/gic-hip04.c
+++ b/xen/arch/arm/gic-hip04.c
@@ -87,6 +87,9 @@ static DEFINE_PER_CPU(u16, gic_cpu_id);
#define HIP04_GICD_SGI_TARGET_SHIFT 8
+#define HIP04_GICH_APR 0x70
+#define HIP04_GICH_LR 0x80
+
static inline void writeb_gicd(uint8_t val, unsigned int offset)
{
writeb_relaxed(val, hip04gic.map_dbase + offset);
@@ -156,9 +159,9 @@ static void hip04gic_save_state(struct vcpu *v)
* accessed simultaneously by another pCPU.
*/
for ( i = 0; i < hip04gic_info.nr_lrs; i++ )
- v->arch.gic.v2.lr[i] = readl_gich(GICH_LR + i * 4);
+ v->arch.gic.v2.lr[i] = readl_gich(HIP04_GICH_LR + i * 4);
- v->arch.gic.v2.apr = readl_gich(GICH_APR);
+ v->arch.gic.v2.apr = readl_gich(HIP04_GICH_APR);
v->arch.gic.v2.vmcr = readl_gich(GICH_VMCR);
/* Disable until next VCPU scheduled */
writel_gich(0, GICH_HCR);
@@ -169,9 +172,9 @@ static void hip04gic_restore_state(const struct vcpu *v)
int i;
for ( i = 0; i < hip04gic_info.nr_lrs; i++ )
- writel_gich(v->arch.gic.v2.lr[i], GICH_LR + i * 4);
+ writel_gich(v->arch.gic.v2.lr[i], HIP04_GICH_LR + i * 4);
- writel_gich(v->arch.gic.v2.apr, GICH_APR);
+ writel_gich(v->arch.gic.v2.apr, HIP04_GICH_APR);
writel_gich(v->arch.gic.v2.vmcr, GICH_VMCR);
writel_gich(GICH_HCR_EN, GICH_HCR);
}
@@ -184,7 +187,7 @@ static void hip04gic_dump_state(const struct vcpu *v)
{
for ( i = 0; i < hip04gic_info.nr_lrs; i++ )
printk(" HW_LR[%d]=%x\n", i,
- readl_gich(GICH_LR + i * 4));
+ readl_gich(HIP04_GICH_LR + i * 4));
}
else
{
@@ -412,12 +415,12 @@ static void hip04gic_update_lr(int lr, const struct pending_irq *p,
<< GICH_V2_LR_PHYSICAL_SHIFT);
}
- writel_gich(lr_reg, GICH_LR + lr * 4);
+ writel_gich(lr_reg, HIP04_GICH_LR + lr * 4);
}
static void hip04gic_clear_lr(int lr)
{
- writel_gich(0, GICH_LR + lr * 4);
+ writel_gich(0, HIP04_GICH_LR + lr * 4);
}
static int hip04gicv_setup(struct domain *d)
@@ -465,7 +468,7 @@ static void hip04gic_read_lr(int lr, struct gic_lr *lr_reg)
{
uint32_t lrv;
- lrv = readl_gich(GICH_LR + lr * 4);
+ lrv = readl_gich(HIP04_GICH_LR + lr * 4);
lr_reg->pirq = (lrv >> GICH_V2_LR_PHYSICAL_SHIFT) & GICH_V2_LR_PHYSICAL_MASK;
lr_reg->virq = (lrv >> GICH_V2_LR_VIRTUAL_SHIFT) & GICH_V2_LR_VIRTUAL_MASK;
lr_reg->priority = (lrv >> GICH_V2_LR_PRIORITY_SHIFT) & GICH_V2_LR_PRIORITY_MASK;
@@ -488,7 +491,7 @@ static void hip04gic_write_lr(int lr, const struct gic_lr *lr_reg)
<< GICH_V2_LR_HW_SHIFT) |
((uint32_t)(lr_reg->grp & GICH_V2_LR_GRP_MASK) << GICH_V2_LR_GRP_SHIFT) );
- writel_gich(lrv, GICH_LR + lr * 4);
+ writel_gich(lrv, HIP04_GICH_LR + lr * 4);
}
static void hip04gic_hcr_status(uint32_t flag, bool_t status)
@@ -511,7 +514,7 @@ static unsigned int hip04gic_read_vmcr_priority(void)
static unsigned int hip04gic_read_apr(int apr_reg)
{
- return readl_gich(GICH_APR);
+ return readl_gich(HIP04_GICH_APR);
}
static void hip04gic_irq_enable(struct irq_desc *desc)
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v6 5/5] xen/arm: Force dom0 to use normal GICv2 driver on Hip04 platform
2015-02-26 12:40 [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform Frediano Ziglio
` (3 preceding siblings ...)
2015-02-26 12:40 ` [PATCH v6 4/5] xen/arm: handle GICH register changes for " Frediano Ziglio
@ 2015-02-26 12:40 ` Frediano Ziglio
2015-02-26 13:24 ` [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform Julien Grall
5 siblings, 0 replies; 16+ messages in thread
From: Frediano Ziglio @ 2015-02-26 12:40 UTC (permalink / raw)
To: Ian Campbell, Stefano Stabellini, Tim Deegan, Julien Grall,
frediano.ziglio
Cc: zoltan.kiss, xen-devel
Until vGIC support is not implemented and tested, this will prevent
guest kernels to use their Hip04 driver, or crash when they don't
have any.
Signed-off-by: Frediano Ziglio <frediano.ziglio@huawei.com>
---
xen/arch/arm/gic-hip04.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/xen/arch/arm/gic-hip04.c b/xen/arch/arm/gic-hip04.c
index d96a29e..c90ea1e 100644
--- a/xen/arch/arm/gic-hip04.c
+++ b/xen/arch/arm/gic-hip04.c
@@ -598,17 +598,21 @@ static int hip04gic_make_dt_node(const struct domain *d,
const struct dt_device_node *node, void *fdt)
{
const struct dt_device_node *gic = dt_interrupt_controller;
- const void *compatible = NULL;
+ const void *compatible;
u32 len;
const __be32 *regs;
int res = 0;
- compatible = dt_get_property(gic, "compatible", &len);
- if ( !compatible )
- {
- dprintk(XENLOG_ERR, "Can't find compatible property for the gic node\n");
- return -FDT_ERR_XEN(ENOENT);
- }
+ /*
+ * Replace compatibility string with a standard one.
+ * dom0 will see a compatible GIC. This as GICC is compatible
+ * with standard one and GICD (emulated by Xen) is compatible
+ * to standard. Otherwise we should implement HIP04 GICD in
+ * the virtual GIC.
+ * This actually limit CPU number to 8 for dom0.
+ */
+ compatible = DT_COMPAT_GIC_CORTEX_A15;
+ len = strlen((char*) compatible) + 1;
res = fdt_begin_node(fdt, "interrupt-controller");
if ( res )
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v6 1/5] xen/arm: Duplicate gic-v2.c file to support hip04 platform version
2015-02-26 12:40 ` [PATCH v6 1/5] xen/arm: Duplicate gic-v2.c file to support hip04 platform version Frediano Ziglio
@ 2015-02-26 13:14 ` Julien Grall
2015-02-26 14:31 ` Frediano Ziglio
0 siblings, 1 reply; 16+ messages in thread
From: Julien Grall @ 2015-02-26 13:14 UTC (permalink / raw)
To: Frediano Ziglio, Ian Campbell, Stefano Stabellini, Tim Deegan
Cc: zoltan.kiss, xen-devel
Hi Frediano,
On 26/02/15 12:40, Frediano Ziglio wrote:
> HiSilison Hip04 platform use a slightly different version.
> This is just a verbatim copy of the file to workaround git
> not fully supporting copy operation.
This is an old verbatim copy. You miss at least one change in the copied
GICv2 driver.
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v6 3/5] xen/arm: Make gic-v2 code handle hip04-d01 platform
2015-02-26 12:40 ` [PATCH v6 3/5] xen/arm: Make gic-v2 code handle hip04-d01 platform Frediano Ziglio
@ 2015-02-26 13:23 ` Julien Grall
2015-02-26 14:45 ` Frediano Ziglio
2015-02-26 16:40 ` Frediano Ziglio
0 siblings, 2 replies; 16+ messages in thread
From: Julien Grall @ 2015-02-26 13:23 UTC (permalink / raw)
To: Frediano Ziglio, Ian Campbell, Stefano Stabellini, Tim Deegan
Cc: zoltan.kiss, xen-devel
Hi Frediano,
On 26/02/15 12:40, Frediano Ziglio wrote:
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index c2dcb49..0834053 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -1038,6 +1038,7 @@ static int handle_node(struct domain *d, struct kernel_info *kinfo,
> static const struct dt_device_match gic_matches[] __initconst =
> {
> DT_MATCH_GIC_V2,
> + DT_MATCH_GIC_HIP04,
> DT_MATCH_GIC_V3,
> { /* sentinel */ },
> };
I think this is the perfect time to introduce a callback to check if the
node is a GIC.
This would avoid to grow up this structure.
[..]
> -static const char * const gicv2_dt_compat[] __initconst =
> +static const char * const hip04gic_dt_compat[] __initconst =
> {
> - DT_COMPAT_GIC_CORTEX_A15,
> - DT_COMPAT_GIC_CORTEX_A7,
> - DT_COMPAT_GIC_400,
> + DT_COMPAT_GIC_HIP04,
> NULL
> };
>
> -DT_DEVICE_START(gicv2, "GICv2:", DEVICE_GIC)
> - .compatible = gicv2_dt_compat,
> - .init = gicv2_init,
> +DT_DEVICE_START(hip04gic, "GIC-HIP04:", DEVICE_GIC)
The ":" was a mistake in the GICv2. Please don't reproduce it here.
> + .compatible = hip04gic_dt_compat,
> + .init = hip04gic_init,
> DT_DEVICE_END
>
> /*
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 390c8b0..e4512a8 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -565,12 +565,13 @@ static void do_sgi(struct cpu_user_regs *regs, enum gic_sgi sgi)
> void gic_interrupt(struct cpu_user_regs *regs, int is_fiq)
> {
> unsigned int irq;
> + unsigned int max_irq = gic_hw_ops->info->nr_lines;
>
> do {
> /* Reading IRQ will ACK it */
> irq = gic_hw_ops->read_irq();
>
> - if ( likely(irq >= 16 && irq < 1021) )
> + if ( likely(irq >= 16 && irq < max_irq) )
> {
> local_irq_enable();
> do_IRQ(regs, irq, is_fiq);
This change should belong to a separate patch.
> diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
> index 187dc46..a36f486 100644
> --- a/xen/include/asm-arm/gic.h
> +++ b/xen/include/asm-arm/gic.h
> @@ -160,6 +160,10 @@
> DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_CORTEX_A7), \
> DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_400)
>
> +#define DT_COMPAT_GIC_HIP04 "hisilicon,hip04-intc"
> +
> +#define DT_MATCH_GIC_HIP04 DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_HIP04)
> +
> #define DT_COMPAT_GIC_V3 "arm,gic-v3"
>
> #define DT_MATCH_GIC_V3 DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_V3)
I would prefer if we avoid to add more compatibles like that in gic.h.
I have a patch to drop a part of this mess. I would advise your to use
cherry-pick the commit [1] in your branch.
[1]
http://xenbits.xen.org/gitweb/?p=people/julieng/xen-unstable.git;a=commit;h=7ba87910e557b06c589c3c0fbc6757fa664d029e
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform
2015-02-26 12:40 [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform Frediano Ziglio
` (4 preceding siblings ...)
2015-02-26 12:40 ` [PATCH v6 5/5] xen/arm: Force dom0 to use normal GICv2 driver on Hip04 platform Frediano Ziglio
@ 2015-02-26 13:24 ` Julien Grall
2015-02-27 16:09 ` Frediano Ziglio
5 siblings, 1 reply; 16+ messages in thread
From: Julien Grall @ 2015-02-26 13:24 UTC (permalink / raw)
To: Frediano Ziglio, Ian Campbell, Stefano Stabellini, Tim Deegan
Cc: zoltan.kiss, xen-devel
Hi Frediano,
On 26/02/15 12:40, Frediano Ziglio wrote:
> xen/arm: Make gic-v2 code handle hip04-d01 platform
> xen/arm: handle GICH register changes for hip04-d01 platform
> xen/arm: Force dom0 to use normal GICv2 driver on Hip04 platform
There is not much benefits to have 3 separate patches. I think they
could be merged in a single-patch.
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v6 1/5] xen/arm: Duplicate gic-v2.c file to support hip04 platform version
2015-02-26 13:14 ` Julien Grall
@ 2015-02-26 14:31 ` Frediano Ziglio
2015-02-26 15:19 ` Julien Grall
0 siblings, 1 reply; 16+ messages in thread
From: Frediano Ziglio @ 2015-02-26 14:31 UTC (permalink / raw)
To: Julien Grall, Ian Campbell, Stefano Stabellini, Tim Deegan
Cc: Zoltan Kiss, xen-devel
>
> Hi Frediano,
>
> On 26/02/15 12:40, Frediano Ziglio wrote:
> > HiSilison Hip04 platform use a slightly different version.
> > This is just a verbatim copy of the file to workaround git not fully
> > supporting copy operation.
>
> This is an old verbatim copy. You miss at least one change in the
> copied
> GICv2 driver.
>
> Regards,
>
> --
> Julien Grall
I think you are referring to changes in staging, right ?
Frediano
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v6 3/5] xen/arm: Make gic-v2 code handle hip04-d01 platform
2015-02-26 13:23 ` Julien Grall
@ 2015-02-26 14:45 ` Frediano Ziglio
2015-02-26 15:20 ` Julien Grall
2015-02-26 16:40 ` Frediano Ziglio
1 sibling, 1 reply; 16+ messages in thread
From: Frediano Ziglio @ 2015-02-26 14:45 UTC (permalink / raw)
To: Julien Grall, Ian Campbell, Stefano Stabellini, Tim Deegan
Cc: Zoltan Kiss, xen-devel
>
> Hi Frediano,
>
> On 26/02/15 12:40, Frediano Ziglio wrote:
> > diff --git a/xen/arch/arm/domain_build.c
> b/xen/arch/arm/domain_build.c
> > index c2dcb49..0834053 100644
> > --- a/xen/arch/arm/domain_build.c
> > +++ b/xen/arch/arm/domain_build.c
> > @@ -1038,6 +1038,7 @@ static int handle_node(struct domain *d, struct
> kernel_info *kinfo,
> > static const struct dt_device_match gic_matches[] __initconst =
> > {
> > DT_MATCH_GIC_V2,
> > + DT_MATCH_GIC_HIP04,
> > DT_MATCH_GIC_V3,
> > { /* sentinel */ },
> > };
>
> I think this is the perfect time to introduce a callback to check if
> the node is a GIC.
>
> This would avoid to grow up this structure.
>
> [..]
>
Actually looking at assignment of dt_interrupt_controller (a dt_device_node) and calls to register_gic_ops there is a one-to-one correspondence so you can check if node == dt_interrupt_controller in handle_node instead of using a manually compiled gic_matches and checking with dt_match_node? This way I could even avoid to defined in a header the DT compatible string.
> > -static const char * const gicv2_dt_compat[] __initconst =
> > +static const char * const hip04gic_dt_compat[] __initconst =
> > {
> > - DT_COMPAT_GIC_CORTEX_A15,
> > - DT_COMPAT_GIC_CORTEX_A7,
> > - DT_COMPAT_GIC_400,
> > + DT_COMPAT_GIC_HIP04,
> > NULL
> > };
> >
> > -DT_DEVICE_START(gicv2, "GICv2:", DEVICE_GIC)
> > - .compatible = gicv2_dt_compat,
> > - .init = gicv2_init,
> > +DT_DEVICE_START(hip04gic, "GIC-HIP04:", DEVICE_GIC)
>
> The ":" was a mistake in the GICv2. Please don't reproduce it here.
>
> > + .compatible = hip04gic_dt_compat,
> > + .init = hip04gic_init,
> > DT_DEVICE_END
> >
> > /*
> > diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index
> > 390c8b0..e4512a8 100644
> > --- a/xen/arch/arm/gic.c
> > +++ b/xen/arch/arm/gic.c
> > @@ -565,12 +565,13 @@ static void do_sgi(struct cpu_user_regs *regs,
> > enum gic_sgi sgi) void gic_interrupt(struct cpu_user_regs *regs, int
> > is_fiq) {
> > unsigned int irq;
> > + unsigned int max_irq = gic_hw_ops->info->nr_lines;
> >
> > do {
> > /* Reading IRQ will ACK it */
> > irq = gic_hw_ops->read_irq();
> >
> > - if ( likely(irq >= 16 && irq < 1021) )
> > + if ( likely(irq >= 16 && irq < max_irq) )
> > {
> > local_irq_enable();
> > do_IRQ(regs, irq, is_fiq);
>
> This change should belong to a separate patch.
>
> > diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
> > index 187dc46..a36f486 100644
> > --- a/xen/include/asm-arm/gic.h
> > +++ b/xen/include/asm-arm/gic.h
> > @@ -160,6 +160,10 @@
> > DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_CORTEX_A7),
> \
> > DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_400)
> >
> > +#define DT_COMPAT_GIC_HIP04 "hisilicon,hip04-intc"
> > +
> > +#define DT_MATCH_GIC_HIP04 DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_HIP04)
> > +
> > #define DT_COMPAT_GIC_V3 "arm,gic-v3"
> >
> > #define DT_MATCH_GIC_V3 DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_V3)
>
> I would prefer if we avoid to add more compatibles like that in gic.h.
>
> I have a patch to drop a part of this mess. I would advise your to use
> cherry-pick the commit [1] in your branch.
>
> [1]
> http://xenbits.xen.org/gitweb/?p=people/julieng/xen-
> unstable.git;a=commit;h=7ba87910e557b06c589c3c0fbc6757fa664d029e
>
> Regards,
>
> --
> Julien Grall
Is this patch in staging?
Frediano
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v6 1/5] xen/arm: Duplicate gic-v2.c file to support hip04 platform version
2015-02-26 14:31 ` Frediano Ziglio
@ 2015-02-26 15:19 ` Julien Grall
2015-02-26 15:31 ` Frediano Ziglio
0 siblings, 1 reply; 16+ messages in thread
From: Julien Grall @ 2015-02-26 15:19 UTC (permalink / raw)
To: Frediano Ziglio, Ian Campbell, Stefano Stabellini, Tim Deegan
Cc: Zoltan Kiss, xen-devel
On 26/02/15 14:31, Frediano Ziglio wrote:
>>
>> Hi Frediano,
>>
>> On 26/02/15 12:40, Frediano Ziglio wrote:
>>> HiSilison Hip04 platform use a slightly different version.
>>> This is just a verbatim copy of the file to workaround git not fully
>>> supporting copy operation.
>>
>> This is an old verbatim copy. You miss at least one change in the
>> copied
>> GICv2 driver.
>>
>> Regards,
>>
>> --
>> Julien Grall
>
> I think you are referring to changes in staging, right ?
Yes. If you already start to diverge from staging that's not good.
We may have some patches reaching upstream before this series. You have
to keep up-date every-time you send a new version.
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v6 3/5] xen/arm: Make gic-v2 code handle hip04-d01 platform
2015-02-26 14:45 ` Frediano Ziglio
@ 2015-02-26 15:20 ` Julien Grall
0 siblings, 0 replies; 16+ messages in thread
From: Julien Grall @ 2015-02-26 15:20 UTC (permalink / raw)
To: Frediano Ziglio, Ian Campbell, Stefano Stabellini, Tim Deegan
Cc: Zoltan Kiss, xen-devel
On 26/02/15 14:45, Frediano Ziglio wrote:
>> I would prefer if we avoid to add more compatibles like that in gic.h.
>>
>> I have a patch to drop a part of this mess. I would advise your to use
>> cherry-pick the commit [1] in your branch.
>>
>> [1]
>> http://xenbits.xen.org/gitweb/?p=people/julieng/xen-
>> unstable.git;a=commit;h=7ba87910e557b06c589c3c0fbc6757fa664d029e
>>
>> Regards,
>>
>> --
>> Julien Grall
Please quote the correct part when you answer.
> Is this patch in staging?
Not yet. But we should avoid to introduce more mess in the headers.
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v6 1/5] xen/arm: Duplicate gic-v2.c file to support hip04 platform version
2015-02-26 15:19 ` Julien Grall
@ 2015-02-26 15:31 ` Frediano Ziglio
0 siblings, 0 replies; 16+ messages in thread
From: Frediano Ziglio @ 2015-02-26 15:31 UTC (permalink / raw)
To: Julien Grall, Ian Campbell, Stefano Stabellini, Tim Deegan
Cc: Zoltan Kiss, xen-devel
> On 26/02/15 14:31, Frediano Ziglio wrote:
> >>
> >> Hi Frediano,
> >>
> >> On 26/02/15 12:40, Frediano Ziglio wrote:
> >>> HiSilison Hip04 platform use a slightly different version.
> >>> This is just a verbatim copy of the file to workaround git not
> fully
> >>> supporting copy operation.
> >>
> >> This is an old verbatim copy. You miss at least one change in the
> >> copied
> >> GICv2 driver.
> >>
> >> Regards,
> >>
> >> --
> >> Julien Grall
> >
> > I think you are referring to changes in staging, right ?
>
> Yes. If you already start to diverge from staging that's not good.
>
> We may have some patches reaching upstream before this series. You have
> to keep up-date every-time you send a new version.
>
> Regards,
>
Ok, I always used master as a start, not staging. I'll rebase on staging then.
Frediano
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v6 3/5] xen/arm: Make gic-v2 code handle hip04-d01 platform
2015-02-26 13:23 ` Julien Grall
2015-02-26 14:45 ` Frediano Ziglio
@ 2015-02-26 16:40 ` Frediano Ziglio
1 sibling, 0 replies; 16+ messages in thread
From: Frediano Ziglio @ 2015-02-26 16:40 UTC (permalink / raw)
To: Julien Grall, Ian Campbell, Stefano Stabellini, Tim Deegan
Cc: Zoltan Kiss, xen-devel
...
> > /*
> > diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index
> > 390c8b0..e4512a8 100644
> > --- a/xen/arch/arm/gic.c
> > +++ b/xen/arch/arm/gic.c
> > @@ -565,12 +565,13 @@ static void do_sgi(struct cpu_user_regs *regs,
> > enum gic_sgi sgi) void gic_interrupt(struct cpu_user_regs *regs, int
> > is_fiq) {
> > unsigned int irq;
> > + unsigned int max_irq = gic_hw_ops->info->nr_lines;
> >
> > do {
> > /* Reading IRQ will ACK it */
> > irq = gic_hw_ops->read_irq();
> >
> > - if ( likely(irq >= 16 && irq < 1021) )
> > + if ( likely(irq >= 16 && irq < max_irq) )
> > {
> > local_irq_enable();
> > do_IRQ(regs, irq, is_fiq);
>
> This change should belong to a separate patch.
>
Looking at code paths and discussing with a colleague that partially wrote the patch I think this test is not necessary at all.
I'll check it.
Frediano
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform
2015-02-26 13:24 ` [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform Julien Grall
@ 2015-02-27 16:09 ` Frediano Ziglio
0 siblings, 0 replies; 16+ messages in thread
From: Frediano Ziglio @ 2015-02-27 16:09 UTC (permalink / raw)
To: Julien Grall
Cc: Zoltan Kiss, Ian Campbell, Tim Deegan, Xen-devel,
Frediano Ziglio, Stefano Stabellini
2015-02-26 13:24 GMT+00:00 Julien Grall <julien.grall@linaro.org>:
> Hi Frediano,
>
> On 26/02/15 12:40, Frediano Ziglio wrote:
>> xen/arm: Make gic-v2 code handle hip04-d01 platform
>> xen/arm: handle GICH register changes for hip04-d01 platform
>> xen/arm: Force dom0 to use normal GICv2 driver on Hip04 platform
>
> There is not much benefits to have 3 separate patches. I think they
> could be merged in a single-patch.
>
In the last version I merged 2 of the 3 patches. In the third the
comment is really specific to the piece of code.
Frediano
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2015-02-27 16:09 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-26 12:40 [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform Frediano Ziglio
2015-02-26 12:40 ` [PATCH v6 1/5] xen/arm: Duplicate gic-v2.c file to support hip04 platform version Frediano Ziglio
2015-02-26 13:14 ` Julien Grall
2015-02-26 14:31 ` Frediano Ziglio
2015-02-26 15:19 ` Julien Grall
2015-02-26 15:31 ` Frediano Ziglio
2015-02-26 12:40 ` [PATCH v6 2/5] xen/arm: Add HAS_NON_STANDARD_DRIVERS build option to arm Frediano Ziglio
2015-02-26 12:40 ` [PATCH v6 3/5] xen/arm: Make gic-v2 code handle hip04-d01 platform Frediano Ziglio
2015-02-26 13:23 ` Julien Grall
2015-02-26 14:45 ` Frediano Ziglio
2015-02-26 15:20 ` Julien Grall
2015-02-26 16:40 ` Frediano Ziglio
2015-02-26 12:40 ` [PATCH v6 4/5] xen/arm: handle GICH register changes for " Frediano Ziglio
2015-02-26 12:40 ` [PATCH v6 5/5] xen/arm: Force dom0 to use normal GICv2 driver on Hip04 platform Frediano Ziglio
2015-02-26 13:24 ` [PATCH v6 0/5] xen/arm: Add support for Huawei hip04-d01 platform Julien Grall
2015-02-27 16:09 ` Frediano Ziglio
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.