oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 1 | //
|
| 2 | // Copyright (c) 2011, 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 <AsmMacroIoLib.h>
|
| 15 | #include <Base.h>
|
| 16 | #include <Library/PcdLib.h>
|
| 17 | #include <AutoGen.h>
|
| 18 |
|
| 19 | INCLUDE AsmMacroIoLib.inc
|
| 20 |
|
| 21 | IMPORT CEntryPoint
|
oliviermartin | 0787bc6 | 2011-09-22 23:01:13 +0000 | [diff] [blame] | 22 | IMPORT ArmReadMpidr
|
oliviermartin | 886f97c | 2011-09-27 16:42:47 +0000 | [diff] [blame] | 23 | IMPORT ArmIsMpCore
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 24 | EXPORT _ModuleEntryPoint
|
| 25 |
|
| 26 | PRESERVE8
|
| 27 | AREA PrePiCoreEntryPoint, CODE, READONLY
|
| 28 |
|
| 29 | StartupAddr DCD CEntryPoint
|
| 30 |
|
| 31 | _ModuleEntryPoint
|
oliviermartin | 0787bc6 | 2011-09-22 23:01:13 +0000 | [diff] [blame] | 32 | // Get ID of this CPU in Multicore system
|
| 33 | bl ArmReadMpidr
|
| 34 | LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCoreMask), r1)
|
| 35 | and r5, r0, r1
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 36 |
|
oliviermartin | d269095 | 2011-07-06 16:27:21 +0000 | [diff] [blame] | 37 | _SetSVCMode
|
oliviermartin | 99565b8 | 2011-11-01 23:41:52 +0000 | [diff] [blame] | 38 | // Enter SVC mode, Disable FIQ and IRQ
|
oliviermartin | d269095 | 2011-07-06 16:27:21 +0000 | [diff] [blame] | 39 | mov r1, #0x13|0x80|0x40
|
| 40 | msr CPSR_c, r1
|
| 41 |
|
oliviermartin | 2dbcb8f | 2011-09-22 23:05:20 +0000 | [diff] [blame] | 42 | // Check if we can install the stack at the top of the System Memory or if we need
|
oliviermartin | d269095 | 2011-07-06 16:27:21 +0000 | [diff] [blame] | 43 | // to install the stacks at the bottom of the Firmware Device (case the FD is located
|
| 44 | // at the top of the DRAM)
|
| 45 | _SetupStackPosition
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 46 | // Compute Top of System Memory
|
| 47 | LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryBase), r1)
|
| 48 | LoadConstantToReg (FixedPcdGet32(PcdSystemMemorySize), r2)
|
| 49 | add r1, r1, r2 // r1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 50 |
|
oliviermartin | d269095 | 2011-07-06 16:27:21 +0000 | [diff] [blame] | 51 | // Calculate Top of the Firmware Device
|
oliviermartin | f92b93c | 2011-09-22 23:06:31 +0000 | [diff] [blame] | 52 | LoadConstantToReg (FixedPcdGet32(PcdFdBaseAddress), r2)
|
| 53 | LoadConstantToReg (FixedPcdGet32(PcdFdSize), r3)
|
| 54 | add r3, r3, r2 // r4 = FdTop = PcdFdBaseAddress + PcdFdSize
|
oliviermartin | d269095 | 2011-07-06 16:27:21 +0000 | [diff] [blame] | 55 |
|
| 56 | // UEFI Memory Size (stacks are allocated in this region)
|
| 57 | LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), r4)
|
| 58 |
|
| 59 | //
|
| 60 | // Reserve the memory for the UEFI region (contain stacks on its top)
|
| 61 | //
|
| 62 |
|
| 63 | // Calculate how much space there is between the top of the Firmware and the Top of the System Memory
|
oliviermartin | 2dbcb8f | 2011-09-22 23:05:20 +0000 | [diff] [blame] | 64 | subs r0, r1, r3 // r0 = SystemMemoryTop - FdTop
|
| 65 | bmi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
|
| 66 | cmp r0, r4
|
oliviermartin | d269095 | 2011-07-06 16:27:21 +0000 | [diff] [blame] | 67 | bge _SetupStack
|
| 68 |
|
| 69 | // Case the top of stacks is the FdBaseAddress
|
| 70 | mov r1, r2
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 71 |
|
| 72 | _SetupStack
|
oliviermartin | 2dbcb8f | 2011-09-22 23:05:20 +0000 | [diff] [blame] | 73 | // r1 contains the top of the stack (and the UEFI Memory)
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 74 |
|
oliviermartin | d269095 | 2011-07-06 16:27:21 +0000 | [diff] [blame] | 75 | // Calculate the Base of the UEFI Memory
|
oliviermartin | 2dbcb8f | 2011-09-22 23:05:20 +0000 | [diff] [blame] | 76 | sub r6, r1, r4
|
oliviermartin | d269095 | 2011-07-06 16:27:21 +0000 | [diff] [blame] | 77 |
|
oliviermartin | 2dbcb8f | 2011-09-22 23:05:20 +0000 | [diff] [blame] | 78 | _GetStackBase
|
| 79 | // Compute Base of Normal stacks for CPU Cores
|
| 80 | // Is it MpCore system
|
oliviermartin | 886f97c | 2011-09-27 16:42:47 +0000 | [diff] [blame] | 81 | bl ArmIsMpCore
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 82 | cmp r0, #0
|
oliviermartin | 2dbcb8f | 2011-09-22 23:05:20 +0000 | [diff] [blame] | 83 | // Case it is not an MP Core system. Just setup the primary core
|
| 84 | beq _SetupUnicoreStack
|
| 85 |
|
| 86 | _GetStackBaseMpCore
|
| 87 | // Stack for the primary core = PrimaryCoreStack
|
| 88 | LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r2)
|
| 89 | sub r7, r1, r2
|
| 90 | // Stack for the secondary core = Number of Cluster * (4 Core per cluster) * SecondaryStackSize
|
| 91 | LoadConstantToReg (FixedPcdGet32(PcdClusterCount), r2)
|
| 92 | lsl r2, r2, #2
|
| 93 | LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), r3)
|
| 94 | mul r2, r2, r3
|
| 95 | sub r7, r7, r2
|
| 96 |
|
| 97 | // The top of the Mpcore Stacks is in r1
|
| 98 | // The base of the MpCore Stacks is in r7
|
| 99 |
|
| 100 | // Is it the Primary Core ?
|
| 101 | LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r4)
|
oliviermartin | 99565b8 | 2011-11-01 23:41:52 +0000 | [diff] [blame] | 102 | cmp r5, r4
|
oliviermartin | 2dbcb8f | 2011-09-22 23:05:20 +0000 | [diff] [blame] | 103 | beq _SetupPrimaryCoreStack
|
| 104 |
|
| 105 | _SetupSecondaryCoreStack
|
| 106 | // Base of the stack for the secondary cores is in r7
|
| 107 |
|
| 108 | // Get the position of the cores (ClusterId * 4) + CoreId
|
| 109 | GetCorePositionInStack(r0, r5, r4)
|
| 110 | // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack
|
| 111 | add r0, r0, #1
|
| 112 | // Get the offset for the Secondary Stack
|
| 113 | mul r0, r0, r3
|
| 114 | add sp, r7, r0
|
| 115 |
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 116 | bne _PrepareArguments
|
| 117 |
|
oliviermartin | 2dbcb8f | 2011-09-22 23:05:20 +0000 | [diff] [blame] | 118 | _SetupPrimaryCoreStack
|
| 119 | // The top of the Mpcore Stacks is in r1
|
| 120 | LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r2)
|
| 121 |
|
| 122 | // The reserved space for global variable must be 8-bytes aligned for pushing
|
| 123 | // 64-bit variable on the stack
|
| 124 | SetPrimaryStack (r1, r2, r3)
|
| 125 |
|
| 126 | _SetGlobals
|
| 127 | // Set all the PrePi global variables to 0
|
| 128 | mov r3, sp
|
| 129 | mov r2, #0x0
|
| 130 | _InitGlobals
|
oliviermartin | 2dbcb8f | 2011-09-22 23:05:20 +0000 | [diff] [blame] | 131 | cmp r3, r1
|
oliviermartin | 5f5b907 | 2011-11-09 11:52:37 +0000 | [diff] [blame^] | 132 | beq _PrepareArguments
|
| 133 | str r2, [r3], #4
|
| 134 | b _InitGlobals
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 135 |
|
| 136 | _PrepareArguments
|
oliviermartin | c524ffb | 2011-09-22 23:07:55 +0000 | [diff] [blame] | 137 | mov r0, r5
|
| 138 | mov r1, r6
|
| 139 | mov r2, r7
|
| 140 | mov r3, sp
|
| 141 |
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 142 | // Move sec startup address into a data register
|
| 143 | // Ensure we're jumping to FV version of the code (not boot remapped alias)
|
oliviermartin | c524ffb | 2011-09-22 23:07:55 +0000 | [diff] [blame] | 144 | ldr r4, StartupAddr
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 145 |
|
oliviermartin | d269095 | 2011-07-06 16:27:21 +0000 | [diff] [blame] | 146 | // Jump to PrePiCore C code
|
oliviermartin | 0787bc6 | 2011-09-22 23:01:13 +0000 | [diff] [blame] | 147 | // r0 = MpId
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 148 | // r1 = UefiMemoryBase
|
oliviermartin | c524ffb | 2011-09-22 23:07:55 +0000 | [diff] [blame] | 149 | // r2 = StacksBase
|
| 150 | // r3 = GlobalVariableBase
|
| 151 | blx r4
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 152 |
|
oliviermartin | 2dbcb8f | 2011-09-22 23:05:20 +0000 | [diff] [blame] | 153 | _NeverReturn
|
| 154 | b _NeverReturn
|
| 155 |
|
| 156 | _SetupUnicoreStack
|
| 157 | // The top of the Unicore Stack is in r1
|
| 158 | LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r2)
|
| 159 | LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r3)
|
| 160 |
|
| 161 | // Calculate the bottom of the primary stack (StackBase)
|
| 162 | sub r7, r1, r3
|
| 163 |
|
| 164 | // The reserved space for global variable must be 8-bytes aligned for pushing
|
| 165 | // 64-bit variable on the stack
|
| 166 | SetPrimaryStack (r1, r2, r3)
|
| 167 |
|
| 168 | b _SetGlobals
|
| 169 |
|
oliviermartin | cd872e4 | 2011-07-01 11:09:00 +0000 | [diff] [blame] | 170 | END
|