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:
oliviermartin
2012-02-28 17:28:44 +00:00
parent 8cc852f791
commit a853088911
4 changed files with 98 additions and 54 deletions

View File

@@ -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);