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

Re: [Minios-devel] [UNIKRAFT PATCHv5 3/6] plat/common: Implement gic-v2 library for Arm


  • To: Sharan Santhanam <sharan.santhanam@xxxxxxxxx>, "Justin He (Arm Technology China)" <Justin.He@xxxxxxx>, "minios-devel@xxxxxxxxxxxxxxxxxxxx" <minios-devel@xxxxxxxxxxxxxxxxxxxx>, Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
  • From: "Jianyong Wu (Arm Technology China)" <Jianyong.Wu@xxxxxxx>
  • Date: Wed, 10 Jul 2019 04:34:54 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1;spf=pass smtp.mailfrom=arm.com;dmarc=pass action=none header.from=arm.com;dkim=pass header.d=arm.com;arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=zrI7MLiBqfTr9F4vn1PWoI0BBI9tFStnArfdLduLRFg=; b=i/0CPrqcGV1JsHiWyESBI9S67jBi6R1mz21AVjfnHbK9SZwRAm9NLgPsFWWBO2M1Gxqd+eQ0vnocEx/8sLG2igHHl9mmWMWRCjGI7eQ6QBIRpt6NZ5w49n2yZZxLIvXTlnPW6h+4GWnt1beHCG7a+d1V3yeQgolFP0hV0dHiGpbIQpw9EZtZZdX1nyW5TQYrqQa+NmR8BVZPWNY3viC28cDGTG2E7LHwCr/cMW2UZF3yNicHJR5JK2RWemuFjdtEPaBdXtjzEKl8zJ1TV8OwrihKUPVz1+7xcJbmmgB2XuW1hJsOQz1ydyaKWNdYEdVYAeThg7AzDAWrmv4jfMbKTg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=l2fHaX//Fa5Y99yoNjkNz2tziFkrLsyVnB0j7mtLfoRztnFui2yRjP6XIzSXDkM2yrK43ys6tDCkHIDtSi8SrZLLDL2+PjN6pJmI6Zz+9m0J4vqf3+3ZHnR22RbhIHGRSoYy6KSUX6HgbnFctTViWsISLwTOqZs1JrqvUEVUu2l5aud4TqzOjV1nteP1tkkuuW7YJ3YL4fW/btN3PoMjsrVVP0Iegah1PxV1t14Gf40uUr2MYi3/aAEmUuDP0U29fg4t7LQ1zy5J0zXjZjsSofbqR5L+70UH/e6FVpnWZxEgOU6uQAUyZBqPXcifhl4Pte+6g0bMocOYVK7u0fj9TA==
  • Authentication-results: spf=none (sender IP is ) smtp.mailfrom=Jianyong.Wu@xxxxxxx;
  • Cc: Felipe Huici <felipe.huici@xxxxxxxxx>, "Wei Chen \(Arm Technology China\)" <Wei.Chen@xxxxxxx>, "Kaly Xin \(Arm Technology China\)" <Kaly.Xin@xxxxxxx>, Florian Schmidt <florian.schmidt@xxxxxxxxx>, Julien Grall <Julien.Grall@xxxxxxx>, "yuri.volchkov@xxxxxxxxx" <yuri.volchkov@xxxxxxxxx>
  • Delivery-date: Wed, 10 Jul 2019 04:35:03 +0000
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>
  • Thread-index: AQHVLYB2Q3v/A3U99EGne+d3pNMqR6bCnaKAgAC4aOA=
  • Thread-topic: [UNIKRAFT PATCHv5 3/6] plat/common: Implement gic-v2 library for Arm

Hi,

> -----Original Message-----
> From: Sharan Santhanam <sharan.santhanam@xxxxxxxxx>
> Sent: Wednesday, July 10, 2019 1:33 AM
> To: Justin He (Arm Technology China) <Justin.He@xxxxxxx>; minios-
> devel@xxxxxxxxxxxxxxxxxxxx; Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
> Cc: Florian Schmidt <florian.schmidt@xxxxxxxxx>; Felipe Huici
> <felipe.huici@xxxxxxxxx>; Julien Grall <Julien.Grall@xxxxxxx>;
> yuri.volchkov@xxxxxxxxx; Kaly Xin (Arm Technology China)
> <Kaly.Xin@xxxxxxx>; Jianyong Wu (Arm Technology China)
> <Jianyong.Wu@xxxxxxx>; Wei Chen (Arm Technology China)
> <Wei.Chen@xxxxxxx>
> Subject: Re: [UNIKRAFT PATCHv5 3/6] plat/common: Implement gic-v2 library
> for Arm
>
> Hello,
>
> Missed another comment.
>
> On 6/28/19 9:09 AM, Jia He wrote:
> > From: Jianyong Wu <jianyong.wu@xxxxxxx>
> >
> > This library has implemented basic GICv2 functions. We don't support
> > GICv2M and security extension in this library.
> >
> > Signed-off-by: Wei Chen <wei.chen@xxxxxxx>
> > Signed-off-by: Jianyong Wu <jianyong.wu@xxxxxxx>
> > Signed-off-by: Jia He <justin.he@xxxxxxx>
> > ---
> >   plat/common/include/irq.h         |  15 ++
> >   plat/drivers/gic/gic-v2.c         | 409 ++++++++++++++++++++++++++++++
> >   plat/drivers/include/gic/gic-v2.h | 370 +++++++++++++++++++++++++++
> >   plat/kvm/Makefile.uk              |   2 +
> >   4 files changed, 796 insertions(+)
> >   create mode 100644 plat/drivers/gic/gic-v2.c
> >   create mode 100644 plat/drivers/include/gic/gic-v2.h
> >
> > diff --git a/plat/common/include/irq.h b/plat/common/include/irq.h
> > index a09685d..fac5022 100644
> > --- a/plat/common/include/irq.h
> > +++ b/plat/common/include/irq.h
> > @@ -45,5 +45,20 @@
> >   #error "Add irq.h for current architecture."
> >   #endif
> >
> > +/* define IRQ trigger types */
> > +enum uk_irq_trigger {
> > +UK_IRQ_TRIGGER_NONE = 0,
> > +UK_IRQ_TRIGGER_EDGE = 1,
> > +UK_IRQ_TRIGGER_LEVEL = 2,
> > +UK_IRQ_TRIGGER_MAX
> > +};
> > +
> > +/* define IRQ trigger polarities */
> > +enum uk_irq_polarity {
> > +UK_IRQ_POLARITY_NONE = 0,
> > +UK_IRQ_POLARITY_HIGH = 1,
> > +UK_IRQ_POLARITY_LOW = 2,
> > +UK_IRQ_POLARITY_MAX
> > +};
> >
> >   #endif /* __PLAT_CMN_IRQ_H__ */
> > diff --git a/plat/drivers/gic/gic-v2.c b/plat/drivers/gic/gic-v2.c new
> > file mode 100644 index 0000000..9321155
> > --- /dev/null
> > +++ b/plat/drivers/gic/gic-v2.c
> > @@ -0,0 +1,409 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause */
> > +/*
> > + * Authors: Wei Chen <Wei.Chen@xxxxxxx>
> > + *          Jianyong Wu <Jianyong.Wu@xxxxxxx>
> > + *
> > + * Copyright (c) 2018, Arm Ltd. All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms, with or without
> > + * modification, are permitted provided that the following conditions
> > + * are met:
> > + *
> > + * 1. Redistributions of source code must retain the above copyright
> > + *    notice, this list of conditions and the following disclaimer.
> > + * 2. Redistributions in binary form must reproduce the above copyright
> > + *    notice, this list of conditions and the following disclaimer in the
> > + *    documentation and/or other materials provided with the distribution.
> > + * 3. Neither the name of the copyright holder nor the names of its
> > + *    contributors may be used to endorse or promote products derived
> from
> > + *    this software without specific prior written permission.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> CONTRIBUTORS "AS IS"
> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> LIMITED
> > +TO, THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> PARTICULAR
> > +PURPOSE
> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
> > +CONTRIBUTORS BE
> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
> > +OR
> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> PROCUREMENT
> > +OF
> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> > +BUSINESS
> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> > +WHETHER IN
> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> > +OTHERWISE)
> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> > +ADVISED OF THE
> > + * POSSIBILITY OF SUCH DAMAGE.
> > + *
> > + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
> > + */
> > +#include <string.h>
> > +#include <libfdt.h>
> > +#include <uk/essentials.h>
> > +#include <uk/print.h>
> > +#include <uk/assert.h>
> > +#include <uk/bitops.h>
> > +#include <uk/asm.h>
> > +#include <irq.h>
> > +#include <kvm/irq.h>
> > +#include <uk/plat/lcpu.h>
> > +#include <arm/cpu.h>
> > +#include <gic/gic-v2.h>
> > +#include <ofw/fdt.h>
> > +
> > +/* Max CPU interface for GICv2 */
> > +#define GIC_MAX_CPUIF8
> > +
> > +/* SPI interrupt base ID */
> > +#define GIC_SPI_BASE32
> > +
> > +/* PPI interrupt base ID */
> > +#define GIC_PPI_BASE16
> > +
> > +/* Max support interrupt number for GICv2 */
> > +#define GIC_MAX_IRQ__MAX_IRQ
> > +
> > +static uint64_t gic_dist_addr, gic_cpuif_addr; static uint64_t
> > +gic_dist_size, gic_cpuif_size;
> > +
> > +#define GIC_DIST_REG(r)((void *)(gic_dist_addr + (r)))
> > +#define GIC_CPU_REG(r)((void *)(gic_cpuif_addr + (r)))
> > +
> > +static const char * const gic_device_list[] = {
> > +"arm,cortex-a15-gic",
> > +NULL
> > +};
> > +
> > +/* inline functions to access GICC & GICD registers */ static inline
> > +void write_gicd8(uint64_t offset, uint8_t val) {
> > +ioreg_write8(GIC_DIST_REG(offset), val); }
> > +
> > +static inline void write_gicd32(uint64_t offset, uint32_t val) {
> > +ioreg_write32(GIC_DIST_REG(offset), val); }
> > +
> > +static inline uint32_t read_gicd32(uint64_t offset) {
> > +return ioreg_read32(GIC_DIST_REG(offset));
> > +}
> > +
> > +static inline void write_gicc32(uint64_t offset, uint32_t val) {
> > +ioreg_write32(GIC_CPU_REG(offset), val); }
> > +
> > +static inline uint32_t read_gicc32(uint64_t offset) {
> > +return ioreg_read32(GIC_CPU_REG(offset));
> > +}
> > +
> > +/*
> > + * Functions of GIC CPU interface
> > + */
> > +
> > +/* Enable GIC cpu interface */
> > +static void gic_enable_cpuif(void)
> > +{
> > +/* just set bit 0 to 1 to enable cpu interface */
> > +write_gicc32(GICC_CTLR, GICC_CTLR_ENABLE); }
> > +
> > +/* Set priority threshold for processor */ static void
> > +gic_set_threshold_priority(uint32_t threshold_prio) {
> > +/* GICC_PMR allocate 1 byte for each irq */
> > +UK_ASSERT(threshold_prio <= GICC_PMR_PRIO_MAX);
> > +write_gicc32(GICC_PMR, threshold_prio); }
> > +
> > +/*
> > + * Acknowledging irq equals reading GICC_IAR also
> > + * get the interrupt ID as the side effect.
> > + */
> > +uint32_t gic_ack_irq(void)
> > +{
> > +return read_gicc32(GICC_IAR);
> > +}
> > +
> > +/*
> > + * write to GICC_EOIR to inform cpu interface completation
> > + * of interrupt processing. If GICC_CTLR.EOImode sets to 1
> > + * this func just gets priority drop.
> > + */
> > +void gic_eoi_irq(uint32_t irq)
> > +{
> > +write_gicc32(GICC_EOIR, irq);
> > +}
> > +
> > +/* Functions of GIC Distributor */
> > +
> > +/*
> > + * @sgintid denotes the sgi ID;
> > + * @targetfilter : this term is TargetListFilter
> > + * @targetlist is bitmask value, A bit set to '1' indicated
> > + * the interrupt is wired to that CPU.
> > + */
> > +static void gic_sgi_gen(uint32_t sgintid, enum sgi_filter targetfilter,
> > +uint8_t targetlist)
> > +{
> > +uint32_t val;
> > +
> > +/* Only INTID 0-15 allocated to sgi */
> > +UK_ASSERT(sgintid <= GICD_SGI_MAX_INITID);
> > +
> > +/* Set SGI tagetfileter field */
> > +val = (targetfilter & GICD_SGI_FILTER_MASK) <<
> > +GICD_SGI_FILTER_SHIFT;
> > +
> > +/* Set SGI targetlist field */
> > +val |= (targetlist & GICD_SGI_TARGET_MASK) <<
> GICD_SGI_TARGET_SHIFT;
> > +
> > +/* Set SGI INITID field */
> > +val |= sgintid;
> > +
> > +/* Generate SGI */
> > +write_gicd32(GICD_SGIR, val);
> > +}
> > +
> > +/*
> > + * Forward the SIG to the CPU interfaces specified in the
> > + * targetlist. Targetlist is a 8-bit bitmap for 0~7 CPU.
> > + * TODO: this will not work until SMP is supported  */ void
> > +gic_sgi_gen_to_list(uint32_t sgintid, uint8_t targetlist) {
> > +unsigned long irqf;
> > +
> > +/* spin lock here is needed when smp is supported */
> > +irqf = ukplat_lcpu_save_irqf();
> > +gic_sgi_gen(sgintid, GICD_SGI_FILTER_TO_LIST, targetlist);
> > +ukplat_lcpu_restore_irqf(irqf);
> > +}
> > +
> > +/*
> > + * Forward the SGI to all CPU interfaces except that of the
> > + * processor that requested the interrupt.
> > + * TODO: this will not work until SMP is supported  */ void
> > +gic_sgi_gen_to_others(uint32_t sgintid) {
> > +unsigned long irqf;
> > +
> > +/* spin lock here is needed when smp is supported */
> > +irqf = ukplat_lcpu_save_irqf();
> > +gic_sgi_gen(sgintid, GICD_SGI_FILTER_TO_OTHERS, 0);
> > +ukplat_lcpu_restore_irqf(irqf);
> > +}
> > +
> > +/*
> > + * Forward the SGI only to the CPU interface of the processor
> > + * that requested the interrupt.
> > + */
> > +void gic_sgi_gen_to_self(uint32_t sgintid) {
> > +gic_sgi_gen(sgintid, GICD_SGI_FILTER_TO_SELF, 0); }
> > +
> > +/*
> > + * set target cpu for irq in distributor,
> > + * @target: bitmask value, bit 1 indicates target to
> > + * corresponding cpu interface
> > + */
> > +void gic_set_irq_target(uint32_t irq, uint8_t target)
> > +{
> > +if (irq < GIC_SPI_BASE)
> > +UK_CRASH("Bad irq number: should not less than %u",
> > +GIC_SPI_BASE);
> > +
> > +write_gicd8(GICD_ITARGETSR(irq), target);
> > +}
> > +
> > +/* set priority for irq in distributor */
> > +void gic_set_irq_prio(uint32_t irq, uint8_t priority)
> > +{
> > +write_gicd8(GICD_IPRIORITYR(irq), priority);
> > +}
> > +
> > +/*
> > + * Enable an irq in distributor, each irq occupies one bit
> > + * to configure in corresponding registor
> > + */
> > +void gic_enable_irq(uint32_t irq)
> > +{
> > +write_gicd32(GICD_ISENABLER(irq),
> > +UK_BIT(irq % GICD_I_PER_ISENABLERn));
> > +}
> > +
> > +/*
> > + * Disable an irq in distributor, one bit reserved for an irq
> > + * to configure in corresponding register
> > + */
> > +void gic_disable_irq(uint32_t irq)
> > +{
> > +write_gicd32(GICD_ICENABLER(irq),
> > +UK_BIT(irq % GICD_I_PER_ICENABLERn));
> > +}
> > +
> > +/* Enable distributor */
> > +static void gic_enable_dist(void)
> > +{
> > +/* just set bit 0 to 1 to enable distributor */
> > +write_gicd32(GICD_CTLR, read_gicd32(GICD_CTLR) |
> GICD_CTLR_ENABLE);
> > +}
> > +
> > +/* disable distributor */
> > +static void gic_disable_dist(void)
> > +{
> > +/* just clear bit 0 to 0 to enable distributor */
> > +write_gicd32(GICD_CTLR, read_gicd32(GICD_CTLR) &
> (~GICD_CTLR_ENABLE));
> > +}
> > +
> > +/* Config interrupt trigger type */
> > +void gic_set_irq_type(uint32_t irq, int trigger)
> > +{
> > +uint32_t val, mask, oldmask;
> > +
> > +if (irq < GIC_PPI_BASE)
> > +UK_CRASH("Bad irq number: should not less than %u",
> > +GIC_PPI_BASE);
> > +if (trigger >= UK_IRQ_TRIGGER_MAX)
> > +return;
> > +
> > +val = read_gicd32(GICD_ICFGR(irq));
> > +mask = oldmask = (val >> ((irq % GICD_I_PER_ICFGRn) * 2)) &
> > +GICD_ICFGR_MASK;
> > +
> > +if (trigger == UK_IRQ_TRIGGER_LEVEL) {
> > +mask &= ~GICD_ICFGR_TRIG_MASK;
> > +mask |= GICD_ICFGR_TRIG_LVL;
> > +} else if (trigger == UK_IRQ_TRIGGER_EDGE) {
> > +mask &= ~GICD_ICFGR_TRIG_MASK;
> > +mask |= GICD_ICFGR_TRIG_EDGE;
> > +}
> > +
> > +/* Check if nothing changed */
> > +if (mask == oldmask)
> > +return;
> > +
> > +/* Update new interrupt type */
> > +val &= (~(GICD_ICFGR_MASK << (irq % GICD_I_PER_ICFGRn) * 2));
> > +val |= (mask << (irq % GICD_I_PER_ICFGRn) * 2);
> > +write_gicd32(GICD_ICFGR(irq), val);
> > +}
> > +
> > +static void gic_init_dist(void)
> > +{
> > +uint32_t val, cpuif_number, irq_number;
> > +uint32_t i;
> > +
> > +/* Turn down distributor */
> > +gic_disable_dist();
> > +
> > +/* Get GIC CPU interface */
> > +val = read_gicd32(GICD_TYPER);
> > +cpuif_number = GICD_TYPER_CPUI_NUM(val);
> > +if (cpuif_number > GIC_MAX_CPUIF)
> > +cpuif_number = GIC_MAX_CPUIF;
> > +uk_pr_info("GICv2 Max CPU interface:%d\n", cpuif_number);
> > +
> > +/* Get the maximum number of interrupts that the GIC supports */
> > +irq_number = GICD_TYPER_LINE_NUM(val);
> > +if (irq_number > GIC_MAX_IRQ)
> > +irq_number = GIC_MAX_IRQ;
> > +uk_pr_info("GICv2 Max interrupt lines:%d\n", irq_number);
> > +/*
> > + * Set all SPI interrupts targets to all CPU.
> > + */
> > +for (i = GIC_SPI_BASE; i < irq_number; i += GICD_I_PER_ITARGETSRn)
> > +write_gicd32(GICD_ITARGETSR(i), GICD_ITARGETSR_DEF);
> > +
> > +/*
> > + * Set all SPI interrupts type to be level triggered
> > + */
> > +for (i = GIC_SPI_BASE; i < irq_number; i += GICD_I_PER_ICFGRn)
> > +write_gicd32(GICD_ICFGR(i), GICD_ICFGR_DEF_TYPE);
> > +
> > +/*
> > + * Set all SPI priority to a default value.
> > + */
> > +for (i = GIC_SPI_BASE; i < irq_number; i += GICD_I_PER_IPRIORITYn)
> > +write_gicd32(GICD_IPRIORITYR(i), GICD_IPRIORITY_DEF);
> > +
> > +/*
> > + * Deactivate and disable all SPIs.
> > + */
> > +for (i = GIC_SPI_BASE; i < irq_number; i += GICD_I_PER_ICACTIVERn)
> {
> > +write_gicd32(GICD_ICACTIVER(i), GICD_DEF_ICACTIVERn);
> > +write_gicd32(GICD_ICENABLER(i), GICD_DEF_ICENABLERn);
> > +}
> > +
> > +/* turn on distributor */
> > +gic_enable_dist();
> > +}
> > +
> > +static void gic_init_cpuif(void)
> > +{
> > +uint32_t i;
> > +/*
> > + * set priority mask to the lowest priority to let all irq
> > + * visible to cpu interface
> > + */
> > +gic_set_threshold_priority(GICC_PMR_PRIO_MAX);
> > +
> > +/* set PPI and SGI to level triggered */
> > +for (i = 0; i < GIC_SPI_BASE; i += GICD_I_PER_ICFGRn)
> > +write_gicd32(GICD_ICFGR(i), GICD_ICFGR_DEF_TYPE);
> > +
> > +/* set PPI and SGI to a default value */
> > +for (i = 0; i < GIC_SPI_BASE; i += GICD_I_PER_IPRIORITYn)
> > +write_gicd32(GICD_IPRIORITYR(i), GICD_IPRIORITY_DEF);
> > +
> > +/*
> > + * Deactivate and disable all PPIs.
> > + */
> > +write_gicd32(GICD_ICACTIVER(i), GICD_DEF_ICACTIVERn);
> > +write_gicd32(GICD_ICENABLER(i), GICD_DEF_PPI_ICENABLERn);
> > +
> > +/* Deactivate and enable all SGIs */
> > +write_gicd32(GICD_ICACTIVER(i), GICD_DEF_ICACTIVERn);
> > +write_gicd32(GICD_ISENABLER(i), GICD_DEF_SGI_ISENABLERn);
> > +
> > +/* enable cpu interface */
> > +gic_enable_cpuif();
> > +}
> > +
> > +int _dtb_init_gic(const void *fdt)
> > +{
> > +int fdt_gic, ret;
> > +
> > +uk_pr_info("Probing GICv2...\n");
> > +
> > +/* Currently, we only support 1 GIC per system */
> > +fdt_gic = fdt_node_offset_by_compatible_list(fdt, -1,
> > +gic_device_list);
> > +if (fdt_gic < 0)
> > +UK_CRASH("Could not find GICv2 Interrupt Controller!\n");
> > +
> > +/* Get device address and size at regs region */
> > +ret = fdt_get_address(fdt, fdt_gic, 0,
> > +&gic_dist_addr, &gic_dist_size);
> > +if (ret < 0)
> > +UK_CRASH("Could not find GICv2 distributor region!\n");
> > +
> > +ret = fdt_get_address(fdt, fdt_gic, 1,
> > +&gic_cpuif_addr, &gic_cpuif_size);
> > +if (ret < 0)
> > +UK_CRASH("Could not find GICv2 cpuif region!\n");
> > +
> > +uk_pr_info("Found GICv2 on:\n");
> > +uk_pr_info("\tDistributor  : 0x%lx - 0x%lx\n",
> > +gic_dist_addr, gic_dist_addr + gic_dist_size - 1);
> > +uk_pr_info("\tCPU interface: 0x%lx - 0x%lx\n",
> > +gic_cpuif_addr, gic_cpuif_addr + gic_cpuif_size - 1);
> > +
> > +
> > +/* Initialize GICv2 distributor */
> > +gic_init_dist();
> > +
> > +/* Initialize GICv2 CPU interface */
> > +gic_init_cpuif();
> > +
> > +return 0;
> > +}
> > diff --git a/plat/drivers/include/gic/gic-v2.h 
> > b/plat/drivers/include/gic/gic-
> v2.h
> > new file mode 100644
> > index 0000000..e04542f
> > --- /dev/null
> > +++ b/plat/drivers/include/gic/gic-v2.h
> > @@ -0,0 +1,370 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause */
> > +/*
> > + * Authors: Wei Chen <Wei.Chen@xxxxxxx>
> > + *          Jianyong Wu <Jianyong.Wu@xxxxxxx>
> > + *
> > + * Copyright (c) 2018, Arm Ltd. All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms, with or without
> > + * modification, are permitted provided that the following conditions
> > + * are met:
> > + *
> > + * 1. Redistributions of source code must retain the above copyright
> > + *    notice, this list of conditions and the following disclaimer.
> > + * 2. Redistributions in binary form must reproduce the above copyright
> > + *    notice, this list of conditions and the following disclaimer in the
> > + *    documentation and/or other materials provided with the distribution.
> > + * 3. Neither the name of the copyright holder nor the names of its
> > + *    contributors may be used to endorse or promote products derived
> from
> > + *    this software without specific prior written permission.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> CONTRIBUTORS "AS IS"
> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> LIMITED TO, THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> PARTICULAR PURPOSE
> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
> CONTRIBUTORS BE
> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
> OR
> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> PROCUREMENT OF
> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> WHETHER IN
> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> OTHERWISE)
> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> ADVISED OF THE
> > + * POSSIBILITY OF SUCH DAMAGE.
> > + *
> > + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
> > + */
> > +#ifndef __PLAT_CMN_ARM_GIC_H__
> > +#define __PLAT_CMN_ARM_GIC_H__
> > +
> > +/*
> > + * Distributor registers. Unikraft only support run on non-secure
> > + * so we just describe non-secure registers.
> > + */
> > +
> > +/*
> > + * Distributor Control Register, GICD_CTLR.
> > + * Enables the forwarding of pending interrupts from the
> > + * Distributor to the CPU interfaces
> > + */
> > +#define GICD_CTLR0x0000
> > +#define GICD_CTLR_ENABLE0x1
> > +
> > +/*
> > + * Interrupt Controller Type Register, GICD_TYPER.
> > + * Provides information about the configuration of the GIC.
> > + */
> > +#define GICD_TYPER0x0004
> > +#define GICD_TYPER_LINE_NUM(r)((((r) & 0x1f) + 1) << 5)
>
> Shouldn't the mask be 0x7 as bit 5-7 are used to identify the CPU number?
Yeah,  it should be 0x7.

Thanks
Jianyong wu
> > +#define GICD_TYPER_CPUI_NUM(r)((((r) >> 5) & 0x3) + 1)
> > +
> > +/*
> > + * Distributor Implementer Identification Register, GICD_IIDR.
> > + * Provides information about the implementer and revision of the
> Distributor.
> > + */
> > +#define GICD_IIDR0x0008
> > +#define GICD_IIDR_PROD(r)(((r) >> 24) & 0xff)
> > +#define GICD_IIDR_VAR(r)(((r) >> 16) & 0xf)
> > +#define GICD_IIDR_REV(r)(((r) >> 12) & 0xf)
> > +#define GICD_IIDR_IMPL(r)((r) & 0xfff)
> > +
> > +/*
> > + * Interrupt Group Registers, GICD_IGROUPRn
> > + * These registers provide a status bit for each interrupt supported by
> > + * the GIC. Each bit controls whether the corresponding interrupt is in
> > + * Group 0 or Group 1
> > + */
> > +#define GICD_IGROUPR(n)(0x0080 + 4 * ((n) >> 5))
> > +#define GICD_I_PER_IGROUPRn32
> > +
> > +/*
> > + * Interrupt Set-Enable Registers, GICD_ISENABLERn.
> > + * These registers provide a Set-enable bit for each interrupt supported
> > + * by the GIC. Writing 1 to a Set-enable bit enables forwarding of the
> > + * corresponding interrupt from the Distributor to the CPU interfaces.
> > + * Reading a bit identifies whether the interrupt is enabled.
> > + */
> > +#define GICD_ISENABLER(n)(0x0100 + 4 * ((n) >> 5))
> > +#define GICD_I_PER_ISENABLERn32
> > +#define GICD_DEF_SGI_ISENABLERn0xffff
> > +
> > +/*
> > + * Interrupt Clear-Enable Registers, GICD_ICENABLERn.
> > + * Provide a Clear-enable bit for each interrupt supported by the GIC.
> > + * Writing 1 to a Clear-enable bit disables forwarding of the
> > + * corresponding interrupt from the Distributor to the CPU interfaces.
> > + * Reading a bit identifies whether the interrupt is enabled.
> > + */
> > +#define GICD_ICENABLER(n)(0x0180 + 4 * ((n) >> 5))
> > +#define GICD_I_PER_ICENABLERn32
> > +#define GICD_DEF_ICENABLERn0xffffffff
> > +#define GICD_DEF_PPI_ICENABLERn0xffff0000
> > +
> > +/*
> > + * Interrupt Set-Pending Registers, GICD_ISPENDRn.
> > + * Provide a Set-pending bit for each interrupt supported by the GIC.
> > + * Writing 1 to a Set-pending bit sets the status of the corresponding
> > + * peripheral interrupt to pending. Reading a bit identifies whether
> > + * the interrupt is pending.
> > + */
> > +#define GICD_ISPENDR(n)(0x0200 + 4 * ((n) >> 5))
> > +#define GICD_I_PER_ISPENDRn32
> > +/*
> > + * Interrupt Clear-Pending Registers, GICD_ICPENDRn
> > + * Provide a Clear-pending bit for each interrupt supported by the GIC.
> > + * Writing 1 to a Clear-pending bit clears the pending state of the
> > + * corresponding peripheral interrupt. Reading a bit identifies whether
> > + * the interrupt is pending.
> > + */
> > +#define GICD_ICPENDR(n)(0x0280 + 4 * ((n) >> 5))
> > +#define GICD_I_PER_ICPENDRn32
> > +
> > +/*
> > + * Interrupt Set-Active Registers, GICD_ISACTIVERn
> > + * Provide a Set-active bit for each interrupt that the GIC supports.
> > + * Writing to a Set-active bit Activates the corresponding interrupt.
> > + * These registers are used when preserving and restoring GIC state.
> > + */
> > +#define GICD_ISACTIVER(n)(0x0300 + 4 * ((n) >> 5))
> > +#define GICD_I_PER_ISACTIVERn32
> > +/*
> > + * Interrupt Clear-Active Registers, GICD_ICACTIVERn
> > + * Provide a Clear-active bit for each interrupt that the GIC supports.
> > + * Writing to a Clear-active bit Deactivates the corresponding interrupt.
> > + * These registers are used when preserving and restoring GIC state.
> > + */
> > +#define GICD_ICACTIVER(n)(0x0380 + 4 * ((n) >> 5))
> > +#define GICD_I_PER_ICACTIVERn32
> > +#define GICD_DEF_ICACTIVERn0xffffffff
> > +
> > +/*
> > + * Interrupt ID mask for GICD_ISENABLER, GICD_ICENABLER,
> GICD_ISPENDR,
> > + * GICD_ICPENDR, GICD_ISACTIVER and GICD_ICACTIVER
> > + */
> > +#define GICD_I_MASK(n)(1ul << ((n) & 0x1f))
> > +
> > +/*
> > + * Interrupt Priority Registers, GICD_IPRIORITYRn
> > + * Provide an 8-bit priority field for each interrupt supported by the
> > + * GIC.
> > + *
> > + * These registers are byte-accessible, so we define this macro
> > + * for byte-access.
> > + */
> > +#define GICD_IPRIORITYR(n)(0x0400 + (n))
> > +#define GICD_I_PER_IPRIORITYn4
> > +#define GICD_IPRIORITY_DEF0x80808080
> > +
> > +/*
> > + * Interrupt Processor Targets Registers, GICD_ITARGETSRn
> > + * Provide an 8-bit CPU targets field for each interrupt supported by
> > + * the GIC.
> > + *
> > + * These registers are byte-accessible, so we define this macro
> > + * for byte-access.
> > + */
> > +#define GICD_ITARGETSR(n)(0x0800 + (n))
> > +#define GICD_I_PER_ITARGETSRn4
> > +#define GICD_ITARGETSR_DEF0xffffffff
> > +
> > +/*
> > + * Interrupt Configuration Registers, GICD_ICFGRn
> > + * The GICD_ICFGRs provide a 2-bit Int_config field for each interrupt
> > + * supported by the GIC. This field identifies whether the corresponding
> > + * interrupt is edge-triggered or level-sensitive.
> > + */
> > +#define GICD_ICFGR(n)(0x0C00 + 4 * ((n) >> 4))
> > +#define GICD_I_PER_ICFGRn16
> > +#define GICD_ICFGR_DEF_TYPE0
> > +#define GICD_ICFGR_MASK0x3
> > +/* First bit is a polarity bit (0 - low, 1 - high) */
> > +#define GICD_ICFGR_POL_LOW(0 << 0)
> > +#define GICD_ICFGR_POL_HIGH(1 << 0)
> > +#define GICD_ICFGR_POL_MASK0x1
> > +/* Second bit is a trigger bit (0 - level, 1 - edge) */
> > +#define GICD_ICFGR_TRIG_LVL(0 << 1)
> > +#define GICD_ICFGR_TRIG_EDGE(1 << 1)
> > +#define GICD_ICFGR_TRIG_MASK0x2
> > +
> > +/*
> > + * Software Generated Interrupt Register, GICD_SGIR
> > + */
> > +#define GICD_SGIR0x0F00
> > +#define GICD_SGI_TARGET_SHIFT16
> > +#define GICD_SGI_TARGET_MASK0xff
> > +#define GICD_SGI_FILTER_SHIFT24
> > +#define GICD_SGI_FILTER_MASK0x3
> > +#define GICD_SGI_MAX_INITID15
> > +#define GICD_PPI_START
> > +
> > +enum sgi_filter {
> > +/*
> > + * Forward the interrupt to the CPU interfaces specified in the
> > + * CPUTargetList field
> > + */
> > +GICD_SGI_FILTER_TO_LIST = 0,
> > +/*
> > + * Forward the interrupt to all CPU interfaces except that of the
> > + * processor that requested the interrupt.
> > + */
> > +GICD_SGI_FILTER_TO_OTHERS,
> > +/*
> > + * Forward the interrupt only to the CPU interface of the processor
> > + * that requested the interrupt.
> > + */
> > +GICD_SGI_FILTER_TO_SELF
> > +};
> > +
> > +/*
> > + * SGI Clear-Pending Registers, GICD_CPENDSGIRn
> > + * Provide a clear-pending bit for each supported SGI and source
> > + * processor combination. When a processor writes a 1 to a clear-pending
> > + * bit, the pending state of the corresponding SGI for the corresponding
> > + * source processor is removed, and no longer targets the processor
> > + * performing the write. Writing a 0 has no effect. Reading a bit 
> > identifies
> > + * whether the SGI is pending, from the corresponding source processor,
> on
> > + * the reading processor.
> > + */
> > +#define GICD_CPENDSGIRn(0x0F10 + 4 * ((n) >> 2))
> > +#define GICD_I_PER_CPENDSGIRn   4
> > +
> > +/*
> > + * SGI Set-Pending Registers, GICD_SPENDSGIRn
> > + * Provide a set-pending bit for each supported SGI and source processor
> > + * combination. When a processor writes a 1 to a set-pending bit, the
> pending
> > + * state is applied to the corresponding SGI for the corresponding source
> > + * processor. Writing a 0 has no effect. Reading a bit identifies whether
> > + * the SGI is pending, from the corresponding source processor, on the
> > + * reading processor.
> > + */
> > +#define GICD_SPENDSGIRn(0x0F20 + 4 * ((n) >> 2))
> > +#define GICD_I_PER_SPENDSGIRn   4
> > +
> > +
> > +/*
> > + * CPU interface registers. Unikraft only support run on non-secure
> > + * so we just describe non-secure registers.
> > + */
> > +
> > +/* CPU Interface Control Register */
> > +#define GICC_CTLR0x0000
> > +#define GICC_CTLR_ENABLE0x1
> > +
> > +/* Interrupt Priority Mask Register */
> > +#define GICC_PMR0x0004
> > +#define GICC_PMR_PRIO_MAX255
> > +
> > +/* Binary Point Register */
> > +#define GICC_BPR0x0008
> > +
> > +/* Interrupt Acknowledge Register */
> > +#define GICC_IAR0x000C
> > +#define GICC_IAR_INTID_MASK0x3FF
> > +#define GICC_IAR_INTID_SPURIOUS1023
> > +
> > +/* End of Interrupt Register */
> > +#define GICC_EOIR0x0010
> > +
> > +/* Running Priority Register */
> > +#define GICC_RPR0x0014
> > +
> > +/* Highest Priority Pending Interrupt Register */
> > +#define GICC_HPPIR0x0018
> > +
> > +/* Aliased Binary Point Register */
> > +#define GICC_ABPR0x001C
> > +
> > +/* CPU Interface Identification Register */
> > +#define GICC_IIDR0x00FC
> > +
> > +/* Deactivate Interrupt Register */
> > +#define GICC_DIR0x1000
> > +
> > +/*
> > + * Acknowledging irq equals reading GICC_IAR also
> > + * get the interrupt ID as the side effect.
> > + */
> > +uint32_t gic_ack_irq(void);
> > +
> > +/*
> > + * write to GICC_EOIR to inform cpu interface completation
> > + * of interrupt processing. If GICC_CTLR.EOImode sets to 1
> > + * this func just gets priority drop.
> > + */
> > +void gic_eoi_irq(uint32_t irq);
> > +
> > +/*
> > + * Forward the SIG to the CPU interfaces specified in the
> > + * targetlist. Targetlist is a 8-bit bitmap for 0~7 CPU.
> > + */
> > +void gic_sgi_gen_to_list(uint32_t sgintid, uint8_t targetlist);
> > +
> > +/*
> > + * Forward the SGI to all CPU interfaces except that of the
> > + * processor that requested the interrupt.
> > + */
> > +void gic_sgi_gen_to_others(uint32_t sgintid);
> > +
> > +/*
> > + * Forward the SGI only to the CPU interface of the processor
> > + * that requested the interrupt.
> > + */
> > +void gic_sgi_gen_to_self(uint32_t sgintid);
> > +
> > +/*
> > + * set target cpu for irq in distributor,
> > + * @target: bitmask value, bit 1 indicates target to
> > + * corresponding cpu interface
> > + */
> > +void gic_set_irq_target(uint32_t irq, uint8_t target);
> > +
> > +/* set priority for irq in distributor */
> > +void gic_set_irq_prio(uint32_t irq, uint8_t priority);
> > +
> > +/*
> > + * Enable an irq in distributor, each irq occupies one bit
> > + * to configure in corresponding registor
> > + */
> > +void gic_enable_irq(uint32_t irq);
> > +
> > +/*
> > + * Disable an irq in distributor, one bit reserved for an irq
> > + * to configure in corresponding register
> > + */
> > +void gic_disable_irq(uint32_t irq);
> > +
> > +/*
> > + * set pending state for an irq in distributor, one bit
> > + * reserved for an irq to configure in corresponding register
> > + */
> > +void gic_set_irq_pending(uint32_t irq);
> > +
> > +/*
> > + * clear pending state for an irq in distributor, one bit
> > + * reserved for an irq to configure in corresponding register
> > + */
> > +void gic_clear_irq_pending(uint32_t irq);
> > +
> > +/*
> > + * inspect that if an irq is in pending state, every bit
> > + * holds the value for the corresponding irq
> > + */
> > +int gic_is_irq_pending(uint32_t irq);
> > +
> > +/* set active state for an irq in distributor */
> > +void gic_set_irq_active(uint32_t irq);
> > +
> > +/* clear active state for an irq in distributor */
> > +void gic_clear_irq_active(uint32_t irq);
> > +
> > +/*
> > + * inspect that if an irq is in active state,
> > + * every bit holds the value for an irq
> > + */
> > +int gic_is_irq_active(uint32_t irq);
> > +
> > +/* Config interrupt trigger type */
> > +void gic_set_irq_type(uint32_t irq, int trigger);
> > +
> > +/* Initialize GICv2 from device tree */
> > +int _dtb_init_gic(const void *fdt);
> > +
> > +#endif //__PLAT_CMN_ARM_GICV2_H__
> > diff --git a/plat/kvm/Makefile.uk b/plat/kvm/Makefile.uk
> > index 18eaca4..9ece678 100644
> > --- a/plat/kvm/Makefile.uk
> > +++ b/plat/kvm/Makefile.uk
> > @@ -18,6 +18,7 @@ LIBKVMPLAT_ASINCLUDES-y        += -
> I$(LIBKVMPLAT_BASE)/include
> >   LIBKVMPLAT_ASINCLUDES-y        += -
> I$(UK_PLAT_COMMON_BASE)/include
> >   LIBKVMPLAT_CINCLUDES-y         += -I$(LIBKVMPLAT_BASE)/include
> >   LIBKVMPLAT_CINCLUDES-y         += -
> I$(UK_PLAT_COMMON_BASE)/include
> > +LIBKVMPLAT_CINCLUDES-$(CONFIG_ARCH_ARM_64)         += -
> I$(UK_PLAT_DRIVERS_BASE)/include
> >
> >   LIBKVMPLAT_ASFLAGS             += -DKVMPLAT
> >   LIBKVMPLAT_CFLAGS              += -DKVMPLAT
> > @@ -66,6 +67,7 @@ LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
> $(UK_PLAT_COMMON_BASE)/arm/psci_arm64.S
> >   LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
> $(UK_PLAT_COMMON_BASE)/arm/time.c|common
> >   LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
> $(UK_PLAT_COMMON_BASE)/arm/traps.c|common
> >   LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
> $(UK_PLAT_DRIVERS_BASE)/ofw/fdt.c|common
> > +LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
> $(UK_PLAT_DRIVERS_BASE)/gic/gic-v2.c|common
> >   LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
> $(LIBKVMPLAT_BASE)/arm/entry64.S
> >   LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
> $(LIBKVMPLAT_BASE)/arm/exceptions.S
> >   LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
> $(LIBKVMPLAT_BASE)/arm/pagetable64.S
> >
IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do not disclose the contents to any 
other person, use it for any purpose, or store or copy the information in any 
medium. Thank you.
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

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