1 /*
2 * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include <sched/sched.h>
13 #include <sched/fpu.h>
14 #include <common/kprint.h>
15 #include <common/vars.h>
16 #include <common/macro.h>
17 #include <common/types.h>
18 #include <common/lock.h>
19 #include <arch/boot.h>
20 #include <arch/machine/smp.h>
21 #include <arch/machine/pmu.h>
22 #include <arch/mm/page_table.h>
23 #include <arch/mmu.h>
24 #include <mm/mm.h>
25 #include <io/uart.h>
26 #include <machine.h>
27 #include <irq/irq.h>
28 #include <object/thread.h>
29 #ifdef CHCORE_OH_TEE
30 #include <arch/trustzone/smc.h>
31 #include <arch/trustzone/tlogger.h>
32 #endif /* CHCORE_OH_TEE */
33
34 ALIGN(STACK_ALIGNMENT)
35 char cpu_stacks[PLAT_CPU_NUM][CPU_STACK_SIZE];
36 struct lock big_kernel_lock;
37
38 ALIGN(PAGE_SIZE)
39 char empty_page[4096] = {0};
40
41 /* Kernel Test */
42 void run_test(void);
43
44 void init_fpu_owner_locks(void);
45
46 /*
47 * @boot_flag is boot flag addresses for smp;
48 * @info is now only used as board_revision for rpi4.
49 */
main(paddr_t boot_flag,void * info)50 void main(paddr_t boot_flag, void *info)
51 {
52 u32 ret = 0;
53
54 #ifdef CHCORE_OH_TEE
55 teeos_cfg_init(boot_flag);
56 #endif /* CHCORE_OH_TEE */
57
58 /* Init big kernel lock */
59 ret = lock_init(&big_kernel_lock);
60 kinfo("[ChCore] lock init finished\n");
61 BUG_ON(ret != 0);
62
63 /* Init uart: no need to init the uart again */
64 uart_init();
65 kinfo("[ChCore] uart init finished\n");
66
67 /* Init per_cpu info */
68 init_per_cpu_info(0);
69 kinfo("[ChCore] per-CPU info init finished\n");
70
71 /* Init mm */
72 mm_init(info);
73
74 kinfo("[ChCore] mm init finished\n");
75
76 /* Mapping KSTACK into kernel page table. */
77 map_range_in_pgtbl_kernel((void *)((unsigned long)boot_ttbr1_l0 + KBASE),
78 KSTACKx_ADDR(0),
79 (unsigned long)(cpu_stacks[0]) - KBASE,
80 CPU_STACK_SIZE,
81 VMR_READ | VMR_WRITE);
82
83 /* Init exception vector */
84 arch_interrupt_init();
85 timer_init();
86 kinfo("[ChCore] interrupt init finished\n");
87
88 /* Enable PMU by setting PMCR_EL0 register */
89 pmu_init();
90 kinfo("[ChCore] pmu init finished\n");
91
92 /* Init scheduler with specified policy */
93 #if defined(CHCORE_KERNEL_RT) || defined(CHCORE_OH_TEE)
94 sched_init(&pbrr);
95 #else
96 sched_init(&rr);
97 #endif
98 kinfo("[ChCore] sched init finished\n");
99
100 init_fpu_owner_locks();
101
102 #ifndef CHCORE_OH_TEE
103 /* Other cores are busy looping on the boot_flag, wake up those cores */
104 enable_smp_cores(boot_flag);
105 kinfo("[ChCore] boot multicore finished\n");
106 #endif /* CHCORE_OH_TEE */
107
108 #ifdef CHCORE_OH_TEE
109 smc_init();
110 kinfo("[ChCore] SMC init finished\n");
111 tmp_tlogger_init();
112 kinfo("[ChCore] tmp tlogger init finished\n");
113 #endif /* CHCORE_OH_TEE */
114
115 #ifdef CHCORE_KERNEL_TEST
116 kinfo("[ChCore] kernel tests start\n");
117 run_test();
118 kinfo("[ChCore] kernel tests done\n");
119 #endif /* CHCORE_KERNEL_TEST */
120
121 #if FPU_SAVING_MODE == LAZY_FPU_MODE
122 disable_fpu_usage();
123 #endif
124
125 /* Create initial thread here, which use the `init.bin` */
126 create_root_thread();
127 kinfo("[ChCore] create initial thread done\n");
128
129 /* Leave the scheduler to do its job */
130 sched();
131
132 /* Context switch to the picked thread */
133 eret_to_thread(switch_context());
134
135 /* Should provide panic and use here */
136 BUG("[FATAL] Should never be here!\n");
137 }
138
secondary_start(u32 cpuid)139 void secondary_start(u32 cpuid)
140 {
141 /* Init per_cpu info */
142 init_per_cpu_info(cpuid);
143
144 /* Mapping KSTACK into kernel page table. */
145 map_range_in_pgtbl_kernel((void *)((unsigned long)boot_ttbr1_l0 + KBASE),
146 KSTACKx_ADDR(cpuid),
147 (unsigned long)(cpu_stacks[cpuid]) - KBASE,
148 CPU_STACK_SIZE,
149 VMR_READ | VMR_WRITE);
150
151 arch_interrupt_init_per_cpu();
152
153 /* Set the cpu status to inform the primary cpu */
154 cpu_status[cpuid] = cpu_run;
155
156 timer_init();
157 pmu_init();
158
159 #ifdef CHCORE_KERNEL_TEST
160 run_test();
161 #endif /* CHCORE_KERNEL_TEST */
162
163 #if FPU_SAVING_MODE == LAZY_FPU_MODE
164 disable_fpu_usage();
165 #endif
166
167 sched();
168 eret_to_thread(switch_context());
169 }
170