1 #include "rtconfig.h"
2 #if defined(TARGET_ARMV8_AARCH64)
3 #include <rthw.h>
4 #include <rtthread.h>
5 #include "interrupt.h"
6 #include "gic.h"
7 #include "gicv3.h"
8 #include "ioremap.h"
9 #include "phytium_cpu.h"
10 #include "ftypes.h"
11 #include "fparameters.h"
12 
13 struct arm_gic *phytium_gic_table;
14 
15 extern struct rt_irq_desc isr_table[MAX_HANDLERS];
16 
arm_gic_redist_address_set(rt_uint64_t index,rt_uint64_t redist_addr,int cpu_id)17 int arm_gic_redist_address_set(rt_uint64_t index, rt_uint64_t redist_addr, int cpu_id)
18 {
19     RT_ASSERT(index < ARM_GIC_MAX_NR);
20 
21     if (cpu_id == 0)
22     {
23         rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, &cpu_id, sizeof(cpu_id));
24     }
25 
26     phytium_gic_table[index].redist_hw_base[cpu_id] = redist_addr;
27 
28     return 0;
29 }
30 
arm_gicv3_wait_rwp(rt_uint64_t index,rt_uint64_t irq)31 static int arm_gicv3_wait_rwp(rt_uint64_t index, rt_uint64_t irq)
32 {
33     rt_uint64_t rwp_bit;
34     rt_uint64_t base;
35 
36     RT_ASSERT(index < ARM_GIC_MAX_NR);
37 
38     if (irq < 32)
39     {
40         rt_int32_t cpu_id = rt_hw_cpu_id();
41 
42         base = phytium_gic_table[index].redist_hw_base[cpu_id];
43         rwp_bit = GICR_CTLR_RWP;
44     }
45     else
46     {
47         base = phytium_gic_table[index].dist_hw_base;
48         rwp_bit = GICD_CTLR_RWP;
49     }
50 
51     while (HWREG32(base) & rwp_bit)
52     {
53     }
54 
55     return 0;
56 }
57 
phytium_aarch64_arm_gic_redist_init()58 int phytium_aarch64_arm_gic_redist_init()
59 {
60     rt_uint64_t cpu_id = rt_hw_cpu_id();
61     rt_uint64_t redist_base = phytium_gic_table[0].redist_hw_base[cpu_id];
62 
63     /* redistributor enable */
64     GIC_RDIST_WAKER(redist_base) &= ~(1 << 1);
65     while (GIC_RDIST_WAKER(redist_base) & (1 << 2))
66     {
67     }
68 
69     /* Disable all sgi and ppi interrupt */
70     GIC_RDISTSGI_ICENABLER0(redist_base) = 0xffffffff;
71     arm_gicv3_wait_rwp(0, 0);
72 
73     /* Clear all inetrrupt pending */
74     GIC_RDISTSGI_ICPENDR0(redist_base) = 0xffffffff;
75 
76     /* the corresponding interrupt is Group 1 or Non-secure Group 1. */
77     GIC_RDISTSGI_IGROUPR0(redist_base, 0) = 0xffffffff;
78     GIC_RDISTSGI_IGRPMODR0(redist_base, 0) = 0xffffffff;
79 
80     /* Configure default priorities for SGI 0:15 and PPI 16:31. */
81     for (int i = 0; i < 32; i += 4)
82     {
83         GIC_RDISTSGI_IPRIORITYR(redist_base, i) = 0xa0a0a0a0U;
84     }
85 
86     /* Trigger level for PPI interrupts*/
87     GIC_RDISTSGI_ICFGR1(redist_base) = 0;
88 
89     return 0;
90 }
91 
phytium_interrupt_init(void)92 void phytium_interrupt_init(void)
93 {
94     rt_uint64_t gic_cpu_base;
95     rt_uint64_t gic_dist_base;
96     rt_uint64_t gic_irq_start;
97 
98     phytium_gic_table = (struct arm_gic *)arm_gic_get_gic_table_addr();
99     /* initialize vector table */
100     rt_hw_vector_init();
101 
102     /* initialize exceptions table */
103     rt_memset(isr_table, 0x00, sizeof(isr_table));
104 
105 #if defined(RT_USING_SMART)
106     gic_dist_base = (rt_uint64_t)rt_ioremap((void *)platform_get_gic_dist_base(), 0x40000);
107     gic_cpu_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_cpu_base(), 0x1000);
108 #else
109     gic_dist_base = platform_get_gic_dist_base();
110     gic_cpu_base = platform_get_gic_cpu_base();
111 #endif
112 
113     gic_irq_start = 0;
114     arm_gic_dist_init(0, gic_dist_base, gic_irq_start);
115     arm_gic_cpu_init(0, gic_cpu_base);
116     arm_gic_redist_address_set(0, platform_get_gic_redist_base(), 0);
117 
118     phytium_aarch64_arm_gic_redist_init();
119 }
120 #endif
121