init.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  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 the main entry point for the UEFI runtime core.
  11. Author:
  12. Evan Green 18-Mar-2014
  13. Environment:
  14. Firmware
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include "rtlib.h"
  20. //
  21. // ---------------------------------------------------------------- Definitions
  22. //
  23. //
  24. // ------------------------------------------------------ Data Type Definitions
  25. //
  26. //
  27. // ----------------------------------------------- Internal Function Prototypes
  28. //
  29. EFIAPI
  30. VOID
  31. EfipRuntimeExitBootServicesNotify (
  32. EFI_EVENT Event,
  33. VOID *Context
  34. );
  35. EFIAPI
  36. VOID
  37. EfipRuntimeVirtualAddressChangeNotify (
  38. EFI_EVENT Event,
  39. VOID *Context
  40. );
  41. EFIAPI
  42. EFI_STATUS
  43. EfipStubGetNextHighMonotonicCount (
  44. UINT32 *HighCount
  45. );
  46. EFIAPI
  47. EFI_STATUS
  48. EfipStubUpdateCapsule (
  49. EFI_CAPSULE_HEADER **CapsuleHeaderArray,
  50. UINTN CapsuleCount,
  51. EFI_PHYSICAL_ADDRESS ScatterGatherList
  52. );
  53. EFIAPI
  54. EFI_STATUS
  55. EfipStubQueryCapsuleCapabilities (
  56. EFI_CAPSULE_HEADER **CapsuleHeaderArray,
  57. UINTN CapsuleCount,
  58. UINT64 *MaximumCapsuleSize,
  59. EFI_RESET_TYPE *ResetType
  60. );
  61. //
  62. // -------------------------------------------------------------------- Globals
  63. //
  64. EFI_SYSTEM_TABLE *EfiSystemTable;
  65. EFI_BOOT_SERVICES *EfiBootServices;
  66. EFI_RUNTIME_SERVICES *EfiRuntimeServices;
  67. EFI_HANDLE EfiRuntimeImageHandle;
  68. //
  69. // Store a boolean indicating whether or not the system is in the runtime
  70. // phase.
  71. //
  72. BOOLEAN EfiAtRuntime;
  73. //
  74. // Store information about where and when an assert might have happened, for
  75. // debugging.
  76. //
  77. CONST CHAR8 *EfiRuntimeAssertExpression;
  78. CONST CHAR8 *EfiRuntimeAssertFile;
  79. UINTN EfiRuntimeAssertLine;
  80. //
  81. // Keep the virtual address change and exit boot services events.
  82. //
  83. EFI_EVENT EfiRuntimeExitBootServicesEvent;
  84. EFI_EVENT EfiRuntimeVirtualAddressChangeEvent;
  85. //
  86. // ------------------------------------------------------------------ Functions
  87. //
  88. __USED
  89. EFIAPI
  90. EFI_STATUS
  91. EfiRuntimeCoreEntry (
  92. EFI_HANDLE ImageHandle,
  93. EFI_SYSTEM_TABLE *SystemTable
  94. )
  95. /*++
  96. Routine Description:
  97. This routine implements the entry point into the runtime services core
  98. driver.
  99. Arguments:
  100. ImageHandle - Supplies the handle associated with this image.
  101. SystemTable - Supplies a pointer to the EFI system table.
  102. Return Value:
  103. EFI_SUCCESS if the driver initialized successfully.
  104. Other status codes on failure.
  105. --*/
  106. {
  107. UINT32 Crc;
  108. EFI_STATUS Status;
  109. //
  110. // Save the important data structures globally.
  111. //
  112. EfiRuntimeImageHandle = ImageHandle;
  113. EfiSystemTable = SystemTable;
  114. EfiBootServices = SystemTable->BootServices;
  115. EfiRuntimeServices = SystemTable->RuntimeServices;
  116. //
  117. // Populate the runtime services handled by the runtime core. Set them
  118. // before calling platform initialize in case the platform wants to
  119. // override them.
  120. //
  121. EfiRuntimeServices->GetVariable = EfiCoreGetVariable;
  122. EfiRuntimeServices->SetVariable = EfiCoreSetVariable;
  123. EfiRuntimeServices->GetNextVariableName = EfiCoreGetNextVariableName;
  124. EfiRuntimeServices->QueryVariableInfo = EfiCoreQueryVariableInfo;
  125. EfiRuntimeServices->GetNextHighMonotonicCount =
  126. EfipStubGetNextHighMonotonicCount;
  127. EfiRuntimeServices->UpdateCapsule = EfipStubUpdateCapsule;
  128. EfiRuntimeServices->QueryCapsuleCapabilities =
  129. EfipStubQueryCapsuleCapabilities;
  130. Status = EfiPlatformRuntimeInitialize();
  131. if (EFI_ERROR(Status)) {
  132. goto RuntimeCoreEntryEnd;
  133. }
  134. //
  135. // Recompute the table CRC.
  136. //
  137. EfiRuntimeServices->Hdr.CRC32 = 0;
  138. Crc = 0;
  139. EfiCalculateCrc32(EfiRuntimeServices,
  140. EfiRuntimeServices->Hdr.HeaderSize,
  141. &Crc);
  142. EfiRuntimeServices->Hdr.CRC32 = Crc;
  143. Status = EfipCoreInitializeVariableServices();
  144. if (EFI_ERROR(Status)) {
  145. goto RuntimeCoreEntryEnd;
  146. }
  147. Status = EfiCreateEvent(EVT_SIGNAL_EXIT_BOOT_SERVICES,
  148. TPL_NOTIFY,
  149. EfipRuntimeExitBootServicesNotify,
  150. NULL,
  151. &EfiRuntimeExitBootServicesEvent);
  152. if (EFI_ERROR(Status)) {
  153. goto RuntimeCoreEntryEnd;
  154. }
  155. Status = EfiCreateEvent(EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
  156. TPL_NOTIFY,
  157. EfipRuntimeVirtualAddressChangeNotify,
  158. NULL,
  159. &EfiRuntimeVirtualAddressChangeEvent);
  160. if (EFI_ERROR(Status)) {
  161. goto RuntimeCoreEntryEnd;
  162. }
  163. Status = EFI_SUCCESS;
  164. RuntimeCoreEntryEnd:
  165. return Status;
  166. }
  167. BOOLEAN
  168. EfiIsAtRuntime (
  169. VOID
  170. )
  171. /*++
  172. Routine Description:
  173. This routine determines whether or not the system has gone through
  174. ExitBootServices.
  175. Arguments:
  176. None.
  177. Return Value:
  178. TRUE if the system has gone past ExitBootServices and is now in the
  179. Runtime phase.
  180. FALSE if the system is currently in the Boot phase.
  181. --*/
  182. {
  183. return EfiAtRuntime;
  184. }
  185. //
  186. // --------------------------------------------------------- Internal Functions
  187. //
  188. EFIAPI
  189. VOID
  190. EfipRuntimeExitBootServicesNotify (
  191. EFI_EVENT Event,
  192. VOID *Context
  193. )
  194. /*++
  195. Routine Description:
  196. This routine does nothing but return. It conforms to the event notification
  197. function prototype.
  198. Arguments:
  199. Event - Supplies an unused event.
  200. Context - Supplies an unused context pointer.
  201. Return Value:
  202. None.
  203. --*/
  204. {
  205. EfiPlatformRuntimeExitBootServices();
  206. EfipCoreVariableHandleExitBootServices();
  207. EfiAtRuntime = TRUE;
  208. EfiBootServices = NULL;
  209. return;
  210. }
  211. EFIAPI
  212. VOID
  213. EfipRuntimeVirtualAddressChangeNotify (
  214. EFI_EVENT Event,
  215. VOID *Context
  216. )
  217. /*++
  218. Routine Description:
  219. This routine does nothing but return. It conforms to the event notification
  220. function prototype.
  221. Arguments:
  222. Event - Supplies an unused event.
  223. Context - Supplies an unused context pointer.
  224. Return Value:
  225. None.
  226. --*/
  227. {
  228. EfiPlatformRuntimeVirtualAddressChange();
  229. EfipCoreVariableHandleVirtualAddressChange();
  230. EfiConvertPointer(0, (VOID **)&EfiSystemTable);
  231. EfiConvertPointer(0, (VOID **)&EfiRuntimeServices);
  232. return;
  233. }
  234. EFIAPI
  235. EFI_STATUS
  236. EfipStubGetNextHighMonotonicCount (
  237. UINT32 *HighCount
  238. )
  239. /*++
  240. Routine Description:
  241. This routine returns the next high 32 bits of the platform's monotonic
  242. counter.
  243. Arguments:
  244. HighCount - Supplies a pointer where the value is returned.
  245. Return Value:
  246. EFI_SUCCESS on success.
  247. EFI_INVALID_PARAMETER if the count is NULL.
  248. EFI_DEVICE_ERROR if the device is not functioning properly.
  249. --*/
  250. {
  251. return EFI_UNSUPPORTED;
  252. }
  253. EFIAPI
  254. EFI_STATUS
  255. EfipStubUpdateCapsule (
  256. EFI_CAPSULE_HEADER **CapsuleHeaderArray,
  257. UINTN CapsuleCount,
  258. EFI_PHYSICAL_ADDRESS ScatterGatherList
  259. )
  260. /*++
  261. Routine Description:
  262. This routine passes capsules to the firmware with both virtual and physical
  263. mapping. Depending on the intended consumption, the firmware may process
  264. the capsule immediately. If the payload should persist across a system
  265. reset, the reset value returned from EFI_QueryCapsuleCapabilities must be
  266. passed into ResetSystem and will cause the capsule to be processed by the
  267. firmware as part of the reset process.
  268. Arguments:
  269. CapsuleHeaderArray - Supplies a virtual pointer to an array of virtual
  270. pointers to the capsules being passed into update capsule.
  271. CapsuleCount - Supplies the number of pointers to EFI_CAPSULE_HEADERs in
  272. the capsule header array.
  273. ScatterGatherList - Supplies an optional physical pointer to a set of
  274. EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the location in physical
  275. memory of a set of capsules.
  276. Return Value:
  277. EFI_SUCCESS if a valid capsule was passed. If
  278. CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the capsule has been
  279. successfully processed by the firmware.
  280. EFI_INVALID_PARAMETER if the capsule size is NULL, the capsule count is
  281. zero, or an incompatible set of flags were set in the capsule header.
  282. EFI_DEVICE_ERROR if the capsule update was started, but failed due to a
  283. device error.
  284. EFI_UNSUPPORTED if the capsule type is not supported on this platform.
  285. EFI_OUT_OF_RESOURCES if resources could not be allocated. If this call
  286. originated during runtime, this error is returned if the caller must retry
  287. the call during boot services.
  288. --*/
  289. {
  290. return EFI_UNSUPPORTED;
  291. }
  292. EFIAPI
  293. EFI_STATUS
  294. EfipStubQueryCapsuleCapabilities (
  295. EFI_CAPSULE_HEADER **CapsuleHeaderArray,
  296. UINTN CapsuleCount,
  297. UINT64 *MaximumCapsuleSize,
  298. EFI_RESET_TYPE *ResetType
  299. )
  300. /*++
  301. Routine Description:
  302. This routine returns whether or not the capsule is supported via the
  303. UpdateCapsule routine.
  304. Arguments:
  305. CapsuleHeaderArray - Supplies a virtual pointer to an array of virtual
  306. pointers to the capsules being passed into update capsule.
  307. CapsuleCount - Supplies the number of pointers to EFI_CAPSULE_HEADERs in
  308. the capsule header array.
  309. MaximumCapsuleSize - Supplies a pointer that on output contains the maximum
  310. size that the update capsule routine can support as an argument to
  311. the update capsule routine.
  312. ResetType - Supplies a pointer where the reset type required to perform the
  313. capsule update is returned.
  314. Return Value:
  315. EFI_SUCCESS if a valid answer was returned.
  316. EFI_UNSUPPORTED if the capsule type is not supported on this platform.
  317. EFI_DEVICE_ERROR if the capsule update was started, but failed due to a
  318. device error.
  319. EFI_INVALID_PARAMETER if the maximum capsule size is NULL.
  320. EFI_OUT_OF_RESOURCES if resources could not be allocated. If this call
  321. originated during runtime, this error is returned if the caller must retry
  322. the call during boot services.
  323. --*/
  324. {
  325. return EFI_UNSUPPORTED;
  326. }
  327. VOID
  328. RtlRaiseAssertion (
  329. CONST CHAR8 *Expression,
  330. CONST CHAR8 *SourceFile,
  331. UINTN SourceLine
  332. )
  333. /*++
  334. Routine Description:
  335. This routine raises an assertion failure exception. If a debugger is
  336. connected, it will attempt to connect to the debugger.
  337. Arguments:
  338. Expression - Supplies the string containing the expression that failed.
  339. SourceFile - Supplies the string describing the source file of the failure.
  340. SourceLine - Supplies the source line number of the failure.
  341. Return Value:
  342. None.
  343. --*/
  344. {
  345. //
  346. // The RTL functions are not linked in here, but this one is referenced by
  347. // various macros. Mark the assert location for some poor soul trying to
  348. // debug, but just keep going.
  349. //
  350. EfiRuntimeAssertExpression = Expression;
  351. EfiRuntimeAssertFile = SourceFile;
  352. EfiRuntimeAssertLine = SourceLine;
  353. return;
  354. }
  355. VOID
  356. RtlDebugBreak (
  357. VOID
  358. )
  359. /*++
  360. Routine Description:
  361. This routine causes a break into the debugger.
  362. Arguments:
  363. None.
  364. Return Value:
  365. None.
  366. --*/
  367. {
  368. return;
  369. }