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