/** @file
* Main file supporting the SEC Phase on ARM Platforms
*
-* Copyright (c) 2011, ARM Limited. All rights reserved.
+* 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
*
**/
+#include <Library/ArmTrustedMonitorLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/PrintLib.h>
#include <Library/BaseMemoryLib.h>
#define SerialPrint(txt) SerialPortWrite ((UINT8*)txt, AsciiStrLen(txt)+1);
-extern VOID *monitor_vector_table;
-
VOID
CEntryPoint (
IN UINTN MpId
UINTN CharCount;
UINTN JumpAddress;
+ // Invalidate the data cache. Doesn't have to do the Data cache clean.
+ ArmInvalidateDataCache();
+
+ // Invalidate Instruction Cache
+ ArmInvalidateInstructionCache();
+
+ // Invalidate I & D TLBs
+ ArmInvalidateInstructionAndDataTlb();
+
+ // CPU specific settings
+ ArmCpuSetup (MpId);
+
+ // Enable Floating Point Coprocessor if supported by the platform
+ if (FixedPcdGet32 (PcdVFPEnabled)) {
+ ArmEnableVFP();
+ }
+
// Primary CPU clears out the SCU tag RAMs, secondaries wait
if (IS_PRIMARY_CORE(MpId)) {
- ArmCpuSetup (MpId);
-
if (ArmIsMpCore()) {
ArmCpuSynchronizeSignal (ARM_CPU_EVENT_BOOT_MEM_INIT);
}
ArmGicEnableInterruptInterface (PcdGet32(PcdGicInterruptInterfaceBase));
}
- // Invalidate the data cache. Doesn't have to do the Data cache clean.
- ArmInvalidateDataCache();
-
- // Invalidate Instruction Cache
- ArmInvalidateInstructionCache();
-
- // Invalidate I & D TLBs
- ArmInvalidateInstructionAndDataTlb();
-
// Enable Full Access to CoProcessors
ArmWriteCPACR (CPACR_CP_FULL_ACCESS);
- if (FixedPcdGet32 (PcdVFPEnabled)) {
- ArmEnableVFP();
- }
-
if (IS_PRIMARY_CORE(MpId)) {
// Initialize peripherals that must be done at the early stage
// Example: Some L2x0 controllers must be initialized in Secure World
// Test if Trustzone is supported on this platform
if (FixedPcdGetBool (PcdTrustzoneSupport)) {
- // Ensure the Monitor Stack Base & Size have been set
- ASSERT(PcdGet32(PcdCPUCoresSecMonStackBase) != 0);
- ASSERT(PcdGet32(PcdCPUCoreSecMonStackSize) != 0);
-
if (ArmIsMpCore()) {
// Setup SMP in Non Secure world
ArmCpuSetupSmpNonSecure (GET_CORE_ID(MpId));
}
// Enter Monitor Mode
- enter_monitor_mode ((VOID*)(PcdGet32(PcdCPUCoresSecMonStackBase) + (PcdGet32(PcdCPUCoreSecMonStackSize) * GET_CORE_POS(MpId))));
-
- //Write the monitor mode vector table address
- ArmWriteVMBar((UINT32) &monitor_vector_table);
-
- //-------------------- Monitor Mode ---------------------
- // Setup the Trustzone Chipsets
- if (IS_PRIMARY_CORE(MpId)) {
- ArmPlatformTrustzoneInit ();
-
- // Waiting for the Primary Core to have finished to initialize the Secure World
- ArmCpuSynchronizeSignal (ARM_CPU_EVENT_SECURE_INIT);
- } else {
- // The secondary cores need to wait until the Trustzone chipsets configuration is done
- // before switching to Non Secure World
-
- // Waiting for the Primary Core to have finished to initialize the Secure World
- ArmCpuSynchronizeWait (ARM_CPU_EVENT_SECURE_INIT);
- }
-
- // Transfer the interrupt to Non-secure World
- ArmGicSetupNonSecure (PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase));
-
- // Write to CP15 Non-secure Access Control Register
- ArmWriteNsacr (PcdGet32 (PcdArmNsacr));
-
- // CP15 Secure Configuration Register
- ArmWriteScr (PcdGet32 (PcdArmScr));
+ enter_monitor_mode ((UINTN)TrustedWorldInitialization, MpId, (VOID*)(PcdGet32(PcdCPUCoresSecMonStackBase) + (PcdGet32(PcdCPUCoreSecMonStackSize) * (GET_CORE_POS(MpId) + 1))));
} else {
if (IS_PRIMARY_CORE(MpId)) {
SerialPrint ("Trust Zone Configuration is disabled\n\r");
// If we want to keep this function call we need to ensure the SVC's SPSR point to the same Program
// Status Register as the the current one (CPSR).
copy_cpsr_into_spsr ();
+
+ // Call the Platform specific function to execute additional actions if required
+ JumpAddress = PcdGet32 (PcdFvBaseAddress);
+ ArmPlatformSecExtraAction (MpId, &JumpAddress);
+
+ NonTrustedWorldTransition (MpId, JumpAddress);
+ }
+ ASSERT (0); // We must never return from the above function
+}
+
+VOID
+TrustedWorldInitialization (
+ IN UINTN MpId
+ )
+{
+ UINTN JumpAddress;
+
+ //-------------------- Monitor Mode ---------------------
+
+ // Set up Monitor World (Vector Table, etc)
+ ArmSecureMonitorWorldInitialize ();
+
+ // Setup the Trustzone Chipsets
+ if (IS_PRIMARY_CORE(MpId)) {
+ ArmPlatformTrustzoneInit ();
+
+ if (ArmIsMpCore()) {
+ // Waiting for the Primary Core to have finished to initialize the Secure World
+ ArmCpuSynchronizeSignal (ARM_CPU_EVENT_SECURE_INIT);
+ }
+ } else {
+ // The secondary cores need to wait until the Trustzone chipsets configuration is done
+ // before switching to Non Secure World
+
+ // Waiting for the Primary Core to have finished to initialize the Secure World
+ ArmCpuSynchronizeWait (ARM_CPU_EVENT_SECURE_INIT);
}
+ // Transfer the interrupt to Non-secure World
+ ArmGicSetupNonSecure (PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase));
+
+ // Call the Platform specific fucntion to execute additional actions if required
JumpAddress = PcdGet32 (PcdFvBaseAddress);
ArmPlatformSecExtraAction (MpId, &JumpAddress);
+ // Write to CP15 Non-secure Access Control Register
+ ArmWriteNsacr (PcdGet32 (PcdArmNsacr));
+
+ // CP15 Secure Configuration Register
+ ArmWriteScr (PcdGet32 (PcdArmScr));
+
+ NonTrustedWorldTransition (MpId, JumpAddress);
+}
+
+VOID
+NonTrustedWorldTransition (
+ IN UINTN MpId,
+ IN UINTN JumpAddress
+ )
+{
// If PcdArmNonSecModeTransition is defined then set this specific mode to CPSR before the transition
// By not set, the mode for Non Secure World is SVC
if (PcdGet32 (PcdArmNonSecModeTransition) != 0) {