]> rtime.felk.cvut.cz Git - jailhouse.git/blob - hypervisor/arch/arm/gic-v2.c
Merge remote-tracking branch 'kiszka/master'
[jailhouse.git] / hypervisor / arch / arm / gic-v2.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 <asm/gic_common.h>
16 #include <asm/irqchip.h>
17 #include <asm/platform.h>
18 #include <asm/setup.h>
19
20 static unsigned int gic_num_lr;
21
22 extern void *gicd_base;
23 extern unsigned int gicd_size;
24 void *gicc_base;
25 unsigned int gicc_size;
26 void *gicv_base;
27 void *gich_base;
28 unsigned int gich_size;
29
30 static int gic_init(void)
31 {
32         int err;
33
34         /* FIXME: parse device tree */
35         gicc_base = GICC_BASE;
36         gicc_size = GICC_SIZE;
37         gich_base = GICH_BASE;
38         gich_size = GICH_SIZE;
39         gicv_base = GICV_BASE;
40
41         err = arch_map_device(gicc_base, gicc_base, gicc_size);
42         if (err)
43                 return err;
44
45         err = arch_map_device(gich_base, gich_base, gich_size);
46
47         return err;
48 }
49
50 static void gic_clear_pending_irqs(void)
51 {
52         unsigned int n;
53
54         /* Clear list registers. */
55         for (n = 0; n < gic_num_lr; n++)
56                 gic_write_lr(n, 0);
57
58         /* Clear active priority bits. */
59         mmio_write32(gich_base + GICH_APR, 0);
60 }
61
62 static int gic_cpu_reset(struct per_cpu *cpu_data, bool is_shutdown)
63 {
64         unsigned int i;
65         bool root_shutdown = is_shutdown && (cpu_data->cell == &root_cell);
66         u32 active;
67         u32 gich_vmcr = 0;
68         u32 gicc_ctlr, gicc_pmr;
69
70         gic_clear_pending_irqs();
71
72         /* Deactivate all PPIs */
73         active = mmio_read32(gicd_base + GICD_ISACTIVER);
74         for (i = 16; i < 32; i++) {
75                 if (test_bit(i, (unsigned long *)&active))
76                         mmio_write32(gicc_base + GICC_DIR, i);
77         }
78
79         /* Ensure all IPIs and the maintenance PPI are enabled */
80         mmio_write32(gicd_base + GICD_ISENABLER,
81                      0x0000ffff | (1 << MAINTENANCE_IRQ));
82
83         /*
84          * Disable PPIs, except for the maintenance interrupt.
85          * On shutdown, the root cell expects to find all its PPIs still
86          * enabled - except for the maintenance interrupt we used.
87          */
88         mmio_write32(gicd_base + GICD_ICENABLER,
89                      root_shutdown ? 1 << MAINTENANCE_IRQ :
90                                      0xffff0000 & ~(1 << MAINTENANCE_IRQ));
91
92         if (is_shutdown)
93                 mmio_write32(gich_base + GICH_HCR, 0);
94
95         if (root_shutdown) {
96                 gich_vmcr = mmio_read32(gich_base + GICH_VMCR);
97                 gicc_ctlr = 0;
98                 gicc_pmr = (gich_vmcr >> GICH_VMCR_PMR_SHIFT) << GICV_PMR_SHIFT;
99
100                 if (gich_vmcr & GICH_VMCR_EN0)
101                         gicc_ctlr |= GICC_CTLR_GRPEN1;
102                 if (gich_vmcr & GICH_VMCR_EOImode)
103                         gicc_ctlr |= GICC_CTLR_EOImode;
104
105                 mmio_write32(gicc_base + GICC_CTLR, gicc_ctlr);
106                 mmio_write32(gicc_base + GICC_PMR, gicc_pmr);
107
108                 gich_vmcr = 0;
109         }
110         mmio_write32(gich_base + GICH_VMCR, gich_vmcr);
111
112         return 0;
113 }
114
115 static int gic_cpu_init(struct per_cpu *cpu_data)
116 {
117         u32 vtr, vmcr;
118         u32 cell_gicc_ctlr, cell_gicc_pmr;
119
120         /* Ensure all IPIs and the maintenance PPI are enabled. */
121         mmio_write32(gicd_base + GICD_ISENABLER,
122                      0x0000ffff | (1 << MAINTENANCE_IRQ));
123
124         cell_gicc_ctlr = mmio_read32(gicc_base + GICC_CTLR);
125         cell_gicc_pmr = mmio_read32(gicc_base + GICC_PMR);
126
127         mmio_write32(gicc_base + GICC_CTLR,
128                      GICC_CTLR_GRPEN1 | GICC_CTLR_EOImode);
129         mmio_write32(gicc_base + GICC_PMR, GICC_PMR_DEFAULT);
130
131         vtr = mmio_read32(gich_base + GICH_VTR);
132         gic_num_lr = (vtr & 0x3f) + 1;
133
134         /* VMCR only contains 5 bits of priority */
135         vmcr = (cell_gicc_pmr >> GICV_PMR_SHIFT) << GICH_VMCR_PMR_SHIFT;
136         /*
137          * All virtual interrupts are group 0 in this driver since the GICV
138          * layout seen by the guest corresponds to GICC without security
139          * extensions:
140          * - A read from GICV_IAR doesn't acknowledge group 1 interrupts
141          *   (GICV_AIAR does it, but the guest never attempts to accesses it)
142          * - A write to GICV_CTLR.GRP0EN corresponds to the GICC_CTLR.GRP1EN bit
143          *   Since the guest's driver thinks that it is accessing a GIC with
144          *   security extensions, a write to GPR1EN will enable group 0
145          *   interrups.
146          * - Group 0 interrupts are presented as virtual IRQs (FIQEn = 0)
147          */
148         if (cell_gicc_ctlr & GICC_CTLR_GRPEN1)
149                 vmcr |= GICH_VMCR_EN0;
150         if (cell_gicc_ctlr & GICC_CTLR_EOImode)
151                 vmcr |= GICH_VMCR_EOImode;
152
153         mmio_write32(gich_base + GICH_VMCR, vmcr);
154         mmio_write32(gich_base + GICH_HCR, GICH_HCR_EN);
155
156         /*
157          * Clear pending virtual IRQs in case anything is left from previous
158          * use. Physically pending IRQs will be forwarded to Linux once we
159          * enable interrupts for the hypervisor.
160          */
161         gic_clear_pending_irqs();
162
163         /* Register ourselves into the CPU itf map */
164         gic_probe_cpu_id(cpu_data->cpu_id);
165
166         return 0;
167 }
168
169 static void gic_eoi_irq(u32 irq_id, bool deactivate)
170 {
171         /*
172          * The GIC doesn't seem to care about the CPUID value written to EOIR,
173          * which is rather convenient...
174          */
175         mmio_write32(gicc_base + GICC_EOIR, irq_id);
176         if (deactivate)
177                 mmio_write32(gicc_base + GICC_DIR, irq_id);
178 }
179
180 static int gic_cell_init(struct cell *cell)
181 {
182         int err;
183
184         /*
185          * Let the guest access the virtual CPU interface instead of the
186          * physical one.
187          *
188          * WARN: some SoCs (EXYNOS4) use a modified GIC which doesn't have any
189          * banked CPU interface, so we should map per-CPU physical addresses
190          * here.
191          * As for now, none of them seem to have virtualization extensions.
192          */
193         err = paging_create(&cell->arch.mm, (unsigned long)gicv_base,
194                             gicc_size, (unsigned long)gicc_base,
195                             (PTE_FLAG_VALID | PTE_ACCESS_FLAG |
196                              S2_PTE_ACCESS_RW | S2_PTE_FLAG_DEVICE),
197                             PAGING_NON_COHERENT);
198         if (err)
199                 return err;
200
201         mmio_region_register(cell, (unsigned long)gicd_base, gicd_size,
202                              gic_handle_dist_access, NULL);
203         return 0;
204 }
205
206 static void gic_cell_exit(struct cell *cell)
207 {
208         paging_destroy(&cell->arch.mm, (unsigned long)gicc_base, gicc_size,
209                        PAGING_NON_COHERENT);
210 }
211
212 static void gic_adjust_irq_target(struct cell *cell, u16 irq_id)
213 {
214         void *itargetsr = gicd_base + GICD_ITARGETSR + (irq_id & ~0x3);
215         u32 targets = mmio_read32(itargetsr);
216         unsigned int shift = irq_id % 4;
217
218         if (gic_targets_in_cell(cell, (u8)(targets >> shift)))
219                 return;
220
221         targets &= ~(0xff << shift);
222         targets |= target_cpu_map[first_cpu(cell->cpu_set)] << shift;
223
224         mmio_write32(itargetsr, targets);
225 }
226
227 static int gic_send_sgi(struct sgi *sgi)
228 {
229         u32 val;
230
231         if (!is_sgi(sgi->id))
232                 return -EINVAL;
233
234         val = (sgi->routing_mode & 0x3) << 24
235                 | (sgi->targets & 0xff) << 16
236                 | (sgi->id & 0xf);
237
238         mmio_write32(gicd_base + GICD_SGIR, val);
239
240         return 0;
241 }
242
243 static int gic_inject_irq(struct per_cpu *cpu_data, u16 irq_id)
244 {
245         int i;
246         int first_free = -1;
247         u32 lr;
248         unsigned long elsr[2];
249
250         elsr[0] = mmio_read32(gich_base + GICH_ELSR0);
251         elsr[1] = mmio_read32(gich_base + GICH_ELSR1);
252         for (i = 0; i < gic_num_lr; i++) {
253                 if (test_bit(i, elsr)) {
254                         /* Entry is available */
255                         if (first_free == -1)
256                                 first_free = i;
257                         continue;
258                 }
259
260                 /* Check that there is no overlapping */
261                 lr = gic_read_lr(i);
262                 if ((lr & GICH_LR_VIRT_ID_MASK) == irq_id)
263                         return -EEXIST;
264         }
265
266         if (first_free == -1)
267                 return -EBUSY;
268
269         /* Inject group 0 interrupt (seen as IRQ by the guest) */
270         lr = irq_id;
271         lr |= GICH_LR_PENDING_BIT;
272
273         if (!is_sgi(irq_id)) {
274                 lr |= GICH_LR_HW_BIT;
275                 lr |= (u32)irq_id << GICH_LR_PHYS_ID_SHIFT;
276         }
277
278         gic_write_lr(first_free, lr);
279
280         return 0;
281 }
282
283 static void gic_enable_maint_irq(bool enable)
284 {
285         u32 hcr;
286
287         hcr = mmio_read32(gich_base + GICH_HCR);
288         if (enable)
289                 hcr |= GICH_HCR_UIE;
290         else
291                 hcr &= ~GICH_HCR_UIE;
292         mmio_write32(gich_base + GICH_HCR, hcr);
293 }
294
295 enum mmio_result gic_handle_irq_route(struct mmio_access *mmio,
296                                       unsigned int irq)
297 {
298         /* doesn't exist in v2 - ignore access */
299         return MMIO_HANDLED;
300 }
301
302 unsigned int irqchip_mmio_count_regions(struct cell *cell)
303 {
304         return 1;
305 }
306
307 struct irqchip_ops irqchip = {
308         .init = gic_init,
309         .cpu_init = gic_cpu_init,
310         .cpu_reset = gic_cpu_reset,
311         .cell_init = gic_cell_init,
312         .cell_exit = gic_cell_exit,
313         .adjust_irq_target = gic_adjust_irq_target,
314
315         .send_sgi = gic_send_sgi,
316         .handle_irq = gic_handle_irq,
317         .inject_irq = gic_inject_irq,
318         .enable_maint_irq = gic_enable_maint_irq,
319         .eoi_irq = gic_eoi_irq,
320 };