]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/Sec/AArch64/SecEntryPoint.S
ArmPlatformPkg/ArmVExpressPkg: Add virtio to RTSM A15 MPCore BSP
[mirror_edk2.git] / ArmPlatformPkg / Sec / AArch64 / SecEntryPoint.S
CommitLineData
1bc83266
HL
1//\r
2// Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
3//\r
4// This program and the accompanying materials\r
5// are licensed and made available under the terms and conditions of the BSD License\r
6// which accompanies this distribution. The full text of the license may be found at\r
7// http://opensource.org/licenses/bsd-license.php\r
8//\r
9// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11//\r
12//\r
13\r
14#include <AutoGen.h>\r
15#include <AsmMacroIoLibV8.h>\r
16#include "SecInternal.h"\r
17\r
18.text\r
19.align 3\r
20\r
21GCC_ASM_IMPORT(CEntryPoint)\r
22GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore)\r
23GCC_ASM_IMPORT(ArmPlatformGetCorePosition)\r
24GCC_ASM_IMPORT(ArmPlatformSecBootAction)\r
25GCC_ASM_IMPORT(ArmPlatformSecBootMemoryInit)\r
26GCC_ASM_IMPORT(ArmDisableInterrupts)\r
27GCC_ASM_IMPORT(ArmDisableCachesAndMmu)\r
28GCC_ASM_IMPORT(ArmReadMpidr)\r
29GCC_ASM_IMPORT(ArmCallWFE)\r
30GCC_ASM_EXPORT(_ModuleEntryPoint)\r
31\r
32StartupAddr: .dword ASM_PFX(CEntryPoint)\r
33\r
34ASM_PFX(_ModuleEntryPoint):\r
35\r
36// NOTE: We could be booting from EL3, EL2 or EL1. Need to correctly detect\r
37// and configure the system accordingly. EL2 is default if possible.\r
38// If we started in EL3 we need to switch and run at EL2.\r
39// If we are running at EL2 stay in EL2\r
40// If we are starting at EL1 stay in EL1.\r
41\r
42// Sec only runs in EL3. Othewise we jump to PEI without changing anything.\r
43// If Sec runs we change to EL2 before switching to PEI.\r
44\r
45// Which EL are we running at? Every EL needs some level of setup...\r
46 EL1_OR_EL2_OR_EL3(x0)\r
471:// If we are at EL1 or EL2 leave SEC for PEI.\r
482:b ASM_PFX(JumpToPEI)\r
49 // If we are at EL3 we need to configure it and switch to EL2\r
503:b ASM_PFX(MainEntryPoint)\r
51\r
52ASM_PFX(MainEntryPoint):\r
53 // First ensure all interrupts are disabled\r
54 bl ASM_PFX(ArmDisableInterrupts)\r
55\r
56 // Ensure that the MMU and caches are off\r
57 bl ASM_PFX(ArmDisableCachesAndMmu)\r
58\r
59 // By default, we are doing a cold boot\r
60 mov x10, #ARM_SEC_COLD_BOOT\r
61\r
62 // Jump to Platform Specific Boot Action function\r
63 bl ASM_PFX(ArmPlatformSecBootAction)\r
64\r
65_IdentifyCpu:\r
66 // Identify CPU ID\r
67 bl ASM_PFX(ArmReadMpidr)\r
68 // Keep a copy of the MpId register value\r
69 mov x5, x0\r
70\r
71 // Is it the Primary Core ?\r
72 bl ASM_PFX(ArmPlatformIsPrimaryCore)\r
73 cmp x0, #1\r
74 // Only the primary core initialize the memory (SMC)\r
75 b.eq _InitMem\r
76\r
77_WaitInitMem:\r
78 // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized\r
79 // Otherwise we have to wait the Primary Core to finish the initialization\r
80 cmp x10, #ARM_SEC_COLD_BOOT\r
81 b.ne _SetupSecondaryCoreStack\r
82\r
83 // Wait for the primary core to initialize the initial memory (event: BOOT_MEM_INIT)\r
84 bl ASM_PFX(ArmCallWFE)\r
85 // Now the Init Mem is initialized, we setup the secondary core stacks\r
86 b _SetupSecondaryCoreStack\r
87\r
88_InitMem:\r
89 // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized\r
90 cmp x10, #ARM_SEC_COLD_BOOT\r
91 b.ne _SetupPrimaryCoreStack\r
92\r
93 // Initialize Init Boot Memory\r
94 bl ASM_PFX(ArmPlatformSecBootMemoryInit)\r
95\r
96_SetupPrimaryCoreStack:\r
97 // Get the top of the primary stacks (and the base of the secondary stacks)\r
98 LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), x1)\r
99 LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), x2)\r
100 add x1, x1, x2\r
101\r
102 LoadConstantToReg (FixedPcdGet32(PcdSecGlobalVariableSize), x2)\r
103\r
104 // The reserved space for global variable must be 8-bytes aligned for pushing\r
105 // 64-bit variable on the stack\r
106 SetPrimaryStack (x1, x2, x3, x4)\r
107 b _PrepareArguments\r
108\r
109_SetupSecondaryCoreStack:\r
110 // Get the top of the primary stacks (and the base of the secondary stacks)\r
111 LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), x1)\r
112 LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), x2)\r
113 add x6, x1, x2\r
114\r
115 // Get the Core Position\r
116 mov x0, x5\r
117 bl ASM_PFX(ArmPlatformGetCorePosition)\r
118 // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack\r
119 add x0, x0, #1\r
120\r
121 // StackOffset = CorePos * StackSize\r
122 LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), x2)\r
123 mul x0, x0, x2\r
124 // SP = StackBase + StackOffset\r
125 add sp, x6, x0\r
126\r
127_PrepareArguments:\r
128 // Move sec startup address into a data register\r
129 // Ensure we're jumping to FV version of the code (not boot remapped alias)\r
130 ldr x3, StartupAddr\r
131\r
132 // Jump to SEC C code\r
133 // r0 = mp_id\r
134 // r1 = Boot Mode\r
135 mov x0, x5\r
136 mov x1, x10\r
137 blr x3\r
138\r
139 ret\r
140\r
141ASM_PFX(JumpToPEI):\r
142 LoadConstantToReg (FixedPcdGet32(PcdFvBaseAddress), x0)\r
143 blr x0\r
144\r
145dead:\r
146 b dead\r