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 INCLUDE AsmMacroIoLib.inc 19 20 IMPORT CEntryPoint 21 IMPORT ArmPlatformIsPrimaryCore 22 IMPORT ArmPlatformGetCorePosition 23 IMPORT ArmPlatformSecBootAction 24 IMPORT ArmPlatformSecBootMemoryInit 25 IMPORT ArmDisableInterrupts 26 IMPORT ArmDisableCachesAndMmu 27 IMPORT ArmReadMpidr 28 IMPORT ArmCallWFE 29 EXPORT _ModuleEntryPoint 30 31 PRESERVE8 32 AREA SecEntryPoint, CODE, READONLY 33 34 StartupAddr DCD CEntryPoint 35 36 _ModuleEntryPoint FUNCTION 37 // First ensure all interrupts are disabled 38 bl ArmDisableInterrupts 39 40 // Ensure that the MMU and caches are off 41 bl ArmDisableCachesAndMmu 42 43 // By default, we are doing a cold boot 44 mov r10, #ARM_SEC_COLD_BOOT 45 46 // Jump to Platform Specific Boot Action function 47 blx ArmPlatformSecBootAction 48 49 _IdentifyCpu 50 // Identify CPU ID 51 bl ArmReadMpidr 52 // Keep a copy of the MpId register value 53 mov r9, r0 54 55 // Is it the Primary Core ? 56 bl ArmPlatformIsPrimaryCore 57 cmp r0, #1 58 // Only the primary core initialize the memory (SMC) 59 beq _InitMem 60 61 _WaitInitMem 62 // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized 63 // Otherwise we have to wait the Primary Core to finish the initialization 64 cmp r10, #ARM_SEC_COLD_BOOT 65 bne _SetupSecondaryCoreStack 66 67 // Wait for the primary core to initialize the initial memory (event: BOOT_MEM_INIT) 68 bl ArmCallWFE 69 // Now the Init Mem is initialized, we setup the secondary core stacks 70 b _SetupSecondaryCoreStack 71 72 _InitMem 73 // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized 74 cmp r10, #ARM_SEC_COLD_BOOT 75 bne _SetupPrimaryCoreStack 76 77 // Initialize Init Boot Memory 78 bl ArmPlatformSecBootMemoryInit 79 80 _SetupPrimaryCoreStack 81 // Get the top of the primary stacks (and the base of the secondary stacks) 82 LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1) 83 LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2) 84 add r1, r1, r2 85 86 mov sp, r1 87 b _PrepareArguments 88 89 _SetupSecondaryCoreStack 90 // Get the top of the primary stacks (and the base of the secondary stacks) 91 LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1) 92 LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2) 93 add r6, r1, r2 94 95 // Get the Core Position 96 mov r0, r9 97 bl ArmPlatformGetCorePosition 98 // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack 99 add r0, r0, #1 100 101 // StackOffset = CorePos * StackSize 102 LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), r2) 103 mul r0, r0, r2 104 // SP = StackBase + StackOffset 105 add sp, r6, r0 106 107 _PrepareArguments 108 // Move sec startup address into a data register 109 // Ensure we're jumping to FV version of the code (not boot remapped alias) 110 ldr r3, StartupAddr 111 112 // Jump to SEC C code 113 // r0 = mp_id 114 // r1 = Boot Mode 115 mov r0, r9 116 mov r1, r10 117 blx r3 118 ENDFUNC 119 120 _NeverReturn 121 b _NeverReturn 122 END 123