1// 2// Copyright (c) 2011-2013, ARM Limited. All rights reserved. 3// 4// This program and the accompanying materials 5// are licensed and made available under the terms and conditions of the BSD License 6// which accompanies this distribution. The full text of the license may be found at 7// http://opensource.org/licenses/bsd-license.php 8// 9// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11// 12// 13 14#include <AutoGen.h> 15#include <AsmMacroIoLib.h> 16#include "SecInternal.h" 17 18.text 19.align 3 20 21GCC_ASM_IMPORT(CEntryPoint) 22GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore) 23GCC_ASM_IMPORT(ArmPlatformGetCorePosition) 24GCC_ASM_IMPORT(ArmPlatformSecBootAction) 25GCC_ASM_IMPORT(ArmPlatformSecBootMemoryInit) 26GCC_ASM_IMPORT(ArmDisableInterrupts) 27GCC_ASM_IMPORT(ArmDisableCachesAndMmu) 28GCC_ASM_IMPORT(ArmReadMpidr) 29GCC_ASM_IMPORT(ArmCallWFE) 30GCC_ASM_EXPORT(_ModuleEntryPoint) 31 32StartupAddr: .word ASM_PFX(CEntryPoint) 33 34ASM_PFX(_ModuleEntryPoint): 35 // First ensure all interrupts are disabled 36 bl ASM_PFX(ArmDisableInterrupts) 37 38 // Ensure that the MMU and caches are off 39 bl ASM_PFX(ArmDisableCachesAndMmu) 40 41 // By default, we are doing a cold boot 42 mov r10, #ARM_SEC_COLD_BOOT 43 44 // Jump to Platform Specific Boot Action function 45 blx ASM_PFX(ArmPlatformSecBootAction) 46 47_IdentifyCpu: 48 // Identify CPU ID 49 bl ASM_PFX(ArmReadMpidr) 50 // Keep a copy of the MpId register value 51 mov r9, r0 52 53 // Is it the Primary Core ? 54 bl ASM_PFX(ArmPlatformIsPrimaryCore) 55 cmp r0, #1 56 // Only the primary core initialize the memory (SMC) 57 beq _InitMem 58 59_WaitInitMem: 60 // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized 61 // Otherwise we have to wait the Primary Core to finish the initialization 62 cmp r10, #ARM_SEC_COLD_BOOT 63 bne _SetupSecondaryCoreStack 64 65 // Wait for the primary core to initialize the initial memory (event: BOOT_MEM_INIT) 66 bl ASM_PFX(ArmCallWFE) 67 // Now the Init Mem is initialized, we setup the secondary core stacks 68 b _SetupSecondaryCoreStack 69 70_InitMem: 71 // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized 72 cmp r10, #ARM_SEC_COLD_BOOT 73 bne _SetupPrimaryCoreStack 74 75 // Initialize Init Boot Memory 76 bl ASM_PFX(ArmPlatformSecBootMemoryInit) 77 78_SetupPrimaryCoreStack: 79 // Get the top of the primary stacks (and the base of the secondary stacks) 80 LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1) 81 LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2) 82 add r1, r1, r2 83 84 mov sp, r1 85 b _PrepareArguments 86 87_SetupSecondaryCoreStack: 88 // Get the top of the primary stacks (and the base of the secondary stacks) 89 LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1) 90 LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2) 91 add r6, r1, r2 92 93 // Get the Core Position 94 mov r0, r9 95 bl ASM_PFX(ArmPlatformGetCorePosition) 96 // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack 97 add r0, r0, #1 98 99 // StackOffset = CorePos * StackSize 100 LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), r2) 101 mul r0, r0, r2 102 // SP = StackBase + StackOffset 103 add sp, r6, r0 104 105_PrepareArguments: 106 // Move sec startup address into a data register 107 // Ensure we're jumping to FV version of the code (not boot remapped alias) 108 ldr r3, StartupAddr 109 110 // Jump to SEC C code 111 // r0 = mp_id 112 // r1 = Boot Mode 113 mov r0, r9 114 mov r1, r10 115 blx r3 116 117_NeverReturn: 118 b _NeverReturn 119