1 /*
2  * Copyright (C) 2015, 2016 ARM Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16 #ifndef __ASM_ARM_NEW_VGIC_H
17 #define __ASM_ARM_NEW_VGIC_H
18 
19 #include <asm/atomic.h>
20 #include <asm/mmio.h>
21 #include <xen/list.h>
22 #include <xen/mm.h>
23 #include <xen/spinlock.h>
24 
25 #define VGIC_V3_MAX_CPUS        255
26 #define VGIC_V2_MAX_CPUS        8
27 #define VGIC_NR_SGIS            16
28 #define VGIC_NR_PPIS            16
29 #define VGIC_NR_PRIVATE_IRQS    (VGIC_NR_SGIS + VGIC_NR_PPIS)
30 #define VGIC_MAX_PRIVATE        (VGIC_NR_PRIVATE_IRQS - 1)
31 #define VGIC_MAX_SPI            1019
32 #define VGIC_MAX_RESERVED       1023
33 #define VGIC_MIN_LPI            8192
34 
35 #define irq_is_ppi(irq) ((irq) >= VGIC_NR_SGIS && (irq) < VGIC_NR_PRIVATE_IRQS)
36 #define irq_is_spi(irq) ((irq) >= VGIC_NR_PRIVATE_IRQS && \
37                          (irq) <= VGIC_MAX_SPI)
38 
39 enum vgic_type {
40     VGIC_V2,        /* Good ol' GICv2 */
41     VGIC_V3,        /* New fancy GICv3 */
42 };
43 
44 #define VGIC_V2_MAX_LRS         (1 << 6)
45 #define VGIC_V3_MAX_LRS         16
46 #define VGIC_V3_LR_INDEX(lr)    (VGIC_V3_MAX_LRS - 1 - (lr))
47 
48 #define VGIC_CONFIG_EDGE        false
49 #define VGIC_CONFIG_LEVEL       true
50 
51 struct vgic_irq {
52     struct list_head ap_list;
53 
54     struct vcpu *vcpu;          /*
55                                  * SGIs and PPIs: The VCPU
56                                  * SPIs and LPIs: The VCPU whose ap_list
57                                  * this is queued on.
58                                  */
59 
60     struct vcpu *target_vcpu;   /*
61                                  * The VCPU that this interrupt should
62                                  * be sent to, as a result of the
63                                  * targets reg (v2) or the affinity reg (v3).
64                                  */
65 
66     spinlock_t irq_lock;        /* Protects the content of the struct */
67     uint32_t intid;             /* Guest visible INTID */
68     atomic_t refcount;          /* Used for LPIs */
69     uint32_t hwintid;           /* HW INTID number */
70     union
71     {
72         struct {
73             uint8_t targets;    /* GICv2 target VCPUs mask */
74             uint8_t source;     /* GICv2 SGIs only */
75         };
76         uint32_t mpidr;         /* GICv3 target VCPU */
77     };
78     uint8_t priority;
79     bool line_level:1;          /* Level only */
80     bool pending_latch:1;       /*
81                                  * The pending latch state used to
82                                  * calculate the pending state for both
83                                  * level and edge triggered IRQs.
84                                  */
85     bool active:1;              /* not used for LPIs */
86     bool enabled:1;
87     bool hw:1;                  /* Tied to HW IRQ */
88     bool config:1;              /* Level or edge */
89     struct list_head lpi_list;  /* Used to link all LPIs together */
90 };
91 
92 enum iodev_type {
93     IODEV_DIST,
94     IODEV_REDIST,
95 };
96 
97 struct vgic_io_device {
98     gfn_t base_fn;
99     struct vcpu *redist_vcpu;
100     const struct vgic_register_region *regions;
101     enum iodev_type iodev_type;
102     unsigned int nr_regions;
103 };
104 
105 struct vgic_dist {
106     bool                ready;
107     bool                initialized;
108 
109     /* vGIC model the kernel emulates for the guest (GICv2 or GICv3) */
110     uint32_t            version;
111 
112     /* Do injected MSIs require an additional device ID? */
113     bool                msis_require_devid;
114 
115     unsigned int        nr_spis;
116 
117     /* base addresses in guest physical address space: */
118     paddr_t             dbase;     /* distributor */
119     union
120     {
121         /* either a GICv2 CPU interface */
122         paddr_t         cbase;
123         /* or a number of GICv3 redistributor regions */
124         struct
125         {
126             paddr_t     vgic_redist_base;
127             paddr_t     vgic_redist_free_offset;
128         };
129     };
130     paddr_t             csize; /* CPU interface size */
131     paddr_t             vbase; /* virtual CPU interface base address */
132 
133     /* distributor enabled */
134     bool                enabled;
135 
136     struct vgic_irq     *spis;
137     unsigned long       *allocated_irqs; /* bitmap of IRQs allocated */
138 
139     struct vgic_io_device   dist_iodev;
140 
141     bool                has_its;
142 
143     /*
144      * Contains the attributes and gpa of the LPI configuration table.
145      * Since we report GICR_TYPER.CommonLPIAff as 0b00, we can share
146      * one address across all redistributors.
147      * GICv3 spec: 6.1.2 "LPI Configuration tables"
148      */
149     uint64_t            propbaser;
150 
151     /* Protects the lpi_list and the count value below. */
152     spinlock_t          lpi_list_lock;
153     struct list_head    lpi_list_head;
154     unsigned int        lpi_list_count;
155 };
156 
157 struct vgic_cpu {
158     struct vgic_irq private_irqs[VGIC_NR_PRIVATE_IRQS];
159 
160     struct list_head ap_list_head;
161     spinlock_t ap_list_lock;    /* Protects the ap_list */
162 
163     unsigned int used_lrs;
164 
165     /*
166      * List of IRQs that this VCPU should consider because they are either
167      * Active or Pending (hence the name; AP list), or because they recently
168      * were one of the two and need to be migrated off this list to another
169      * VCPU.
170      */
171 
172     /*
173      * Members below are used with GICv3 emulation only and represent
174      * parts of the redistributor.
175      */
176     struct vgic_io_device   rd_iodev;
177     struct vgic_io_device   sgi_iodev;
178 
179     /* Contains the attributes and gpa of the LPI pending tables. */
180     uint64_t pendbaser;
181 
182     bool lpis_enabled;
183 
184     /* Cache guest priority bits */
185     uint32_t num_pri_bits;
186 
187     /* Cache guest interrupt ID bits */
188     uint32_t num_id_bits;
189 };
190 
vgic_cpu_base(const struct vgic_dist * vgic)191 static inline paddr_t vgic_cpu_base(const struct vgic_dist *vgic)
192 {
193     return vgic->cbase;
194 }
195 
vgic_dist_base(const struct vgic_dist * vgic)196 static inline paddr_t vgic_dist_base(const struct vgic_dist *vgic)
197 {
198     return vgic->dbase;
199 }
200 
201 #endif /* __ASM_ARM_NEW_VGIC_H */
202 
203 /*
204  * Local variables:
205  * mode: C
206  * c-file-style: "BSD"
207  * c-basic-offset: 4
208  * indent-tabs-mode: nil
209  * End:
210  */
211