• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <common/vars.h>
13 #include <common/kprint.h>
14 #include <mm/mm.h>
15 #include <arch/machine/smp.h>
16 #include <arch/mmu.h>
17 #include <common/types.h>
18 #include <arch/tools.h>
19 #include <irq/ipi.h>
20 
21 volatile char cpu_status[PLAT_CPU_NUM] = {cpu_hang};
22 
23 struct per_cpu_info cpu_info[PLAT_CPU_NUM] __attribute__((aligned(64)));
24 u64 ctr_el0;
25 
enable_smp_cores(paddr_t boot_flag)26 void enable_smp_cores(paddr_t boot_flag)
27 {
28     int i = 0;
29     long *secondary_boot_flag;
30 
31     /* Set current cpu status */
32     cpu_status[smp_get_cpu_id()] = cpu_run;
33     secondary_boot_flag = (long *)phys_to_virt(boot_flag);
34     for (i = 0; i < PLAT_CPU_NUM; i++) {
35         secondary_boot_flag[i] = 1;
36         flush_dcache_area((u64)secondary_boot_flag,
37                           (u64)sizeof(u64) * PLAT_CPU_NUM);
38         asm volatile("dsb sy");
39         while (cpu_status[i] == cpu_hang)
40             ;
41         kinfo("CPU %d is active\n", i);
42     }
43     /* wait all cpu to boot */
44     kinfo("All %d CPUs are active\n", PLAT_CPU_NUM);
45     init_ipi_data();
46 }
47 
smp_get_cpu_id(void)48 inline u32 smp_get_cpu_id(void)
49 {
50     return get_per_cpu_info() - cpu_info;
51 }
52 
get_per_cpu_info(void)53 inline struct per_cpu_info *get_per_cpu_info(void)
54 {
55     struct per_cpu_info *info;
56 
57     asm volatile("mrs %0, tpidr_el1" : "=r"(info));
58 
59     return info;
60 }
61 
read_ctr(void)62 static inline u64 read_ctr(void)
63 {
64     u64 reg;
65 
66     asm volatile("mrs %0, ctr_el0" : "=r"(reg)::"memory");
67     return reg;
68 }
69 
init_per_cpu_info(u32 cpuid)70 void init_per_cpu_info(u32 cpuid)
71 {
72     struct per_cpu_info *info;
73 
74     if (cpuid == 0)
75         ctr_el0 = read_ctr();
76 
77     info = &cpu_info[cpuid];
78 
79     info->cur_exec_ctx = 0;
80 
81     info->cpu_stack = (char *)(KSTACKx_ADDR(cpuid) + CPU_STACK_SIZE);
82 
83     info->fpu_owner = NULL;
84     info->fpu_disable = 0;
85 
86     asm volatile("msr tpidr_el1, %0" ::"r"(info));
87 }
88 
smp_get_mpidr(void)89 u64 smp_get_mpidr(void)
90 {
91     u64 mpidr = 0;
92 
93     asm volatile("mrs %0, mpidr_el1" : "=r"(mpidr));
94     return mpidr;
95 }
96 
smp_print_status(u32 cpuid)97 void smp_print_status(u32 cpuid)
98 {
99 }
100