[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v7 2/3] xen/arm: Make gic-v2 code handle hip04-d01 platform
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; - GICH APR and LR register offsets. Signed-off-by: Frediano Ziglio <frediano.ziglio@xxxxxxxxxx> Signed-off-by: Zoltan Kiss <zoltan.kiss@xxxxxxxxxx> --- xen/arch/arm/Makefile | 1 + xen/arch/arm/domain_build.c | 2 +- xen/arch/arm/gic-hip04.c | 400 +++++++++++++++++++++++--------------------- 3 files changed, 207 insertions(+), 196 deletions(-) diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index 41aba2e..72499e9 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -12,6 +12,7 @@ obj-y += domctl.o obj-y += sysctl.o obj-y += domain_build.o obj-y += gic.o gic-v2.o +obj-$(arm32) += gic-hip04.o 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 9f1f59f..83951a3 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -1069,7 +1069,7 @@ static int handle_node(struct domain *d, struct kernel_info *kinfo, /* Replace these nodes with our own. Note that the original may be * used_by DOMID_XEN so this check comes first. */ - if ( dt_match_node(gic_matches, node) ) + if ( node == dt_interrupt_controller || dt_match_node(gic_matches, node) ) return make_gic_node(d, kinfo->fdt, node); if ( dt_match_node(timer_matches, node) ) return make_timer_node(d, kinfo->fdt, node); diff --git a/xen/arch/arm/gic-hip04.c b/xen/arch/arm/gic-hip04.c index fa695d1..9977f9b 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@xxxxxxx> * Copyright (c) 2011 Citrix Systems. @@ -71,59 +72,71 @@ 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 + +#define HIP04_GICH_APR 0x70 +#define HIP04_GICH_LR 0x80 + +#define DT_COMPAT_GIC_HIP04 "hisilicon,hip04-intc" 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 +152,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,58 +160,58 @@ 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++ ) - v->arch.gic.v2.lr[i] = readl_gich(GICH_LR + i * 4); + for ( i = 0; i < hip04gic_info.nr_lrs; i++ ) + 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); } -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++ ) - writel_gich(v->arch.gic.v2.lr[i], GICH_LR + i * 4); + for ( i = 0; i < hip04gic_info.nr_lrs; i++ ) + 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); } -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)); + readl_gich(HIP04_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 +220,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, actual, 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)); @@ -232,7 +245,7 @@ static void gicv2_set_irq_properties(struct irq_desc *desc, actual = readl_gicd(GICD_ICFGR + (irq / 16) * 4); if ( ( cfg & edgebit ) ^ ( actual & edgebit ) ) { - printk(XENLOG_WARNING "GICv2: WARNING: " + printk(XENLOG_WARNING "GIC-HIP04: WARNING: " "CPU%d: Failed to configure IRQ%u as %s-triggered. " "H/w forces to %s-triggered.\n", smp_processor_id(), desc->irq, @@ -244,62 +257,61 @@ static void gicv2_set_irq_properties(struct irq_desc *desc, } /* 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); - 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 = 32 * ((type & GICD_TYPE_LINES) + 1); + gic_cpus = 16; + printk("GIC-HIP04: %d lines, %d cpu%s%s (IID %8.8x).\n", + 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 @@ -328,41 +340,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; @@ -378,9 +390,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: @@ -389,20 +401,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) | @@ -419,15 +431,15 @@ static void gicv2_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 gicv2_clear_lr(int lr) +static void hip04gic_clear_lr(int lr) { - writel_gich(0, GICH_LR + lr * 4); + writel_gich(0, HIP04_GICH_LR + lr * 4); } -static int gicv2v_setup(struct domain *d) +static int hip04gicv_setup(struct domain *d) { int ret; @@ -437,8 +449,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 { @@ -454,25 +466,25 @@ 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; - 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; @@ -481,7 +493,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; @@ -495,10 +507,10 @@ static void gicv2_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 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); @@ -510,95 +522,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); + return readl_gich(HIP04_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; @@ -652,145 +664,143 @@ 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) ) - panic("GICv2: Cannot find a valid address for the distributor"); + res = dt_device_get_address(node, 0, &hip04gic.dbase, NULL); + if ( res || !hip04gic.dbase || (hip04gic.dbase & ~PAGE_MASK) ) + panic("GIC-HIP04: 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, 1, &hip04gic.cbase, NULL); + if ( res || !hip04gic.cbase || (hip04gic.cbase & ~PAGE_MASK) ) + panic("GIC-HIP04: 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, 2, &hip04gic.hbase, NULL); + if ( res || !hip04gic.hbase || (hip04gic.hbase & ~PAGE_MASK) ) + panic("GIC-HIP04: 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 = dt_device_get_address(node, 3, &hip04gic.vbase, NULL); + if ( res || !hip04gic.vbase || (hip04gic.vbase & ~PAGE_MASK) ) + panic("GIC-HIP04: 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; + panic("GIC-HIP04: Cannot find the maintenance IRQ"); + hip04gic_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" + printk("GIC-HIP04 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); + 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) ) - panic("GICv2 interfaces not page aligned"); + if ( (hip04gic.dbase & ~PAGE_MASK) || (hip04gic.cbase & ~PAGE_MASK) || + (hip04gic.hbase & ~PAGE_MASK) || (hip04gic.vbase & ~PAGE_MASK) ) + panic("GIC-HIP04 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"); + hip04gic.map_dbase = ioremap_nocache(hip04gic.dbase, PAGE_SIZE); + if ( !hip04gic.map_dbase ) + panic("GIC-HIP04: 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] ) - panic("GICv2: Failed to ioremap for GIC CPU interface\n"); + if ( !hip04gic.map_cbase[0] || !hip04gic.map_cbase[1] ) + panic("GIC-HIP04: 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"); + hip04gic.map_hbase = ioremap_nocache(hip04gic.hbase, PAGE_SIZE); + if ( !hip04gic.map_hbase ) + panic("GIC-HIP04: 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 /* -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |