/*++ Routine Description: This is the service to load the SEC Core from the Firmware Volume Arguments: LargestRegion - Memory to use for SEC. LargestRegionSize - Size of Memory to use for PEI BootFirmwareVolumeBase - Start of the Boot FV PeiCorePe32File - SEC PE32 Returns: Success means control is transfered and thus we should never return **/ VOID SecLoadFromCore ( IN UINTN LargestRegion, IN UINTN LargestRegionSize, IN UINTN BootFirmwareVolumeBase, IN VOID *PeiCorePe32File ) { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS TopOfMemory; VOID *TopOfStack; EFI_PHYSICAL_ADDRESS PeiCoreEntryPoint; EFI_SEC_PEI_HAND_OFF *SecCoreData; UINTN PeiStackSize; // // Compute Top Of Memory for Stack and PEI Core Allocations // TopOfMemory = LargestRegion + LargestRegionSize; PeiStackSize = (UINTN)RShiftU64((UINT64)STACK_SIZE,1); // // |-----------| <---- TemporaryRamBase + TemporaryRamSize // | Heap | // | | // |-----------| <---- StackBase / PeiTemporaryMemoryBase // | | // | Stack | // |-----------| <---- TemporaryRamBase // TopOfStack = (VOID *)(LargestRegion + PeiStackSize); TopOfMemory = LargestRegion + PeiStackSize; // // Reservet space for storing PeiCore's parament in stack. // TopOfStack = (VOID *)((UINTN)TopOfStack - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT); TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); // // Bind this information into the SEC hand-off state // SecCoreData = (EFI_SEC_PEI_HAND_OFF*)(UINTN) TopOfStack; SecCoreData->DataSize = sizeof(EFI_SEC_PEI_HAND_OFF); SecCoreData->BootFirmwareVolumeBase = (VOID*)BootFirmwareVolumeBase; SecCoreData->BootFirmwareVolumeSize = PcdGet32 (PcdEmuFirmwareFdSize); SecCoreData->TemporaryRamBase = (VOID*)(UINTN)LargestRegion; SecCoreData->TemporaryRamSize = STACK_SIZE; SecCoreData->StackBase = SecCoreData->TemporaryRamBase; SecCoreData->StackSize = PeiStackSize; SecCoreData->PeiTemporaryRamBase = (VOID*) ((UINTN) SecCoreData->TemporaryRamBase + PeiStackSize); SecCoreData->PeiTemporaryRamSize = STACK_SIZE - PeiStackSize; // // Find the SEC Core Entry Point // Status = SecPeCoffGetEntryPoint (PeiCorePe32File, (VOID **)&PeiCoreEntryPoint); if (EFI_ERROR (Status)) { return ; } // // Transfer control to the SEC Core // PeiSwitchStacks ( (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint, SecCoreData, (VOID *)gPpiList, TopOfStack ); // // If we get here, then the SEC Core returned. This is an error // return ; }
VOID SecLoadSecCore ( IN UINTN TemporaryRam, IN UINTN TemporaryRamSize, IN VOID *BootFirmwareVolumeBase, IN UINTN BootFirmwareVolumeSize, IN VOID *SecCorePe32File ) /*++ Routine Description: This is the service to load the SEC Core from the Firmware Volume Arguments: TemporaryRam - Memory to use for SEC. TemporaryRamSize - Size of Memory to use for SEC BootFirmwareVolumeBase - Start of the Boot FV SecCorePe32File - SEC Core PE32 Returns: Success means control is transfered and thus we should never return --*/ { EFI_STATUS Status; VOID *TopOfStack; VOID *SecCoreEntryPoint; EFI_SEC_PEI_HAND_OFF *SecCoreData; UINTN SecStackSize; // // Compute Top Of Memory for Stack and PEI Core Allocations // SecStackSize = TemporaryRamSize >> 1; // // |-----------| <---- TemporaryRamBase + TemporaryRamSize // | Heap | // | | // |-----------| <---- StackBase / PeiTemporaryMemoryBase // | | // | Stack | // |-----------| <---- TemporaryRamBase // TopOfStack = (VOID *)(TemporaryRam + SecStackSize); // // Reservet space for storing PeiCore's parament in stack. // TopOfStack = (VOID *)((UINTN)TopOfStack - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT); TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); // // Bind this information into the SEC hand-off state // SecCoreData = (EFI_SEC_PEI_HAND_OFF*)(UINTN)TopOfStack; SecCoreData->DataSize = sizeof (EFI_SEC_PEI_HAND_OFF); SecCoreData->BootFirmwareVolumeBase = BootFirmwareVolumeBase; SecCoreData->BootFirmwareVolumeSize = BootFirmwareVolumeSize; SecCoreData->TemporaryRamBase = (VOID*)TemporaryRam; SecCoreData->TemporaryRamSize = TemporaryRamSize; SecCoreData->StackBase = SecCoreData->TemporaryRamBase; SecCoreData->StackSize = SecStackSize; SecCoreData->PeiTemporaryRamBase = (VOID*) ((UINTN) SecCoreData->TemporaryRamBase + SecStackSize); SecCoreData->PeiTemporaryRamSize = TemporaryRamSize - SecStackSize; // // Load the PEI Core from a Firmware Volume // Status = SecPeCoffGetEntryPoint ( SecCorePe32File, &SecCoreEntryPoint ); if (EFI_ERROR (Status)) { return ; } // // Transfer control to the SEC Core // SwitchStack ( (SWITCH_STACK_ENTRY_POINT)(UINTN)SecCoreEntryPoint, SecCoreData, GetThunkPpiList (), TopOfStack ); // // If we get here, then the SEC Core returned. This is an error // return ; }