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