2009-05-27 23:10:18 +02:00
|
|
|
/** @file
|
|
|
|
Main SEC phase code. Transitions to PEI.
|
|
|
|
|
|
|
|
Copyright (c) 2008 - 2009, Intel Corporation
|
|
|
|
|
|
|
|
All rights reserved. This program and the accompanying materials
|
|
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include <PiPei.h>
|
|
|
|
#include <Library/BaseLib.h>
|
|
|
|
#include <Library/DebugLib.h>
|
|
|
|
#include <Library/BaseMemoryLib.h>
|
2010-01-04 17:17:59 +01:00
|
|
|
#include <Library/PeimEntryPoint.h>
|
2009-05-27 23:10:18 +02:00
|
|
|
#include <Library/PeiServicesLib.h>
|
|
|
|
#include <Ppi/TemporaryRamSupport.h>
|
|
|
|
#include <Library/PcdLib.h>
|
2009-11-25 05:26:09 +01:00
|
|
|
#include <Library/UefiCpuLib.h>
|
2009-05-27 23:10:18 +02:00
|
|
|
|
|
|
|
#include "SecMain.h"
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
TemporaryRamMigration (
|
|
|
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
|
|
|
IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
|
|
|
|
IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
|
|
|
|
IN UINTN CopySize
|
|
|
|
);
|
|
|
|
|
|
|
|
STATIC TEMPORARY_RAM_SUPPORT_PPI mTempRamSupportPpi = {
|
|
|
|
(TEMPORARY_RAM_MIGRATION) TemporaryRamMigration
|
|
|
|
};
|
|
|
|
|
|
|
|
STATIC EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
|
|
|
|
{
|
|
|
|
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
|
|
|
&gEfiTemporaryRamSupportPpiGuid,
|
|
|
|
&mTempRamSupportPpi
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
|
|
InitializeIdtPtr (
|
|
|
|
IN VOID* IdtPtr
|
|
|
|
)
|
|
|
|
{
|
|
|
|
IA32_DESCRIPTOR IdtDescriptor;
|
|
|
|
|
|
|
|
IdtDescriptor.Base = (UINTN)IdtPtr;
|
|
|
|
IdtDescriptor.Limit = (UINT16) 0;
|
|
|
|
AsmWriteIdtr (&IdtDescriptor);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
EFIAPI
|
|
|
|
SecCoreStartupWithStack (
|
2010-01-04 17:17:59 +01:00
|
|
|
IN EFI_FIRMWARE_VOLUME_HEADER *BootFv,
|
2009-12-17 00:29:17 +01:00
|
|
|
IN VOID *TopOfCurrentStack
|
2009-05-27 23:10:18 +02:00
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_SEC_PEI_HAND_OFF *SecCoreData;
|
|
|
|
UINT8 *BottomOfTempRam;
|
|
|
|
UINT8 *TopOfTempRam;
|
|
|
|
UINTN SizeOfTempRam;
|
|
|
|
VOID *IdtPtr;
|
2009-12-17 00:29:17 +01:00
|
|
|
VOID *PeiCoreEntryPoint;
|
2009-05-27 23:10:18 +02:00
|
|
|
|
2010-01-04 17:17:59 +01:00
|
|
|
DEBUG ((EFI_D_INFO,
|
|
|
|
"SecCoreStartupWithStack(0x%x, 0x%x)\n",
|
|
|
|
(UINT32)(UINTN)BootFv,
|
|
|
|
(UINT32)(UINTN)TopOfCurrentStack
|
|
|
|
));
|
|
|
|
|
|
|
|
ProcessLibraryConstructorList (NULL, NULL);
|
|
|
|
|
2009-11-25 05:26:09 +01:00
|
|
|
//
|
|
|
|
// Initialize floating point operating environment
|
|
|
|
// to be compliant with UEFI spec.
|
|
|
|
//
|
|
|
|
InitializeFloatingPointUnits ();
|
|
|
|
|
2009-05-27 23:10:18 +02:00
|
|
|
BottomOfTempRam = (UINT8*)(UINTN) INITIAL_TOP_OF_STACK;
|
|
|
|
SizeOfTempRam = (UINTN) SIZE_64KB;
|
|
|
|
TopOfTempRam = BottomOfTempRam + SizeOfTempRam;
|
|
|
|
|
|
|
|
//
|
|
|
|
// |-------------|
|
|
|
|
// | SecCoreData | 4k
|
|
|
|
// |-------------|
|
|
|
|
// | Heap | 28k
|
|
|
|
// |-------------|
|
|
|
|
// | Stack | 32k
|
|
|
|
// |-------------| <---- INITIAL_TOP_OF_STACK
|
|
|
|
//
|
|
|
|
|
|
|
|
//
|
|
|
|
// Bind this information into the SEC hand-off state
|
|
|
|
//
|
|
|
|
SecCoreData = (EFI_SEC_PEI_HAND_OFF*)((UINTN) TopOfTempRam - SIZE_4KB);
|
|
|
|
SecCoreData->DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
|
|
|
|
|
|
|
|
SecCoreData->TemporaryRamBase = (VOID*) BottomOfTempRam;
|
|
|
|
SecCoreData->TemporaryRamSize = SizeOfTempRam;
|
|
|
|
|
|
|
|
SecCoreData->PeiTemporaryRamSize = 28 * SIZE_1KB;
|
|
|
|
SecCoreData->PeiTemporaryRamBase = (VOID*)((UINTN)SecCoreData - SecCoreData->PeiTemporaryRamSize);
|
|
|
|
|
|
|
|
SecCoreData->StackBase = SecCoreData->TemporaryRamBase;
|
|
|
|
SecCoreData->StackSize = (UINTN)SecCoreData->PeiTemporaryRamBase - (UINTN)SecCoreData->TemporaryRamBase;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Initialize the IDT Pointer, since IA32 & X64 architectures
|
|
|
|
// use it to store the PEI Services pointer.
|
|
|
|
//
|
|
|
|
IdtPtr = (VOID*)((UINT8*)SecCoreData + sizeof (*SecCoreData) + sizeof (UINTN));
|
|
|
|
IdtPtr = ALIGN_POINTER(IdtPtr, 16);
|
|
|
|
InitializeIdtPtr (IdtPtr);
|
|
|
|
|
2010-01-04 17:17:59 +01:00
|
|
|
FindPeiCoreEntryPoint (&BootFv, &PeiCoreEntryPoint);
|
|
|
|
|
|
|
|
SecCoreData->BootFirmwareVolumeBase = BootFv;
|
|
|
|
SecCoreData->BootFirmwareVolumeSize = BootFv->FvLength;
|
2009-12-17 00:29:17 +01:00
|
|
|
|
|
|
|
if (PeiCoreEntryPoint != NULL) {
|
|
|
|
DEBUG ((EFI_D_INFO,
|
|
|
|
"Calling PEI Core entry point at 0x%x\n",
|
|
|
|
PeiCoreEntryPoint
|
|
|
|
));
|
|
|
|
//
|
|
|
|
// Transfer control to the PEI Core
|
|
|
|
//
|
|
|
|
PeiSwitchStacks (
|
|
|
|
(SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint,
|
|
|
|
SecCoreData,
|
|
|
|
(VOID *) (UINTN) ((EFI_PEI_PPI_DESCRIPTOR *) &mPrivateDispatchTable),
|
|
|
|
NULL,
|
|
|
|
TopOfCurrentStack,
|
|
|
|
(VOID *)((UINTN)SecCoreData->StackBase + SecCoreData->StackSize)
|
|
|
|
);
|
|
|
|
}
|
2009-05-27 23:10:18 +02:00
|
|
|
|
|
|
|
//
|
2009-12-17 00:29:17 +01:00
|
|
|
// If we get here, then either we couldn't locate the PEI Core, or
|
|
|
|
// the PEI Core returned.
|
|
|
|
//
|
|
|
|
// Both of these errors are unrecoverable.
|
2009-05-27 23:10:18 +02:00
|
|
|
//
|
|
|
|
ASSERT (FALSE);
|
|
|
|
CpuDeadLoop ();
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
TemporaryRamMigration (
|
|
|
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
|
|
|
IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
|
|
|
|
IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
|
|
|
|
IN UINTN CopySize
|
|
|
|
)
|
|
|
|
{
|
|
|
|
DEBUG ((EFI_D_ERROR, "TemporaryRamMigration(0x%x, 0x%x, 0x%x)\n", (UINTN)TemporaryMemoryBase, (UINTN)PermanentMemoryBase, CopySize));
|
|
|
|
|
|
|
|
//
|
|
|
|
// Migrate the whole temporary memory to permenent memory.
|
|
|
|
//
|
|
|
|
CopyMem((VOID*)(UINTN)PermanentMemoryBase, (VOID*)(UINTN)TemporaryMemoryBase, CopySize);
|
|
|
|
|
|
|
|
//
|
|
|
|
// SecSwitchStack function must be invoked after the memory migration
|
|
|
|
// immediatly, also we need fixup the stack change caused by new call into
|
|
|
|
// permenent memory.
|
|
|
|
//
|
|
|
|
SecSwitchStack (
|
|
|
|
(UINTN) TemporaryMemoryBase,
|
|
|
|
(UINTN) PermanentMemoryBase,
|
|
|
|
CopySize
|
|
|
|
);
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|