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