summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ArmPkg/ArmPkg.dec28
-rw-r--r--ArmPlatformPkg/Sec/Helper.S13
-rw-r--r--ArmPlatformPkg/Sec/Helper.asm13
-rw-r--r--ArmPlatformPkg/Sec/Sec.c21
-rw-r--r--ArmPlatformPkg/Sec/Sec.inf7
-rw-r--r--ArmPlatformPkg/Sec/SecInternal.h5
6 files changed, 77 insertions, 10 deletions
diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index c9bf606666..9a3bc3a7b0 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -101,6 +101,34 @@
gArmTokenSpaceGuid.PcdFdSize|0|UINT32|0x0000002C
gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT32|0x0000002D
gArmTokenSpaceGuid.PcdFvSize|0|UINT32|0x0000002E
+
+ #
+ # ARM Security Extension
+ #
+
+ # Secure Configuration Register
+ # - BIT0 : NS - Non Secure bit
+ # - BIT1 : IRQ Handler
+ # - BIT2 : FIQ Handler
+ # - BIT3 : EA - External Abort
+ # - BIT4 : FW - F bit writable
+ # - BIT5 : AW - A bit writable
+ # - BIT6 : nET - Not Early Termination
+ # - BIT7 : SCD - Secure Monitor Call Disable
+ # - BIT8 : HCE - Hyp Call enable
+ # - BIT9 : SIF - Secure Instruction Fetch
+ # 0x31 = NS | EA | FW
+ gArmTokenSpaceGuid.PcdArmScr|0x31|UINT32|0x00000038
+
+ # Non Secure Access Control Register
+ # - BIT15 : NSASEDIS - Disable Non-secure Advanced SIMD functionality
+ # - BIT14 : NSD32DIS - Disable Non-secure use of D16-D31
+ # - BIT11 : cp11 - Non-secure access to coprocessor 11 enable
+ # - BIT10 : cp10 - Non-secure access to coprocessor 10 enable
+ # 0xC00 = cp10 | cp11
+ gArmTokenSpaceGuid.PcdArmNsacr|0xC00|UINT32|0x00000039
+
+ gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x0|UINT32|0x0000003E
# System Memory (DRAM): These PCDs define the region of in-built system memory
# Some platforms can get DRAM extensions, these additional regions will be declared
diff --git a/ArmPlatformPkg/Sec/Helper.S b/ArmPlatformPkg/Sec/Helper.S
index da3b0e033b..61491b5655 100644
--- a/ArmPlatformPkg/Sec/Helper.S
+++ b/ArmPlatformPkg/Sec/Helper.S
@@ -19,6 +19,7 @@ GCC_ASM_EXPORT(monitor_vector_table)
GCC_ASM_EXPORT(return_from_exception)
GCC_ASM_EXPORT(enter_monitor_mode)
GCC_ASM_EXPORT(copy_cpsr_into_spsr)
+GCC_ASM_EXPORT(set_non_secure_mode)
ASM_PFX(monitor_vector_table):
ldr pc, dead
@@ -68,6 +69,18 @@ ASM_PFX(copy_cpsr_into_spsr):
msr spsr_cxsf, r0
bx lr
+# Set the Non Secure Mode
+ASM_PFX(set_non_secure_mode):
+ push { r1 }
+ and r0, r0, #0x1f @ Keep only the mode bits
+ mrs r1, spsr @ Read the spsr
+ bic r1, r1, #0x1f @ Clear all mode bits
+ orr r1, r1, r0
+ msr spsr_cxsf, r1 @ write back spsr (may have caused a mode switch)
+ isb
+ pop { r1 }
+ bx lr @ return (hopefully thumb-safe!)
+
dead:
b dead
diff --git a/ArmPlatformPkg/Sec/Helper.asm b/ArmPlatformPkg/Sec/Helper.asm
index 43a0749138..1649df399a 100644
--- a/ArmPlatformPkg/Sec/Helper.asm
+++ b/ArmPlatformPkg/Sec/Helper.asm
@@ -15,6 +15,7 @@
EXPORT return_from_exception
EXPORT enter_monitor_mode
EXPORT copy_cpsr_into_spsr
+ EXPORT set_non_secure_mode
AREA Helper, CODE, READONLY
@@ -60,6 +61,18 @@ copy_cpsr_into_spsr
msr spsr_cxsf, r0
bx lr
+// Set the Non Secure Mode
+set_non_secure_mode
+ push { r1 }
+ and r0, r0, #0x1f // Keep only the mode bits
+ mrs r1, spsr // Read the spsr
+ bic r1, r1, #0x1f // Clear all mode bits
+ orr r1, r1, r0
+ msr spsr_cxsf, r1 // write back spsr (may have caused a mode switch)
+ isb
+ pop { r1 }
+ bx lr // return (hopefully thumb-safe!)
+
dead
B dead
diff --git a/ArmPlatformPkg/Sec/Sec.c b/ArmPlatformPkg/Sec/Sec.c
index a40f43683a..d9831a5c44 100644
--- a/ArmPlatformPkg/Sec/Sec.c
+++ b/ArmPlatformPkg/Sec/Sec.c
@@ -133,16 +133,11 @@ CEntryPoint (
// Transfer the interrupt to Non-secure World
ArmGicSetupNonSecure (PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase));
- // Write to CP15 Non-secure Access Control Register :
- // - Enable CP10 and CP11 accesses in NS World
- // - Enable Access to Preload Engine in NS World
- // - Enable lockable TLB entries allocation in NS world
- // - Enable R/W access to SMP bit of Auxiliary Control Register in NS world
- ArmWriteNsacr (NSACR_NS_SMP | NSACR_TL | NSACR_PLE | NSACR_CP(10) | NSACR_CP(11));
-
- // CP15 Secure Configuration Register with Non Secure bit (SCR_NS), CPSR.A modified in any
- // security state (SCR_AW), CPSR.F modified in any security state (SCR_FW)
- ArmWriteScr (SCR_NS | SCR_FW | SCR_AW);
+ // Write to CP15 Non-secure Access Control Register
+ ArmWriteNsacr (PcdGet32 (PcdArmNsacr));
+
+ // CP15 Secure Configuration Register
+ ArmWriteScr (PcdGet32 (PcdArmScr));
} else {
if (IS_PRIMARY_CORE(MpId)) {
SerialPrint ("Trust Zone Configuration is disabled\n\r");
@@ -157,6 +152,12 @@ CEntryPoint (
JumpAddress = PcdGet32 (PcdFvBaseAddress);
ArmPlatformSecExtraAction (MpId, &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) {
+ set_non_secure_mode ((ARM_PROCESSOR_MODE)PcdGet32 (PcdArmNonSecModeTransition));
+ }
+
return_from_exception (JumpAddress);
//-------------------- Non Secure Mode ---------------------
diff --git a/ArmPlatformPkg/Sec/Sec.inf b/ArmPlatformPkg/Sec/Sec.inf
index 9980c6b951..f80db4a630 100644
--- a/ArmPlatformPkg/Sec/Sec.inf
+++ b/ArmPlatformPkg/Sec/Sec.inf
@@ -54,9 +54,16 @@
gArmTokenSpaceGuid.PcdTrustzoneSupport
gArmTokenSpaceGuid.PcdVFPEnabled
+ gArmTokenSpaceGuid.PcdArmScr
+ gArmTokenSpaceGuid.PcdArmNsacr
+ gArmTokenSpaceGuid.PcdArmNonSecModeTransition
+
gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
gArmTokenSpaceGuid.PcdArmPrimaryCore
+ gArmTokenSpaceGuid.PcdSecureFvBaseAddress
+ gArmTokenSpaceGuid.PcdSecureFvSize
+
gArmTokenSpaceGuid.PcdFvBaseAddress
gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase
diff --git a/ArmPlatformPkg/Sec/SecInternal.h b/ArmPlatformPkg/Sec/SecInternal.h
index 4d1b0f6089..cf9c1707d5 100644
--- a/ArmPlatformPkg/Sec/SecInternal.h
+++ b/ArmPlatformPkg/Sec/SecInternal.h
@@ -59,6 +59,11 @@ copy_cpsr_into_spsr (
);
VOID
+set_non_secure_mode (
+ IN ARM_PROCESSOR_MODE Mode
+ );
+
+VOID
SecCommonExceptionEntry (
IN UINT32 Entry,
IN UINT32 LR