]> rtime.felk.cvut.cz Git - jailhouse.git/blob - hypervisor/arch/arm/gic-v3.c
arm: GIC: reset the CPU interface before running a new guest
[jailhouse.git] / hypervisor / arch / arm / gic-v3.c
1 /*
2  * Jailhouse, a Linux-based partitioning hypervisor
3  *
4  * Copyright (c) ARM Limited, 2014
5  *
6  * Authors:
7  *  Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  */
12
13 #include <jailhouse/control.h>
14 #include <jailhouse/mmio.h>
15 #include <jailhouse/printk.h>
16 #include <jailhouse/processor.h>
17 #include <jailhouse/types.h>
18 #include <asm/control.h>
19 #include <asm/gic_common.h>
20 #include <asm/irqchip.h>
21 #include <asm/platform.h>
22 #include <asm/setup.h>
23 #include <asm/traps.h>
24
25 /*
26  * This implementation assumes that the kernel driver already initialised most
27  * of the GIC.
28  * There is almost no instruction barrier, since IRQs are always disabled in the
29  * hyp, and ERET serves as the context synchronization event.
30  */
31
32 static unsigned int gic_num_lr;
33 static unsigned int gic_num_priority_bits;
34
35 static void *gicr_base;
36 static unsigned int gicr_size;
37
38 static int gic_init(void)
39 {
40         int err;
41
42         /* FIXME: parse a dt */
43         gicr_base = GICR_BASE;
44         gicr_size = GICR_SIZE;
45
46         /* Let the per-cpu code access the redistributors */
47         err = arch_map_device(gicr_base, gicr_base, gicr_size);
48
49         return err;
50 }
51
52 static int gic_cpu_reset(struct per_cpu *cpu_data)
53 {
54         unsigned int i;
55         void *gicr = cpu_data->gicr_base;
56         unsigned long active;
57
58         if (gicr == 0)
59                 return -ENODEV;
60
61         /* Clear list registers */
62         for (i = 0; i < gic_num_lr; i++)
63                 gic_write_lr(i, 0);
64
65         gicr += GICR_SGI_BASE;
66         active = mmio_read32(gicr + GICR_ICACTIVER);
67         /* Deactivate all active PPIs */
68         for (i = 16; i < 32; i++) {
69                 if (test_bit(i, &active))
70                         arm_write_sysreg(ICC_DIR_EL1, i);
71         }
72
73         /* Disable all PPIs, ensure IPIs are enabled */
74         mmio_write32(gicr + GICR_ICENABLER, 0xffff0000);
75         mmio_write32(gicr + GICR_ISENABLER, 0x0000ffff);
76
77         /* Clear active priority bits */
78         if (gic_num_priority_bits >= 5)
79                 arm_write_sysreg(ICH_AP1R0_EL2, 0);
80         if (gic_num_priority_bits >= 6)
81                 arm_write_sysreg(ICH_AP1R1_EL2, 0);
82         if (gic_num_priority_bits > 6) {
83                 arm_write_sysreg(ICH_AP1R2_EL2, 0);
84                 arm_write_sysreg(ICH_AP1R3_EL2, 0);
85         }
86
87         arm_write_sysreg(ICH_VMCR_EL2, 0);
88         arm_write_sysreg(ICH_HCR_EL2, ICH_HCR_EN);
89
90         return 0;
91 }
92
93 static int gic_cpu_init(struct per_cpu *cpu_data)
94 {
95         u64 typer;
96         u32 pidr;
97         u32 gic_version;
98         u32 cell_icc_ctlr, cell_icc_pmr, cell_icc_igrpen1;
99         u32 ich_vtr;
100         u32 ich_vmcr;
101         void *redist_base = gicr_base;
102
103         /* Find redistributor */
104         do {
105                 pidr = mmio_read32(redist_base + GICR_PIDR2);
106                 gic_version = GICR_PIDR2_ARCH(pidr);
107                 if (gic_version != 3 && gic_version != 4)
108                         break;
109
110                 typer = mmio_read64(redist_base + GICR_TYPER);
111                 if ((typer >> 32) == cpu_data->cpu_id) {
112                         cpu_data->gicr_base = redist_base;
113                         break;
114                 }
115
116                 redist_base += 0x20000;
117                 if (gic_version == 4)
118                         redist_base += 0x20000;
119         } while (!(typer & GICR_TYPER_Last));
120
121         if (cpu_data->gicr_base == 0) {
122                 printk("GIC: No redist found for CPU%d\n", cpu_data->cpu_id);
123                 return -ENODEV;
124         }
125
126         /* Ensure all IPIs are enabled */
127         mmio_write32(redist_base + GICR_SGI_BASE + GICR_ISENABLER, 0x0000ffff);
128
129         /*
130          * Set EOIMode to 1
131          * This allow to drop the priority of level-triggered interrupts without
132          * deactivating them, and thus ensure that they won't be immediately
133          * re-triggered. (e.g. timer)
134          * They can then be injected into the guest using the LR.HW bit, and
135          * will be deactivated once the guest does an EOI after handling the
136          * interrupt source.
137          */
138         arm_read_sysreg(ICC_CTLR_EL1, cell_icc_ctlr);
139         arm_write_sysreg(ICC_CTLR_EL1, ICC_CTLR_EOImode);
140
141         arm_read_sysreg(ICC_PMR_EL1, cell_icc_pmr);
142         arm_write_sysreg(ICC_PMR_EL1, ICC_PMR_DEFAULT);
143
144         arm_read_sysreg(ICC_IGRPEN1_EL1, cell_icc_igrpen1);
145         arm_write_sysreg(ICC_IGRPEN1_EL1, ICC_IGRPEN1_EN);
146
147         arm_read_sysreg(ICH_VTR_EL2, ich_vtr);
148         gic_num_lr = (ich_vtr & 0xf) + 1;
149         gic_num_priority_bits = (ich_vtr >> 29) + 1;
150
151         ich_vmcr = (cell_icc_pmr & ICC_PMR_MASK) << ICH_VMCR_VPMR_SHIFT;
152         if (cell_icc_igrpen1 & ICC_IGRPEN1_EN)
153                 ich_vmcr |= ICH_VMCR_VENG1;
154         if (cell_icc_ctlr & ICC_CTLR_EOImode)
155                 ich_vmcr |= ICH_VMCR_VEOIM;
156         arm_write_sysreg(ICH_VMCR_EL2, ich_vmcr);
157
158         /* After this, the cells access the virtual interface of the GIC. */
159         arm_write_sysreg(ICH_HCR_EL2, ICH_HCR_EN);
160
161         return 0;
162 }
163
164 static int gic_send_sgi(struct sgi *sgi)
165 {
166         u64 val;
167         u16 targets = sgi->targets;
168
169         if (!is_sgi(sgi->id))
170                 return -EINVAL;
171
172         if (sgi->routing_mode == 2)
173                 targets = 1 << phys_processor_id();
174
175         val = (u64)sgi->aff3 << ICC_SGIR_AFF3_SHIFT
176             | (u64)sgi->aff2 << ICC_SGIR_AFF2_SHIFT
177             | sgi->aff1 << ICC_SGIR_AFF1_SHIFT
178             | (targets & ICC_SGIR_TARGET_MASK)
179             | (sgi->id & 0xf) << ICC_SGIR_IRQN_SHIFT;
180
181         if (sgi->routing_mode == 1)
182                 val |= ICC_SGIR_ROUTING_BIT;
183
184         /*
185          * Ensure the targets see our modifications to their per-cpu
186          * structures.
187          */
188         dsb(ish);
189
190         arm_write_sysreg(ICC_SGI1R_EL1, val);
191         isb();
192
193         return 0;
194 }
195
196 int gicv3_handle_sgir_write(struct per_cpu *cpu_data, u64 sgir)
197 {
198         struct sgi sgi;
199         struct cell *cell = cpu_data->cell;
200         unsigned int cpu;
201         unsigned long this_cpu = cpu_data->cpu_id;
202         unsigned long routing_mode = !!(sgir & ICC_SGIR_ROUTING_BIT);
203         unsigned long targets = sgir & ICC_SGIR_TARGET_MASK;
204         u32 irq = sgir >> ICC_SGIR_IRQN_SHIFT & 0xf;
205
206         /* FIXME: clusters are not supported yet. */
207         sgi.targets = 0;
208         sgi.routing_mode = routing_mode;
209         sgi.aff1 = sgir >> ICC_SGIR_AFF1_SHIFT & 0xff;
210         sgi.aff2 = sgir >> ICC_SGIR_AFF2_SHIFT & 0xff;
211         sgi.aff3 = sgir >> ICC_SGIR_AFF3_SHIFT & 0xff;
212         sgi.id = SGI_INJECT;
213
214         for_each_cpu_except(cpu, cell->cpu_set, this_cpu) {
215                 if (routing_mode == 0 && !test_bit(cpu, &targets))
216                         continue;
217                 else if (routing_mode == 1 && cpu == this_cpu)
218                         continue;
219
220                 irqchip_set_pending(per_cpu(cpu), irq, false);
221                 sgi.targets |= (1 << cpu);
222         }
223
224         /* Let the other CPUS inject their SGIs */
225         gic_send_sgi(&sgi);
226
227         return TRAP_HANDLED;
228 }
229
230 /*
231  * Handle the maintenance interrupt, the rest is injected into the cell.
232  * Return true when the IRQ has been handled by the hyp.
233  */
234 static bool arch_handle_phys_irq(struct per_cpu *cpu_data, u32 irqn)
235 {
236         if (irqn == MAINTENANCE_IRQ) {
237                 irqchip_inject_pending(cpu_data);
238                 return true;
239         }
240
241         irqchip_set_pending(cpu_data, irqn, true);
242
243         return false;
244 }
245
246 static void gic_eoi_irq(u32 irq_id, bool deactivate)
247 {
248         arm_write_sysreg(ICC_EOIR1_EL1, irq_id);
249         if (deactivate)
250                 arm_write_sysreg(ICC_DIR_EL1, irq_id);
251 }
252
253 static void gic_handle_irq(struct per_cpu *cpu_data)
254 {
255         bool handled = false;
256         u32 irq_id;
257
258         while (1) {
259                 /* Read ICC_IAR1: set 'active' state */
260                 arm_read_sysreg(ICC_IAR1_EL1, irq_id);
261
262                 if (irq_id == 0x3ff) /* Spurious IRQ */
263                         break;
264
265                 /* Handle IRQ */
266                 if (is_sgi(irq_id)) {
267                         arch_handle_sgi(cpu_data, irq_id);
268                         handled = true;
269                 } else {
270                         handled = arch_handle_phys_irq(cpu_data, irq_id);
271                 }
272
273                 /*
274                  * Write ICC_EOIR1: drop priority, but stay active if handled is
275                  * false.
276                  * This allows to not be re-interrupted by a level-triggered
277                  * interrupt that needs handling in the guest (e.g. timer)
278                  */
279                 gic_eoi_irq(irq_id, handled);
280         }
281 }
282
283 static int gic_inject_irq(struct per_cpu *cpu_data, struct pending_irq *irq)
284 {
285         int i;
286         int free_lr = -1;
287         u32 elsr;
288         u64 lr;
289
290         arm_read_sysreg(ICH_ELSR_EL2, elsr);
291         for (i = 0; i < gic_num_lr; i++) {
292                 if ((elsr >> i) & 1) {
293                         /* Entry is invalid, candidate for injection */
294                         if (free_lr == -1)
295                                 free_lr = i;
296                         continue;
297                 }
298
299                 /*
300                  * Entry is in use, check that it doesn't match the one we want
301                  * to inject.
302                  */
303                 lr = gic_read_lr(i);
304
305                 /*
306                  * A strict phys->virt id mapping is used for SPIs, so this test
307                  * should be sufficient.
308                  */
309                 if ((u32)lr == irq->virt_id)
310                         return -EINVAL;
311         }
312
313         if (free_lr == -1) {
314                 u32 hcr;
315                 /*
316                  * All list registers are in use, trigger a maintenance
317                  * interrupt once they are available again.
318                  */
319                 arm_read_sysreg(ICH_HCR_EL2, hcr);
320                 hcr |= ICH_HCR_UIE;
321                 arm_write_sysreg(ICH_HCR_EL2, hcr);
322
323                 return -EBUSY;
324         }
325
326         lr = irq->virt_id;
327         /* Only group 1 interrupts */
328         lr |= ICH_LR_GROUP_BIT;
329         lr |= ICH_LR_PENDING;
330         if (irq->hw) {
331                 lr |= ICH_LR_HW_BIT;
332                 lr |= (u64)irq->type.irq << ICH_LR_PHYS_ID_SHIFT;
333         } else if (irq->type.sgi.maintenance) {
334                 lr |= ICH_LR_SGI_EOI;
335         }
336
337         gic_write_lr(free_lr, lr);
338
339         return 0;
340 }
341
342 struct irqchip_ops gic_irqchip = {
343         .init = gic_init,
344         .cpu_init = gic_cpu_init,
345         .cpu_reset = gic_cpu_reset,
346         .send_sgi = gic_send_sgi,
347         .handle_irq = gic_handle_irq,
348         .inject_irq = gic_inject_irq,
349         .eoi_irq = gic_eoi_irq,
350 };