diff --git a/arch/arm/src/armv8-r/CMakeLists.txt b/arch/arm/src/armv8-r/CMakeLists.txt index 79a08e37f86ac..6e58ceddec4cd 100644 --- a/arch/arm/src/armv8-r/CMakeLists.txt +++ b/arch/arm/src/armv8-r/CMakeLists.txt @@ -47,6 +47,10 @@ list( arm_perf.c cp15_cacheops.c) +if(CONFIG_SMP OR CONFIG_BMP) + list(APPEND SRCS arm_cpuhead.S arm_cpuindex.c arm_cpuidlestack.c) +endif() + if(CONFIG_ARCH_FPU) list(APPEND SRCS arm_fpucmp.c arm_fpuconfig.S) endif() diff --git a/arch/arm/src/armv8-r/arm_cpuhead.S b/arch/arm/src/armv8-r/arm_cpuhead.S new file mode 100644 index 0000000000000..eee17766cf34d --- /dev/null +++ b/arch/arm/src/armv8-r/arm_cpuhead.S @@ -0,0 +1,312 @@ +/**************************************************************************** + * arch/arm/src/armv8-r/arm_cpuhead.S + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "arm.h" +#include "cp15.h" +#include "cp15_cacheops.h" +#include "sctlr.h" +#include "smp.h" +#include "chip.h" +#include "arm_internal.h" + +#if defined(CONFIG_SMP) || defined(CONFIG_BMP) + + .file "arm_cpuhead.S" + +/**************************************************************************** + * Global Symbols + ****************************************************************************/ + +/* Imported symbols */ + + .global _hyp_vector_start + .global _sys_vector_start + +/**************************************************************************** + * .text + ****************************************************************************/ + + .text + .syntax unified + .arm + +/**************************************************************************** + * Name: __cpu[n]_start + * + * Description: + * Boot functions for each CPU (other than CPU0). These functions set up + * the ARM operating mode, the initial stack, and configure co-processor + * registers. At the end of the boot, arm_cpu_boot() is called. + * + * These functions are provided by the common ARMv7-A logic. + * + * Input Parameters: + * None + * + * Returned Value: + * Do not return. + * + ****************************************************************************/ + +#if CONFIG_NR_CPUS > 1 + .global __cpu1_start + .type __cpu1_start, #function + +__cpu1_start: + /* Make sure that we are in SYS mode with IRQs and FIQs disabled */ + + cpsid if + + /* Set up the stack pointer and the CPU index */ + + ldr sp, .Lcpu1_stackpointer + mov fp, #0 + + /* Then branch to the common startup logic (PC-relative) */ + + b .Lcpu_start + +.Lcpu1_stackpointer: + .long .Lcpu1_stacktop + .size __cpu1_start, .-__cpu1_start + +#if CONFIG_NR_CPUS > 2 + .global __cpu2_start + .type __cpu2_start, #function + +__cpu2_start: + /* Make sure that we are in SYS mode with IRQs and FIQs disabled */ + + cpsid if + + /* Set up the stack pointer and the CPU index */ + + ldr sp, .Lcpu2_stackpointer + mov fp, #0 + + /* Then branch to the common startup logic (PC-relative) */ + + b .Lcpu_start + +.Lcpu2_stackpointer: + .long .Lcpu2_stacktop + .size __cpu2_start, .-__cpu2_start + +#if CONFIG_NR_CPUS > 3 + .global __cpu3_start + .type __cpu3_start, #function + +__cpu3_start: + /* Make sure that we are in SYS mode with IRQs and FIQs disabled */ + + cpsid if + + /* Set up the stack pointer and the CPU index */ + + ldr sp, .Lcpu3_stackpointer + mov fp, #0 + + /* Then branch to the common startup logic (PC-relative) */ + + b .Lcpu_start + +.Lcpu3_stackpointer: + .long .Lcpu3_stacktop + .size __cpu3_start, .-__cpu3_start + +#if CONFIG_NR_CPUS > 4 +# error This logic needs to extended for CONFIG_NR_CPUS > 4 + +#endif /* CONFIG_NR_CPUS > 4 */ +#endif /* CONFIG_NR_CPUS > 3 */ +#endif /* CONFIG_NR_CPUS > 2 */ +#endif /* CONFIG_NR_CPUS > 1 */ + +/**************************************************************************** + * Name: .Lcpu_start + * + * Description: + * Common CPUn startup logic (n > 0) + * + * On input: + * SP = Set to top of CPU IDLE stack (virtual) + * R5 = CPU number + * + ****************************************************************************/ + + .type .Lcpu_start, #function + +.Lcpu_start: + + /* Set Hyp/PL2 Vector table base register */ + ldr r0, .Lhypvectorstart + mcr CP15_HVBAR(r0) + + /* Invalidate caches and TLBs. + * + * NOTE: "The ARMv7 Virtual Memory System Architecture (VMSA) does not + * support a CP15 operation to invalidate the entire data cache. ... + * In normal usage the only time the entire data cache has to be + * invalidated is on reset." + * + * The instruction cache is virtually indexed and physically tagged but + * the data cache is physically indexed and physically tagged. So it + * should not be an issue if the system comes up with a dirty Dcache; + * the ICache, however, must be invalidated. + */ + + mov r0, #0 + mcr CP15_BPIALL(r0) /* Invalidate entire branch prediction array */ + mcr CP15_ICIALLU(r0) /* Invalidate I-cache */ + mov r1, CP15_CACHE_INVALIDATE + bl cp15_dcache_op_level + isb + + bl hsctlr_initialize /* Init Hyp system control register */ + + ldr r0, =HACTLR_INIT + mcr CP15_HACTLR(r0) /* Enable EL1 access all IMP DEFINED registers */ + + /* Initialize .bss and .data assumt that RAM that is ready to use. */ + bl arm_data_initialize + + /* Platform hook for highest EL */ + bl arm_el_init + + /* Move to PL1 SYS with all exceptions masked */ + mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT | PSR_A_BIT) + msr spsr_hyp, r0 + + adr r0, 1f + msr elr_hyp, r0 + dsb + isb + eret + +1: + mrc CP15_MPIDR(r0) + and r0, r0, #0x3 + cmp r0, #1 + beq __cpu1_stack + cmp r0, #2 + beq __cpu2_stack + cmp r0, #3 + beq __cpu3_stack + +__cpu1_stack: + + /* Set up the stack pointer and clear the frame pointer. */ + ldr sp, .Lcpu1_stackpointer + b 2f +__cpu2_stack: + + /* Set up the stack pointer and clear the frame pointer. */ + ldr sp, .Lcpu2_stackpointer + b 2f +__cpu3_stack: + + /* Set up the stack pointer and clear the frame pointer. */ + ldr sp, .Lcpu3_stackpointer +2: + mov fp, #0 + + /* Set PL1 Vector table base register */ + ldr r0, .Lsysvectorstart + mcr CP15_VBAR(r0) + + bl sctlr_initialize + +#ifdef CONFIG_ARCH_FPU + bl arm_fpuconfig +#endif + + bl arm_boot + + mov lr, #0 /* LR = return address (none) */ + b nx_start /* Branch to nx_start */ + +/**************************************************************************** + * PC_Relative Data + ****************************************************************************/ + + .size .Lcpu_start, .-.Lcpu_start + +.Lhypvectorstart: + .long _hyp_vector_start +.Lsysvectorstart: + .long _sys_vector_start + +/*************************************************************************** + * Text-section constants + ***************************************************************************/ + +/*************************************************************************** + * .noinit section data + ***************************************************************************/ + + .section .noinit, "aw" + +#if CONFIG_NR_CPUS > 1 + .align 8 + .globl g_cpu1_idlestack + .type g_cpu1_idlestack, object + +g_cpu1_idlestack: + .space SMP_STACK_SIZE +.Lcpu1_stacktop: + .size g_cpu1_idlestack, .Lcpu1_stacktop-g_cpu1_idlestack + +#if CONFIG_NR_CPUS > 2 + .align 8 + .globl g_cpu2_idlestack + .type g_cpu2_idlestack, object + +g_cpu2_idlestack: + .space SMP_STACK_SIZE +.Lcpu2_stacktop: + .size g_cpu2_idlestack, .Lcpu2_stacktop-g_cpu2_idlestack + +#if CONFIG_NR_CPUS > 3 + .align 8 + .globl g_cpu3_idlestack + .type g_cpu3_idlestack, object + +g_cpu3_idlestack: + .space SMP_STACK_SIZE +.Lcpu3_stacktop: + .size g_cpu3_idlestack, .Lcpu3_stacktop-g_cpu3_idlestack + +#if CONFIG_NR_CPUS > 4 +# error This logic needs to extended for CONFIG_NR_CPUS > 4 + +#endif /* CONFIG_NR_CPUS > 4 */ +#endif /* CONFIG_NR_CPUS > 3 */ +#endif /* CONFIG_NR_CPUS > 2 */ +#endif /* CONFIG_NR_CPUS > 1 */ +#endif /* CONFIG_SMP */ + .end diff --git a/arch/arm/src/armv8-r/arm_cpuidlestack.c b/arch/arm/src/armv8-r/arm_cpuidlestack.c new file mode 100644 index 0000000000000..fce8b9af02f6d --- /dev/null +++ b/arch/arm/src/armv8-r/arm_cpuidlestack.c @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/arm/src/armv8-r/arm_cpuidlestack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "smp.h" +#include "arm_internal.h" + +#if defined(CONFIG_SMP) || defined(CONFIG_BMP) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Stack alignment macros */ + +#define STACK_ISALIGNED(a) ((uintptr_t)(a) & ~SMP_STACK_MASK) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#if CONFIG_NR_CPUS > 1 +static const uint32_t *g_cpu_stackalloc[CONFIG_NR_CPUS] = +{ + 0 + , g_cpu1_idlestack +#if CONFIG_NR_CPUS > 2 + , g_cpu2_idlestack +#if CONFIG_NR_CPUS > 3 + , g_cpu3_idlestack +#endif /* CONFIG_NR_CPUS > 3 */ +#endif /* CONFIG_NR_CPUS > 2 */ +}; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_cpu_idlestack + * + * Description: + * Allocate a stack for the CPU[n] IDLE task (n > 0) if appropriate and + * setup up stack-related information in the IDLE task's TCB. This + * function is always called before up_cpu_start(). This function is + * only called for the CPU's initial IDLE task; up_create_task is used for + * all normal tasks, pthreads, and kernel threads for all CPUs. + * + * The initial IDLE task is a special case because the CPUs can be started + * in different wans in different environments: + * + * 1. The CPU may already have been started and waiting in a low power + * state for up_cpu_start(). In this case, the IDLE thread's stack + * has already been allocated and is already in use. Here + * up_cpu_idlestack() only has to provide information about the + * already allocated stack. + * + * 2. The CPU may be disabled but started when up_cpu_start() is called. + * In this case, a new stack will need to be created for the IDLE + * thread and this function is then equivalent to: + * + * return up_create_stack(tcb, stack_size, TCB_FLAG_TTYPE_KERNEL); + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. + * + * Input Parameters: + * - cpu: CPU index that indicates which CPU the IDLE task is + * being created for. + * - tcb: The TCB of new CPU IDLE task + * - stack_size: The requested stack size for the IDLE task. At least + * this much must be allocated. This should be + * CONFIG_SMP_STACK_SIZE. + * + ****************************************************************************/ + +int up_cpu_idlestack(int cpu, struct tcb_s *tcb, size_t stack_size) +{ +#if CONFIG_NR_CPUS > 1 + uintptr_t stack_alloc; + + DEBUGASSERT(cpu > 0 && cpu < CONFIG_NR_CPUS && tcb != NULL && + stack_size <= SMP_STACK_SIZE); + + /* Get the top of the stack */ + + stack_alloc = (uintptr_t)g_cpu_stackalloc[cpu]; + DEBUGASSERT(stack_alloc != 0 && STACK_ISALIGNED(stack_alloc)); + + tcb->adj_stack_size = SMP_STACK_SIZE; + tcb->stack_alloc_ptr = (void *)stack_alloc; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; +#endif + + return OK; +} + +#endif /* CONFIG_SMP */ diff --git a/arch/arm/src/armv8-r/arm_cpuindex.c b/arch/arm/src/armv8-r/arm_cpuindex.c new file mode 100644 index 0000000000000..b2da36e105749 --- /dev/null +++ b/arch/arm/src/armv8-r/arm_cpuindex.c @@ -0,0 +1,71 @@ +/**************************************************************************** + * arch/arm/src/armv8-r/arm_cpuindex.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "cp15.h" +#include "sctlr.h" + +#if defined(CONFIG_SMP) || defined(CONFIG_BMP) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_cpu_index + * + * Description: + * Return an index in the range of 0 through (CONFIG_SMP_NCPUS-1) that + * corresponds to the currently executing CPU. + * + * If TLS is enabled, then the RTOS can get this information from the TLS + * info structure. Otherwise, the MCU-specific logic must provide some + * mechanism to provide the CPU index. + * + * Input Parameters: + * None + * + * Returned Value: + * An integer index in the range of 0 through (CONFIG_SMP_NCPUS-1) that + * corresponds to the currently executing CPU. + * + ****************************************************************************/ + +int up_cpu_index(void) +{ + /* Read the Multiprocessor Affinity Register (MPIDR) */ + + uint32_t mpidr = cp15_rdmpidr(); + + /* And return the CPU ID field */ + + return (mpidr & MPIDR_CPUID_MASK) >> MPIDR_CPUID_SHIFT; +} + +#endif /* CONFIG_SMP */ diff --git a/arch/arm/src/armv8-r/arm_gicv3.c b/arch/arm/src/armv8-r/arm_gicv3.c index 51ec1c6835d9b..44b892caae517 100644 --- a/arch/arm/src/armv8-r/arm_gicv3.c +++ b/arch/arm/src/armv8-r/arm_gicv3.c @@ -67,7 +67,7 @@ /* Redistributor base addresses for each core */ -static unsigned long gic_rdists[CONFIG_SMP_NCPUS]; +static unsigned long g_gic_rdists[CONFIG_NR_CPUS]; /*************************************************************************** * Private Functions @@ -101,7 +101,7 @@ static inline int sys_test_bit(unsigned long addr, unsigned int bit) static inline unsigned long gic_get_rdist(void) { - return gic_rdists[this_cpu()]; + return g_gic_rdists[up_cpu_index()]; } static inline uint32_t read_gicd_wait_rwp(void) @@ -630,7 +630,7 @@ void up_affinity_irq(int irq, cpu_set_t cpuset) { if (GIC_IS_SPI(irq)) { - arm_gic_write_irouter(cpuset, irq); + arm_gic_write_irouter(ffs(cpuset) - 1, irq); } } @@ -797,9 +797,9 @@ static void arm_gic_init(void) uint8_t cpu; int err; - cpu = this_cpu(); - gic_rdists[cpu] = CONFIG_GICR_BASE + - up_cpu_index() * CONFIG_GICR_OFFSET; + cpu = up_cpu_index(); + g_gic_rdists[cpu] = CONFIG_GICR_BASE + + up_cpu_index() * CONFIG_GICR_OFFSET; err = gic_validate_redist_version(); if (err) @@ -821,21 +821,24 @@ int arm_gic_initialize(void) { int err; - err = gic_validate_dist_version(); - if (err) + if (up_cpu_index() == 0) { - sinfo("no distributor detected, giving up ret=%d\n", err); - return err; - } + err = gic_validate_dist_version(); + if (err) + { + sinfo("no distributor detected, giving up ret=%d\n", err); + return err; + } - gicv3_dist_init(); + gicv3_dist_init(); + } arm_gic_init(); return 0; } -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) void arm_gic_secondary_init(void) { arm_gic_init(); diff --git a/arch/arm/src/armv8-r/arm_head.S b/arch/arm/src/armv8-r/arm_head.S index 16819dc32c824..2ef7daaafeb52 100644 --- a/arch/arm/src/armv8-r/arm_head.S +++ b/arch/arm/src/armv8-r/arm_head.S @@ -24,6 +24,8 @@ #include +#include + #include "arm.h" #include "cp15.h" #include "cp15_cacheops.h" @@ -137,26 +139,24 @@ __start: mrc CP15_MPIDR(r0) and r0, r0, #0x3 cmp r0, #0 -#if defined(CONFIG_SMP) && CONFIG_SMP_NCPUS > 1 beq __cpu0_start wfe cmp r0, #1 +#if (defined(CONFIG_SMP) || defined(CONFIG_BMP)) && CONFIG_NR_CPUS > 1 beq __cpu1_start -# if CONFIG_SMP_NCPUS > 2 +# if CONFIG_NR_CPUS > 2 cmp r0, #2 beq __cpu2_start # endif -# if CONFIG_SMP_NCPUS > 3 +# if CONFIG_NR_CPUS > 3 cmp r0, #3 beq __cpu3_start # endif -# if CONFIG_SMP_NCPUS > 4 +# if CONFIG_NR_CPUS > 4 cmp r0, #4 beq __cpu4_start # endif - -#else - beq __cpu0_start +#endif __cpux_wfi: @@ -166,8 +166,6 @@ __cpux_wfi: wfi b __cpux_wfi -#endif - __cpu0_start: /* Make sure that IRQs and FIQs are disabled */ diff --git a/arch/arm/src/armv8-r/arm_initialstate.c b/arch/arm/src/armv8-r/arm_initialstate.c index 079eba403d85d..d5431b9392c05 100644 --- a/arch/arm/src/armv8-r/arm_initialstate.c +++ b/arch/arm/src/armv8-r/arm_initialstate.c @@ -63,10 +63,20 @@ void up_initial_state(struct tcb_s *tcb) if (tcb->pid == IDLE_PROCESS_ID) { - tcb->stack_alloc_ptr = (void *)(g_idle_topstack - - CONFIG_IDLETHREAD_STACKSIZE); - tcb->stack_base_ptr = tcb->stack_alloc_ptr; - tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; +#ifdef CONFIG_BMP + if (up_cpu_index() > 0) + { + up_cpu_idlestack(up_cpu_index(), tcb, + CONFIG_IDLETHREAD_STACKSIZE); + } + else +#endif + { + tcb->stack_alloc_ptr = (void *)(g_idle_topstack - + CONFIG_IDLETHREAD_STACKSIZE); + tcb->stack_base_ptr = tcb->stack_alloc_ptr; + tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; + } #ifdef CONFIG_STACK_COLORATION /* If stack debug is enabled, then fill the stack with a diff --git a/arch/arm/src/armv8-r/arm_vectors.S b/arch/arm/src/armv8-r/arm_vectors.S index 5ac537c853189..a1647b90a1327 100644 --- a/arch/arm/src/armv8-r/arm_vectors.S +++ b/arch/arm/src/armv8-r/arm_vectors.S @@ -27,6 +27,7 @@ #include "arm.h" #include "cp15.h" +#include "chip.h" .file "arm_vectors.S" @@ -42,6 +43,21 @@ * Assembly Macros ****************************************************************************/ +/**************************************************************************** + * Name: cpuindex + * + * Description: + * Return an index idenifying the current CPU. Single CPU case. Must be + * provided by MCU-specific logic in chip.h for the SMP case. + * + ****************************************************************************/ + +#if !defined(CONFIG_SMP) && !defined(CONFIG_BMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 + .macro cpuindex, index + .mov \index, #0 + .endm +#endif + /**************************************************************************** * Name: setirqstack * @@ -51,7 +67,7 @@ * ****************************************************************************/ -#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 +#if !defined(CONFIG_SMP) && !defined(CONFIG_BMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 .macro setirqstack, tmp1, tmp2 ldr sp, .Lirqstacktop /* SP = IRQ stack top */ .endm @@ -66,7 +82,7 @@ * ****************************************************************************/ -#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 +#if !defined(CONFIG_SMP) && !defined(CONFIG_BMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 .macro setfiqstack, tmp1, tmp2 ldr sp, .Lfiqstacktop /* SP = FIQ stack top */ .endm @@ -246,7 +262,7 @@ arm_vectorirq: rfeia r14 -#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 +#if !defined(CONFIG_SMP) && !defined(CONFIG_BMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 .Lirqstacktop: .word g_intstacktop #endif @@ -706,7 +722,7 @@ arm_vectorfiq: rfeia r14 -#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 +#if !defined(CONFIG_SMP) && !defined(CONFIG_BMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 .Lfiqstacktop: .word g_fiqstacktop #endif @@ -736,7 +752,7 @@ arm_vectoraddrexcptn: * Name: g_intstackalloc/g_intstacktop ****************************************************************************/ -#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 +#if !defined(CONFIG_SMP) && !defined(CONFIG_BMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 .bss .balign 8 diff --git a/arch/arm/src/armv8-r/smp.h b/arch/arm/src/armv8-r/smp.h new file mode 100644 index 0000000000000..5b53aad9eb16b --- /dev/null +++ b/arch/arm/src/armv8-r/smp.h @@ -0,0 +1,128 @@ +/**************************************************************************** + * arch/arm/src/armv8-r/smp.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_SMP_H +#define __ARCH_ARM_SRC_ARMV7_A_SMP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#if defined(CONFIG_SMP) || defined(CONFIG_BMP) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* ARM requires at least a 4-byte stack alignment. For use with EABI and + * floating point, the stack must be aligned to 8-byte addresses. We will + * always use the EABI stack alignment + */ + +#define SMP_STACK_ALIGNMENT 8 +#define SMP_STACK_MASK 7 +#define SMP_STACK_SIZE ((CONFIG_IDLETHREAD_STACKSIZE + 7) & ~7) +#define SMP_STACK_WORDS (SMP_STACK_SIZE >> 2) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#if CONFIG_NR_CPUS > 1 +extern uint32_t g_cpu1_idlestack[SMP_STACK_WORDS]; +#if CONFIG_NR_CPUS > 2 +extern uint32_t g_cpu2_idlestack[SMP_STACK_WORDS]; +#if CONFIG_NR_CPUS > 3 +extern uint32_t g_cpu3_idlestack[SMP_STACK_WORDS]; +#if CONFIG_NR_CPUS > 4 +# error This logic needs to extended for CONFIG_NR_CPUS > 4 +#endif /* CONFIG_NR_CPUS > 4 */ +#endif /* CONFIG_NR_CPUS > 3 */ +#endif /* CONFIG_NR_CPUS > 2 */ +#endif /* CONFIG_NR_CPUS > 1 */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: __cpu[n]_start + * + * Description: + * Boot functions for each CPU (other than CPU0). These functions set up + * the ARM operating mode, the initial stack, and configure co-processor + * registers. At the end of the boot, arm_cpu_boot() is called. + * + * These functions are provided by the common ARMv7-A logic. + * + * Input Parameters: + * None + * + * Returned Value: + * Do not return. + * + ****************************************************************************/ + +#if CONFIG_NR_CPUS > 1 +void __cpu1_start(void); +#endif + +#if CONFIG_NR_CPUS > 2 +void __cpu2_start(void); +#endif + +#if CONFIG_NR_CPUS > 3 +void __cpu3_start(void); +#endif + +#if CONFIG_NR_CPUS > 4 +# error This logic needs to extended for CONFIG_NR_CPUS > 4 +#endif + +/**************************************************************************** + * Name: arm_cpu_boot + * + * Description: + * Continues the C-level initialization started by the assembly language + * __cpu[n]_start function. At a minimum, this function needs to + * initialize interrupt handling and, perhaps, wait on WFI for + * arm_cpu_start() to issue an SGI. + * + * This function must be provided by the each ARMv7-A MCU and implement + * MCU-specific initialization logic. + * + * Input Parameters: + * cpu - The CPU index. This is the same value that would be obtained by + * calling up_cpu_index(); + * + * Returned Value: + * Does not return. + * + ****************************************************************************/ + +void arm_cpu_boot(int cpu); + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_SMP */ +#endif /* __ARCH_ARM_SRC_ARMV7_A_SMP_H */