commit
40297a6dbc
|
@ -49,6 +49,7 @@ kernel_module(module_name) {
|
||||||
"src/strncpy_from_user.c",
|
"src/strncpy_from_user.c",
|
||||||
"src/strnlen_user.c",
|
"src/strnlen_user.c",
|
||||||
"src/user_copy.c",
|
"src/user_copy.c",
|
||||||
|
"src/smp.c",
|
||||||
]
|
]
|
||||||
|
|
||||||
if (LOSCFG_ARCH_ARM_VER == "armv7-a") {
|
if (LOSCFG_ARCH_ARM_VER == "armv7-a") {
|
||||||
|
|
|
@ -53,6 +53,8 @@ extern "C" {
|
||||||
#define ISB __asm__ volatile("isb" ::: "memory")
|
#define ISB __asm__ volatile("isb" ::: "memory")
|
||||||
#define WFI __asm__ volatile("wfi" ::: "memory")
|
#define WFI __asm__ volatile("wfi" ::: "memory")
|
||||||
#define BARRIER __asm__ volatile("":::"memory")
|
#define BARRIER __asm__ volatile("":::"memory")
|
||||||
|
#define WFE __asm__ volatile("wfe" ::: "memory")
|
||||||
|
#define SEV __asm__ volatile("sev" ::: "memory")
|
||||||
|
|
||||||
#define ARM_SYSREG_READ(REG) \
|
#define ARM_SYSREG_READ(REG) \
|
||||||
({ \
|
({ \
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ASSEMBLY
|
#define ASSEMBLY
|
||||||
#include "arch_config.h"
|
#include "arch_config.h"
|
||||||
#include "los_vm_boot.h"
|
#include "los_vm_boot.h"
|
||||||
|
@ -54,6 +55,8 @@
|
||||||
.extern __stack_chk_guard_setup
|
.extern __stack_chk_guard_setup
|
||||||
.extern g_firstPageTable
|
.extern g_firstPageTable
|
||||||
.extern g_mmuJumpPageTable
|
.extern g_mmuJumpPageTable
|
||||||
|
.extern g_archMmuInitMapping
|
||||||
|
.extern HalSecondaryCpuStart
|
||||||
|
|
||||||
.equ MPIDR_CPUID_MASK, 0xffU
|
.equ MPIDR_CPUID_MASK, 0xffU
|
||||||
|
|
||||||
|
@ -77,14 +80,6 @@
|
||||||
bl excstack_magic
|
bl excstack_magic
|
||||||
.endm
|
.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
|
.code 32
|
||||||
.section ".vectors","ax"
|
.section ".vectors","ax"
|
||||||
|
|
||||||
|
@ -184,12 +179,15 @@ reloc_img_to_bottom_done:
|
||||||
mov r2, #MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS
|
mov r2, #MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS
|
||||||
bl memset_optimized /* optimized memset since r0 is 64-byte aligned */
|
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
|
ldr r5, =g_archMmuInitMapping
|
||||||
PAGE_TABLE_SET SYS_MEM_BASE, UNCACHED_VMM_BASE, UNCACHED_VMM_SIZE, MMU_INITIAL_MAP_NORMAL_NOCACHE
|
add r5, r5, r11
|
||||||
PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_DEVICE_BASE, PERIPH_DEVICE_SIZE, MMU_INITIAL_MAP_DEVICE
|
init_mmu_loop:
|
||||||
PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_CACHED_BASE, PERIPH_CACHED_SIZE, MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS
|
ldmia r5!, {r6-r10} /* r6 = phys, r7 = virt, r8 = size, r9 = mmu_flags, r10 = name */
|
||||||
PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_UNCACHED_BASE, PERIPH_UNCACHED_SIZE, MMU_INITIAL_MAP_STRONGLY_ORDERED
|
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 */
|
orr r8, r4, #MMU_TTBRx_FLAGS /* r8 = r4 and set cacheable attributes on translation walk */
|
||||||
ldr r4, =g_mmuJumpPageTable /* r4: jump pagetable vaddr */
|
ldr r4, =g_mmuJumpPageTable /* r4: jump pagetable vaddr */
|
||||||
add r4, r4, r11
|
add r4, r4, r11
|
||||||
|
@ -205,9 +203,7 @@ reloc_img_to_bottom_done:
|
||||||
str r12, [r4, r7, lsr #(20 - 2)] /* jumpTable[paIndex] = pt entry */
|
str r12, [r4, r7, lsr #(20 - 2)] /* jumpTable[paIndex] = pt entry */
|
||||||
rsb r7, r11, r6, lsl #20 /* r7: va */
|
rsb r7, r11, r6, lsl #20 /* r7: va */
|
||||||
str r12, [r4, r7, lsr #(20 - 2)] /* jumpTable[vaIndex] = pt entry */
|
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 */
|
bl mmu_setup /* set up the mmu */
|
||||||
#endif
|
#endif
|
||||||
/* clear out the interrupt and exception stack and set magic num to check the overflow */
|
/* 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 r0, #0
|
||||||
mov pc, r0 // Jump to reset vector
|
mov pc, r0 // Jump to reset vector
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cpu_start:
|
cpu_start:
|
||||||
#ifdef LOSCFG_KERNEL_MMU
|
#ifdef LOSCFG_KERNEL_MMU
|
||||||
ldr r4, =g_firstPageTable /* r4 = physical address of translation table and clear it */
|
ldr r4, =g_firstPageTable /* r4 = physical address of translation table and clear it */
|
||||||
|
@ -330,7 +327,8 @@ cpu_start:
|
||||||
|
|
||||||
bl mmu_setup
|
bl mmu_setup
|
||||||
#endif
|
#endif
|
||||||
bl secondary_cpu_start
|
|
||||||
|
bl HalSecondaryCpuStart
|
||||||
b .
|
b .
|
||||||
|
|
||||||
secondary_cpu_init:
|
secondary_cpu_init:
|
||||||
|
@ -370,9 +368,9 @@ sp_set:
|
||||||
*/
|
*/
|
||||||
#ifdef LOSCFG_KERNEL_MMU
|
#ifdef LOSCFG_KERNEL_MMU
|
||||||
page_table_build:
|
page_table_build:
|
||||||
mov r9, r6
|
mov r10, r6
|
||||||
bfc r9, #20, #12 /* r9: pa % MB */
|
bfc r10, #20, #12 /* r9: pa % MB */
|
||||||
add r8, r8, r9
|
add r8, r8, r10
|
||||||
add r8, r8, #(1 << 20)
|
add r8, r8, #(1 << 20)
|
||||||
sub r8, r8, #1
|
sub r8, r8, #1
|
||||||
lsr r6, #20 /* r6 = physical address / MB */
|
lsr r6, #20 /* r6 = physical address / MB */
|
||||||
|
@ -380,7 +378,7 @@ page_table_build:
|
||||||
lsr r8, #20 /* r8 = roundup(size, MB) */
|
lsr r8, #20 /* r8 = roundup(size, MB) */
|
||||||
|
|
||||||
page_table_build_loop:
|
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 */
|
str r12, [r4, r7, lsl #2] /* gPgTable[l1Index] = physAddr | flags */
|
||||||
add r6, #1 /* physAddr+ */
|
add r6, #1 /* physAddr+ */
|
||||||
add r7, #1 /* l1Index++ */
|
add r7, #1 /* l1Index++ */
|
||||||
|
@ -422,24 +420,6 @@ excstack_magic_loop:
|
||||||
blt excstack_magic_loop
|
blt excstack_magic_loop
|
||||||
bx lr
|
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
|
#ifdef LOSCFG_KERNEL_MMU
|
||||||
memset_optimized:
|
memset_optimized:
|
||||||
mov r3, r0
|
mov r3, r0
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
.extern __stack_chk_guard_setup
|
.extern __stack_chk_guard_setup
|
||||||
.extern g_firstPageTable
|
.extern g_firstPageTable
|
||||||
.extern g_mmuJumpPageTable
|
.extern g_mmuJumpPageTable
|
||||||
|
.extern g_archMmuInitMapping
|
||||||
|
|
||||||
.equ MPIDR_CPUID_MASK, 0xffU
|
.equ MPIDR_CPUID_MASK, 0xffU
|
||||||
|
|
||||||
|
@ -77,14 +78,6 @@
|
||||||
bl excstack_magic
|
bl excstack_magic
|
||||||
.endm
|
.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
|
.code 32
|
||||||
.section ".vectors","ax"
|
.section ".vectors","ax"
|
||||||
|
|
||||||
|
@ -161,12 +154,15 @@ reloc_img_to_bottom_done:
|
||||||
mov r2, #MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS
|
mov r2, #MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS
|
||||||
bl memset_optimized /* optimized memset since r0 is 64-byte aligned */
|
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
|
ldr r5, =g_archMmuInitMapping
|
||||||
PAGE_TABLE_SET SYS_MEM_BASE, UNCACHED_VMM_BASE, UNCACHED_VMM_SIZE, MMU_INITIAL_MAP_NORMAL_NOCACHE
|
add r5, r5, r11
|
||||||
PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_DEVICE_BASE, PERIPH_DEVICE_SIZE, MMU_INITIAL_MAP_DEVICE
|
init_mmu_loop:
|
||||||
PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_CACHED_BASE, PERIPH_CACHED_SIZE, MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS
|
ldmia r5!, {r6-r10} /* r6 = phys, r7 = virt, r8 = size, r9 = mmu_flags, r10 = name */
|
||||||
PAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_UNCACHED_BASE, PERIPH_UNCACHED_SIZE, MMU_INITIAL_MAP_STRONGLY_ORDERED
|
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 */
|
orr r8, r4, #MMU_TTBRx_FLAGS /* r8 = r4 and set cacheable attributes on translation walk */
|
||||||
ldr r4, =g_mmuJumpPageTable /* r4: jump pagetable vaddr */
|
ldr r4, =g_mmuJumpPageTable /* r4: jump pagetable vaddr */
|
||||||
add r4, r4, r11
|
add r4, r4, r11
|
||||||
|
@ -231,9 +227,6 @@ warm_reset:
|
||||||
LDR r0, =__exception_handlers
|
LDR r0, =__exception_handlers
|
||||||
MCR p15, 0, r0, c12, c0, 0
|
MCR p15, 0, r0, c12, c0, 0
|
||||||
|
|
||||||
cmp r11, #0
|
|
||||||
bne cpu_start
|
|
||||||
|
|
||||||
clear_bss:
|
clear_bss:
|
||||||
ldr r0, =__bss_start
|
ldr r0, =__bss_start
|
||||||
ldr r2, =__bss_end
|
ldr r2, =__bss_end
|
||||||
|
@ -310,11 +303,6 @@ reset_platform:
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
mov pc, r0 // Jump to reset vector
|
mov pc, r0 // Jump to reset vector
|
||||||
#endif
|
#endif
|
||||||
cpu_start:
|
|
||||||
bl secondary_cpu_start
|
|
||||||
b .
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set sp for current cpu
|
* set sp for current cpu
|
||||||
|
@ -336,9 +324,9 @@ sp_set:
|
||||||
*/
|
*/
|
||||||
#ifdef LOSCFG_KERNEL_MMU
|
#ifdef LOSCFG_KERNEL_MMU
|
||||||
page_table_build:
|
page_table_build:
|
||||||
mov r9, r6
|
mov r10, r6
|
||||||
bfc r9, #20, #12 /* r9: pa % MB */
|
bfc r10, #20, #12 /* r9: pa % MB */
|
||||||
add r8, r8, r9
|
add r8, r8, r10
|
||||||
add r8, r8, #(1 << 20)
|
add r8, r8, #(1 << 20)
|
||||||
sub r8, r8, #1
|
sub r8, r8, #1
|
||||||
lsr r6, #20 /* r6 = physical address / MB */
|
lsr r6, #20 /* r6 = physical address / MB */
|
||||||
|
@ -346,7 +334,7 @@ page_table_build:
|
||||||
lsr r8, #20 /* r8 = roundup(size, MB) */
|
lsr r8, #20 /* r8 = roundup(size, MB) */
|
||||||
|
|
||||||
page_table_build_loop:
|
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 */
|
str r12, [r4, r7, lsl #2] /* gPgTable[l1Index] = physAddr | flags */
|
||||||
add r6, #1 /* physAddr+ */
|
add r6, #1 /* physAddr+ */
|
||||||
add r7, #1 /* l1Index++ */
|
add r7, #1 /* l1Index++ */
|
||||||
|
@ -388,24 +376,6 @@ excstack_magic_loop:
|
||||||
blt excstack_magic_loop
|
blt excstack_magic_loop
|
||||||
bx lr
|
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
|
#ifdef LOSCFG_KERNEL_MMU
|
||||||
memset_optimized:
|
memset_optimized:
|
||||||
mov r3, r0
|
mov r3, r0
|
||||||
|
|
|
@ -38,6 +38,7 @@ kernel_module(module_name) {
|
||||||
"core/los_sys.c",
|
"core/los_sys.c",
|
||||||
"core/los_task.c",
|
"core/los_task.c",
|
||||||
"core/los_tick.c",
|
"core/los_tick.c",
|
||||||
|
"core/los_smp.c",
|
||||||
"ipc/los_event.c",
|
"ipc/los_event.c",
|
||||||
"ipc/los_futex.c",
|
"ipc/los_futex.c",
|
||||||
"ipc/los_ipcdebug.c",
|
"ipc/los_ipcdebug.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
|
|
@ -57,6 +57,8 @@ typedef struct ArchMmuInitMapping {
|
||||||
const char *name;
|
const char *name;
|
||||||
} LosArchMmuInitMapping;
|
} LosArchMmuInitMapping;
|
||||||
|
|
||||||
|
extern LosArchMmuInitMapping g_archMmuInitMapping[];
|
||||||
|
|
||||||
extern UINTPTR g_vmBootMemBase;
|
extern UINTPTR g_vmBootMemBase;
|
||||||
extern BOOL g_kHeapInited;
|
extern BOOL g_kHeapInited;
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "los_task_pri.h"
|
#include "los_task_pri.h"
|
||||||
#include "los_tick.h"
|
#include "los_tick.h"
|
||||||
#include "los_vm_boot.h"
|
#include "los_vm_boot.h"
|
||||||
|
#include "los_smp.h"
|
||||||
|
|
||||||
STATIC SystemRebootFunc g_rebootHook = NULL;
|
STATIC SystemRebootFunc g_rebootHook = NULL;
|
||||||
|
|
||||||
|
@ -65,9 +66,6 @@ SystemRebootFunc OsGetRebootHook(VOID)
|
||||||
|
|
||||||
extern UINT32 OsSystemInit(VOID);
|
extern UINT32 OsSystemInit(VOID);
|
||||||
extern VOID SystemInit(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)
|
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);
|
OsInitCall(LOS_INIT_LEVEL_KMOD_EXTENDED);
|
||||||
|
|
||||||
#ifdef LOSCFG_KERNEL_SMP
|
#ifdef LOSCFG_KERNEL_SMP
|
||||||
release_secondary_cores();
|
OsSmpInit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
OsInitCall(LOS_INIT_LEVEL_KMOD_TASK);
|
OsInitCall(LOS_INIT_LEVEL_KMOD_TASK);
|
||||||
|
|
111
platform/main.c
111
platform/main.c
|
@ -30,117 +30,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "los_config.h"
|
#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_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)
|
LITE_OS_SEC_TEXT_INIT INT32 main(VOID)
|
||||||
{
|
{
|
||||||
|
@ -150,7 +40,6 @@ LITE_OS_SEC_TEXT_INIT INT32 main(VOID)
|
||||||
if (uwRet != LOS_OK) {
|
if (uwRet != LOS_OK) {
|
||||||
return LOS_NOK;
|
return LOS_NOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPU_MAP_SET(0, OsHwIDGet());
|
CPU_MAP_SET(0, OsHwIDGet());
|
||||||
|
|
||||||
OsSchedStart();
|
OsSchedStart();
|
||||||
|
|
Loading…
Reference in New Issue