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