diff --git a/arch/arm/arm/BUILD.gn b/arch/arm/arm/BUILD.gn index 11f3115b..86153251 100644 --- a/arch/arm/arm/BUILD.gn +++ b/arch/arm/arm/BUILD.gn @@ -49,6 +49,7 @@ kernel_module(module_name) { "src/strncpy_from_user.c", "src/strnlen_user.c", "src/user_copy.c", + "src/smp.c", ] if (LOSCFG_ARCH_ARM_VER == "armv7-a") { diff --git a/arch/arm/arm/include/los_hw_cpu.h b/arch/arm/arm/include/los_hw_cpu.h index 425ca449..0234052f 100644 --- a/arch/arm/arm/include/los_hw_cpu.h +++ b/arch/arm/arm/include/los_hw_cpu.h @@ -53,6 +53,8 @@ extern "C" { #define ISB __asm__ volatile("isb" ::: "memory") #define WFI __asm__ volatile("wfi" ::: "memory") #define BARRIER __asm__ volatile("":::"memory") +#define WFE __asm__ volatile("wfe" ::: "memory") +#define SEV __asm__ volatile("sev" ::: "memory") #define ARM_SYSREG_READ(REG) \ ({ \ diff --git a/arch/arm/arm/include/smp.h b/arch/arm/arm/include/smp.h new file mode 100644 index 00000000..bc3b335d --- /dev/null +++ b/arch/arm/arm/include/smp.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ARCH_SMP_H +#define _ARCH_SMP_H + +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +struct SmpOps { + INT32 (*SmpCpuOn)(UINT32 cpuNum, UINTPTR startEntry); /* The startEntry is physical addr. */ +}; + +typedef VOID (*ArchCpuStartFunc)(VOID *arg); + +VOID HalArchCpuOn(UINT32 cpuNum, ArchCpuStartFunc func, struct SmpOps *ops, VOID *arg); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _ARCH_SMP_H */ + diff --git a/arch/arm/arm/src/smp.c b/arch/arm/arm/src/smp.c new file mode 100644 index 00000000..a747a744 --- /dev/null +++ b/arch/arm/arm/src/smp.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "smp.h" +#include "arch_config.h" +#include "los_base.h" +#include "los_hw.h" +#include "los_atomic.h" +#include "los_arch_mmu.h" +#include "los_init_pri.h" +#include "gic_common.h" +#include "los_task_pri.h" + +#ifdef LOSCFG_KERNEL_SMP + +extern VOID reset_vector(VOID); + +struct OsCpuInit { + ArchCpuStartFunc cpuStart; + VOID *arg; + Atomic initFlag; +}; + +STATIC struct OsCpuInit g_cpuInit[CORE_NUM - 1] = {0}; + +VOID HalArchCpuOn(UINT32 cpuNum, ArchCpuStartFunc func, struct SmpOps *ops, VOID *arg) +{ + struct OsCpuInit *cpuInit = &g_cpuInit[cpuNum - 1]; + UINTPTR startEntry = (UINTPTR)&reset_vector - KERNEL_VMM_BASE + SYS_MEM_BASE; + INT32 ret = 0; + + cpuInit->cpuStart = func; + cpuInit->arg = arg; + cpuInit->initFlag = 0; + + DCacheFlushRange((UINTPTR)cpuInit, (UINTPTR)cpuInit + sizeof(struct OsCpuInit)); + + LOS_ASSERT(ops != NULL); + + + ret = ops->SmpCpuOn(cpuNum, startEntry); + if (ret < 0) { + PRINT_ERR("cpu start failed, cpu num: %u, ret: %d\n", cpuNum, ret); + return; + } + + while (!LOS_AtomicRead(&cpuInit->initFlag)) { + WFE; + } +} + +VOID HalSecondaryCpuStart(VOID) +{ + UINT32 cpuid = ArchCurrCpuid(); + struct OsCpuInit *cpuInit = &g_cpuInit[cpuid - 1]; + + OsCurrTaskSet(OsGetMainTask()); + + LOS_AtomicSet(&cpuInit->initFlag, 1); + SEV; + +#ifdef LOSCFG_KERNEL_MMU + OsArchMmuInitPerCPU(); +#endif + + /* store each core's hwid */ + CPU_MAP_SET(cpuid, OsHwIDGet()); + HalIrqInitPercpu(); + OsInitCall(LOS_INIT_LEVEL_ARCH); + + cpuInit->cpuStart(cpuInit->arg); + + while (1) { + WFI; + } +} +#endif + diff --git a/arch/arm/arm/src/startup/reset_vector_mp.S b/arch/arm/arm/src/startup/reset_vector_mp.S index 2ac92e1a..7f7e2962 100644 --- a/arch/arm/arm/src/startup/reset_vector_mp.S +++ b/arch/arm/arm/src/startup/reset_vector_mp.S @@ -28,6 +28,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #define ASSEMBLY #include "arch_config.h" #include "los_vm_boot.h" @@ -54,6 +55,8 @@ .extern __stack_chk_guard_setup .extern g_firstPageTable .extern g_mmuJumpPageTable + .extern g_archMmuInitMapping + .extern HalSecondaryCpuStart .equ MPIDR_CPUID_MASK, 0xffU @@ -77,14 +80,6 @@ bl excstack_magic .endm -/* param0 is physical address, param1 virtual address, param2 is sizes, param3 is flag */ -.macro PAGE_TABLE_SET param0, param1, param2, param3 - ldr r6, =\param0 - ldr r7, =\param1 - ldr r8, =\param2 - ldr r10, =\param3 - bl page_table_build -.endm .code 32 .section ".vectors","ax" @@ -184,12 +179,15 @@ reloc_img_to_bottom_done: mov r2, #MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS bl memset_optimized /* optimized memset since r0 is 64-byte aligned */ - PAGE_TABLE_SET SYS_MEM_BASE, KERNEL_VMM_BASE, KERNEL_VMM_SIZE, MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS - PAGE_TABLE_SET SYS_MEM_BASE, UNCACHED_VMM_BASE, UNCACHED_VMM_SIZE, MMU_INITIAL_MAP_NORMAL_NOCACHE - PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_DEVICE_BASE, PERIPH_DEVICE_SIZE, MMU_INITIAL_MAP_DEVICE - PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_CACHED_BASE, PERIPH_CACHED_SIZE, MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS - PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_UNCACHED_BASE, PERIPH_UNCACHED_SIZE, MMU_INITIAL_MAP_STRONGLY_ORDERED - + ldr r5, =g_archMmuInitMapping + add r5, r5, r11 +init_mmu_loop: + ldmia r5!, {r6-r10} /* r6 = phys, r7 = virt, r8 = size, r9 = mmu_flags, r10 = name */ + cmp r8, 0 /* if size = 0, the mmu init done */ + beq init_mmu_done + bl page_table_build + b init_mmu_loop +init_mmu_done: orr r8, r4, #MMU_TTBRx_FLAGS /* r8 = r4 and set cacheable attributes on translation walk */ ldr r4, =g_mmuJumpPageTable /* r4: jump pagetable vaddr */ add r4, r4, r11 @@ -205,9 +203,7 @@ reloc_img_to_bottom_done: str r12, [r4, r7, lsr #(20 - 2)] /* jumpTable[paIndex] = pt entry */ rsb r7, r11, r6, lsl #20 /* r7: va */ str r12, [r4, r7, lsr #(20 - 2)] /* jumpTable[vaIndex] = pt entry */ -#endif - bl _bootaddr_setup -#ifdef LOSCFG_KERNEL_MMU + bl mmu_setup /* set up the mmu */ #endif /* clear out the interrupt and exception stack and set magic num to check the overflow */ @@ -317,6 +313,7 @@ reset_platform: mov r0, #0 mov pc, r0 // Jump to reset vector #endif + cpu_start: #ifdef LOSCFG_KERNEL_MMU ldr r4, =g_firstPageTable /* r4 = physical address of translation table and clear it */ @@ -330,7 +327,8 @@ cpu_start: bl mmu_setup #endif - bl secondary_cpu_start + + bl HalSecondaryCpuStart b . secondary_cpu_init: @@ -370,9 +368,9 @@ sp_set: */ #ifdef LOSCFG_KERNEL_MMU page_table_build: - mov r9, r6 - bfc r9, #20, #12 /* r9: pa % MB */ - add r8, r8, r9 + mov r10, r6 + bfc r10, #20, #12 /* r9: pa % MB */ + add r8, r8, r10 add r8, r8, #(1 << 20) sub r8, r8, #1 lsr r6, #20 /* r6 = physical address / MB */ @@ -380,7 +378,7 @@ page_table_build: lsr r8, #20 /* r8 = roundup(size, MB) */ page_table_build_loop: - orr r12, r10, r6, lsl #20 /* r12: flags | physAddr */ + orr r12, r9, r6, lsl #20 /* r12: flags | physAddr */ str r12, [r4, r7, lsl #2] /* gPgTable[l1Index] = physAddr | flags */ add r6, #1 /* physAddr+ */ add r7, #1 /* l1Index++ */ @@ -422,24 +420,6 @@ excstack_magic_loop: blt excstack_magic_loop bx lr -/* - * 0xe51ff004 = "ldr pc, [pc, #-4]" - * next addr value will be the real booting addr - */ -_bootaddr_setup: - mov r0, #0 - ldr r1, =0xe51ff004 - str r1, [r0] - - add r0, r0, #4 - ldr r1, =SYS_MEM_BASE - str r1, [r0] - - dsb - isb - - bx lr - #ifdef LOSCFG_KERNEL_MMU memset_optimized: mov r3, r0 diff --git a/arch/arm/arm/src/startup/reset_vector_up.S b/arch/arm/arm/src/startup/reset_vector_up.S index 5d3b5f61..75994ac1 100644 --- a/arch/arm/arm/src/startup/reset_vector_up.S +++ b/arch/arm/arm/src/startup/reset_vector_up.S @@ -54,6 +54,7 @@ .extern __stack_chk_guard_setup .extern g_firstPageTable .extern g_mmuJumpPageTable + .extern g_archMmuInitMapping .equ MPIDR_CPUID_MASK, 0xffU @@ -77,14 +78,6 @@ bl excstack_magic .endm -/* param0 is physical address, param1 virtual address, param2 is sizes, param3 is flag */ -.macro PAGE_TABLE_SET param0, param1, param2, param3 - ldr r6, =\param0 - ldr r7, =\param1 - ldr r8, =\param2 - ldr r10, =\param3 - bl page_table_build -.endm .code 32 .section ".vectors","ax" @@ -161,12 +154,15 @@ reloc_img_to_bottom_done: mov r2, #MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS bl memset_optimized /* optimized memset since r0 is 64-byte aligned */ - PAGE_TABLE_SET SYS_MEM_BASE, KERNEL_VMM_BASE, KERNEL_VMM_SIZE, MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS - PAGE_TABLE_SET SYS_MEM_BASE, UNCACHED_VMM_BASE, UNCACHED_VMM_SIZE, MMU_INITIAL_MAP_NORMAL_NOCACHE - PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_DEVICE_BASE, PERIPH_DEVICE_SIZE, MMU_INITIAL_MAP_DEVICE - PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_CACHED_BASE, PERIPH_CACHED_SIZE, MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS - PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_UNCACHED_BASE, PERIPH_UNCACHED_SIZE, MMU_INITIAL_MAP_STRONGLY_ORDERED - + ldr r5, =g_archMmuInitMapping + add r5, r5, r11 +init_mmu_loop: + ldmia r5!, {r6-r10} /* r6 = phys, r7 = virt, r8 = size, r9 = mmu_flags, r10 = name */ + cmp r8, 0 /* if size = 0, the mmu init done */ + beq init_mmu_done + bl page_table_build + b init_mmu_loop +init_mmu_done: orr r8, r4, #MMU_TTBRx_FLAGS /* r8 = r4 and set cacheable attributes on translation walk */ ldr r4, =g_mmuJumpPageTable /* r4: jump pagetable vaddr */ add r4, r4, r11 @@ -231,9 +227,6 @@ warm_reset: LDR r0, =__exception_handlers MCR p15, 0, r0, c12, c0, 0 - cmp r11, #0 - bne cpu_start - clear_bss: ldr r0, =__bss_start ldr r2, =__bss_end @@ -310,11 +303,6 @@ reset_platform: mov r0, #0 mov pc, r0 // Jump to reset vector #endif -cpu_start: - bl secondary_cpu_start - b . - - /* * set sp for current cpu @@ -336,9 +324,9 @@ sp_set: */ #ifdef LOSCFG_KERNEL_MMU page_table_build: - mov r9, r6 - bfc r9, #20, #12 /* r9: pa % MB */ - add r8, r8, r9 + mov r10, r6 + bfc r10, #20, #12 /* r9: pa % MB */ + add r8, r8, r10 add r8, r8, #(1 << 20) sub r8, r8, #1 lsr r6, #20 /* r6 = physical address / MB */ @@ -346,7 +334,7 @@ page_table_build: lsr r8, #20 /* r8 = roundup(size, MB) */ page_table_build_loop: - orr r12, r10, r6, lsl #20 /* r12: flags | physAddr */ + orr r12, r9, r6, lsl #20 /* r12: flags | physAddr */ str r12, [r4, r7, lsl #2] /* gPgTable[l1Index] = physAddr | flags */ add r6, #1 /* physAddr+ */ add r7, #1 /* l1Index++ */ @@ -388,24 +376,6 @@ excstack_magic_loop: blt excstack_magic_loop bx lr -/* - * 0xe51ff004 = "ldr pc, [pc, #-4]" - * next addr value will be the real booting addr - */ -_bootaddr_setup: - mov r0, #0 - ldr r1, =0xe51ff004 - str r1, [r0] - - add r0, r0, #4 - ldr r1, =SYS_MEM_BASE - str r1, [r0] - - dsb - isb - - bx lr - #ifdef LOSCFG_KERNEL_MMU memset_optimized: mov r3, r0 diff --git a/kernel/base/BUILD.gn b/kernel/base/BUILD.gn index 769e93ed..a2ec0922 100644 --- a/kernel/base/BUILD.gn +++ b/kernel/base/BUILD.gn @@ -38,6 +38,7 @@ kernel_module(module_name) { "core/los_sys.c", "core/los_task.c", "core/los_tick.c", + "core/los_smp.c", "ipc/los_event.c", "ipc/los_futex.c", "ipc/los_ipcdebug.c", diff --git a/kernel/base/core/los_smp.c b/kernel/base/core/los_smp.c new file mode 100644 index 00000000..15002274 --- /dev/null +++ b/kernel/base/core/los_smp.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_smp.h" +#include "arch_config.h" +#include "los_atomic.h" +#include "los_task_pri.h" +#include "los_init_pri.h" +#include "los_process_pri.h" +#include "los_sched_pri.h" +#include "los_swtmr_pri.h" + +#ifdef LOSCFG_KERNEL_SMP +STATIC struct SmpOps *g_smpOps = NULL; + +STATIC VOID OsSmpSecondaryInit(VOID *arg) +{ + UNUSED(arg); + OsInitCall(LOS_INIT_LEVEL_PLATFORM); + + OsCurrProcessSet(OS_PCB_FROM_PID(OsGetKernelInitProcessID())); + OsInitCall(LOS_INIT_LEVEL_KMOD_BASIC); + +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE + OsSwtmrInit(); +#endif + + OsInitCall(LOS_INIT_LEVEL_KMOD_EXTENDED); + + OsIdleTaskCreate(); + OsInitCall(LOS_INIT_LEVEL_KMOD_TASK); + + OsSchedStart(); +} + +VOID LOS_SmpOpsSet(struct SmpOps *ops) +{ + g_smpOps = ops; +} + +VOID OsSmpInit(VOID) +{ + UINT32 cpuNum = 1; /* Start the secondary cpus. */ + + if (g_smpOps == NULL) { + PRINT_ERR("Must call the interface(LOS_SmpOpsSet) to register smp operations firstly!\n"); + return; + } + + for (; cpuNum < CORE_NUM; cpuNum++) { + HalArchCpuOn(cpuNum, OsSmpSecondaryInit, g_smpOps, 0); + } + + return; +} +#endif diff --git a/kernel/base/include/los_vm_boot.h b/kernel/base/include/los_vm_boot.h index 18e6b031..fb6e714a 100644 --- a/kernel/base/include/los_vm_boot.h +++ b/kernel/base/include/los_vm_boot.h @@ -57,6 +57,8 @@ typedef struct ArchMmuInitMapping { const char *name; } LosArchMmuInitMapping; +extern LosArchMmuInitMapping g_archMmuInitMapping[]; + extern UINTPTR g_vmBootMemBase; extern BOOL g_kHeapInited; diff --git a/kernel/include/los_smp.h b/kernel/include/los_smp.h new file mode 100644 index 00000000..e501f9c5 --- /dev/null +++ b/kernel/include/los_smp.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SMP_H +#define _LOS_SMP_H + +#include "smp.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +VOID LOS_SmpOpsSet(struct SmpOps *ops); +VOID OsSmpInit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SMP_H */ + diff --git a/platform/los_config.c b/platform/los_config.c index d99161ab..3096dc07 100644 --- a/platform/los_config.c +++ b/platform/los_config.c @@ -50,6 +50,7 @@ #include "los_task_pri.h" #include "los_tick.h" #include "los_vm_boot.h" +#include "los_smp.h" STATIC SystemRebootFunc g_rebootHook = NULL; @@ -65,9 +66,6 @@ SystemRebootFunc OsGetRebootHook(VOID) extern UINT32 OsSystemInit(VOID); extern VOID SystemInit(VOID); -#ifdef LOSCFG_KERNEL_SMP -extern VOID release_secondary_cores(VOID); -#endif LITE_OS_SEC_TEXT_INIT STATIC UINT32 EarliestInit(VOID) { @@ -266,7 +264,7 @@ LITE_OS_SEC_TEXT_INIT INT32 OsMain(VOID) OsInitCall(LOS_INIT_LEVEL_KMOD_EXTENDED); #ifdef LOSCFG_KERNEL_SMP - release_secondary_cores(); + OsSmpInit(); #endif OsInitCall(LOS_INIT_LEVEL_KMOD_TASK); diff --git a/platform/main.c b/platform/main.c index 7a9aa62c..02e7a948 100644 --- a/platform/main.c +++ b/platform/main.c @@ -30,117 +30,7 @@ */ #include "los_config.h" -#include "gic_common.h" -#include "los_arch_mmu.h" -#include "los_atomic.h" -#include "los_init_pri.h" -#include "los_printf.h" -#include "los_process_pri.h" #include "los_sched_pri.h" -#include "los_swtmr_pri.h" -#include "los_task_pri.h" - -#ifdef LOSCFG_KERNEL_SMP -STATIC Atomic g_ncpu = 1; -#endif - -LITE_OS_SEC_TEXT_INIT VOID secondary_cpu_start(VOID) -{ -#ifdef LOSCFG_KERNEL_SMP - UINT32 cpuid = ArchCurrCpuid(); - - OsCurrTaskSet(OsGetMainTask()); - - /* increase cpu counter and sync multi-core */ - LOS_AtomicInc(&g_ncpu); - while (LOS_AtomicRead(&g_ncpu) < LOSCFG_KERNEL_CORE_NUM) { - asm volatile("wfe"); - } - asm volatile("sev"); - - OsInitCall(LOS_INIT_LEVEL_VM_COMPLETE); - -#ifdef LOSCFG_KERNEL_MMU - OsArchMmuInitPerCPU(); -#endif - /* store each core's hwid */ - CPU_MAP_SET(cpuid, OsHwIDGet()); - HalIrqInitPercpu(); - OsInitCall(LOS_INIT_LEVEL_ARCH); - - OsInitCall(LOS_INIT_LEVEL_PLATFORM); - - OsCurrProcessSet(OS_PCB_FROM_PID(OsGetKernelInitProcessID())); - OsInitCall(LOS_INIT_LEVEL_KMOD_BASIC); - -#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE - OsSwtmrInit(); -#endif - - OsInitCall(LOS_INIT_LEVEL_KMOD_EXTENDED); - - OsIdleTaskCreate(); - OsInitCall(LOS_INIT_LEVEL_KMOD_TASK); - - OsSchedStart(); - while (1) { - __asm volatile("wfi"); - } -#endif -} - -#ifdef LOSCFG_KERNEL_SMP -#ifdef LOSCFG_TEE_ENABLE -#define TSP_CPU_ON 0xb2000011UL -STATIC INT32 raw_smc_send(UINT32 cmd) -{ - register UINT32 smc_id asm("r0") = cmd; - do { - asm volatile ( - "mov r0, %[a0]\n" - "smc #0\n" - : [a0] "+r"(smc_id) - ); - } while (0); - - return (INT32)smc_id; -} - -STATIC VOID trigger_secondary_cpu(VOID) -{ - (VOID)raw_smc_send(TSP_CPU_ON); -} - -LITE_OS_SEC_TEXT_INIT VOID release_secondary_cores(VOID) -{ - PRINT_RELEASE("releasing %u secondary cores\n", LOSCFG_KERNEL_SMP_CORE_NUM - 1); - - trigger_secondary_cpu(); - /* wait until all APs are ready */ - while (LOS_AtomicRead(&g_ncpu) < LOSCFG_KERNEL_CORE_NUM) { - asm volatile("wfe"); - } -} -#else -#define CLEAR_RESET_REG_STATUS(regval) (regval) &= ~(1U << 2) -LITE_OS_SEC_TEXT_INIT VOID release_secondary_cores(VOID) -{ - UINT32 regval; - - PRINT_RELEASE("releasing %u secondary cores\n", LOSCFG_KERNEL_SMP_CORE_NUM - 1); - - /* clear the second cpu reset status */ - READ_UINT32(regval, PERI_CRG30_BASE); - CLEAR_RESET_REG_STATUS(regval); - WRITE_UINT32(regval, PERI_CRG30_BASE); - - /* wait until all APs are ready */ - while (LOS_AtomicRead(&g_ncpu) < LOSCFG_KERNEL_CORE_NUM) { - asm volatile("wfe"); - } -} -#endif /* LOSCFG_TEE_ENABLE */ -#endif /* LOSCFG_KERNEL_SMP */ LITE_OS_SEC_TEXT_INIT INT32 main(VOID) { @@ -150,7 +40,6 @@ LITE_OS_SEC_TEXT_INIT INT32 main(VOID) if (uwRet != LOS_OK) { return LOS_NOK; } - CPU_MAP_SET(0, OsHwIDGet()); OsSchedStart();