init.c 23 KB

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