1/** @file 2 3 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php. 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12**/ 13 14#include "SecMain.h" 15#include "SecFsp.h" 16 17EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = { 18 SecTemporaryRamSupport 19}; 20 21EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = { 22 { 23 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), 24 &gEfiTemporaryRamSupportPpiGuid, 25 &gSecTemporaryRamSupportPpi 26 } 27}; 28 29// 30// These are IDT entries pointing to 08:FFFFFFE4h. 31// 32UINT64 mIdtEntryTemplate = 0xffff8e000008ffe4ULL; 33 34/** 35 36 Entry point to the C language phase of SEC. After the SEC assembly 37 code has initialized some temporary memory and set up the stack, 38 the control is transferred to this function. 39 40 41 @param[in] SizeOfRam Size of the temporary memory available for use. 42 @param[in] TempRamBase Base address of temporary ram 43 @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume. 44 @param[in] PeiCore PeiCore entry point. 45 @param[in] BootLoaderStack BootLoader stack. 46 @param[in] ApiIdx the index of API. 47 48 @return This function never returns. 49 50**/ 51VOID 52EFIAPI 53SecStartup ( 54 IN UINT32 SizeOfRam, 55 IN UINT32 TempRamBase, 56 IN VOID *BootFirmwareVolume, 57 IN PEI_CORE_ENTRY PeiCore, 58 IN UINT32 BootLoaderStack, 59 IN UINT32 ApiIdx 60 ) 61{ 62 EFI_SEC_PEI_HAND_OFF SecCoreData; 63 IA32_DESCRIPTOR IdtDescriptor; 64 SEC_IDT_TABLE IdtTableInStack; 65 UINT32 Index; 66 FSP_GLOBAL_DATA PeiFspData; 67 UINT64 ExceptionHandler; 68 69 // 70 // Process all libraries constructor function linked to SecCore. 71 // 72 ProcessLibraryConstructorList (); 73 74 // 75 // Initialize floating point operating environment 76 // to be compliant with UEFI spec. 77 // 78 InitializeFloatingPointUnits (); 79 80 81 // |-------------------|----> 82 // |Idt Table | 83 // |-------------------| 84 // |PeiService Pointer | PeiStackSize 85 // |-------------------| 86 // | | 87 // | Stack | 88 // |-------------------|----> 89 // | | 90 // | | 91 // | Heap | PeiTemporayRamSize 92 // | | 93 // | | 94 // |-------------------|----> TempRamBase 95 IdtTableInStack.PeiService = NULL; 96 ExceptionHandler = FspGetExceptionHandler(mIdtEntryTemplate); 97 for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) { 98 CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&ExceptionHandler, sizeof (UINT64)); 99 } 100 101 IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable; 102 IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1); 103 104 AsmWriteIdtr (&IdtDescriptor); 105 106 // 107 // Initialize the global FSP data region 108 // 109 FspGlobalDataInit (&PeiFspData, BootLoaderStack, (UINT8)ApiIdx); 110 111 // 112 // Update the base address and length of Pei temporary memory 113 // 114 SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF); 115 SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume; 116 SecCoreData.BootFirmwareVolumeSize = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)BootFirmwareVolume)->FvLength; 117 SecCoreData.TemporaryRamBase = (VOID*)(UINTN) TempRamBase; 118 SecCoreData.TemporaryRamSize = SizeOfRam; 119 SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase; 120 SecCoreData.PeiTemporaryRamSize = SizeOfRam >> 1; 121 SecCoreData.StackBase = (VOID*)(UINTN)(TempRamBase + SecCoreData.PeiTemporaryRamSize); 122 SecCoreData.StackSize = SizeOfRam >> 1; 123 124 // 125 // Call PeiCore Entry 126 // 127 PeiCore (&SecCoreData, mPeiSecPlatformInformationPpi); 128 129 // 130 // Should never be here 131 // 132 CpuDeadLoop (); 133} 134 135/** 136 This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into 137 permanent memory. 138 139 @param[in] PeiServices Pointer to the PEI Services Table. 140 @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the 141 Temporary RAM contents. 142 @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the 143 Temporary RAM contents. 144 @param[in] CopySize Amount of memory to migrate from temporary to permanent memory. 145 146 @retval EFI_SUCCESS The data was successfully returned. 147 @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when 148 TemporaryMemoryBase > PermanentMemoryBase. 149 150**/ 151EFI_STATUS 152EFIAPI 153SecTemporaryRamSupport ( 154 IN CONST EFI_PEI_SERVICES **PeiServices, 155 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, 156 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, 157 IN UINTN CopySize 158 ) 159{ 160 IA32_DESCRIPTOR IdtDescriptor; 161 VOID* OldHeap; 162 VOID* NewHeap; 163 VOID* OldStack; 164 VOID* NewStack; 165 166 OldHeap = (VOID*)(UINTN)TemporaryMemoryBase; 167 NewHeap = (VOID*)((UINTN)PermanentMemoryBase + CopySize / 2); 168 169 OldStack = (VOID*)((UINTN)TemporaryMemoryBase + CopySize / 2); 170 NewStack = (VOID*)(UINTN)PermanentMemoryBase; 171 172 // 173 // Migrate Heap 174 // 175 CopyMem (NewHeap, OldHeap, CopySize / 2); 176 177 // 178 // Migrate Stack 179 // 180 CopyMem (NewStack, OldStack, CopySize / 2); 181 182 183 // 184 // We need *not* fix the return address because currently, 185 // The PeiCore is executed in flash. 186 // 187 188 // 189 // Rebase IDT table in permanent memory 190 // 191 AsmReadIdtr (&IdtDescriptor); 192 IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack; 193 194 AsmWriteIdtr (&IdtDescriptor); 195 196 // 197 // Fixed the FSP data pointer 198 // 199 FspDataPointerFixUp ((UINTN)NewStack - (UINTN)OldStack); 200 201 // 202 // SecSwitchStack function must be invoked after the memory migration 203 // immediately, also we need fixup the stack change caused by new call into 204 // permanent memory. 205 // 206 SecSwitchStack ( 207 (UINT32) (UINTN) OldStack, 208 (UINT32) (UINTN) NewStack 209 ); 210 211 return EFI_SUCCESS; 212} 213