runtime.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. /*++
  2. Copyright (c) 2014 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. runtime.c
  9. Abstract:
  10. This module implements the UEFI runtime driver core.
  11. Author:
  12. Evan Green 10-Mar-2014
  13. Environment:
  14. Firmware
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include <minoca/lib/types.h>
  20. #include "uefifw.h"
  21. #include "runtime.h"
  22. #include "peimage.h"
  23. #include <minoca/uefi/protocol/loadimg.h>
  24. //
  25. // ---------------------------------------------------------------- Definitions
  26. //
  27. //
  28. // ------------------------------------------------------ Data Type Definitions
  29. //
  30. //
  31. // ----------------------------------------------- Internal Function Prototypes
  32. //
  33. EFIAPI
  34. EFI_STATUS
  35. EfiCoreConvertPointer (
  36. UINTN DebugDisposition,
  37. VOID **Address
  38. );
  39. EFIAPI
  40. EFI_STATUS
  41. EfiCoreSetVirtualAddressMap (
  42. UINTN MemoryMapSize,
  43. UINTN DescriptorSize,
  44. UINT32 DescriptorVersion,
  45. EFI_MEMORY_DESCRIPTOR *VirtualMap
  46. );
  47. VOID
  48. EfipPeLoaderRelocateImageForRuntime (
  49. PHYSICAL_ADDRESS ImageBase,
  50. PHYSICAL_ADDRESS VirtualBase,
  51. UINTN ImageSize,
  52. VOID *RelocationData
  53. );
  54. VOID
  55. EfipRuntimeCalculateHeaderCrc (
  56. EFI_TABLE_HEADER *Header
  57. );
  58. //
  59. // -------------------------------------------------------------------- Globals
  60. //
  61. //
  62. // Store the EFI runtime architectural protocol instance produced by this
  63. // driver.
  64. //
  65. EFI_RUNTIME_ARCH_PROTOCOL EfiRuntimeProtocol;
  66. //
  67. // These globals are used while switching from physical to virtual mode.
  68. //
  69. EFI_MEMORY_DESCRIPTOR *EfiVirtualMap;
  70. UINTN EfiVirtualMapCount;
  71. UINTN EfiVirtualMapDescriptorSize;
  72. //
  73. // Store the handle onto which the runtime protocol is installed.
  74. //
  75. EFI_HANDLE EfiRuntimeHandle;
  76. //
  77. // Remember the image base of the runtime driver itself to avoid relocating it.
  78. //
  79. VOID *EfiRuntimeImageBase;
  80. EFI_GUID EfiLoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
  81. EFI_GUID EfiRuntimeArchProtocolGuid = EFI_RUNTIME_ARCH_PROTOCOL_GUID;
  82. EFI_BOOT_SERVICES *EfiBootServices;
  83. EFI_RUNTIME_SERVICES *EfiRuntimeServices;
  84. EFI_SYSTEM_TABLE *EfiSystemTable;
  85. //
  86. // ------------------------------------------------------------------ Functions
  87. //
  88. EFIAPI
  89. EFI_STATUS
  90. EfiRuntimeDriverEntry (
  91. EFI_HANDLE ImageHandle,
  92. EFI_SYSTEM_TABLE *SystemTable
  93. )
  94. /*++
  95. Routine Description:
  96. This routine implements the entry point into the runtime services driver.
  97. Arguments:
  98. ImageHandle - Supplies the handle associated with this image.
  99. SystemTable - Supplies a pointer to the EFI system table.
  100. Return Value:
  101. EFI_SUCCESS if the driver initialized successfully.
  102. Other status codes on failure.
  103. --*/
  104. {
  105. EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
  106. EFI_STATUS Status;
  107. EfiSystemTable = SystemTable;
  108. EfiBootServices = SystemTable->BootServices;
  109. EfiRuntimeServices = SystemTable->RuntimeServices;
  110. EfiSetMem(&EfiRuntimeProtocol, sizeof(EFI_RUNTIME_ARCH_PROTOCOL), 0);
  111. INITIALIZE_LIST_HEAD(&(EfiRuntimeProtocol.ImageListHead));
  112. INITIALIZE_LIST_HEAD(&(EfiRuntimeProtocol.EventListHead));
  113. //
  114. // Artificially adjust the size of the memory descriptor to catch anybody
  115. // doing pointer arithmetic directly.
  116. //
  117. EfiRuntimeProtocol.MemoryDescriptorSize =
  118. sizeof(EFI_MEMORY_DESCRIPTOR) + sizeof(UINT64) -
  119. (sizeof(EFI_MEMORY_DESCRIPTOR) % sizeof(UINT64));
  120. EfiRuntimeProtocol.MemoryDescriptorVersion = EFI_MEMORY_DESCRIPTOR_VERSION;
  121. //
  122. // The image needs to be excluded from the list of images to relocate
  123. // during SetVirtualAddress map, so get the base address of this image
  124. // now.
  125. //
  126. Status = EfiHandleProtocol(ImageHandle,
  127. &EfiLoadedImageProtocolGuid,
  128. (VOID **)&LoadedImage);
  129. if (EFI_ERROR(Status)) {
  130. return Status;
  131. }
  132. EfiRuntimeImageBase = LoadedImage->ImageBase;
  133. //
  134. // Take over certain boot and runtime services.
  135. //
  136. EfiBootServices->CalculateCrc32 = EfiCoreCalculateCrc32;
  137. EfiRuntimeServices->SetVirtualAddressMap = EfiCoreSetVirtualAddressMap;
  138. EfiRuntimeServices->ConvertPointer = EfiCoreConvertPointer;
  139. //
  140. // Install the Runtime Architectural Protocol onto a new handle.
  141. //
  142. EfiRuntimeHandle = NULL;
  143. Status = EfiInstallMultipleProtocolInterfaces(&EfiRuntimeHandle,
  144. &EfiRuntimeArchProtocolGuid,
  145. &EfiRuntimeProtocol,
  146. NULL);
  147. if (EFI_ERROR(Status)) {
  148. return Status;
  149. }
  150. return EFI_SUCCESS;
  151. }
  152. //
  153. // --------------------------------------------------------- Internal Functions
  154. //
  155. EFIAPI
  156. EFI_STATUS
  157. EfiCoreConvertPointer (
  158. UINTN DebugDisposition,
  159. VOID **Address
  160. )
  161. /*++
  162. Routine Description:
  163. This routine determines the new virtual address that is to be used on
  164. subsequent memory accesses.
  165. Arguments:
  166. DebugDisposition - Supplies type information for the pointer being
  167. converted.
  168. Address - Supplies a pointer to a pointer that is to be fixed to be the
  169. value needed for the new virtual address mappings being applied.
  170. Return Value:
  171. EFI_SUCCESS if the pointer was modified.
  172. EFI_INVALID_PARAMETER if the address is NULL or the value of Address is
  173. NULL and the debug disposition does not have the EFI_OPTIONAL_PTR bit set.
  174. EFI_NOT_FOUND if the pointer pointed to by the address parameter was not
  175. found to be part of the current memory map. This is normally fatal.
  176. --*/
  177. {
  178. UINTN ConvertAddress;
  179. UINT64 End;
  180. EFI_MEMORY_DESCRIPTOR *Entry;
  181. UINTN Index;
  182. if (Address == NULL) {
  183. return EFI_INVALID_PARAMETER;
  184. }
  185. ConvertAddress = (UINTN)*Address;
  186. if (ConvertAddress == 0) {
  187. if ((DebugDisposition & EFI_OPTIONAL_PTR) != 0) {
  188. return EFI_SUCCESS;
  189. }
  190. return EFI_INVALID_PARAMETER;
  191. }
  192. Entry = EfiVirtualMap;
  193. for (Index = 0; Index < EfiVirtualMapCount; Index += 1) {
  194. if ((Entry->Attribute & EFI_MEMORY_RUNTIME) != 0) {
  195. if (ConvertAddress >= Entry->PhysicalStart) {
  196. End = Entry->PhysicalStart +
  197. (Entry->NumberOfPages << EFI_PAGE_SHIFT);
  198. if (ConvertAddress < End) {
  199. *Address = (VOID *)(ConvertAddress -
  200. (UINTN)(Entry->PhysicalStart) +
  201. (UINTN)(Entry->VirtualStart));
  202. return EFI_SUCCESS;
  203. }
  204. }
  205. }
  206. Entry = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Entry +
  207. EfiVirtualMapDescriptorSize);
  208. }
  209. //
  210. // Bad news bears.
  211. //
  212. return EFI_NOT_FOUND;
  213. }
  214. EFIAPI
  215. EFI_STATUS
  216. EfiCoreSetVirtualAddressMap (
  217. UINTN MemoryMapSize,
  218. UINTN DescriptorSize,
  219. UINT32 DescriptorVersion,
  220. EFI_MEMORY_DESCRIPTOR *VirtualMap
  221. )
  222. /*++
  223. Routine Description:
  224. This routine changes the runtime addressing mode of EFI firmware from
  225. physical to virtual.
  226. Arguments:
  227. MemoryMapSize - Supplies the size of the virtual map.
  228. DescriptorSize - Supplies the size of an entry in the virtual map.
  229. DescriptorVersion - Supplies the version of the structure entries in the
  230. virtual map.
  231. VirtualMap - Supplies the array of memory descriptors which contain the
  232. new virtual address mappings for all runtime ranges.
  233. Return Value:
  234. EFI_SUCCESS on success.
  235. EFI_UNSUPPORTED if the firmware is not at runtime, or the firmware is
  236. already in virtual address mapped mode.
  237. EFI_INVALID_PARAMETER if the descriptor size or version is invalid.
  238. EFI_NO_MAPPING if the virtual address was not supplied for a range in the
  239. memory map that requires a mapping.
  240. EFI_NOT_FOUND if a virtual address was supplied for an address that is not
  241. found in the memory map.
  242. --*/
  243. {
  244. PLIST_ENTRY CurrentEntry;
  245. UINTN Remainder;
  246. EFI_RUNTIME_EVENT_ENTRY *RuntimeEvent;
  247. EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage;
  248. EFI_PHYSICAL_ADDRESS VirtualBase;
  249. //
  250. // The switch to virtual mode can only happen once the memory map is locked
  251. // down, and it can only be set once.
  252. //
  253. if ((EfiRuntimeProtocol.AtRuntime == FALSE) ||
  254. (EfiRuntimeProtocol.VirtualMode != FALSE)) {
  255. return EFI_UNSUPPORTED;
  256. }
  257. if ((DescriptorVersion != EFI_MEMORY_DESCRIPTOR_VERSION) ||
  258. (DescriptorSize < sizeof(EFI_MEMORY_DESCRIPTOR))) {
  259. return EFI_INVALID_PARAMETER;
  260. }
  261. EfiRuntimeProtocol.VirtualMode = TRUE;
  262. //
  263. // Set up the globals for the convert pointer function. Avoid doing a
  264. // divide and pulling a bunch more junk in.
  265. //
  266. EfiVirtualMapDescriptorSize = DescriptorSize;
  267. Remainder = MemoryMapSize;
  268. EfiVirtualMapCount = 0;
  269. while (Remainder >= DescriptorSize) {
  270. Remainder -= DescriptorSize;
  271. EfiVirtualMapCount += 1;
  272. }
  273. EfiVirtualMap = VirtualMap;
  274. //
  275. // Signal all the virtual address change events.
  276. //
  277. CurrentEntry = EfiRuntimeProtocol.EventListHead.Next;
  278. while (CurrentEntry != &(EfiRuntimeProtocol.EventListHead)) {
  279. RuntimeEvent = LIST_VALUE(CurrentEntry,
  280. EFI_RUNTIME_EVENT_ENTRY,
  281. ListEntry);
  282. CurrentEntry = CurrentEntry->Next;
  283. if ((RuntimeEvent->Type & EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) != 0) {
  284. RuntimeEvent->NotifyFunction(RuntimeEvent->Event,
  285. RuntimeEvent->NotifyContext);
  286. }
  287. }
  288. //
  289. // Relocate all the runtime images.
  290. //
  291. CurrentEntry = EfiRuntimeProtocol.ImageListHead.Next;
  292. while (CurrentEntry != &(EfiRuntimeProtocol.ImageListHead)) {
  293. RuntimeImage = LIST_VALUE(CurrentEntry,
  294. EFI_RUNTIME_IMAGE_ENTRY,
  295. ListEntry);
  296. CurrentEntry = CurrentEntry->Next;
  297. //
  298. // Skip relocating this image.
  299. //
  300. if (RuntimeImage->ImageBase == EfiRuntimeImageBase) {
  301. continue;
  302. }
  303. VirtualBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(RuntimeImage->ImageBase);
  304. EfiCoreConvertPointer(0, (VOID **)&VirtualBase);
  305. EfipPeLoaderRelocateImageForRuntime(
  306. (EFI_PHYSICAL_ADDRESS)(UINTN)(RuntimeImage->ImageBase),
  307. VirtualBase,
  308. (UINTN)(RuntimeImage->ImageSize),
  309. RuntimeImage->RelocationData);
  310. EfiCoreInvalidateInstructionCacheRange(
  311. RuntimeImage->ImageBase,
  312. (UINTN)(RuntimeImage->ImageSize));
  313. }
  314. //
  315. // Convert all runtime services except ConvertPointer and
  316. // SetVirtualAddressMap, and recompute the CRC.
  317. //
  318. EfiCoreConvertPointer(0, (VOID **)&(EfiRuntimeServices->GetTime));
  319. EfiCoreConvertPointer(0, (VOID **)&(EfiRuntimeServices->SetTime));
  320. EfiCoreConvertPointer(0, (VOID **)&(EfiRuntimeServices->GetWakeupTime));
  321. EfiCoreConvertPointer(0, (VOID **)&(EfiRuntimeServices->SetWakeupTime));
  322. EfiCoreConvertPointer(0, (VOID **)&(EfiRuntimeServices->ResetSystem));
  323. EfiCoreConvertPointer(
  324. 0,
  325. (VOID **)&(EfiRuntimeServices->GetNextHighMonotonicCount));
  326. EfiCoreConvertPointer(0, (VOID **)&(EfiRuntimeServices->GetVariable));
  327. EfiCoreConvertPointer(0, (VOID **)&(EfiRuntimeServices->SetVariable));
  328. EfiCoreConvertPointer(0,
  329. (VOID **)&(EfiRuntimeServices->GetNextVariableName));
  330. EfiCoreConvertPointer(0, (VOID **)&(EfiRuntimeServices->QueryVariableInfo));
  331. EfiCoreConvertPointer(0, (VOID **)&(EfiRuntimeServices->UpdateCapsule));
  332. EfiCoreConvertPointer(
  333. 0,
  334. (VOID **)&(EfiRuntimeServices->QueryCapsuleCapabilities));
  335. EfipRuntimeCalculateHeaderCrc(&(EfiRuntimeServices->Hdr));
  336. //
  337. // Convert the runtime fields of the system table and recompute the CRC.
  338. //
  339. EfiCoreConvertPointer(0, (VOID **)&(EfiSystemTable->FirmwareVendor));
  340. EfiCoreConvertPointer(0, (VOID **)&(EfiSystemTable->ConfigurationTable));
  341. EfiCoreConvertPointer(0, (VOID **)&(EfiSystemTable->RuntimeServices));
  342. EfiSystemTable->BootServices = NULL;
  343. EfipRuntimeCalculateHeaderCrc(&(EfiSystemTable->Hdr));
  344. EfiVirtualMap = NULL;
  345. return EFI_SUCCESS;
  346. }
  347. VOID
  348. EfipPeLoaderRelocateImageForRuntime (
  349. PHYSICAL_ADDRESS ImageBase,
  350. PHYSICAL_ADDRESS VirtualBase,
  351. UINTN ImageSize,
  352. VOID *RelocationData
  353. )
  354. /*++
  355. Routine Description:
  356. This routine reapplies fixups on a PE32/PE32+ image so that it can be
  357. called from virtual mode.
  358. Arguments:
  359. ImageBase - Supplies the base physical address where the PE image has
  360. been loaded.
  361. VirtualBase - Supplies the new virtual address where the PE image is
  362. going to execute in virtual mode.
  363. ImageSize - Supplies the size in bytes of the image.
  364. RelocationData - Supplies a pointer to the relocation data that was
  365. collected when the image was originally relocated.
  366. Return Value:
  367. None.
  368. --*/
  369. {
  370. UINTN Adjust;
  371. EFI_IMAGE_DATA_DIRECTORY *DataDirectory;
  372. EFI_IMAGE_DOS_HEADER *DosHeader;
  373. CHAR8 *Fixup;
  374. UINT16 *Fixup16;
  375. UINT32 *Fixup32;
  376. UINT64 *Fixup64;
  377. CHAR8 *FixupBase;
  378. CHAR8 *FixupData;
  379. EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Header;
  380. UINT16 Magic;
  381. CHAR8 *NewBase;
  382. UINT32 NumberOfRvaAndSizes;
  383. CHAR8 *OldBase;
  384. UINT16 *Relocation;
  385. EFI_IMAGE_BASE_RELOCATION *RelocationBase;
  386. EFI_IMAGE_BASE_RELOCATION *RelocationBaseEnd;
  387. EFI_IMAGE_DATA_DIRECTORY *RelocationDirectory;
  388. UINT16 *RelocationEnd;
  389. OldBase = (CHAR8 *)((UINTN)ImageBase);
  390. NewBase = (CHAR8 *)((UINTN)VirtualBase);
  391. Adjust = (UINTN)NewBase - (UINTN)OldBase;
  392. //
  393. // Find the image's relocation directory. Start by finding the PE headers,
  394. // which are either directly at the beginning or pointed to by the DOS
  395. // header.
  396. //
  397. DosHeader = (EFI_IMAGE_DOS_HEADER *)OldBase;
  398. if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
  399. Header.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(((CHAR8 *)DosHeader) +
  400. DosHeader->e_lfanew);
  401. } else {
  402. Header.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)OldBase;
  403. }
  404. if (Header.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
  405. return;
  406. }
  407. Magic = Header.Pe32->OptionalHeader.Magic;
  408. if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
  409. NumberOfRvaAndSizes = Header.Pe32->OptionalHeader.NumberOfRvaAndSizes;
  410. DataDirectory = &(Header.Pe32->OptionalHeader.DataDirectory[0]);
  411. } else {
  412. NumberOfRvaAndSizes =
  413. Header.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
  414. DataDirectory = &(Header.Pe32Plus->OptionalHeader.DataDirectory[0]);
  415. }
  416. //
  417. // Find the relocation block. It had better be there.
  418. //
  419. if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
  420. return;
  421. }
  422. RelocationDirectory = DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC;
  423. RelocationBase =
  424. (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(ImageBase +
  425. RelocationDirectory->VirtualAddress);
  426. RelocationBaseEnd =
  427. (EFI_IMAGE_BASE_RELOCATION *)((UINTN)RelocationBase +
  428. RelocationDirectory->Size);
  429. //
  430. // Run the whole relocation block. Re-fix up data that has not been
  431. // modified. The fixup data is used to see if the image has been modified
  432. // since it was relocated. Data sections that have been updated by code
  433. // will not be fixed up, since that would set them back to their defaults.
  434. //
  435. FixupData = RelocationData;
  436. while (RelocationBase < RelocationBaseEnd) {
  437. if ((RelocationBase->SizeOfBlock == 0) ||
  438. (RelocationBase->SizeOfBlock > RelocationDirectory->Size)) {
  439. return;
  440. }
  441. Relocation = (UINT16 *)((UINT8 *)RelocationBase +
  442. sizeof(EFI_IMAGE_BASE_RELOCATION));
  443. RelocationEnd = (UINT16 *)((UINT8 *)RelocationBase +
  444. RelocationBase->SizeOfBlock);
  445. FixupBase = (CHAR8 *)((UINTN)ImageBase) +
  446. RelocationBase->VirtualAddress;
  447. //
  448. // Run this relocation page.
  449. //
  450. while (Relocation < RelocationEnd) {
  451. Fixup = FixupBase + (*Relocation & 0x0FFF);
  452. switch (*Relocation >> 12) {
  453. case EFI_IMAGE_REL_BASED_ABSOLUTE:
  454. break;
  455. case EFI_IMAGE_REL_BASED_HIGH:
  456. Fixup16 = (UINT16 *)Fixup;
  457. if (*(UINT16 *)FixupData == *Fixup16) {
  458. *Fixup16 =
  459. (UINT16)(*Fixup16 + ((UINT16)((UINT32)Adjust >> 16)));
  460. }
  461. FixupData = FixupData + sizeof(UINT16);
  462. break;
  463. case EFI_IMAGE_REL_BASED_LOW:
  464. Fixup16 = (UINT16 *)Fixup;
  465. if (*(UINT16 *)FixupData == *Fixup16) {
  466. *Fixup16 = (UINT16)(*Fixup16 +
  467. ((UINT16)((UINT32)Adjust & 0xFFFF)));
  468. }
  469. FixupData = FixupData + sizeof(UINT16);
  470. break;
  471. case EFI_IMAGE_REL_BASED_HIGHLOW:
  472. Fixup32 = (UINT32 *)Fixup;
  473. FixupData = ALIGN_POINTER(FixupData, sizeof(UINT32));
  474. if (*(UINT32 *)FixupData == *Fixup32) {
  475. *Fixup32 = *Fixup32 + (UINT32)Adjust;
  476. }
  477. FixupData = FixupData + sizeof(UINT32);
  478. break;
  479. case EFI_IMAGE_REL_BASED_DIR64:
  480. Fixup64 = (UINT64 *)Fixup;
  481. FixupData = ALIGN_POINTER(FixupData, sizeof(UINT64));
  482. if (*(UINT64 *)FixupData == *Fixup64) {
  483. *Fixup64 = *Fixup64 + (UINT64)Adjust;
  484. }
  485. FixupData = FixupData + sizeof(UINT64);
  486. break;
  487. default:
  488. break;
  489. }
  490. //
  491. // Move to the next relocation.
  492. //
  493. Relocation += 1;
  494. }
  495. //
  496. // Move to the next relocation block.
  497. //
  498. RelocationBase = (EFI_IMAGE_BASE_RELOCATION *)RelocationEnd;
  499. }
  500. return;
  501. }
  502. VOID
  503. EfipRuntimeCalculateHeaderCrc (
  504. EFI_TABLE_HEADER *Header
  505. )
  506. /*++
  507. Routine Description:
  508. This routine recomputes the CRC of the given EFI table.
  509. Arguments:
  510. Header - Supplies a pointer to the head of the table.
  511. Return Value:
  512. None.
  513. --*/
  514. {
  515. UINT32 Crc;
  516. Header->CRC32 = 0;
  517. EfiCoreCalculateCrc32((UINT8 *)Header, Header->HeaderSize, &Crc);
  518. Header->CRC32 = Crc;
  519. return;
  520. }