]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Sec/Sec.c
ArmPlatformPkg/Sec: Move 'ArmPlatformSecExtraAction' before we set NSACR & SCR
[mirror_edk2.git] / ArmPlatformPkg / Sec / Sec.c
index d9831a5c44ce671c4fd7fe792255642d07f82405..00d042cf094d6d39b5cd60b3bf47b6f4fbd9d2ff 100644 (file)
@@ -1,7 +1,7 @@
 /** @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         
@@ -13,6 +13,7 @@
 *
 **/
 
+#include <Library/ArmTrustedMonitorLib.h>
 #include <Library/DebugAgentLib.h>
 #include <Library/PrintLib.h>
 #include <Library/BaseMemoryLib.h>
@@ -24,8 +25,6 @@
 
 #define SerialPrint(txt)  SerialPortWrite ((UINT8*)txt, AsciiStrLen(txt)+1);
 
-extern VOID *monitor_vector_table;
-
 VOID
 CEntryPoint (
   IN  UINTN                     MpId
@@ -35,10 +34,25 @@ CEntryPoint (
   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);
     }
@@ -69,22 +83,9 @@ CEntryPoint (
     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
@@ -100,44 +101,13 @@ CEntryPoint (
 
   // 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");
@@ -147,11 +117,66 @@ CEntryPoint (
     // 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) {