1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Email: opensource_embedded@phytium.com.cn
7 *
8 * Change Logs:
9 * Date Author Notes
10 * 2022-10-26 huanghe first commit
11 * 2022-10-26 zhugengyu support aarch64
12 * 2023-07-26 huanghe update psci uage
13 *
14 */
15
16 #include <rtthread.h>
17 #include "board.h"
18 #include <gicv3.h>
19 #include "rtconfig.h"
20 #include "phytium_cpu.h"
21
22 #if defined(TARGET_ARMV8_AARCH64)
23 #include "cpuport.h"
24 #include "gtimer.h"
25 #include "mmu.h"
26 #include "cp15.h"
27 #endif
28
29 #ifdef RT_USING_SMP
30 #include <interrupt.h>
31 #include "phytium_interrupt.h"
32
33 #if defined(TARGET_ARMV8_AARCH64)
34 #include "psci.h"
35 extern void _secondary_cpu_entry(void);
36 #else
37 extern void rt_secondary_cpu_entry(void);
38 #endif
39
40 #include "fpsci.h"
41 rt_uint64_t rt_cpu_mpidr_early[] =
42 {
43 #if defined(TARGET_PE2202)
44 [0] = RT_CORE_AFF(0),
45 [1] = RT_CORE_AFF(1),
46 #elif defined(TARGET_PE2204)
47 [0] = RT_CORE_AFF(0),
48 [1] = RT_CORE_AFF(1),
49 [2] = RT_CORE_AFF(2),
50 [3] = RT_CORE_AFF(3),
51 #elif defined(TARGET_PD2408)
52 [0] = RT_CORE_AFF(0),
53 [1] = RT_CORE_AFF(1),
54 [2] = RT_CORE_AFF(2),
55 [3] = RT_CORE_AFF(3),
56 [4] = RT_CORE_AFF(4),
57 [5] = RT_CORE_AFF(5),
58 [6] = RT_CORE_AFF(6),
59 [7] = RT_CORE_AFF(7),
60 #endif
61 [RT_CPUS_NR] = 0
62 };
63
64 extern int rt_hw_timer_init(void);
65
rt_hw_secondary_cpu_up(void)66 void rt_hw_secondary_cpu_up(void)
67 {
68 rt_uint32_t i;
69 rt_uint32_t cpu_mask = 0;
70 int cpu_id;
71 cpu_id = rt_hw_cpu_id();
72 rt_kprintf("rt_hw_secondary_cpu_up is processing \r\n");
73 for (i = 0; i < RT_CPUS_NR; i++)
74 {
75 if (i == cpu_id)
76 {
77 continue;
78 }
79 cpu_mask = (1 << phytium_cpu_id_mapping(i));
80
81 #if defined(TARGET_ARMV8_AARCH64)
82 /* code */
83 char *entry = (char *)_secondary_cpu_entry;
84 entry += PV_OFFSET;
85 FPsciCpuMaskOn(cpu_mask, (uintptr)entry);
86 __DSB();
87 #else
88 /* code */
89 char *entry = (char *)rt_secondary_cpu_entry;
90 entry += PV_OFFSET;
91 FPsciCpuMaskOn(cpu_mask, (uintptr)entry);
92 __asm__ volatile("dsb" ::: "memory");
93 #endif
94
95 }
96 }
97
98 /**
99 * This function will initialize board
100 */
101 extern size_t MMUTable[];
102
rt_hw_secondary_cpu_bsp_start(void)103 void rt_hw_secondary_cpu_bsp_start(void)
104 {
105 /* spin lock init */
106 rt_hw_spin_lock(&_cpus_lock);
107
108 /* mmu init */
109 #if defined(TARGET_ARMV8_AARCH64)
110 extern unsigned long MMUTable[];
111 rt_hw_mmu_ktbl_set((unsigned long)MMUTable);
112 #else
113 rt_uint32_t mmutable_p;
114 mmutable_p = (rt_uint32_t)MMUTable + (rt_uint32_t)PV_OFFSET ;
115 rt_hw_mmu_switch((void*)mmutable_p) ;
116 #endif
117
118 /* vector init */
119 rt_hw_vector_init();
120
121 /* interrupt init */
122 #if defined(TARGET_ARMV8_AARCH64)
123 arm_gic_cpu_init(0, 0);
124 arm_gic_redist_address_set(0, platform_get_gic_redist_base(), rt_hw_cpu_id());
125 phytium_aarch64_arm_gic_redist_init();
126 #else
127 arm_gic_cpu_init(0);
128 arm_gic_redist_address_set(0, platform_get_gic_redist_base(), rt_hw_cpu_id());
129 arm_gic_redist_init(0);
130 #endif
131
132 /* gtimer init */
133 #if defined(TARGET_ARMV8_AARCH64)
134 rt_hw_gtimer_init();
135 #else
136 rt_hw_timer_init();
137 #endif
138 rt_hw_interrupt_umask(RT_SCHEDULE_IPI);
139
140 /* start scheduler */
141 rt_kprintf("\rcall cpu %d on success\n", rt_hw_cpu_id());
142 rt_hw_secondary_cpu_idle_exec();
143 rt_system_scheduler_start();
144 }
145
rt_hw_secondary_cpu_idle_exec(void)146 void rt_hw_secondary_cpu_idle_exec(void)
147 {
148 #if defined(TARGET_ARMV8_AARCH64)
149 __WFE();
150 #else
151 asm volatile("wfe" ::
152 : "memory", "cc");
153 #endif
154 }
155
156 #endif
157