init.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  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. init.c
  9. Abstract:
  10. This module implements initialization for the UEFI core. It is called by
  11. platform-specific portions of the firmware.
  12. Author:
  13. Evan Green 26-Feb-2014
  14. Environment:
  15. Firmware
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include "ueficore.h"
  21. #include <minoca/kernel/hmod.h>
  22. #include <minoca/kernel/kdebug.h>
  23. //
  24. // ---------------------------------------------------------------- Definitions
  25. //
  26. //
  27. // Define the maximum size of the firmware image name.
  28. //
  29. #define EFI_FIRMWARE_BINARY_NAME_MAX_SIZE 25
  30. //
  31. // Define the size of the EFI loaded module buffer.
  32. //
  33. #define EFI_MODULE_BUFFER_SIZE \
  34. (sizeof(DEBUG_MODULE) + EFI_FIRMWARE_BINARY_NAME_MAX_SIZE)
  35. //
  36. // ------------------------------------------------------ Data Type Definitions
  37. //
  38. typedef struct _EFI_CORE_PROTOCOL_NOTIFY_ENTRY {
  39. EFI_GUID *ProtocolGuid;
  40. VOID **Protocol;
  41. EFI_EVENT Event;
  42. VOID *Registration;
  43. BOOLEAN Present;
  44. } EFI_CORE_PROTOCOL_NOTIFY_ENTRY, *PEFI_CORE_PROTOCOL_NOTIFY_ENTRY;
  45. //
  46. // ----------------------------------------------- Internal Function Prototypes
  47. //
  48. EFIAPI
  49. EFI_STATUS
  50. EfiCoreExitBootServices (
  51. EFI_HANDLE ImageHandle,
  52. UINTN MapKey
  53. );
  54. EFI_STATUS
  55. EfipCoreRegisterForInterestingNotifies (
  56. VOID
  57. );
  58. EFIAPI
  59. VOID
  60. EfipCoreRuntimeArchProtocolNotify (
  61. EFI_EVENT Event,
  62. VOID *Context
  63. );
  64. EFIAPI
  65. EFI_STATUS
  66. EfiCoreNotYetAvailable1 (
  67. UINTN Argument1
  68. );
  69. EFIAPI
  70. EFI_STATUS
  71. EfiCoreNotYetAvailable2 (
  72. UINTN Argument1,
  73. UINTN Argument2
  74. );
  75. EFIAPI
  76. EFI_STATUS
  77. EfiCoreNotYetAvailable3 (
  78. UINTN Argument1,
  79. UINTN Argument2,
  80. UINTN Argument3
  81. );
  82. EFIAPI
  83. EFI_STATUS
  84. EfiCoreNotYetAvailable4 (
  85. UINTN Argument1,
  86. UINTN Argument2,
  87. UINTN Argument3,
  88. UINTN Argument4
  89. );
  90. EFIAPI
  91. EFI_STATUS
  92. EfiCoreNotYetAvailable5 (
  93. UINTN Argument1,
  94. UINTN Argument2,
  95. UINTN Argument3,
  96. UINTN Argument4,
  97. UINTN Argument5
  98. );
  99. //
  100. // -------------------------------------------------------------------- Globals
  101. //
  102. //
  103. // Set this to TRUE to enable debugging throughout the firmware.
  104. //
  105. BOOL EfiDebugFirmware = FALSE;
  106. //
  107. // Carve out some space for the loaded module structure reported to the
  108. // debugger.
  109. //
  110. UINT8 EfiModuleBuffer[EFI_MODULE_BUFFER_SIZE];
  111. //
  112. // Store the EFI debug device description.
  113. //
  114. extern DEBUG_DEVICE_DESCRIPTION EfiDebugDevice;
  115. //
  116. // Store the runtime handoff information.
  117. //
  118. EFI_RUNTIME_ARCH_PROTOCOL EfiRuntimeProtocolTemplate;
  119. EFI_RUNTIME_ARCH_PROTOCOL *EfiRuntimeProtocol = &EfiRuntimeProtocolTemplate;
  120. //
  121. // Store the image handle of the firmware itself.
  122. //
  123. EFI_HANDLE EfiFirmwareImageHandle;
  124. //
  125. // Define a template for the EFI services.
  126. //
  127. EFI_BOOT_SERVICES EfiBootServicesTemplate = {
  128. {
  129. EFI_BOOT_SERVICES_SIGNATURE,
  130. EFI_BOOT_SERVICES_REVISION,
  131. sizeof(EFI_BOOT_SERVICES),
  132. 0,
  133. 0
  134. },
  135. EfiCoreRaiseTpl,
  136. EfiCoreRestoreTpl,
  137. EfiCoreAllocatePages,
  138. EfiCoreFreePages,
  139. EfiCoreGetMemoryMap,
  140. EfiCoreAllocatePool,
  141. EfiCoreFreePool,
  142. EfiCoreCreateEvent,
  143. EfiCoreSetTimer,
  144. EfiCoreWaitForEvent,
  145. EfiCoreSignalEvent,
  146. EfiCoreCloseEvent,
  147. EfiCoreCheckEvent,
  148. EfiCoreInstallProtocolInterface,
  149. EfiCoreReinstallProtocolInterface,
  150. EfiCoreUninstallProtocolInterface,
  151. EfiCoreHandleProtocol,
  152. NULL,
  153. EfiCoreRegisterProtocolNotify,
  154. EfiCoreLocateHandle,
  155. EfiCoreLocateDevicePath,
  156. EfiCoreInstallConfigurationTable,
  157. EfiCoreLoadImage,
  158. EfiCoreStartImage,
  159. EfiCoreExit,
  160. EfiCoreUnloadImage,
  161. EfiCoreExitBootServices,
  162. EfiCoreGetNextMonotonicCount,
  163. EfiCoreStall,
  164. EfiCoreSetWatchdogTimer,
  165. EfiCoreConnectController,
  166. EfiCoreDisconnectController,
  167. EfiCoreOpenProtocol,
  168. EfiCoreCloseProtocol,
  169. EfiCoreOpenProtocolInformation,
  170. EfiCoreProtocolsPerHandle,
  171. EfiCoreLocateHandleBuffer,
  172. EfiCoreLocateProtocol,
  173. EfiCoreInstallMultipleProtocolInterfaces,
  174. EfiCoreUninstallMultipleProtocolInterfaces,
  175. (EFI_CALCULATE_CRC32)EfiCoreNotYetAvailable3,
  176. EfiCoreCopyMemory,
  177. EfiCoreSetMemory,
  178. EfiCoreCreateEventEx
  179. };
  180. EFI_RUNTIME_SERVICES EfiRuntimeServicesTemplate = {
  181. {
  182. EFI_RUNTIME_SERVICES_SIGNATURE,
  183. EFI_RUNTIME_SERVICES_REVISION,
  184. sizeof(EFI_RUNTIME_SERVICES),
  185. 0,
  186. 0
  187. },
  188. (EFI_GET_TIME)EfiCoreNotYetAvailable2,
  189. (EFI_SET_TIME)EfiCoreNotYetAvailable1,
  190. (EFI_GET_WAKEUP_TIME)EfiCoreNotYetAvailable3,
  191. (EFI_SET_WAKEUP_TIME)EfiCoreNotYetAvailable2,
  192. (EFI_SET_VIRTUAL_ADDRESS_MAP)EfiCoreNotYetAvailable4,
  193. (EFI_CONVERT_POINTER)EfiCoreNotYetAvailable2,
  194. (EFI_GET_VARIABLE)EfiCoreNotYetAvailable5,
  195. (EFI_GET_NEXT_VARIABLE_NAME)EfiCoreNotYetAvailable3,
  196. (EFI_SET_VARIABLE)EfiCoreNotYetAvailable5,
  197. (EFI_GET_NEXT_HIGH_MONO_COUNT)EfiCoreNotYetAvailable1,
  198. (EFI_RESET_SYSTEM)EfiCoreNotYetAvailable4,
  199. (EFI_UPDATE_CAPSULE)EfiCoreNotYetAvailable3,
  200. (EFI_QUERY_CAPSULE_CAPABILITIES)EfiCoreNotYetAvailable4,
  201. (EFI_QUERY_VARIABLE_INFO)EfiCoreNotYetAvailable4
  202. };
  203. //
  204. // Define pointers to the true system table and firmware services.
  205. //
  206. EFI_SYSTEM_TABLE *EfiSystemTable;
  207. EFI_BOOT_SERVICES *EfiBootServices = &EfiBootServicesTemplate;
  208. EFI_RUNTIME_SERVICES *EfiRuntimeServices = &EfiRuntimeServicesTemplate;
  209. //
  210. // Define the protocols the core is interested in hearing about.
  211. //
  212. EFI_GUID EfiRuntimeArchProtocolGuid = EFI_RUNTIME_ARCH_PROTOCOL_GUID;
  213. EFI_CORE_PROTOCOL_NOTIFY_ENTRY EfiRuntimeProtocolNotifyEntry = {
  214. &EfiRuntimeArchProtocolGuid,
  215. (VOID **)&EfiRuntimeProtocol,
  216. NULL,
  217. NULL,
  218. FALSE
  219. };
  220. //
  221. // ------------------------------------------------------------------ Functions
  222. //
  223. VOID
  224. EfiCoreMain (
  225. VOID *FirmwareBaseAddress,
  226. VOID *FirmwareLowestAddress,
  227. UINTN FirmwareSize,
  228. CHAR8 *FirmwareBinaryName,
  229. VOID *StackBase,
  230. UINTN StackSize
  231. )
  232. /*++
  233. Routine Description:
  234. This routine implements the entry point into the UEFI firmware. This
  235. routine is called by the platform firmware, and should be called as early
  236. as possible. It will perform callouts to allow the platform to initialize
  237. further.
  238. Arguments:
  239. FirmwareBaseAddress - Supplies the base address where the firmware was
  240. loaded into memory. Supply -1 to indicate that the image is loaded at
  241. its preferred base address and was not relocated.
  242. FirmwareLowestAddress - Supplies the lowest address where the firmware was
  243. loaded into memory.
  244. FirmwareSize - Supplies the size of the firmware image in memory, in bytes.
  245. FirmwareBinaryName - Supplies the name of the binary that's loaded, which
  246. is reported to the debugger for symbol loading.
  247. StackBase - Supplies the base (lowest) address of the stack.
  248. StackSize - Supplies the size in bytes of the stack. This should be at
  249. least 0x4000 bytes (16kB).
  250. Return Value:
  251. This routine does not return.
  252. --*/
  253. {
  254. PDEBUG_MODULE DebugModule;
  255. EFI_STATUS EfiStatus;
  256. KSTATUS KStatus;
  257. UINTN ModuleNameLength;
  258. ULONG OriginalTimeout;
  259. UINTN Step;
  260. EFI_TIME Time;
  261. EfiStatus = EFI_SUCCESS;
  262. OriginalTimeout = 0;
  263. KStatus = STATUS_SUCCESS;
  264. Step = 0;
  265. //
  266. // Perform very basic processor initialization, preparing it to take
  267. // exceptions and use the serial port.
  268. //
  269. EfipInitializeProcessor();
  270. Step += 1;
  271. DebugModule = (PDEBUG_MODULE)EfiModuleBuffer;
  272. //
  273. // Initialize the debugging subsystem.
  274. //
  275. RtlZeroMemory(&EfiModuleBuffer, sizeof(EfiModuleBuffer));
  276. ModuleNameLength = RtlStringLength(FirmwareBinaryName) + 1;
  277. if (ModuleNameLength > EFI_FIRMWARE_BINARY_NAME_MAX_SIZE) {
  278. ModuleNameLength = EFI_FIRMWARE_BINARY_NAME_MAX_SIZE;
  279. }
  280. DebugModule->StructureSize = sizeof(DEBUG_MODULE) + ModuleNameLength -
  281. (ANYSIZE_ARRAY * sizeof(CHAR));
  282. RtlStringCopy(DebugModule->BinaryName,
  283. FirmwareBinaryName,
  284. ModuleNameLength);
  285. DebugModule->LowestAddress = FirmwareLowestAddress;
  286. DebugModule->Size = FirmwareSize;
  287. if (EfiDebugFirmware != FALSE) {
  288. //
  289. // Stall does not work this early, so prevent KD from using it.
  290. //
  291. OriginalTimeout = KdSetConnectionTimeout(MAX_ULONG);
  292. KStatus = KdInitialize(&EfiDebugDevice, DebugModule);
  293. if (!KSUCCESS(KStatus)) {
  294. goto InitializeEnd;
  295. }
  296. }
  297. //
  298. // Initialize the runtime protocol template.
  299. //
  300. Step += 1;
  301. INITIALIZE_LIST_HEAD(&(EfiRuntimeProtocol->ImageListHead));
  302. INITIALIZE_LIST_HEAD(&(EfiRuntimeProtocol->EventListHead));
  303. EfiRuntimeProtocol->MemoryDescriptorSize =
  304. sizeof(EFI_MEMORY_DESCRIPTOR) + sizeof(UINT64) -
  305. (sizeof(EFI_MEMORY_DESCRIPTOR) % sizeof(UINT64));
  306. EfiRuntimeProtocol->MemoryDescriptorVersion = EFI_MEMORY_DESCRIPTOR_VERSION;
  307. //
  308. // Allow the platform to do some initialization now that code is
  309. // debuggable.
  310. //
  311. EfiStatus = EfiPlatformInitialize(0);
  312. if (EFI_ERROR(EfiStatus)) {
  313. goto InitializeEnd;
  314. }
  315. Step += 1;
  316. EfiCoreInitializeHandleDatabase();
  317. EfiStatus = EfiCoreInitializeEventServices(0);
  318. if (EFI_ERROR(EfiStatus)) {
  319. goto InitializeEnd;
  320. }
  321. Step += 1;
  322. EfiStatus = EfiCoreInitializeMemoryServices(FirmwareLowestAddress,
  323. FirmwareSize,
  324. StackBase,
  325. StackSize);
  326. if (EFI_ERROR(EfiStatus)) {
  327. goto InitializeEnd;
  328. }
  329. Step += 1;
  330. EfiStatus = EfiCoreInitializeEventServices(1);
  331. if (EFI_ERROR(EfiStatus)) {
  332. goto InitializeEnd;
  333. }
  334. Step += 1;
  335. EfiStatus = EfiCoreInitializeInterruptServices();
  336. if (EFI_ERROR(EfiStatus)) {
  337. goto InitializeEnd;
  338. }
  339. Step += 1;
  340. EfiStatus = EfiCoreInitializeTimerServices();
  341. if (EFI_ERROR(EfiStatus)) {
  342. goto InitializeEnd;
  343. }
  344. //
  345. // Create the runtime services table.
  346. //
  347. Step += 1;
  348. EfiBootServices = &EfiBootServicesTemplate;
  349. EfiRuntimeServices =
  350. EfiCoreAllocateRuntimePool(sizeof(EFI_RUNTIME_SERVICES));
  351. if (EfiRuntimeServices == NULL) {
  352. goto InitializeEnd;
  353. }
  354. EfiCoreCopyMemory(EfiRuntimeServices,
  355. &EfiRuntimeServicesTemplate,
  356. sizeof(EFI_RUNTIME_SERVICES));
  357. //
  358. // Create the system table.
  359. //
  360. Step += 1;
  361. EfiSystemTable = EfiCoreAllocateRuntimePool(sizeof(EFI_SYSTEM_TABLE));
  362. if (EfiSystemTable == NULL) {
  363. goto InitializeEnd;
  364. }
  365. Step += 1;
  366. EfiCoreSetMemory(EfiSystemTable, sizeof(EFI_SYSTEM_TABLE), 0);
  367. EfiSystemTable->Hdr.Signature = EFI_SYSTEM_TABLE_SIGNATURE;
  368. EfiSystemTable->Hdr.Revision = EFI_SYSTEM_TABLE_REVISION;
  369. EfiSystemTable->Hdr.HeaderSize = sizeof(EFI_SYSTEM_TABLE);
  370. EfiSystemTable->Hdr.CRC32 = 0;
  371. EfiSystemTable->Hdr.Reserved = 0;
  372. EfiSystemTable->BootServices = EfiBootServices;
  373. EfiSystemTable->RuntimeServices = EfiRuntimeServices;
  374. //
  375. // Allow KD to use stall now that timer services are set up.
  376. //
  377. if (EfiDebugFirmware != FALSE) {
  378. KdSetConnectionTimeout(OriginalTimeout);
  379. }
  380. EfiStatus = EfiCoreInitializeImageServices(FirmwareBaseAddress,
  381. FirmwareLowestAddress,
  382. FirmwareSize);
  383. if (EFI_ERROR(EfiStatus)) {
  384. goto InitializeEnd;
  385. }
  386. Step += 1;
  387. EfiStatus = EfipCoreRegisterForInterestingNotifies();
  388. if (EFI_ERROR(EfiStatus)) {
  389. goto InitializeEnd;
  390. }
  391. Step += 1;
  392. EfiStatus = EfiFvInitializeSectionExtraction(EfiFirmwareImageHandle,
  393. EfiSystemTable);
  394. if (EFI_ERROR(EfiStatus)) {
  395. goto InitializeEnd;
  396. }
  397. Step += 1;
  398. EfiStatus = EfiFvInitializeBlockSupport(EfiFirmwareImageHandle,
  399. EfiSystemTable);
  400. if (EFI_ERROR(EfiStatus)) {
  401. goto InitializeEnd;
  402. }
  403. Step += 1;
  404. EfiStatus = EfiPlatformInitialize(1);
  405. if (EFI_ERROR(EfiStatus)) {
  406. goto InitializeEnd;
  407. }
  408. Step += 1;
  409. EfiStatus = EfiFvDriverInit(EfiFirmwareImageHandle, EfiSystemTable);
  410. if (EFI_ERROR(EfiStatus)) {
  411. goto InitializeEnd;
  412. }
  413. //
  414. // Initialize builtin drivers.
  415. //
  416. Step += 1;
  417. EfiStatus = EfiDiskIoDriverEntry(NULL, EfiSystemTable);
  418. if (EFI_ERROR(EfiStatus)) {
  419. goto InitializeEnd;
  420. }
  421. Step += 1;
  422. EfiStatus = EfiPartitionDriverEntry(NULL, EfiSystemTable);
  423. if (EFI_ERROR(EfiStatus)) {
  424. goto InitializeEnd;
  425. }
  426. Step += 1;
  427. EfiStatus = EfiFatDriverEntry(NULL, EfiSystemTable);
  428. if (EFI_ERROR(EfiStatus)) {
  429. goto InitializeEnd;
  430. }
  431. Step += 1;
  432. EfiStatus = EfiGraphicsTextDriverEntry(NULL, EfiSystemTable);
  433. if (EFI_ERROR(EfiStatus)) {
  434. goto InitializeEnd;
  435. }
  436. //
  437. // The EFI core is up, tell the platform to enumerate any firmware volumes,
  438. // followed by any devices.
  439. //
  440. Step += 1;
  441. EfiStatus = EfiPlatformEnumerateFirmwareVolumes();
  442. if (EFI_ERROR(EfiStatus)) {
  443. goto InitializeEnd;
  444. }
  445. EfiCoreInitializeDispatcher();
  446. EfiCoreDispatcher();
  447. //
  448. // Now that the firmware volumes are up, install any ACPI tables found in
  449. // them.
  450. //
  451. Step += 1;
  452. EfiStatus = EfiAcpiDriverEntry(NULL, EfiSystemTable);
  453. if (EFI_ERROR(EfiStatus)) {
  454. goto InitializeEnd;
  455. }
  456. Step += 1;
  457. EfiStatus = EfiSmbiosDriverEntry(NULL, EfiSystemTable);
  458. if (EFI_ERROR(EfiStatus)) {
  459. goto InitializeEnd;
  460. }
  461. //
  462. // Ask the platform to enumerate any builtin devices it knows about.
  463. //
  464. Step += 1;
  465. EfiStatus = EfiPlatformEnumerateDevices();
  466. if (EFI_ERROR(EfiStatus)) {
  467. goto InitializeEnd;
  468. }
  469. Step += 1;
  470. EfiStatus = EfiPlatformInitialize(2);
  471. if (EFI_ERROR(EfiStatus)) {
  472. goto InitializeEnd;
  473. }
  474. //
  475. // Let's get the time, just for kicks.
  476. //
  477. EfiStatus = EfiGetTime(&Time, NULL);
  478. if (!EFI_ERROR(EfiStatus)) {
  479. RtlDebugPrint("%d/%d/%d %02d:%02d:%02d\n",
  480. Time.Month,
  481. Time.Day,
  482. Time.Year,
  483. Time.Hour,
  484. Time.Minute,
  485. Time.Second);
  486. }
  487. //
  488. // Here we go, let's boot this thing.
  489. //
  490. Step += 1;
  491. EfiBdsEntry();
  492. InitializeEnd:
  493. //
  494. // Never return.
  495. //
  496. RtlDebugPrint("EFI firmware failed. KStatus %d, EFI Status 0x%x, Step %d\n",
  497. KStatus,
  498. EfiStatus,
  499. Step);
  500. while (TRUE) {
  501. RtlDebugBreak();
  502. }
  503. return;
  504. }
  505. //
  506. // --------------------------------------------------------- Internal Functions
  507. //
  508. EFIAPI
  509. EFI_STATUS
  510. EfiCoreExitBootServices (
  511. EFI_HANDLE ImageHandle,
  512. UINTN MapKey
  513. )
  514. /*++
  515. Routine Description:
  516. This routine terminates all boot services.
  517. Arguments:
  518. ImageHandle - Supplies the handle that identifies the exiting image.
  519. MapKey - Supplies the latest memory map key.
  520. Return Value:
  521. EFI_SUCCESS on success.
  522. EFI_INVALID_PARAMETER if the map key is incorrect.
  523. --*/
  524. {
  525. EFI_STATUS Status;
  526. Status = EfiCoreTerminateMemoryServices(MapKey);
  527. if (EFI_ERROR(Status)) {
  528. return Status;
  529. }
  530. EfiSetWatchdogTimer(0, 0, 0, NULL);
  531. EfiCoreTerminateTimerServices();
  532. EfiCoreTerminateInterruptServices();
  533. EfipCoreNotifySignalList(&EfiEventExitBootServicesGuid);
  534. EfiDisableInterrupts();
  535. //
  536. // Remove the boot services from the system table and recalculate the CRC.
  537. //
  538. EfiSystemTable->BootServices = NULL;
  539. EfiSystemTable->ConIn = NULL;
  540. EfiSystemTable->ConsoleInHandle = NULL;
  541. EfiSystemTable->ConOut = NULL;
  542. EfiSystemTable->ConsoleOutHandle = NULL;
  543. EfiSystemTable->StdErr = NULL;
  544. EfiSystemTable->StandardErrorHandle = NULL;
  545. EfiCoreCalculateTableCrc32(&(EfiSystemTable->Hdr));
  546. EfiSetMem(EfiBootServices, sizeof(EFI_BOOT_SERVICES), 0);
  547. EfiBootServices = NULL;
  548. EfiRuntimeProtocol->AtRuntime = TRUE;
  549. return Status;
  550. }
  551. EFI_STATUS
  552. EfipCoreRegisterForInterestingNotifies (
  553. VOID
  554. )
  555. /*++
  556. Routine Description:
  557. This routine signs up for registration of notifications for protocols the
  558. UEFI core is interested in.
  559. Arguments:
  560. None.
  561. Return Value:
  562. EFI Status code.
  563. --*/
  564. {
  565. EFI_STATUS Status;
  566. Status = EfiCoreCreateEvent(EVT_NOTIFY_SIGNAL,
  567. TPL_CALLBACK,
  568. EfipCoreRuntimeArchProtocolNotify,
  569. &EfiRuntimeProtocolNotifyEntry,
  570. &(EfiRuntimeProtocolNotifyEntry.Event));
  571. if (EFI_ERROR(Status)) {
  572. ASSERT(FALSE);
  573. return Status;
  574. }
  575. Status = EfiCoreRegisterProtocolNotify(
  576. EfiRuntimeProtocolNotifyEntry.ProtocolGuid,
  577. EfiRuntimeProtocolNotifyEntry.Event,
  578. &(EfiRuntimeProtocolNotifyEntry.Registration));
  579. if (EFI_ERROR(Status)) {
  580. ASSERT(FALSE);
  581. return Status;
  582. }
  583. return Status;
  584. }
  585. EFIAPI
  586. VOID
  587. EfipCoreRuntimeArchProtocolNotify (
  588. EFI_EVENT Event,
  589. VOID *Context
  590. )
  591. /*++
  592. Routine Description:
  593. This routine is called when the runtime driver produces the runtime
  594. architectural protocol.
  595. Arguments:
  596. Event - Supplies a pointer to the event that fired.
  597. Context - Supplies a context pointer containing in this case a pointer to
  598. the core protocl notify entry.
  599. Return Value:
  600. None.
  601. --*/
  602. {
  603. PLIST_ENTRY CurrentEntry;
  604. PEFI_CORE_PROTOCOL_NOTIFY_ENTRY Entry;
  605. VOID *Protocol;
  606. EFI_STATUS Status;
  607. Entry = (PEFI_CORE_PROTOCOL_NOTIFY_ENTRY)Context;
  608. Status = EfiCoreLocateProtocol(Entry->ProtocolGuid,
  609. Entry->Registration,
  610. &Protocol);
  611. if (EFI_ERROR(Status)) {
  612. return;
  613. }
  614. //
  615. // Mark the entry as present, and update the global variable if one exists.
  616. //
  617. Entry->Present = TRUE;
  618. if (Entry->Protocol != NULL) {
  619. *(Entry->Protocol) = Protocol;
  620. }
  621. if (EfiCoreCompareGuids(Entry->ProtocolGuid, &EfiRuntimeArchProtocolGuid) !=
  622. FALSE) {
  623. //
  624. // Move all the images and events from the temporary template over to
  625. // the new list.
  626. //
  627. while (LIST_EMPTY(&(EfiRuntimeProtocolTemplate.ImageListHead)) ==
  628. FALSE) {
  629. CurrentEntry = EfiRuntimeProtocolTemplate.ImageListHead.Next;
  630. LIST_REMOVE(CurrentEntry);
  631. INSERT_AFTER(CurrentEntry, &(EfiRuntimeProtocol->ImageListHead));
  632. }
  633. while (LIST_EMPTY(&(EfiRuntimeProtocolTemplate.EventListHead)) ==
  634. FALSE) {
  635. CurrentEntry = EfiRuntimeProtocolTemplate.EventListHead.Next;
  636. LIST_REMOVE(CurrentEntry);
  637. INSERT_AFTER(CurrentEntry, &(EfiRuntimeProtocol->EventListHead));
  638. }
  639. }
  640. //
  641. // Recalculate the CRCs of the major tables.
  642. //
  643. EfiCoreCalculateTableCrc32(&(EfiRuntimeServices->Hdr));
  644. EfiCoreCalculateTableCrc32(&(EfiBootServices->Hdr));
  645. EfiCoreCalculateTableCrc32(&(EfiSystemTable->Hdr));
  646. return;
  647. }
  648. EFIAPI
  649. EFI_STATUS
  650. EfiCoreNotYetAvailable1 (
  651. UINTN Argument1
  652. )
  653. /*++
  654. Routine Description:
  655. This routine implements an EFI service stub that simply returns failure.
  656. This is better than jumping off and executing NULL.
  657. Arguments:
  658. Argument1 - Supplies an unsed argument to satisfy the prototype of the
  659. function this routine is stubbing out.
  660. Return Value:
  661. EFI_UNSUPPORTED always.
  662. --*/
  663. {
  664. return EFI_UNSUPPORTED;
  665. }
  666. EFIAPI
  667. EFI_STATUS
  668. EfiCoreNotYetAvailable2 (
  669. UINTN Argument1,
  670. UINTN Argument2
  671. )
  672. /*++
  673. Routine Description:
  674. This routine implements an EFI service stub that simply returns failure.
  675. This is better than jumping off and executing NULL.
  676. Arguments:
  677. Argument1 - Supplies an unsed argument to satisfy the prototype of the
  678. function this routine is stubbing out.
  679. Argument2 - Supplies an unsed argument to satisfy the prototype of the
  680. function this routine is stubbing out.
  681. Return Value:
  682. EFI_UNSUPPORTED always.
  683. --*/
  684. {
  685. return EFI_UNSUPPORTED;
  686. }
  687. EFIAPI
  688. EFI_STATUS
  689. EfiCoreNotYetAvailable3 (
  690. UINTN Argument1,
  691. UINTN Argument2,
  692. UINTN Argument3
  693. )
  694. /*++
  695. Routine Description:
  696. This routine implements an EFI service stub that simply returns failure.
  697. This is better than jumping off and executing NULL.
  698. Arguments:
  699. Argument1 - Supplies an unsed argument to satisfy the prototype of the
  700. function this routine is stubbing out.
  701. Argument2 - Supplies an unsed argument to satisfy the prototype of the
  702. function this routine is stubbing out.
  703. Argument3 - Supplies an unsed argument to satisfy the prototype of the
  704. function this routine is stubbing out.
  705. Return Value:
  706. EFI_UNSUPPORTED always.
  707. --*/
  708. {
  709. return EFI_UNSUPPORTED;
  710. }
  711. EFIAPI
  712. EFI_STATUS
  713. EfiCoreNotYetAvailable4 (
  714. UINTN Argument1,
  715. UINTN Argument2,
  716. UINTN Argument3,
  717. UINTN Argument4
  718. )
  719. /*++
  720. Routine Description:
  721. This routine implements an EFI service stub that simply returns failure.
  722. This is better than jumping off and executing NULL.
  723. Arguments:
  724. Argument1 - Supplies an unsed argument to satisfy the prototype of the
  725. function this routine is stubbing out.
  726. Argument2 - Supplies an unsed argument to satisfy the prototype of the
  727. function this routine is stubbing out.
  728. Argument3 - Supplies an unsed argument to satisfy the prototype of the
  729. function this routine is stubbing out.
  730. Argument4 - Supplies an unsed argument to satisfy the prototype of the
  731. function this routine is stubbing out.
  732. Return Value:
  733. EFI_UNSUPPORTED always.
  734. --*/
  735. {
  736. return EFI_UNSUPPORTED;
  737. }
  738. EFIAPI
  739. EFI_STATUS
  740. EfiCoreNotYetAvailable5 (
  741. UINTN Argument1,
  742. UINTN Argument2,
  743. UINTN Argument3,
  744. UINTN Argument4,
  745. UINTN Argument5
  746. )
  747. /*++
  748. Routine Description:
  749. This routine implements an EFI service stub that simply returns failure.
  750. This is better than jumping off and executing NULL.
  751. Arguments:
  752. Argument1 - Supplies an unsed argument to satisfy the prototype of the
  753. function this routine is stubbing out.
  754. Argument2 - Supplies an unsed argument to satisfy the prototype of the
  755. function this routine is stubbing out.
  756. Argument3 - Supplies an unsed argument to satisfy the prototype of the
  757. function this routine is stubbing out.
  758. Argument4 - Supplies an unsed argument to satisfy the prototype of the
  759. function this routine is stubbing out.
  760. Argument5 - Supplies an unsed argument to satisfy the prototype of the
  761. function this routine is stubbing out.
  762. Return Value:
  763. EFI_UNSUPPORTED always.
  764. --*/
  765. {
  766. return EFI_UNSUPPORTED;
  767. }