]> rtime.felk.cvut.cz Git - jailhouse.git/blob - hypervisor/arch/arm/include/asm/irqchip.h
arm: irqchip: add hypervisor shutdown
[jailhouse.git] / hypervisor / arch / arm / include / asm / irqchip.h
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 #ifndef _JAILHOUSE_ASM_IRQCHIP_H
14 #define _JAILHOUSE_ASM_IRQCHIP_H
15
16 /*
17  * Since there is no finer-grained allocation than page-alloc for the moment,
18  * and it is very complicated to predict the total size needed at
19  * initialisation, each cpu is allocated one page of pending irqs.
20  * This allows for 256 pending IRQs, which should be sufficient.
21  */
22 #define MAX_PENDING_IRQS        (PAGE_SIZE / sizeof(struct pending_irq))
23
24 #include <jailhouse/mmio.h>
25 #include <asm/percpu.h>
26 #include <asm/traps.h>
27
28 #ifndef __ASSEMBLY__
29
30 struct sgi {
31         /*
32          * Routing mode values:
33          * 0: use aff3.aff2.aff1.targets
34          * 1: all processors in the cell except this CPU
35          * 2: only this CPU
36          */
37         u8      routing_mode;
38         /* GICv2 only uses 8bit in targets, and no affinity routing */
39         u8      aff1;
40         u8      aff2;
41         /* Only available on 64-bit, when CTLR.A3V is 1 */
42         u8      aff3;
43         u16     targets;
44         u16     id;
45 };
46
47 struct irqchip_ops {
48         int     (*init)(void);
49         int     (*cpu_init)(struct per_cpu *cpu_data);
50         void    (*cell_init)(struct cell *cell);
51         void    (*cell_exit)(struct cell *cell);
52         int     (*cpu_reset)(struct per_cpu *cpu_data, bool is_shutdown);
53
54         int     (*send_sgi)(struct sgi *sgi);
55         void    (*handle_irq)(struct per_cpu *cpu_data);
56         void    (*eoi_irq)(u32 irqn, bool deactivate);
57         int     (*inject_irq)(struct per_cpu *cpu_data,
58                               struct pending_irq *irq);
59
60         int     (*mmio_access)(struct per_cpu *cpu_data,
61                                struct mmio_access *access);
62 };
63
64 /* Virtual interrupts waiting to be injected */
65 struct pending_irq {
66         u32     virt_id;
67
68         u8      priority;
69         u8      hw;
70         union {
71                 /* Physical id, when hw is 1 */
72                 u16 irq;
73                 struct {
74                         /* GICv2 needs cpuid for SGIs */
75                         u16 cpuid       : 15;
76                         /* EOI generates a maintenance irq */
77                         u16 maintenance : 1;
78                 } sgi __attribute__((packed));
79         } type;
80
81         struct pending_irq *next;
82         struct pending_irq *prev;
83 } __attribute__((packed));
84
85 int irqchip_init(void);
86 int irqchip_cpu_init(struct per_cpu *cpu_data);
87 int irqchip_cpu_reset(struct per_cpu *cpu_data);
88 void irqchip_cpu_shutdown(struct per_cpu *cpu_data);
89
90 void irqchip_cell_init(struct cell *cell);
91 void irqchip_cell_exit(struct cell *cell);
92 void irqchip_root_cell_shrink(struct cell *cell);
93
94 int irqchip_send_sgi(struct sgi *sgi);
95 void irqchip_handle_irq(struct per_cpu *cpu_data);
96 void irqchip_eoi_irq(u32 irqn, bool deactivate);
97
98 int irqchip_mmio_access(struct per_cpu *cpu_data, struct mmio_access *access);
99
100 int irqchip_inject_pending(struct per_cpu *cpu_data);
101 int irqchip_insert_pending(struct per_cpu *cpu_data, struct pending_irq *irq);
102 int irqchip_remove_pending(struct per_cpu *cpu_data, struct pending_irq *irq);
103 int irqchip_set_pending(struct per_cpu *cpu_data, u32 irq_id, bool try_inject);
104
105 static inline bool spi_in_cell(struct cell *cell, unsigned int spi)
106 {
107         /* FIXME: Change the configuration to a bitmask range */
108         u64 spi_mask;
109
110         if (spi > 64)
111                 return false;
112
113         spi_mask = cell->arch.spis;
114
115         return spi_mask & (1 << spi);
116 }
117
118 #endif /* __ASSEMBLY__ */
119 #endif /* _JAILHOUSE_ASM_IRQCHIP_H */