summaryrefslogtreecommitdiff
path: root/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S
diff options
context:
space:
mode:
Diffstat (limited to 'SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S')
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S287
1 files changed, 287 insertions, 0 deletions
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S
new file mode 100644
index 000000000..aecbc939f
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S
@@ -0,0 +1,287 @@
+//
+// Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+
+#include <AutoGen.h>
+#include <AsmMacroIoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <ArmPlatform.h>
+#include "SecInternal.h"
+
+.text
+.align 3
+
+GCC_ASM_IMPORT(CEntryPoint)
+GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_IMPORT(CopyFirmwareFromEMMC)
+GCC_ASM_IMPORT(CopyFirmwareFromSDMMC)
+GCC_ASM_IMPORT(ArmPlatformClockInitialize)
+GCC_ASM_IMPORT(ArmPlatformSecBootAction)
+GCC_ASM_IMPORT(ArmPlatformSecBootMemoryInit)
+GCC_ASM_IMPORT(ArmDisableInterrupts)
+GCC_ASM_IMPORT(ArmDisableCachesAndMmu)
+GCC_ASM_IMPORT(ArmEnableBranchPrediction)
+GCC_ASM_IMPORT(ArmReadMpidr)
+GCC_ASM_IMPORT(ArmCallWFE)
+GCC_ASM_IMPORT(_SecEntryFromTzsw)
+GCC_ASM_EXPORT(_ModuleEntryPoint)
+
+SecStartupAddr: .word ASM_PFX(_SecEntryFromTzsw)
+StartupAddr: .word ASM_PFX(CEntryPoint)
+
+// Convert the (ClusterId,CoreId) into a Core Position
+// 0x0F03 is the magic value for ARM_CORE_MASK | ARM_CLUSTER_MASK
+//Core is 0-1 bits and cluster is 8-11 bits
+#define GetCorePositionFromMpId(Pos, MpId, Tmp) \
+ ldr Tmp, =0x0F03 ; \
+ and MpId, Tmp ; \
+ lsr Pos, MpId, #6 ; \
+ and Tmp, MpId, #3 ; \
+ add Pos, Pos, Tmp
+
+// Reserve a region at the top of the IRAM Core stack
+// for Global variables for the XIP phase
+#define SetiRamStack(StackTop, GlobalSize, Tmp) \
+ and Tmp, GlobalSize, #7 ; \
+ rsbne Tmp, Tmp, #8 ; \
+ add GlobalSize, GlobalSize, Tmp ; \
+ sub sp, StackTop, GlobalSize ; \
+ ; \
+ mov Tmp, sp ; \
+ mov GlobalSize, #0x0 ; \
+_SetiRamStackInitGlobals: ; \
+ cmp Tmp, StackTop ; \
+ beq _SetiRamStackEnd ; \
+ str GlobalSize, [Tmp], #4 ; \
+ b _SetiRamStackInitGlobals ; \
+_SetiRamStackEnd:
+
+
+ASM_PFX(_ModuleEntryPoint):
+ // First ensure all interrupts are disabled
+ bl ASM_PFX(ArmDisableInterrupts)
+
+ // Ensure that the MMU and caches are off
+ bl ASM_PFX(ArmDisableCachesAndMmu)
+
+ // Jump to Platform Specific Boot Action function
+ blx ASM_PFX(ArmPlatformSecBootAction)
+
+ # Enable branch prediction
+ bl ASM_PFX(ArmEnableBranchPrediction)
+
+ # TZPC1_DECPROT1Set (work-around for connecting T32 in SD booting mode)
+// ldr r0, =0x10110810
+// mov r1, #0xF
+// str r1, [r0]
+// dsb
+// isb
+// sev
+
+// ldr r0, =0x1
+// ldr r1, =0x2
+//infloop:
+// cmp r0, r1
+// bme infloop
+
+
+_IdentifyCpu:
+ // Identify CPU ID
+ bl ASM_PFX(ArmReadMpidr)
+ // Keep a copy of the MpId register value
+ mov r5, r0
+
+ // Is it the Primary Core ?
+ bl ASM_PFX(ArmPlatformIsPrimaryCore)
+ cmp r0, #1
+
+ // Only the primary core initialize the memory (SMC)
+ beq _InitMem
+
+_WaitInitMem:
+ // Wait for the primary core to initialize the initial memory (event: BOOT_MEM_INIT)
+ bl ASM_PFX(ArmCallWFE)
+ // Now the Init Mem is initialized, we setup the secondary core stacks
+ b _SetupSecondaryCoreStack
+
+_InitMem:
+ // Initialize Init Boot Memory
+ mov r0, pc
+ ldr r1, =0x40000000
+ cmp r0, r1
+ bgt _SetupPrimaryCoreStack
+
+ bl ASM_PFX(ArmPlatformClockInitialize)
+
+ LoadConstantToReg (FixedPcdGet32(PcdiRamStackBase), r1)
+ LoadConstantToReg (FixedPcdGet32(PcdiRamStackSize), r2)
+
+ // The reserved space for global variable must be 8-bytes aligned for pushing
+ // 64-bit variable on the stack
+ SetiRamStack (r1, r2, r3)
+
+ bl ASM_PFX(ArmPlatformSecBootMemoryInit)
+
+_SetupPrimaryCoreStack:
+ // Get the top of the primary stacks (and the base of the secondary stacks)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
+ add r1, r1, r2
+
+ LoadConstantToReg (FixedPcdGet32(PcdSecGlobalVariableSize), r2)
+
+ // The reserved space for global variable must be 8-bytes aligned for pushing
+ // 64-bit variable on the stack
+ SetPrimaryStack (r1, r2, r3)
+
+ mov r0, pc
+ ldr r1, =0x40000000
+ cmp r0, r1
+ bgt _PrepareArguments_NonTZ
+
+ b _CopyFirmware
+
+_SetupSecondaryCoreStack:
+ // Get the top of the primary stacks (and the base of the secondary stacks)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
+ add r1, r1, r2
+
+ // Get the Core Position (ClusterId * 4) + CoreId
+ GetCorePositionFromMpId(r0, r5, r2)
+ // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack
+ add r0, r0, #1
+
+ // StackOffset = CorePos * StackSize
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), r2)
+ mul r0, r0, r2
+ // SP = StackBase + StackOffset
+ add sp, r1, r0
+
+ b _PrepareArguments_NonTZ
+
+_PrepareArguments:
+ // Move sec startup address into a data register
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
+ LoadConstantToReg (FixedPcdGet32(PcdTrustzoneSupport), r2)
+ cmp r2, #0x1 /* TrustZone Enable */
+ beq _PrepareArguments_TZ
+
+_PrepareArguments_NonTZ:
+ ldr r3, StartupAddr
+ // Jump to SEC C code
+ // r0 = mp_id
+ mov r0, r5
+ blx r3
+
+_PrepareArguments_TZ:
+ /* Load IRAM_NS on IRAM_NS_BASE */
+ /* TZSW will call IRAM_NS code */
+ bl relocate_code
+
+ /* Jump to Coldboot in TZSW */
+ ldr r0, SecStartupAddr
+ b _ColdBootTzsw
+
+_CopyFirmware:
+ ldr r0, =Exynos5250_CMU_BASE
+ ldr r2, =CLK_DIV_FSYS2_OFFSET
+ ldr r1, [r0, r2]
+ bic r1, r1, #(0xFF << 8)
+ bic r1, r1, #(0xF)
+ orr r1, r1, #(0x9<< 8)
+ orr r1, r1, #0x3
+ str r1, [r0, r2]
+
+ /* Read booting information */
+ ldr r0, =0x10040000
+ ldr r1, [r0,#0x0]
+ bic r2, r1, #0xffffffc1
+
+ cmp r2, #0x8
+ beq _CopyFirmwareEMMC
+
+ /* SD/MMC BOOT */
+ cmp r2, #0x4
+ beq _CopyFirmwareSDMMC
+
+
+_CopyFirmwareSDMMC:
+ bl ASM_PFX(CopyFirmwareFromSDMMC)
+ b _PrepareArguments
+
+_CopyFirmwareEMMC:
+ bl ASM_PFX(CopyFirmwareFromEMMC)
+ b _PrepareArguments
+
+_ColdBootTzsw:
+ bl ASM_PFX(ColdBootForTzsw)
+_NeverReturn:
+ b _NeverReturn
+
+
+/*
+ * relocate_code: load NonSecure code(cpu1_wait)
+ */
+relocate_code:
+ adr r0, nscode_base @ r0: source address (start)
+ adr r1, nscode_end @ r1: source address (end)
+ ldr r2, =CONFIG_PHY_IRAM_NS_BASE @ r2: target address
+
+1:
+ ldmia r0!, {r3-r6}
+ stmia r2!, {r3-r6}
+ cmp r0, r1
+ blt 1b
+
+ .word 0xF57FF04F @dsb sy
+ .word 0xF57FF06F @isb sy
+
+ mov pc, lr
+
+/*
+ * CPU1 waits here until CPU0 wake it up.
+ * - below code is copied to CONFIG_PHY_IRAM_NS_BASE, which is non-secure memory.
+ */
+nscode_base:
+ adr r0, _ns_reg5
+ b 1f
+
+ .word 0x0 @ REG0: RESUME_ADDR
+ .word 0x0 @ REG1: RESUME_FLAG
+ .word 0x0 @ REG2
+ .word 0x0 @ REG3
+ .word 0x0 @ REG4
+_ns_reg5:
+ .word 0x0 @ REG5: CPU1_BOOT_REG
+ .word 0x0 @ REG6: REG_DIRECTGO_FLAG
+ .word 0x0 @ REG7: REG_DIRECTGO_ADDR
+ .word 0x0 @ REG8
+ .word 0x0 @ REG9
+
+ nop
+ nop
+
+1:
+#if 0 /* Exynos5250 do not require this code */
+ mrc p15, 0, r1, c0, c0, 5 @ MPIDR
+ and r1, r1, #0x3
+ add r0, r0, r1, lsl #0x2
+#endif
+cpu1_wait:
+ .word 0xE320F002 @ wfe instruction
+ ldr r1, [r0]
+ cmp r1, #0x0
+ bxne r1
+ b cpu1_wait
+ nop
+nscode_end: