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

Re: [Xen-devel] [RFC PATCH v1 09/10] xen/arm: Add vgic support for GIC v3



On Wed, 19 Mar 2014, vijay.kilari@xxxxxxxxx wrote:
> From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
> 
> Add vgic driver support for GIC v3 version.
> 
> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
> ---
>  xen/arch/arm/Makefile     |    2 +-
>  xen/arch/arm/vgic-v3.c    |  927 
> +++++++++++++++++++++++++++++++++++++++++++++
>  xen/arch/arm/vgic.c       |   12 +
>  xen/include/asm-arm/gic.h |    1 +
>  4 files changed, 941 insertions(+), 1 deletion(-)
> 
> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
> index a11c699..5a6cb07 100644
> --- a/xen/arch/arm/Makefile
> +++ b/xen/arch/arm/Makefile
> @@ -26,7 +26,7 @@ obj-y += smpboot.o
>  obj-y += smp.o
>  obj-y += shutdown.o
>  obj-y += traps.o
> -obj-y += vgic.o vgic-v2.o
> +obj-y += vgic.o vgic-v2.o vgic-v3.o
>  obj-y += vtimer.o
>  obj-y += vuart.o
>  obj-y += hvm.o
> diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
> new file mode 100644
> index 0000000..b5c1d1e
> --- /dev/null
> +++ b/xen/arch/arm/vgic-v3.c
> @@ -0,0 +1,927 @@
> +/*
> + * xen/arch/arm/vgic-v3.c
> + *
> + * ARM Virtual Generic Interrupt Controller v3 support
> + * based on xen/arch/arm/vgic.c
> + *
> + * Vijaya Kumar K <vijaya.kumar@xxxxxxxxxxxxxxxxxx>
> + * Copyright (c) 2014 Cavium Inc.
> + *
> + * 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/bitops.h>
> +#include <xen/config.h>
> +#include <xen/lib.h>
> +#include <xen/init.h>
> +#include <xen/softirq.h>
> +#include <xen/irq.h>
> +#include <xen/sched.h>
> +
> +#include <asm/current.h>
> +
> +#include "io.h"
> +#include <asm/gic-v3.h>
> +#include <asm/gic.h>
> +
> +struct vgic_irq_rank {
> +    spinlock_t lock; /* Covers access to all other members of this struct */
> +    uint32_t ienable, iactive, ipend, pendsgi;
> +    uint32_t icfg[2];
> +    uint32_t ipriority[8];
> +    uint64_t irouter[32];
> +};
> +
> +#define REG(n) (n)
> +
> +/* Number of ranks of interrupt registers for a domain */
> +#define DOMAIN_NR_RANKS(d) (((d)->arch.vgic.nr_lines+31)/32)
> +
> +/*
> + * Rank containing GICD_<FOO><n> for GICD_<FOO> with
> + * <b>-bits-per-interrupt
> + */
> +static inline int REG_RANK_NR(int b, uint32_t n)
> +{
> +    switch ( b )
> +    {
> +        case 64: return n >> 6;
> +        case 32: return n >> 5;
> +        case 16: return n >> 4;
> +        case 8: return n >> 3;
> +        case 4: return n >> 2;
> +        case 2: return n >> 1;
> +        case 1: return n;
> +        default: BUG();
> +    }
> +}
> +
> +/*
> + * Offset of GICD_<FOO><n> with its rank, for GICD_<FOO> with
> + * <b>-bits-per-interrupt.
> + */
> +/* Shift n >> 2 to make it byte register diff */
> +#define REG_RANK_INDEX(b, n) (((n) >> 2) & ((b)-1))
> +
> +/*
> + * Returns rank corresponding to a GICD_<FOO><n> register for
> + * GICD_<FOO> with <b>-bits-per-interrupt.
> + */
> +static struct vgic_irq_rank *vgic_irq_rank(struct vcpu *v, int b, int n)
> +{
> +    int rank;
> +
> +    n = n >> 2;
> +    rank  = REG_RANK_NR(b, n);
> +
> +    if ( rank == 0 ) /* Rank 0 is nothing but GICR registers in GICv3 */
> +        return (struct vgic_irq_rank *)v->arch.vgic.private_irqs;
> +    else if ( rank <= DOMAIN_NR_RANKS(v->domain) )
> +        return (struct vgic_irq_rank *)((unsigned char 
> *)(v->domain->arch.vgic.shared_irqs)
> +                + (sizeof(struct vgic_irq_rank) *(rank - 1)));
> +    else
> +        return NULL;

code style


> +}
> +
> +#define vgic_lock(v)   spin_lock_irq(&(v)->domain->arch.vgic.lock)
> +#define vgic_unlock(v) spin_unlock_irq(&(v)->domain->arch.vgic.lock)
> +
> +#define vgic_lock_rank(v, r) spin_lock(&(r)->lock)
> +#define vgic_unlock_rank(v, r) spin_unlock(&(r)->lock)
> +
> +static uint32_t byte_read(uint32_t val, int sign, int offset)
> +{
> +    int byte = offset & 0x3;
> +
> +    val = val >> (8*byte);
> +    if ( sign && (val & 0x80) )
> +        val |= 0xffffff00;
> +    else
> +        val &= 0x000000ff;
> +    return val;
> +}
> +
> +static void byte_write(uint32_t *reg, uint32_t var, int offset)
> +{
> +    int byte = offset & 0x3;
> +
> +    var &= (0xff << (8*byte));
> +
> +    *reg &= ~(0xff << (8*byte));
> +    *reg |= var;
> +}
> +
> +static int vgic_read_priority(struct vcpu *v, int irq)
> +{
> +   struct vgic_irq_rank *rank = vgic_irq_rank(v, 8, irq);
> +   return byte_read(rank->ipriority[REG_RANK_INDEX(8, irq)], 0, irq & 0x3);
> +}
> + 
> +static int __vgic_rdistr_mmio_read(struct vcpu *v, mmio_info_t *info)
> +{
> +    struct hsr_dabt dabt = info->dabt;
> +    struct cpu_user_regs *regs = guest_cpu_user_regs();
> +    register_t *r = select_user_reg(regs, dabt.reg);
> +    int offset = (int)(info->gpa - gic_data_rdist_rd_base());
> +    int gicr_reg = REG(offset);
> +    u64 mpidr;
> +    u64 aff;
> +
> +    switch ( gicr_reg )
> +    {
> +    case GICR_CTLR:
> +        /* We have implemented LPI's, read zero */
> +        goto read_as_zero;
> +    case GICR_IIDR:
> +        *r = 0x34;
> +        return 1;
> +    case GICR_TYPER:
> +        if(((info->gpa) & (~((SZ_64K * 2 * smp_processor_id()) - 1))) ==
> +            (gic_data_rdist_rd_base() & (~((SZ_64K * 2 * smp_processor_id()) 
> - 1))) )

Please add a comment to explain what you are doing here

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


 


Rackspace

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