1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2023-01-30 GuEe-GUI first version
9 */
10
11 #include <rthw.h>
12 #include <rtthread.h>
13 #include <rtdevice.h>
14
15 #define DBG_TAG "pic.gicv3-its"
16 #define DBG_LVL DBG_INFO
17 #include <rtdbg.h>
18
19 #include <mmu.h>
20 #include <mm_page.h>
21 #include <cpuport.h>
22 #include <dt-bindings/size.h>
23 #include "pic-gicv3.h"
24 #include "pic-gic-common.h"
25
26 #define ITS_CMD_QUEUE_SIZE (64 * SIZE_KB)
27 #define ITS_CMD_QUEUE_ALIGN (64 * SIZE_KB)
28 #define ITS_CMD_QUEUE_NR (ITS_CMD_QUEUE_SIZE / sizeof(struct its_command))
29
30 #define ITS_ITT_ALIGN (256 * SIZE_KB)
31
32 #define ITS_LPI_CONFIG_TABLE_ALIGN (64 * SIZE_KB)
33 #define ITS_LPI_CONFIG_PROP_DEFAULT_PRIO GICD_INT_DEF_PRI
34 #define ITS_LPI_CONFIG_PROP_SHIFT 2
35 #define ITS_LPI_CONFIG_PROP_MASK RT_GENMASK(7, ITS_LPI_CONFIG_PROP_SHIFT)
36 #define ITS_LPI_PENDING_TABLE_ALIGN (64 * SIZE_KB)
37
38 #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING RT_BIT(0)
39 #define RDIST_FLAGS_RD_TABLES_PREALLOCATED RT_BIT(1)
40 #define RDIST_FLAGS_FORCE_NON_SHAREABLE RT_BIT(2)
41
42 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING RT_BIT(0)
43 #define ITS_FLAGS_WORKAROUND_CAVIUM_22375 RT_BIT(1)
44 #define ITS_FLAGS_FORCE_NON_SHAREABLE RT_BIT(2)
45
46 #define RD_LOCAL_LPI_ENABLED RT_BIT(0)
47 #define RD_LOCAL_PENDTABLE_PREALLOCATED RT_BIT(1)
48 #define RD_LOCAL_MEMRESERVE_DONE RT_BIT(2)
49
50 struct its_command
51 {
52 union
53 {
54 rt_le64_t code_raw[4];
55 rt_uint64_t code[4];
56 };
57 };
58
59 struct its_table
60 {
61 void *base;
62 rt_uint64_t val;
63 rt_uint32_t size_bits;
64 rt_uint32_t page_size;
65 union
66 {
67 struct
68 {
69 rt_uint32_t itt_entries;
70 rt_uint32_t lvl2_bits;
71 };
72 };
73 };
74
75 struct its_collection
76 {
77 rt_uint64_t target_address;
78 rt_uint16_t id;
79 };
80
81 struct gicv3_its;
82
83 struct its_map
84 {
85 rt_list_t list;
86 struct rt_ref ref;
87 struct gicv3_its *its;
88
89 int device_id;
90 int lpi_base;
91 int cpu_id;
92
93 void *itt;
94 void *lvl2_dte;
95 };
96
97 struct gicv3_its
98 {
99 struct rt_pic parent;
100 rt_list_t list;
101
102 void *base;
103 void *base_phy;
104
105 void *cmd_base;
106 rt_ubase_t cmd_idx;
107 rt_uint32_t flags;
108 struct rt_spinlock cmd_lock;
109
110 struct its_table tbls[GITS_BASER_NR_REGS];
111 struct its_collection collections[RT_CPUS_NR];
112
113 struct gicv3 *gic;
114 struct rt_ofw_node *np;
115 };
116
117 #define raw_to_gicv3_its(raw) rt_container_of(raw, struct gicv3_its, parent)
118
119 static rt_size_t lpi_nr;
120 static rt_uint32_t lpi_id_bits;
121 static void *lpi_table;
122 static void *lpi_pending_table;
123 static rt_bitmap_t *lpis_vectors = RT_NULL;
124 static RT_DEFINE_SPINLOCK(lpis_lock);
125 static RT_DEFINE_SPINLOCK(map_lock);
126 static rt_list_t its_nodes = RT_LIST_OBJECT_INIT(its_nodes);
127 static rt_list_t map_nodes = RT_LIST_OBJECT_INIT(map_nodes);
128
its_readq(struct gicv3_its * its,int off)129 rt_inline rt_uint64_t its_readq(struct gicv3_its *its, int off)
130 {
131 return HWREG32(its->base + off) |
132 (rt_uint64_t)HWREG32(its->base + off + 4) << 32;
133 }
134
its_writeq(struct gicv3_its * its,int off,rt_uint64_t value)135 rt_inline void its_writeq(struct gicv3_its *its, int off, rt_uint64_t value)
136 {
137 HWREG32(its->base + off) = (rt_uint32_t)value;
138 HWREG32(its->base + off + 4) = (rt_uint32_t)(value >> 32);
139 }
140
its_readl(struct gicv3_its * its,int off)141 rt_inline rt_uint32_t its_readl(struct gicv3_its *its, int off)
142 {
143 return HWREG32(its->base + off);
144 }
145
its_writel(struct gicv3_its * its,int off,rt_uint32_t value)146 rt_inline void its_writel(struct gicv3_its *its, int off, rt_uint32_t value)
147 {
148 HWREG32(its->base + off) = value;
149 }
150
its_pirq_event_id(struct gicv3_its * its,struct rt_pic_irq * pirq)151 rt_inline rt_uint32_t its_pirq_event_id(struct gicv3_its *its, struct rt_pic_irq *pirq)
152 {
153 return pirq->hwirq - 8192;
154 }
155
its_pirq_device_id(struct gicv3_its * its,struct rt_pic_irq * pirq)156 rt_inline rt_uint32_t its_pirq_device_id(struct gicv3_its *its, struct rt_pic_irq *pirq)
157 {
158 struct its_map *map = pirq->msi_desc->priv;
159
160 return map->device_id;
161 }
162
its_device_id_bits(struct gicv3_its * its)163 rt_inline rt_size_t its_device_id_bits(struct gicv3_its *its)
164 {
165 return RT_FIELD_GET(GITS_TYPER_DEVBITS, HWREG64(its->base + GITS_TYPER)) + 1;
166 }
167
lpi_base_config(int index)168 rt_inline void *lpi_base_config(int index)
169 {
170 return &((rt_uint8_t *)lpi_table)[index - 8192];
171 }
172
its_mask_encode(rt_uint64_t * raw_code,rt_uint64_t val,int h,int l)173 static void its_mask_encode(rt_uint64_t *raw_code, rt_uint64_t val, int h, int l)
174 {
175 rt_uint64_t mask = RT_GENMASK_ULL(h, l);
176 *raw_code &= ~mask;
177 *raw_code |= (val << l) & mask;
178 }
179
its_encode_cmd(struct its_command * cmd,rt_uint8_t cmd_nr)180 rt_inline void its_encode_cmd(struct its_command *cmd, rt_uint8_t cmd_nr)
181 {
182 its_mask_encode(&cmd->code[0], cmd_nr, 7, 0);
183 }
184
its_encode_valid(struct its_command * cmd,rt_bool_t valid)185 rt_inline void its_encode_valid(struct its_command *cmd, rt_bool_t valid)
186 {
187 its_mask_encode(&cmd->code[2], !!valid, 63, 63);
188 }
189
its_encode_phys_id(struct its_command * cmd,rt_uint32_t phys_id)190 rt_inline void its_encode_phys_id(struct its_command *cmd, rt_uint32_t phys_id)
191 {
192 its_mask_encode(&cmd->code[1], phys_id, 63, 32);
193 }
194
its_encode_size(struct its_command * cmd,rt_uint8_t size)195 rt_inline void its_encode_size(struct its_command *cmd, rt_uint8_t size)
196 {
197 its_mask_encode(&cmd->code[1], size, 4, 0);
198 }
199
its_encode_itt(struct its_command * cmd,rt_uint64_t itt_addr)200 rt_inline void its_encode_itt(struct its_command *cmd, rt_uint64_t itt_addr)
201 {
202 its_mask_encode(&cmd->code[2], itt_addr >> 8, 51, 8);
203 }
204
its_encode_target(struct its_command * cmd,rt_uint64_t target_addr)205 rt_inline void its_encode_target(struct its_command *cmd, rt_uint64_t target_addr)
206 {
207 its_mask_encode(&cmd->code[2], target_addr >> 16, 51, 16);
208 }
209
its_encode_device_id(struct its_command * cmd,rt_uint32_t device_id)210 rt_inline void its_encode_device_id(struct its_command *cmd, rt_uint32_t device_id)
211 {
212 its_mask_encode(&cmd->code[0], device_id, 63, 32);
213 }
214
its_encode_event_id(struct its_command * cmd,rt_uint32_t event_id)215 rt_inline void its_encode_event_id(struct its_command *cmd, rt_uint32_t event_id)
216 {
217 its_mask_encode(&cmd->code[1], event_id, 31, 0);
218 }
219
its_encode_collection(struct its_command * cmd,rt_uint16_t collection_id)220 rt_inline void its_encode_collection(struct its_command *cmd, rt_uint16_t collection_id)
221 {
222 its_mask_encode(&cmd->code[2], collection_id, 15, 0);
223 }
224
its_baser_type(struct gicv3_its * its,int type)225 static struct its_table *its_baser_type(struct gicv3_its *its, int type)
226 {
227 for (int i = 0; i < RT_ARRAY_SIZE(its->tbls); ++i)
228 {
229 if (GITS_BASER_TYPE(its->tbls[i].val) == type)
230 {
231 return &its->tbls[i];
232 }
233 }
234
235 return RT_NULL;
236 }
237
its_cmd_alloc(struct gicv3_its * its)238 static struct its_command *its_cmd_alloc(struct gicv3_its *its)
239 {
240 struct its_command *cmd = RT_NULL;
241
242 for (rt_uint32_t count = 0; count <= 10000; ++count)
243 {
244 if ((its->cmd_idx + 1) % ITS_CMD_QUEUE_NR != its_readl(its, GITS_CREADR) / sizeof(*cmd))
245 {
246 struct its_command *cmds = its->cmd_base;
247
248 cmd = &cmds[its->cmd_idx++];
249 its->cmd_idx %= ITS_CMD_QUEUE_NR;
250
251 rt_memset(cmd, 0, sizeof(*cmd));
252
253 break;
254 }
255
256 rt_hw_us_delay(10);
257 }
258
259 return cmd;
260 }
261
its_cmd_submit_raw(struct gicv3_its * its,struct its_command * cmd)262 static rt_err_t its_cmd_submit_raw(struct gicv3_its *its, struct its_command *cmd)
263 {
264 rt_uint64_t cwriter;
265 rt_bool_t retry = RT_FALSE;
266
267 cwriter = (void *)(cmd + 1) - its->cmd_base;
268 rt_hw_rmb();
269
270 #ifdef ARCH_CPU_BIG_ENDIAN
271 cmd->code_raw[0] = rt_cpu_to_le64(cmd->code[0]);
272 cmd->code_raw[1] = rt_cpu_to_le64(cmd->code[1]);
273 cmd->code_raw[2] = rt_cpu_to_le64(cmd->code[2]);
274 cmd->code_raw[3] = rt_cpu_to_le64(cmd->code[3]);
275 #endif /* ARCH_CPU_BIG_ENDIAN */
276
277 /* Make sure the commands written to memory are observable by the ITS */
278 if (its->flags & ITS_FLAGS_CMDQ_NEEDS_FLUSHING)
279 {
280 rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cmd, sizeof(*cmd));
281 }
282 else
283 {
284 rt_hw_wmb();
285 }
286
287 its_writel(its, GITS_CWRITER, cwriter);
288
289 for (rt_uint32_t count = 0; count < 10000; ++count)
290 {
291 if (its_readl(its, GITS_CREADR) == cwriter)
292 {
293 return RT_EOK;
294 }
295
296 /* Stalled */
297 if (!retry && its_readl(its, GITS_CREADR) & 1)
298 {
299 /* Retry */
300 its_writel(its, GITS_CWRITER, cwriter);
301 retry = RT_TRUE;
302 }
303 else if (retry)
304 {
305 LOG_E("Retry command 0x%02x fail", cmd->code[0] & 0xff);
306
307 return -RT_EIO;
308 }
309
310 rt_hw_us_delay(10);
311 }
312
313 return -RT_ETIMEOUT;
314 }
315
its_cmd_submit_nomap(struct gicv3_its * its,struct its_command * cmd,int cpu_id,rt_bool_t sync)316 static rt_err_t its_cmd_submit_nomap(struct gicv3_its *its, struct its_command *cmd,
317 int cpu_id, rt_bool_t sync)
318 {
319 rt_err_t err;
320 struct its_command *hw_cmd;
321
322 rt_hw_spin_lock(&its->cmd_lock.lock);
323
324 if (!(hw_cmd = its_cmd_alloc(its)))
325 {
326 err = -RT_EBUSY;
327 goto _out_lock;
328 }
329
330 rt_memcpy(hw_cmd, cmd, sizeof(*hw_cmd));
331
332 if ((err = its_cmd_submit_raw(its, hw_cmd)))
333 {
334 goto _out_lock;
335 }
336
337 if (sync)
338 {
339 if (!(hw_cmd = its_cmd_alloc(its)))
340 {
341 err = -RT_EBUSY;
342 goto _out_lock;
343 }
344
345 its_encode_cmd(hw_cmd, GITS_CMD_SYNC);
346 its_encode_target(hw_cmd, its->collections[cpu_id].target_address);
347
348 err = its_cmd_submit_raw(its, hw_cmd);
349 }
350
351 _out_lock:
352 rt_hw_spin_unlock(&its->cmd_lock.lock);
353
354 return err;
355 }
356
its_cmd_submit(struct gicv3_its * its,struct its_command * cmd,struct its_map * map,rt_bool_t sync)357 static rt_err_t its_cmd_submit(struct gicv3_its *its, struct its_command *cmd,
358 struct its_map *map, rt_bool_t sync)
359 {
360 return its_cmd_submit_nomap(its, cmd, map->cpu_id, sync);
361 }
362
lpi_flush_config(struct gicv3_its * its,rt_uint8_t * conf,struct rt_pic_irq * pirq)363 static rt_err_t lpi_flush_config(struct gicv3_its *its, rt_uint8_t *conf,
364 struct rt_pic_irq *pirq)
365 {
366 struct its_command cmd;
367 struct its_map *map = pirq->msi_desc->priv;
368
369 if (its->gic->redist_flags & RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING)
370 {
371 /* Clean D-cache under command */
372 rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, conf, sizeof(*conf));
373 }
374 else
375 {
376 /* DSB inner shareable, store */
377 rt_hw_wmb();
378 }
379
380 rt_memset(&cmd, 0, sizeof(cmd));
381 its_encode_cmd(&cmd, GITS_CMD_INV);
382 its_encode_device_id(&cmd, its_pirq_device_id(its, pirq));
383 its_encode_event_id(&cmd, its_pirq_event_id(its, pirq));
384
385 return its_cmd_submit(its, &cmd, map, RT_FALSE);
386 }
387
gicr_rd_base_percpu(struct gicv3 * gic)388 rt_inline void *gicr_rd_base_percpu(struct gicv3 *gic)
389 {
390 return gic->redist_regions[rt_hw_cpu_id()].base;
391 }
392
gicr_rd_base(struct gicv3_its * its)393 rt_inline void *gicr_rd_base(struct gicv3_its *its)
394 {
395 return its->gic->redist_percpu_base[rt_hw_cpu_id()];
396 }
397
gicr_rd_flags(struct gicv3_its * its)398 rt_inline rt_uint64_t *gicr_rd_flags(struct gicv3_its *its)
399 {
400 return &its->gic->redist_percpu_flags[rt_hw_cpu_id()];
401 }
402
gicr_supports_plpis(struct gicv3_its * its)403 static rt_bool_t gicr_supports_plpis(struct gicv3_its *its)
404 {
405 return !!(HWREG64(gicr_rd_base(its) + GICR_TYPER) & GICR_TYPER_PLPIS);
406 }
407
redist_disable_lpis(struct gicv3_its * its)408 static rt_err_t redist_disable_lpis(struct gicv3_its *its)
409 {
410 void *gicr = gicr_rd_base(its);
411 rt_uint64_t timeout = 1000000L, val;
412
413 if (!gicr_supports_plpis(its))
414 {
415 LOG_E("CPU#%d: LPIs not supported", rt_hw_cpu_id());
416 return -RT_ENOSYS;
417 }
418
419 val = HWREG32(gicr + GICR_CTLR);
420 if (!(val & GICR_CTLR_ENABLE_LPIS))
421 {
422 return RT_EOK;
423 }
424
425 /*
426 * If coming via a CPU hotplug event, we don't need to disable
427 * LPIs before trying to re-enable them. They are already
428 * configured and all is well in the world.
429 *
430 * If running with preallocated tables, there is nothing to do.
431 */
432 if ((*gicr_rd_flags(its) & RD_LOCAL_LPI_ENABLED) ||
433 (its->gic->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED))
434 {
435 return RT_EOK;
436 }
437
438 /* From that point on, we only try to do some damage control */
439 LOG_W("CPU%d: Booted with LPIs enabled, memory probably corrupted", rt_hw_cpu_id());
440
441 /* Disable LPIs */
442 val &= ~GICR_CTLR_ENABLE_LPIS;
443 HWREG32(gicr + GICR_CTLR) = val;
444
445 /* Make sure any change to GICR_CTLR is observable by the GIC */
446 rt_hw_barrier(dsb, sy);
447
448 /*
449 * Software must observe RWP==0 after clearing GICR_CTLR.EnableLPIs
450 * from 1 to 0 before programming GICR_PEND{PROP}BASER registers.
451 * Error out if we time out waiting for RWP to clear.
452 */
453 while (HWREG32(gicr + GICR_CTLR) & GICR_CTLR_RWP)
454 {
455 if (!timeout)
456 {
457 LOG_E("CPU#%d: Timeout while disabling LPIs", rt_hw_cpu_id());
458
459 return -RT_ETIMEOUT;
460 }
461
462 rt_hw_us_delay(1);
463 --timeout;
464 }
465
466 /*
467 * After it has been written to 1, it is IMPLEMENTATION
468 * DEFINED whether GICR_CTLR.EnableLPI becomes RES1 or can be
469 * cleared to 0. Error out if clearing the bit failed.
470 */
471 if (HWREG32(gicr + GICR_CTLR) & GICR_CTLR_ENABLE_LPIS)
472 {
473 LOG_E("CPU#%d: Failed to disable LPIs", rt_hw_cpu_id());
474
475 return -RT_EBUSY;
476 }
477
478 return RT_EOK;
479 }
480
gicv3_its_cpu_init_lpis(struct gicv3_its * its)481 static void gicv3_its_cpu_init_lpis(struct gicv3_its *its)
482 {
483 void *gicr;
484 rt_ubase_t paddr;
485 rt_uint64_t val, tmp;
486
487 if (*gicr_rd_flags(its) & RD_LOCAL_LPI_ENABLED)
488 {
489 return;
490 }
491
492 gicr = gicr_rd_base(its);
493
494 val = HWREG32(gicr + GICR_CTLR);
495
496 if ((its->gic->redist_flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED) &&
497 (val & GICR_CTLR_ENABLE_LPIS))
498 {
499 *gicr_rd_flags(its) |= RD_LOCAL_PENDTABLE_PREALLOCATED;
500
501 goto _out;
502 }
503
504 paddr = (rt_ubase_t)rt_kmem_v2p(lpi_pending_table);
505
506 /* Set PROPBASE */
507 val = ((rt_ubase_t)rt_kmem_v2p(lpi_table) |
508 GITS_CBASER_InnerShareable |
509 GITS_CBASER_RaWaWb |
510 ((lpi_id_bits - 1) & GICR_PROPBASER_IDBITS_MASK));
511
512 HWREG64(gicr + GICR_PROPBASER) = val;
513 tmp = HWREG64(gicr + GICR_PROPBASER);
514
515 if (its->gic->redist_flags & RDIST_FLAGS_FORCE_NON_SHAREABLE)
516 {
517 tmp &= ~GICR_PBASER_SHARE_MASK_ALL;
518 }
519
520 if ((tmp ^ val) & GICR_PBASER_SHARE_MASK_ALL)
521 {
522 if (!(tmp & GICR_PBASER_SHARE_MASK_ALL))
523 {
524 /*
525 * The HW reports non-shareable,
526 * we must remove the cacheability attributes as well.
527 */
528 val &= ~(GICR_PBASER_SHARE_MASK_ALL | GICR_PBASER_INNER_MASK_ALL);
529 val |= GICR_PBASER_nC;
530 HWREG64(gicr + GICR_PROPBASER) = val;
531 }
532
533 if (!rt_hw_cpu_id())
534 {
535 LOG_I("Using cache flushing for LPI property table");
536 }
537 its->gic->redist_flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING;
538 }
539
540 val = (paddr | GICR_PBASER_InnerShareable | GICR_PBASER_RaWaWb);
541
542 HWREG64(gicr + GICR_PENDBASER) = val;
543 tmp = HWREG64(gicr + GICR_PENDBASER);
544
545 if (its->gic->redist_flags & RDIST_FLAGS_FORCE_NON_SHAREABLE)
546 {
547 tmp &= ~GICR_PBASER_SHARE_MASK_ALL;
548 }
549
550 if (!(tmp & GICR_PBASER_SHARE_MASK_ALL))
551 {
552 /*
553 * The HW reports non-shareable, we must remove the
554 * cacheability attributes as well.
555 */
556 val &= ~(GICR_PBASER_SHARE_MASK_ALL | GICR_PBASER_INNER_MASK_ALL);
557 val |= GICR_PBASER_nC;
558 HWREG64(gicr + GICR_PENDBASER) = val;
559 }
560
561 /* Enable LPIs */
562 val = HWREG32(gicr + GICR_CTLR);
563 val |= GICR_CTLR_ENABLE_LPIS;
564 HWREG32(gicr + GICR_CTLR) = val;
565
566 rt_hw_barrier(dsb, sy);
567
568 _out:
569 *gicr_rd_flags(its) |= RD_LOCAL_LPI_ENABLED;
570 }
571
gicv3_its_cpu_init_collection(struct gicv3_its * its)572 static void gicv3_its_cpu_init_collection(struct gicv3_its *its)
573 {
574 rt_uint64_t target;
575 int cpu_id = rt_hw_cpu_id();
576 struct its_command cmd;
577 struct its_collection *collection;
578
579 if (HWREG64(its->base + GITS_TYPER) & GITS_TYPER_PTA)
580 {
581 target = (rt_uint64_t)rt_kmem_v2p(gicr_rd_base(its));
582 }
583 else
584 {
585 /* Linear by GICR processor number */
586 target = HWREG64(gicr_rd_base(its) + GICR_TYPER);
587 target = GICR_TYPER_CPU_NO(target) << 16;
588 }
589
590 collection = &its->collections[cpu_id];
591 collection->target_address = target;
592 collection->id = cpu_id;
593
594 rt_memset(&cmd, 0, sizeof(cmd));
595 its_encode_cmd(&cmd, GITS_CMD_MAPC);
596 its_encode_collection(&cmd, collection->id);
597 its_encode_target(&cmd, target);
598 its_encode_valid(&cmd, RT_TRUE);
599 its_cmd_submit_nomap(its, &cmd, cpu_id, RT_TRUE);
600
601 rt_memset(&cmd, 0, sizeof(cmd));
602 its_encode_cmd(&cmd, GITS_CMD_INVALL);
603 its_encode_collection(&cmd, collection->id);
604 its_cmd_submit_nomap(its, &cmd, cpu_id, RT_TRUE);
605 }
606
gicv3_its_irq_init(struct rt_pic * pic)607 static rt_err_t gicv3_its_irq_init(struct rt_pic *pic)
608 {
609 rt_err_t err;
610 struct gicv3_its *its = raw_to_gicv3_its(pic);
611
612 if ((err = redist_disable_lpis(its)))
613 {
614 return err;
615 }
616
617 gicv3_its_cpu_init_lpis(its);
618 gicv3_its_cpu_init_collection(its);
619
620 return RT_EOK;
621 }
622
gicv3_its_irq_mask(struct rt_pic_irq * pirq)623 static void gicv3_its_irq_mask(struct rt_pic_irq *pirq)
624 {
625 rt_uint8_t *conf = lpi_base_config(pirq->hwirq);
626 struct gicv3_its *its = raw_to_gicv3_its(pirq->pic);
627
628 *conf &= ~GITS_LPI_CFG_ENABLED;
629 lpi_flush_config(its, conf, pirq);
630
631 rt_pci_msi_mask_irq(pirq);
632 }
633
gicv3_its_irq_unmask(struct rt_pic_irq * pirq)634 static void gicv3_its_irq_unmask(struct rt_pic_irq *pirq)
635 {
636 rt_uint8_t *conf = lpi_base_config(pirq->hwirq);
637 struct gicv3_its *its = raw_to_gicv3_its(pirq->pic);
638
639 *conf |= GITS_LPI_CFG_ENABLED;
640 lpi_flush_config(its, conf, pirq);
641
642 rt_pci_msi_unmask_irq(pirq);
643 }
644
gicv3_its_irq_set_priority(struct rt_pic_irq * pirq,rt_uint32_t priority)645 static rt_err_t gicv3_its_irq_set_priority(struct rt_pic_irq *pirq, rt_uint32_t priority)
646 {
647 rt_uint8_t *conf = lpi_base_config(pirq->hwirq);
648 struct gicv3_its *its = raw_to_gicv3_its(pirq->pic);
649
650 *conf = (priority << ITS_LPI_CONFIG_PROP_SHIFT) | (*conf & (~ITS_LPI_CONFIG_PROP_MASK));
651
652 return lpi_flush_config(its, conf, pirq);
653 }
654
gicv3_its_irq_set_affinity(struct rt_pic_irq * pirq,rt_bitmap_t * affinity)655 static rt_err_t gicv3_its_irq_set_affinity(struct rt_pic_irq *pirq, rt_bitmap_t *affinity)
656 {
657 int cpu_id;
658 rt_err_t err;
659 struct its_map *map;
660 struct its_command cmd;
661 struct its_collection *collection;
662 struct gicv3_its *its = raw_to_gicv3_its(pirq->pic);
663
664 map = pirq->msi_desc->priv;
665 cpu_id = rt_bitmap_next_set_bit(affinity, 0, RT_CPUS_NR);
666 collection = &its->collections[cpu_id];
667
668 if (collection->target_address == ~0ULL)
669 {
670 return -RT_EIO;
671 }
672
673 if (map->cpu_id == cpu_id)
674 {
675 return RT_EOK;
676 }
677
678 rt_memset(&cmd, 0, sizeof(cmd));
679 its_encode_cmd(&cmd, GITS_CMD_MOVI);
680 its_encode_device_id(&cmd, map->device_id);
681 its_encode_event_id(&cmd, its_pirq_event_id(its, pirq));
682 its_encode_collection(&cmd, collection->id);
683
684 if (!(err = its_cmd_submit(its, &cmd, map, RT_TRUE)))
685 {
686 map->cpu_id = cpu_id;
687 }
688
689 return err;
690 }
691
gicv3_its_irq_compose_msi_msg(struct rt_pic_irq * pirq,struct rt_pci_msi_msg * msg)692 static void gicv3_its_irq_compose_msi_msg(struct rt_pic_irq *pirq, struct rt_pci_msi_msg *msg)
693 {
694 rt_ubase_t addr;
695 struct gicv3_its *its = raw_to_gicv3_its(pirq->pic);
696
697 addr = (rt_ubase_t)its->base_phy + GITS_TRANSLATER;
698
699 msg->address_hi = rt_upper_32_bits(addr);
700 msg->address_lo = rt_lower_32_bits(addr);
701 msg->data = its_pirq_event_id(its, pirq);
702 }
703
gicv3_its_irq_alloc_msi(struct rt_pic * pic,struct rt_pci_msi_desc * msi_desc)704 static int gicv3_its_irq_alloc_msi(struct rt_pic *pic, struct rt_pci_msi_desc *msi_desc)
705 {
706 rt_ubase_t level;
707 rt_uint32_t device_id = -1;
708 int irq = -1, hwirq, parent_irq, hwirq_index, lpi_base = 0;
709 struct its_map *map = RT_NULL, *map_tmp;
710 struct its_table *tbl;
711 struct its_command cmd;
712 struct rt_pic_irq *pirq;
713 struct rt_pci_device *pdev = msi_desc->pdev;
714 struct gicv3_its *its = raw_to_gicv3_its(pic);
715 struct rt_pic *ppic = &its->gic->parent;
716
717 tbl = its_baser_type(its, GITS_BASER_TYPE_DEVICE);
718 RT_ASSERT(tbl != RT_NULL);
719
720 if (!pdev->parent.ofw_node)
721 {
722 device_id = rt_pci_dev_id(pdev);
723 }
724 else
725 {
726 struct rt_ofw_cell_args args;
727
728 for (int index = 0; ; ++index)
729 {
730 rt_err_t err = rt_ofw_parse_phandle_cells(pdev->parent.ofw_node,
731 "msi-parent", "#msi-cells", index, &args);
732
733 if (err)
734 {
735 return (int)err;
736 }
737
738 if (args.data == its->np)
739 {
740 device_id = args.args[0];
741 }
742
743 rt_ofw_node_put(args.data);
744
745 if ((rt_int32_t)device_id >= 0)
746 {
747 break;
748 }
749 }
750 }
751
752 if (device_id >= (1 << tbl->size_bits))
753 {
754 LOG_E("Device ID = is %x not supported", device_id);
755
756 return -RT_EINVAL;
757 }
758
759 /* Find old map info */
760 level = rt_spin_lock_irqsave(&map_lock);
761 rt_list_for_each_entry(map_tmp, &map_nodes, list)
762 {
763 if (map_tmp->device_id == device_id)
764 {
765 map = map_tmp;
766 lpi_base = map->lpi_base - 8192;
767 break;
768 }
769 }
770 rt_spin_unlock_irqrestore(&map_lock, level);
771
772 if (!map)
773 {
774 rt_size_t itt_size;
775
776 if (!(map = rt_calloc(1, sizeof(*map))))
777 {
778 return -RT_ENOMEM;
779 }
780
781 itt_size = tbl->itt_entries * (RT_FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE,
782 HWREG64(its->base + GITS_TYPER)) + 1);
783 itt_size = rt_max_t(rt_size_t, itt_size, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
784
785 map->itt = rt_malloc_align(itt_size, ITS_ITT_ALIGN);
786
787 if (!map->itt)
788 {
789 rt_free(map);
790 return -RT_ENOMEM;
791 }
792
793 if (tbl->lvl2_bits)
794 {
795 void *lvl2_dte;
796 rt_uint64_t *entry;
797
798 entry = tbl->base;
799 entry += device_id / (tbl->page_size / GITS_LVL1_ENTRY_SIZE);
800
801 if (*entry)
802 {
803 lvl2_dte = (void *)(*entry - PV_OFFSET);
804 rt_page_ref_inc(lvl2_dte, tbl->lvl2_bits);
805 }
806 else
807 {
808 rt_size_t dte_size;
809
810 lvl2_dte = rt_pages_alloc(tbl->lvl2_bits);
811
812 if (!lvl2_dte)
813 {
814 rt_free_align(map->itt);
815 rt_free(map);
816 return -RT_ENOMEM;
817 }
818
819 dte_size = rt_page_bits(tbl->lvl2_bits);
820 rt_memset(lvl2_dte, 0, dte_size);
821
822 if (!(tbl->val & GITS_BASER_SHARE_MASK_ALL))
823 {
824 rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, lvl2_dte, dte_size);
825 }
826
827 *entry = rt_cpu_to_le64((rt_uint64_t)rt_kmem_v2p(lvl2_dte) | GITS_BASER_VALID);
828
829 if (!(tbl->val & GITS_BASER_SHARE_MASK_ALL))
830 {
831 rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, entry, sizeof(*entry));
832 }
833
834 rt_hw_dsb();
835 }
836
837 map->lvl2_dte = lvl2_dte;
838 }
839
840 rt_memset(map->itt, 0, itt_size);
841 rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, map->itt, itt_size);
842 }
843 msi_desc->priv = map;
844
845 /* Alloc the LPI base on the first LPI */
846 level = rt_spin_lock_irqsave(&lpis_lock);
847 hwirq_index = rt_bitmap_next_clear_bit(lpis_vectors, lpi_base, lpi_nr);
848
849 if (hwirq_index >= lpi_nr)
850 {
851 irq = -RT_EEMPTY;
852 goto _out_lock;
853 }
854
855 hwirq = 8192 + hwirq_index;
856 parent_irq = ppic->ops->irq_map(ppic, hwirq, RT_IRQ_MODE_EDGE_RISING);
857 if (parent_irq < 0)
858 {
859 irq = parent_irq;
860 goto _out_lock;
861 }
862
863 irq = rt_pic_config_irq(pic, hwirq_index, hwirq);
864 if (irq < 0)
865 {
866 goto _out_lock;
867 }
868 pirq = rt_pic_find_irq(pic, hwirq_index);
869
870 pirq->mode = RT_IRQ_MODE_EDGE_RISING;
871 rt_pic_cascade(pirq, parent_irq);
872
873 rt_bitmap_set_bit(lpis_vectors, hwirq_index);
874
875 _out_lock:
876 rt_spin_unlock_irqrestore(&lpis_lock, level);
877
878 if (irq < 0)
879 {
880 return irq;
881 }
882
883 if (map->its)
884 {
885 rt_ref_get(&map->ref);
886 }
887 else
888 {
889 rt_list_init(&map->list);
890 rt_ref_init(&map->ref);
891 map->its = its;
892 map->device_id = device_id;
893 map->lpi_base = hwirq;
894
895 level = rt_spin_lock_irqsave(&map_lock);
896 rt_list_insert_before(&map_nodes, &map->list);
897 rt_spin_unlock_irqrestore(&map_lock, level);
898 }
899
900 /* Default to CPU#0 */
901 map->cpu_id = 0;
902 RT_IRQ_AFFINITY_SET(pirq->affinity, map->cpu_id);
903
904 rt_memset(&cmd, 0, sizeof(cmd));
905 its_encode_cmd(&cmd, GITS_CMD_MAPD);
906 its_encode_device_id(&cmd, device_id);
907 its_encode_size(&cmd, rt_ilog2(tbl->itt_entries) - 1);
908 its_encode_itt(&cmd, (rt_uint64_t)rt_kmem_v2p(map->itt));
909 its_encode_valid(&cmd, RT_TRUE);
910 its_cmd_submit(its, &cmd, map, RT_FALSE);
911
912 rt_memset(&cmd, 0, sizeof(cmd));
913 its_encode_cmd(&cmd, GITS_CMD_MAPTI);
914 its_encode_device_id(&cmd, device_id);
915 its_encode_event_id(&cmd, its_pirq_event_id(its, pirq));
916 its_encode_phys_id(&cmd, hwirq);
917 its_encode_collection(&cmd, its->collections[map->cpu_id].id);
918 its_cmd_submit(its, &cmd, map, RT_TRUE);
919
920 return irq;
921 }
922
its_map_release(struct rt_ref * r)923 static void its_map_release(struct rt_ref *r)
924 {
925 rt_ubase_t level;
926 struct gicv3_its *its;
927 struct its_table *tbl;
928 struct its_command cmd;
929 struct its_map *map = rt_container_of(r, struct its_map, ref);
930
931 its = map->its;
932 tbl = its_baser_type(its, GITS_BASER_TYPE_DEVICE);
933
934 rt_memset(&cmd, 0, sizeof(cmd));
935 its_encode_cmd(&cmd, GITS_CMD_MAPD);
936 its_encode_device_id(&cmd, map->device_id);
937 its_encode_size(&cmd, rt_ilog2(tbl->itt_entries) - 1);
938 its_encode_itt(&cmd, (rt_uint64_t)rt_kmem_v2p(map->itt));
939 its_encode_valid(&cmd, RT_FALSE);
940 its_cmd_submit(its, &cmd, map, RT_TRUE);
941
942 level = rt_spin_lock_irqsave(&map_lock);
943 rt_list_insert_before(&map_nodes, &map->list);
944 rt_spin_unlock_irqrestore(&map_lock, level);
945
946 if (map->itt)
947 {
948 rt_free_align(map->itt);
949 }
950 if (map->lvl2_dte)
951 {
952 if (rt_page_ref_get(map->lvl2_dte, tbl->lvl2_bits) == 1)
953 {
954 rt_uint64_t *entry;
955
956 entry = tbl->base + (map->device_id / (tbl->page_size / GITS_LVL1_ENTRY_SIZE));
957 *entry = rt_cpu_to_le64(0);
958
959 if (!(tbl->val & GITS_BASER_SHARE_MASK_ALL))
960 {
961 rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, entry, sizeof(*entry));
962 }
963 }
964 rt_pages_free(map->lvl2_dte, tbl->lvl2_bits);
965 }
966 rt_free(map);
967 }
968
gicv3_its_irq_free_msi(struct rt_pic * pic,int irq)969 static void gicv3_its_irq_free_msi(struct rt_pic *pic, int irq)
970 {
971 rt_ubase_t level;
972 struct its_map *map;
973 struct its_command cmd;
974 struct rt_pic_irq *pirq;
975 struct gicv3_its *its = raw_to_gicv3_its(pic);
976
977 pirq = rt_pic_find_pirq(pic, irq);
978
979 if (!pirq)
980 {
981 return;
982 }
983
984 map = pirq->msi_desc->priv;
985
986 rt_memset(&cmd, 0, sizeof(cmd));
987 its_encode_cmd(&cmd, GITS_CMD_DISCARD);
988 its_encode_device_id(&cmd, map->device_id);
989 its_encode_event_id(&cmd, its_pirq_event_id(its, pirq));
990 its_cmd_submit(its, &cmd, map, RT_TRUE);
991
992 rt_pic_uncascade(pirq);
993
994 level = rt_spin_lock_irqsave(&lpis_lock);
995 rt_bitmap_clear_bit(lpis_vectors, pirq->hwirq - 8192);
996 rt_spin_unlock_irqrestore(&lpis_lock, level);
997
998 rt_ref_put(&map->ref, its_map_release);
999 }
1000
gicv3_its_irq_set_state(struct rt_pic * pic,int hwirq,int type,rt_bool_t state)1001 static rt_err_t gicv3_its_irq_set_state(struct rt_pic *pic, int hwirq, int type, rt_bool_t state)
1002 {
1003 struct its_map *map;
1004 struct its_command cmd;
1005 struct rt_pic_irq *pirq;
1006 struct gicv3_its *its = raw_to_gicv3_its(pic);
1007
1008 if (type != RT_IRQ_STATE_PENDING || hwirq > 8192 + lpi_nr)
1009 {
1010 return -RT_ENOSYS;
1011 }
1012
1013 if (!(pirq = rt_pic_find_irq(pic, hwirq - 8192)))
1014 {
1015 return -RT_ENOSYS;
1016 }
1017
1018 map = pirq->msi_desc->priv;
1019 rt_memset(&cmd, 0, sizeof(cmd));
1020
1021 if (state)
1022 {
1023 its_encode_cmd(&cmd, GITS_CMD_INT);
1024 its_encode_device_id(&cmd, map->device_id);
1025 its_encode_event_id(&cmd, its_pirq_event_id(its, pirq));
1026 }
1027 else
1028 {
1029 its_encode_cmd(&cmd, GITS_CMD_CLEAR);
1030 its_encode_device_id(&cmd, map->device_id);
1031 its_encode_event_id(&cmd, its_pirq_event_id(its, pirq));
1032 }
1033
1034 its_cmd_submit(its, &cmd, map, RT_TRUE);
1035
1036 return RT_EOK;
1037 }
1038
1039 const static struct rt_pic_ops gicv3_its_ops =
1040 {
1041 .name = "GICv3-ITS",
1042 .irq_init = gicv3_its_irq_init,
1043 .irq_ack = rt_pic_irq_parent_ack,
1044 .irq_mask = gicv3_its_irq_mask,
1045 .irq_unmask = gicv3_its_irq_unmask,
1046 .irq_eoi = rt_pic_irq_parent_eoi,
1047 .irq_set_priority = gicv3_its_irq_set_priority,
1048 .irq_set_affinity = gicv3_its_irq_set_affinity,
1049 .irq_compose_msi_msg = gicv3_its_irq_compose_msi_msg,
1050 .irq_alloc_msi = gicv3_its_irq_alloc_msi,
1051 .irq_free_msi = gicv3_its_irq_free_msi,
1052 .irq_set_state = gicv3_its_irq_set_state,
1053 .flags = RT_PIC_F_IRQ_ROUTING,
1054 };
1055
its_baser_page_size(struct gicv3_its * its,struct its_table * tbl)1056 static rt_ssize_t its_baser_page_size(struct gicv3_its *its, struct its_table *tbl)
1057 {
1058 rt_size_t page_size = 64 * SIZE_KB;
1059
1060 while (page_size)
1061 {
1062 rt_uint64_t val, baser_page_size;
1063 rt_off_t baser = GITS_BASERn((int)(tbl - its->tbls));
1064
1065 val = its_readq(its, baser);
1066 val &= ~GITS_BASER_PAGE_SIZE_MASK;
1067
1068 switch (page_size)
1069 {
1070 case 64 * SIZE_KB:
1071 baser_page_size = GITS_BASER_PAGE_SIZE_64K;
1072 break;
1073 case 16 * SIZE_KB:
1074 baser_page_size = GITS_BASER_PAGE_SIZE_16K;
1075 break;
1076 case 4 * SIZE_KB:
1077 default:
1078 baser_page_size = GITS_BASER_PAGE_SIZE_4K;
1079 break;
1080 }
1081
1082 baser_page_size >>= GITS_BASER_PAGE_SIZE_SHIFT;
1083
1084 val |= RT_FIELD_PREP(GITS_BASER_PAGE_SIZE_MASK, baser_page_size);
1085 its_writeq(its, baser, val);
1086 tbl->val = its_readq(its, baser);
1087
1088 if (RT_FIELD_GET(GITS_BASER_PAGE_SIZE_MASK, tbl->val) == baser_page_size)
1089 {
1090 break;
1091 }
1092
1093 switch (page_size)
1094 {
1095 case 64 * SIZE_KB:
1096 page_size = 16 * SIZE_KB;
1097 break;
1098 case 16 * SIZE_KB:
1099 page_size = 4 * SIZE_KB;
1100 break;
1101 case 4 * SIZE_KB:
1102 default:
1103 return -RT_EINVAL;
1104 }
1105 }
1106
1107 return page_size;
1108 }
1109
its_table_init(struct gicv3_its * its)1110 static rt_err_t its_table_init(struct gicv3_its *its)
1111 {
1112 int inited = 0;
1113 rt_off_t baser;
1114 rt_bool_t indirect = RT_FALSE;
1115 rt_size_t pages_nr, alloc_size;
1116 rt_uint64_t val, type, entry_size, share, cache;
1117 struct its_table *tbl;
1118
1119 share = GITS_BASER_InnerShareable;
1120 cache = GITS_BASER_RaWaWb;
1121
1122 for (int i = 0; i < RT_ARRAY_SIZE(its->tbls); ++i)
1123 {
1124 tbl = &its->tbls[i];
1125
1126 val = its_readq(its, GITS_BASERn(i));
1127 type = GITS_BASER_TYPE(val);
1128
1129 if (type != GITS_BASER_TYPE_DEVICE &&
1130 type != GITS_BASER_TYPE_COLLECTION)
1131 {
1132 continue;
1133 }
1134
1135 tbl->page_size = its_baser_page_size(its, tbl);
1136
1137 if (tbl->page_size < 0)
1138 {
1139 continue;
1140 }
1141
1142 baser = GITS_BASERn((int)(tbl - its->tbls));
1143 entry_size = GITS_BASER_ENTRY_SIZE(val);
1144
1145 if (type == GITS_BASER_TYPE_DEVICE)
1146 {
1147 tbl->size_bits = its_device_id_bits(its);
1148 LOG_D("Device Max IDs = %lu", 1UL << tbl->size_bits);
1149
1150 /* For MSI-X */
1151 tbl->itt_entries = 2048;
1152 while (MAX_HANDLERS / tbl->itt_entries < (1 << tbl->size_bits) &&
1153 tbl->itt_entries > 32)
1154 {
1155 tbl->itt_entries >>= 1;
1156 }
1157 }
1158
1159 its_writeq(its, baser, tbl->val | GITS_BASER_INDIRECT);
1160 tbl->val = its_readq(its, baser);
1161
1162 indirect = !!(tbl->val & GITS_BASER_INDIRECT);
1163 if (indirect && type == GITS_BASER_TYPE_DEVICE)
1164 {
1165 /* The size of the level 2 table is equal to ITS page size */
1166 tbl->lvl2_bits = tbl->size_bits - rt_ilog2(tbl->page_size / (int)entry_size);
1167
1168 /* Get level 1 entries count */
1169 alloc_size = (1 << tbl->size_bits) / (tbl->page_size / entry_size);
1170 alloc_size *= GITS_LVL1_ENTRY_SIZE;
1171 }
1172 else
1173 {
1174 alloc_size = (1 << tbl->size_bits) * entry_size;
1175 indirect = RT_FALSE;
1176 }
1177
1178 tbl->base = rt_malloc_align(alloc_size, tbl->page_size);
1179 pages_nr = alloc_size / tbl->page_size;
1180
1181 if (!tbl->base)
1182 {
1183 return -RT_ENOMEM;
1184 }
1185
1186 if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_22375)
1187 {
1188 cache = GITS_BASER_nCnB;
1189 }
1190
1191 if (its->flags & ITS_FLAGS_FORCE_NON_SHAREABLE)
1192 {
1193 cache = GITS_BASER_nC;
1194 share = 0;
1195 }
1196
1197 val = ((rt_ubase_t)rt_kmem_v2p(tbl->base) |
1198 (type << GITS_BASER_TYPE_SHIFT) |
1199 ((entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) |
1200 (pages_nr << GITS_BASER_PAGES_SHIFT) |
1201 cache | share | GITS_BASER_VALID);
1202 val |= indirect ? GITS_BASER_INDIRECT : 0;
1203
1204 switch (tbl->page_size)
1205 {
1206 case 4 * SIZE_KB:
1207 val |= GITS_BASER_PAGE_SIZE_4K;
1208 break;
1209 case 16 * SIZE_KB:
1210 val |= GITS_BASER_PAGE_SIZE_16K;
1211 break;
1212 case 64 * SIZE_KB:
1213 val |= GITS_BASER_PAGE_SIZE_64K;
1214 break;
1215 }
1216
1217 its_writeq(its, baser, val);
1218 tbl->val = its_readq(its, baser);
1219
1220 rt_memset(tbl->base, 0, alloc_size);
1221 rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, tbl->base, alloc_size);
1222
1223 cache = tbl->val & GITS_BASER_INNER_MASK_ALL;
1224 share = tbl->val & GITS_BASER_SHARE_MASK_ALL;
1225
1226 ++inited;
1227 }
1228
1229 return inited == 2 ? RT_EOK : -RT_ENOSYS;
1230 }
1231
its_cmd_queue_init(struct gicv3_its * its)1232 static rt_err_t its_cmd_queue_init(struct gicv3_its *its)
1233 {
1234 void *cmd_phy_base;
1235 rt_uint64_t baser, tmp;
1236
1237 its->cmd_base = rt_malloc_align(ITS_CMD_QUEUE_SIZE, ITS_CMD_QUEUE_ALIGN);
1238
1239 if (!its->cmd_base)
1240 {
1241 return -RT_ENOMEM;
1242 }
1243
1244 its->cmd_idx = 0;
1245 rt_memset(its->cmd_base, 0, ITS_CMD_QUEUE_SIZE);
1246
1247 cmd_phy_base = rt_kmem_v2p(its->cmd_base);
1248
1249 baser = GITS_CBASER_VALID | GITS_CBASER_RaWaWb | GITS_CBASER_InnerShareable | \
1250 ((rt_uint64_t)cmd_phy_base) | (ITS_CMD_QUEUE_SIZE / (4 * SIZE_KB) - 1);
1251
1252 its_writeq(its, GITS_CBASER, baser);
1253 tmp = its_readq(its, GITS_CBASER);
1254
1255 if (its->flags & ITS_FLAGS_FORCE_NON_SHAREABLE)
1256 {
1257 tmp &= ~GITS_CBASER_SHARE_MASK_ALL;
1258 }
1259
1260 if ((tmp ^ baser) & GITS_CBASER_SHARE_MASK_ALL)
1261 {
1262 if (!(tmp & GITS_CBASER_SHARE_MASK_ALL))
1263 {
1264 /* The HW reports non-shareable, we must remove the cacheability attributes as well */
1265 baser &= ~(GITS_CBASER_SHARE_MASK_ALL | GITS_CBASER_INNER_MASK_ALL);
1266 baser |= GITS_CBASER_nC;
1267
1268 its_writeq(its, GITS_CBASER, baser);
1269 }
1270
1271 LOG_I("Using cache flushing for CMD queue");
1272 its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING;
1273
1274 rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, its->cmd_base, ITS_CMD_QUEUE_SIZE);
1275 }
1276
1277 /* Get the next command from the start of the buffer */
1278 its_writeq(its, GITS_CWRITER, 0);
1279
1280 return RT_EOK;
1281 }
1282
its_lpi_table_init(struct gicv3 * gic)1283 static rt_err_t its_lpi_table_init(struct gicv3 *gic)
1284 {
1285 rt_size_t lpi_table_size, lpi_pending_table_size;
1286 rt_uint32_t numlpis = 1UL << GICD_TYPER_NUM_LPIS(gic->gicd_typer);
1287
1288 if (HWREG32(gicr_rd_base_percpu(gic) + GICR_CTLR) & GICR_CTLR_ENABLE_LPIS)
1289 {
1290 gic->redist_flags |= RDIST_FLAGS_RD_TABLES_PREALLOCATED;
1291 gic->redist_flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING;
1292
1293 LOG_I("Using preallocated redistributor tables");
1294 }
1295
1296 lpi_id_bits = GICD_TYPER_ID_BITS(gic->gicd_typer);
1297
1298 if (gic->redist_flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED)
1299 {
1300 rt_uint64_t val = HWREG64(gicr_rd_base_percpu(gic) + GICR_PROPBASER);
1301 lpi_id_bits = rt_min_t(rt_uint32_t, lpi_id_bits, (val & GICR_PROPBASER_IDBITS_MASK) + 1);
1302 }
1303
1304 lpi_nr = rt_min_t(rt_size_t, (1UL << lpi_id_bits) - 8192, gic->lpi_nr);
1305 lpi_id_bits = __rt_clz(lpi_nr + 8192);
1306
1307 if (numlpis > 2 && numlpis > lpi_nr)
1308 {
1309 lpi_nr = numlpis;
1310 LOG_W("Using hypervisor restricted LPI range [%u]", lpi_nr);
1311 }
1312
1313 gic->lpi_nr = lpi_nr;
1314
1315 /* LPI Configuration table entry is 1 byte, Pending table bytes is N / 8. */
1316 lpi_table_size = RT_GENMASK(lpi_id_bits, 0);
1317 lpi_pending_table_size = lpi_table_size / 8;
1318
1319 lpi_table = rt_malloc_align(lpi_table_size, ITS_LPI_CONFIG_TABLE_ALIGN);
1320 lpi_pending_table = rt_malloc_align(lpi_pending_table_size, ITS_LPI_PENDING_TABLE_ALIGN);
1321 lpis_vectors = rt_calloc(1, RT_BITMAP_LEN(lpi_nr) * sizeof(rt_bitmap_t));
1322
1323 if (!lpi_table || !lpi_pending_table || !lpis_vectors)
1324 {
1325 if (lpi_table)
1326 {
1327 rt_free_align(lpi_table);
1328 }
1329 if (lpi_pending_table)
1330 {
1331 rt_free_align(lpi_pending_table);
1332 }
1333 if (lpis_vectors)
1334 {
1335 rt_free_align(lpis_vectors);
1336 }
1337
1338 lpi_table = RT_NULL;
1339 lpi_pending_table = RT_NULL;
1340 lpis_vectors = RT_NULL;
1341
1342 return -RT_ENOMEM;
1343 }
1344
1345 /* Set the default configuration */
1346 rt_memset(lpi_table, ITS_LPI_CONFIG_PROP_DEFAULT_PRIO | GITS_LPI_CFG_GROUP1, lpi_table_size);
1347 /*
1348 * We should make a full mask size with lpi_id_bits,
1349 * otherwise 'undefined' LPI will occur.
1350 */
1351 rt_memset(lpi_pending_table, 0, lpi_pending_table_size);
1352
1353 /* Flush the table to memory */
1354 rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, lpi_table, lpi_table_size);
1355 rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, lpi_pending_table, lpi_pending_table_size);
1356
1357 LOG_D("ITS: Allocator initialized for %u LPIs", lpi_nr);
1358
1359 return RT_EOK;
1360 }
1361
its_init_fail(struct gicv3_its * its)1362 static void its_init_fail(struct gicv3_its *its)
1363 {
1364 if (its->base)
1365 {
1366 rt_iounmap(its->base);
1367 }
1368
1369 if (its->cmd_base)
1370 {
1371 rt_free_align(its->cmd_base);
1372 }
1373
1374 for (int i = 0; i < RT_ARRAY_SIZE(its->tbls); ++i)
1375 {
1376 struct its_table *tbl = &its->tbls[i];
1377
1378 if (tbl->base)
1379 {
1380 rt_free_align(tbl->base);
1381 }
1382 }
1383
1384 rt_list_remove(&its->list);
1385 rt_free(its);
1386 }
1387
its_quirk_cavium_22375(void * data)1388 static rt_err_t its_quirk_cavium_22375(void *data)
1389 {
1390 struct gicv3_its *its = data;
1391
1392 its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_22375;
1393
1394 return RT_EOK;
1395 }
1396
its_enable_rockchip(void * data)1397 static rt_err_t its_enable_rockchip(void *data)
1398 {
1399 struct gicv3_its *its = data;
1400 struct gicv3 *gic = its->gic;
1401
1402 if (!rt_ofw_machine_is_compatible("rockchip,rk3566") &&
1403 !rt_ofw_machine_is_compatible("rockchip,rk3567") &&
1404 !rt_ofw_machine_is_compatible("rockchip,rk3568") &&
1405 !rt_ofw_machine_is_compatible("rockchip,rk3588") &&
1406 !rt_ofw_machine_is_compatible("rockchip,rk3588s"))
1407 {
1408 return -RT_EINVAL;
1409 }
1410
1411 its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
1412 gic->redist_flags |= RDIST_FLAGS_FORCE_NON_SHAREABLE;
1413
1414 return RT_EOK;
1415 }
1416
its_set_non_coherent(void * data)1417 static rt_err_t its_set_non_coherent(void *data)
1418 {
1419 struct gicv3_its *its = data;
1420
1421 if (!rt_ofw_prop_read_bool(its->np, "dma-noncoherent"))
1422 {
1423 return -RT_EINVAL;
1424 }
1425
1426 its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
1427
1428 return RT_EOK;
1429 }
1430
1431 static const struct gic_quirk _its_quirks[] =
1432 {
1433 {
1434 .desc = "ITS: Cavium ThunderX errata: 22375, 24313",
1435 .iidr = 0xa100034c,
1436 .iidr_mask = 0xffff0fff,
1437 .init = its_quirk_cavium_22375,
1438 },
1439 {
1440 .desc = "ITS: Rockchip erratum RK3566 ~ RK3588",
1441 .iidr = 0x0201743b,
1442 .iidr_mask = 0xffffffff,
1443 .init = its_enable_rockchip,
1444 },
1445 {
1446 .desc = "ITS: non-coherent attribute",
1447 .compatible = "arm,gic-v3-its",
1448 .init = its_set_non_coherent,
1449 },
1450 { /* sentinel */ }
1451 };
1452
1453 static const struct rt_ofw_node_id gicv3_its_ofw_match[] =
1454 {
1455 { .compatible = "arm,gic-v3-its" },
1456 { /* sentinel */ }
1457 };
1458
gicv3_its_ofw_probe(struct rt_ofw_node * np,const struct rt_ofw_node_id * id)1459 rt_err_t gicv3_its_ofw_probe(struct rt_ofw_node *np, const struct rt_ofw_node_id *id)
1460 {
1461 rt_err_t err = -RT_EEMPTY;
1462 struct rt_ofw_node *its_np;
1463 struct gicv3_its *its, *its_next;
1464
1465 rt_ofw_foreach_available_child_node(np, its_np)
1466 {
1467 if (!rt_ofw_node_match(its_np, gicv3_its_ofw_match))
1468 {
1469 continue;
1470 }
1471
1472 if (!rt_ofw_prop_read_bool(its_np, "msi-controller"))
1473 {
1474 continue;
1475 }
1476
1477 if (!(its = rt_calloc(1, sizeof(struct gicv3_its))))
1478 {
1479 rt_ofw_node_put(its_np);
1480
1481 err = -RT_ENOMEM;
1482 goto _free_all;
1483 }
1484
1485 its->base = rt_ofw_iomap(its_np, 0);
1486
1487 if (!its->base)
1488 {
1489 LOG_E("%s: IO map failed", rt_ofw_node_full_name(its_np));
1490 its_init_fail(its);
1491 continue;
1492 }
1493
1494 /*
1495 * Make sure ALL the ITS are reset before we probe any,
1496 * as they may be sharing memory
1497 */
1498 for (int i = 0; i < GITS_BASER_NR_REGS; ++i)
1499 {
1500 its_writeq(its, GITS_BASER + (i << 3), 0);
1501 }
1502
1503 its->np = its_np;
1504 rt_list_init(&its->list);
1505 rt_list_insert_before(&its_nodes, &its->list);
1506 }
1507
1508 if (!rt_list_isempty(&its_nodes))
1509 {
1510 if ((err = its_lpi_table_init(rt_ofw_data(np))))
1511 {
1512 goto _free_all;
1513 }
1514 }
1515
1516 rt_list_for_each_entry_safe(its, its_next, &its_nodes, list)
1517 {
1518 rt_uint32_t ctlr;
1519
1520 its->base_phy = rt_kmem_v2p(its->base);
1521 its->gic = rt_ofw_data(np);
1522
1523 gic_common_init_quirk_hw(HWREG32(its->base + GITS_IIDR), _its_quirks, its);
1524 gic_common_init_quirk_ofw(its->np, _its_quirks, its);
1525
1526 if ((err = its_cmd_queue_init(its)))
1527 {
1528 goto _fail;
1529 }
1530 rt_spin_lock_init(&its->cmd_lock);
1531
1532 if ((err = its_table_init(its)))
1533 {
1534 goto _fail;
1535 }
1536
1537 for (int i = 0; i < RT_CPUS_NR; ++i)
1538 {
1539 its->collections[i].target_address = ~0ULL;
1540 }
1541
1542 ctlr = its_readl(its, GITS_CTLR);
1543 ctlr |= GITS_CTLR_ENABLE;
1544 its_writel(its, GITS_CTLR, ctlr);
1545
1546 its->parent.priv_data = its;
1547 its->parent.ops = &gicv3_its_ops;
1548
1549 rt_pic_linear_irq(&its->parent, its->gic->lpi_nr);
1550 rt_pic_user_extends(&its->parent);
1551
1552 its_np = its->np;
1553 rt_ofw_data(its_np) = &its->parent;
1554 rt_ofw_node_set_flag(its_np, RT_OFW_F_READLY);
1555
1556 continue;
1557
1558 _fail:
1559 its_init_fail(its);
1560
1561 if (err == -RT_ENOMEM)
1562 {
1563 break;
1564 }
1565 }
1566
1567 if (rt_list_isempty(&its_nodes) && lpis_vectors)
1568 {
1569 rt_free(lpis_vectors);
1570 rt_free_align(lpi_table);
1571 rt_free_align(lpi_pending_table);
1572 lpis_vectors = RT_NULL;
1573 }
1574
1575 return err;
1576
1577 _free_all:
1578 rt_list_for_each_entry_safe(its, its_next, &its_nodes, list)
1579 {
1580 rt_free(its);
1581 rt_list_remove(&its->list);
1582 }
1583
1584 return err;
1585 }
1586