ArmPlatformPkg/Sec: Fix transition to Trusted Monitor World with ARMGCC
The enter_monitor_world() function was trashing r0/r1/r2 registers and then was returning back to 'C'. The compiler might have used these registers in the C code. These new design prevents register corruptions. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13060 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -32,7 +32,6 @@ CEntryPoint (
|
||||
{
|
||||
CHAR8 Buffer[100];
|
||||
UINTN CharCount;
|
||||
UINTN JumpAddress;
|
||||
|
||||
// Invalidate the data cache. Doesn't have to do the Data cache clean.
|
||||
ArmInvalidateDataCache();
|
||||
@@ -111,35 +110,7 @@ CEntryPoint (
|
||||
}
|
||||
|
||||
// Enter Monitor Mode
|
||||
enter_monitor_mode ((VOID*)(PcdGet32(PcdCPUCoresSecMonStackBase) + (PcdGet32(PcdCPUCoreSecMonStackSize) * (GET_CORE_POS(MpId) + 1))));
|
||||
|
||||
//-------------------- Monitor Mode ---------------------
|
||||
|
||||
// Set up Monitor World (Vector Table, etc)
|
||||
ArmSecureMonitorWorldInitialize ();
|
||||
|
||||
// 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");
|
||||
@@ -149,7 +120,56 @@ 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 ();
|
||||
|
||||
NonTrustedWorldTransition (MpId);
|
||||
}
|
||||
ASSERT (0); // We must never return from the above function
|
||||
}
|
||||
|
||||
VOID
|
||||
TrustedWorldInitialization (
|
||||
IN UINTN MpId
|
||||
)
|
||||
{
|
||||
//-------------------- 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));
|
||||
|
||||
// Write to CP15 Non-secure Access Control Register
|
||||
ArmWriteNsacr (PcdGet32 (PcdArmNsacr));
|
||||
|
||||
// CP15 Secure Configuration Register
|
||||
ArmWriteScr (PcdGet32 (PcdArmScr));
|
||||
|
||||
NonTrustedWorldTransition (MpId);
|
||||
}
|
||||
|
||||
VOID
|
||||
NonTrustedWorldTransition (
|
||||
IN UINTN MpId
|
||||
)
|
||||
{
|
||||
UINTN JumpAddress;
|
||||
|
||||
JumpAddress = PcdGet32 (PcdFvBaseAddress);
|
||||
ArmPlatformSecExtraAction (MpId, &JumpAddress);
|
||||
|
Reference in New Issue
Block a user