1 /*
2  * ARM GICv3 ITS support
3  *
4  * Andre Przywara <andre.przywara@arm.com>
5  * Copyright (c) 2016,2017 ARM Ltd.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; under version 2 of the License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef __ASM_ARM_ITS_H__
21 #define __ASM_ARM_ITS_H__
22 
23 #define GITS_CTLR                       0x000
24 #define GITS_IIDR                       0x004
25 #define GITS_TYPER                      0x008
26 #define GITS_CBASER                     0x080
27 #define GITS_CWRITER                    0x088
28 #define GITS_CREADR                     0x090
29 #define GITS_BASER_NR_REGS              8
30 #define GITS_BASER0                     0x100
31 #define GITS_BASER1                     0x108
32 #define GITS_BASER2                     0x110
33 #define GITS_BASER3                     0x118
34 #define GITS_BASER4                     0x120
35 #define GITS_BASER5                     0x128
36 #define GITS_BASER6                     0x130
37 #define GITS_BASER7                     0x138
38 #define GITS_PIDR2                      GICR_PIDR2
39 
40 /* Register bits */
41 #define GITS_VALID_BIT                  BIT(63)
42 
43 #define GITS_CTLR_QUIESCENT             BIT(31)
44 #define GITS_CTLR_ENABLE                BIT(0)
45 
46 #define GITS_TYPER_PTA                  BIT(19)
47 #define GITS_TYPER_DEVIDS_SHIFT         13
48 #define GITS_TYPER_DEVIDS_MASK          (0x1fUL << GITS_TYPER_DEVIDS_SHIFT)
49 #define GITS_TYPER_DEVICE_ID_BITS(r)    (((r & GITS_TYPER_DEVIDS_MASK) >> \
50                                                GITS_TYPER_DEVIDS_SHIFT) + 1)
51 
52 #define GITS_TYPER_IDBITS_SHIFT         8
53 #define GITS_TYPER_IDBITS_MASK          (0x1fUL << GITS_TYPER_IDBITS_SHIFT)
54 #define GITS_TYPER_EVENT_ID_BITS(r)     (((r & GITS_TYPER_IDBITS_MASK) >> \
55                                                GITS_TYPER_IDBITS_SHIFT) + 1)
56 
57 #define GITS_TYPER_ITT_SIZE_SHIFT       4
58 #define GITS_TYPER_ITT_SIZE_MASK        (0xfUL << GITS_TYPER_ITT_SIZE_SHIFT)
59 #define GITS_TYPER_ITT_SIZE(r)          ((((r) & GITS_TYPER_ITT_SIZE_MASK) >> \
60                                                  GITS_TYPER_ITT_SIZE_SHIFT) + 1)
61 #define GITS_TYPER_PHYSICAL             (1U << 0)
62 
63 #define GITS_BASER_INDIRECT             BIT(62)
64 #define GITS_BASER_INNER_CACHEABILITY_SHIFT        59
65 #define GITS_BASER_TYPE_SHIFT           56
66 #define GITS_BASER_TYPE_MASK            (7ULL << GITS_BASER_TYPE_SHIFT)
67 #define GITS_BASER_OUTER_CACHEABILITY_SHIFT        53
68 #define GITS_BASER_TYPE_NONE            0UL
69 #define GITS_BASER_TYPE_DEVICE          1UL
70 #define GITS_BASER_TYPE_VCPU            2UL
71 #define GITS_BASER_TYPE_CPU             3UL
72 #define GITS_BASER_TYPE_COLLECTION      4UL
73 #define GITS_BASER_TYPE_RESERVED5       5UL
74 #define GITS_BASER_TYPE_RESERVED6       6UL
75 #define GITS_BASER_TYPE_RESERVED7       7UL
76 #define GITS_BASER_ENTRY_SIZE_SHIFT     48
77 #define GITS_BASER_ENTRY_SIZE(reg)                                       \
78                         (((reg >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1)
79 #define GITS_BASER_SHAREABILITY_SHIFT   10
80 #define GITS_BASER_PAGE_SIZE_SHIFT      8
81 #define GITS_BASER_SIZE_MASK            0xff
82 #define GITS_BASER_SHAREABILITY_MASK   (0x3ULL << GITS_BASER_SHAREABILITY_SHIFT)
83 #define GITS_BASER_OUTER_CACHEABILITY_MASK   (0x7ULL << GITS_BASER_OUTER_CACHEABILITY_SHIFT)
84 #define GITS_BASER_INNER_CACHEABILITY_MASK   (0x7ULL << GITS_BASER_INNER_CACHEABILITY_SHIFT)
85 
86 #define GITS_CBASER_SIZE_MASK           0xff
87 
88 /* ITS command definitions */
89 #define ITS_CMD_SIZE                    32
90 
91 #define GITS_CMD_MOVI                   0x01
92 #define GITS_CMD_INT                    0x03
93 #define GITS_CMD_CLEAR                  0x04
94 #define GITS_CMD_SYNC                   0x05
95 #define GITS_CMD_MAPD                   0x08
96 #define GITS_CMD_MAPC                   0x09
97 #define GITS_CMD_MAPTI                  0x0a
98 #define GITS_CMD_MAPI                   0x0b
99 #define GITS_CMD_INV                    0x0c
100 #define GITS_CMD_INVALL                 0x0d
101 #define GITS_CMD_MOVALL                 0x0e
102 #define GITS_CMD_DISCARD                0x0f
103 
104 #define ITS_DOORBELL_OFFSET             0x10040
105 #define GICV3_ITS_SIZE                  SZ_128K
106 
107 #include <xen/device_tree.h>
108 #include <xen/rbtree.h>
109 
110 #define HOST_ITS_FLUSH_CMD_QUEUE        (1U << 0)
111 #define HOST_ITS_USES_PTA               (1U << 1)
112 
113 /* We allocate LPIs on the hosts in chunks of 32 to reduce handling overhead. */
114 #define LPI_BLOCK                       32U
115 
116 /* data structure for each hardware ITS */
117 struct host_its {
118     struct list_head entry;
119     const struct dt_device_node *dt_node;
120     paddr_t addr;
121     paddr_t size;
122     void __iomem *its_base;
123     unsigned int devid_bits;
124     unsigned int evid_bits;
125     unsigned int itte_size;
126     spinlock_t cmd_lock;
127     void *cmd_buf;
128     unsigned int flags;
129 };
130 
131 
132 #ifdef CONFIG_HAS_ITS
133 
134 extern struct list_head host_its_list;
135 
136 /* Parse the host DT and pick up all host ITSes. */
137 void gicv3_its_dt_init(const struct dt_device_node *node);
138 
139 #ifdef CONFIG_ACPI
140 void gicv3_its_acpi_init(void);
141 unsigned long gicv3_its_make_hwdom_madt(const struct domain *d,
142                                         void *base_ptr);
143 #endif
144 
145 /* Deny iomem access for its */
146 int gicv3_its_deny_access(const struct domain *d);
147 
148 bool gicv3_its_host_has_its(void);
149 
150 unsigned int vgic_v3_its_count(const struct domain *d);
151 
152 void gicv3_do_LPI(unsigned int lpi);
153 
154 int gicv3_lpi_init_rdist(void __iomem * rdist_base);
155 
156 /* Initialize the host structures for LPIs and the host ITSes. */
157 int gicv3_lpi_init_host_lpis(unsigned int host_lpi_bits);
158 int gicv3_its_init(void);
159 
160 /* Store the physical address and ID for each redistributor as read from DT. */
161 void gicv3_set_redist_address(paddr_t address, unsigned int redist_id);
162 uint64_t gicv3_get_redist_address(unsigned int cpu, bool use_pta);
163 
164 /* Map a collection for this host CPU to each host ITS. */
165 int gicv3_its_setup_collection(unsigned int cpu);
166 
167 /* Initialize and destroy the per-domain parts of the virtual ITS support. */
168 int vgic_v3_its_init_domain(struct domain *d);
169 void vgic_v3_its_free_domain(struct domain *d);
170 
171 /* Create the appropriate DT nodes for a hardware domain. */
172 int gicv3_its_make_hwdom_dt_nodes(const struct domain *d,
173                                   const struct dt_device_node *gic,
174                                   void *fdt);
175 
176 /*
177  * Map a device on the host by allocating an ITT on the host (ITS).
178  * "nr_event" specifies how many events (interrupts) this device will need.
179  * Setting "valid" to false deallocates the device.
180  */
181 int gicv3_its_map_guest_device(struct domain *d,
182                                paddr_t host_doorbell, uint32_t host_devid,
183                                paddr_t guest_doorbell, uint32_t guest_devid,
184                                uint64_t nr_events, bool valid);
185 
186 int gicv3_allocate_host_lpi_block(struct domain *d, uint32_t *first_lpi);
187 void gicv3_free_host_lpi_block(uint32_t first_lpi);
188 
189 void vgic_vcpu_inject_lpi(struct domain *d, unsigned int virq);
190 
191 struct pending_irq *gicv3_its_get_event_pending_irq(struct domain *d,
192                                                     paddr_t vdoorbell_address,
193                                                     uint32_t vdevid,
194                                                     uint32_t eventid);
195 int gicv3_remove_guest_event(struct domain *d, paddr_t vdoorbell_address,
196                                      uint32_t vdevid, uint32_t eventid);
197 struct pending_irq *gicv3_assign_guest_event(struct domain *d, paddr_t doorbell,
198                                              uint32_t devid, uint32_t eventid,
199                                              uint32_t virt_lpi);
200 void gicv3_lpi_update_host_entry(uint32_t host_lpi, int domain_id,
201                                  uint32_t virt_lpi);
202 
203 #else
204 
gicv3_its_dt_init(const struct dt_device_node * node)205 static inline void gicv3_its_dt_init(const struct dt_device_node *node)
206 {
207 }
208 
209 #ifdef CONFIG_ACPI
gicv3_its_acpi_init(void)210 static inline void gicv3_its_acpi_init(void)
211 {
212 }
213 
gicv3_its_make_hwdom_madt(const struct domain * d,void * base_ptr)214 static inline unsigned long gicv3_its_make_hwdom_madt(const struct domain *d,
215                                                       void *base_ptr)
216 {
217     return 0;
218 }
219 #endif
220 
gicv3_its_deny_access(const struct domain * d)221 static inline int gicv3_its_deny_access(const struct domain *d)
222 {
223     return 0;
224 }
225 
gicv3_its_host_has_its(void)226 static inline bool gicv3_its_host_has_its(void)
227 {
228     return false;
229 }
230 
vgic_v3_its_count(const struct domain * d)231 static inline unsigned int vgic_v3_its_count(const struct domain *d)
232 {
233     return 0;
234 }
235 
gicv3_do_LPI(unsigned int lpi)236 static inline void gicv3_do_LPI(unsigned int lpi)
237 {
238     /* We don't enable LPIs without an ITS. */
239     BUG();
240 }
241 
gicv3_lpi_init_rdist(void __iomem * rdist_base)242 static inline int gicv3_lpi_init_rdist(void __iomem * rdist_base)
243 {
244     return -ENODEV;
245 }
246 
gicv3_lpi_init_host_lpis(unsigned int host_lpi_bits)247 static inline int gicv3_lpi_init_host_lpis(unsigned int host_lpi_bits)
248 {
249     return 0;
250 }
251 
gicv3_its_init(void)252 static inline int gicv3_its_init(void)
253 {
254     return 0;
255 }
256 
gicv3_set_redist_address(paddr_t address,unsigned int redist_id)257 static inline void gicv3_set_redist_address(paddr_t address,
258                                             unsigned int redist_id)
259 {
260 }
261 
gicv3_its_setup_collection(unsigned int cpu)262 static inline int gicv3_its_setup_collection(unsigned int cpu)
263 {
264     /* We should never get here without an ITS. */
265     BUG();
266 }
267 
vgic_v3_its_init_domain(struct domain * d)268 static inline int vgic_v3_its_init_domain(struct domain *d)
269 {
270     return 0;
271 }
272 
vgic_v3_its_free_domain(struct domain * d)273 static inline void vgic_v3_its_free_domain(struct domain *d)
274 {
275 }
276 
gicv3_its_make_hwdom_dt_nodes(const struct domain * d,const struct dt_device_node * gic,void * fdt)277 static inline int gicv3_its_make_hwdom_dt_nodes(const struct domain *d,
278                                                 const struct dt_device_node *gic,
279                                                 void *fdt)
280 {
281     return 0;
282 }
283 
284 #endif /* CONFIG_HAS_ITS */
285 
286 #endif
287 
288 /*
289  * Local variables:
290  * mode: C
291  * c-file-style: "BSD"
292  * c-basic-offset: 4
293  * indent-tabs-mode: nil
294  * End:
295  */
296