PageRenderTime 64ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/EdkCompatibilityPkg/Foundation/Library/RuntimeDxe/EfiRuntimeLib/Ipf/RuntimeLib.c

https://bitbucket.org/incubaid/edk2
C | 1319 lines | 568 code | 119 blank | 632 comment | 18 complexity | a41c379c190b634dd6c6e553c9553f3c MD5 | raw file
  1. /*++
  2. Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
  3. This program and the accompanying materials
  4. are licensed and made available under the terms and conditions of the BSD License
  5. which accompanies this distribution. The full text of the license may be found at
  6. http://opensource.org/licenses/bsd-license.php
  7. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  9. Module Name:
  10. RuntimeLib.c
  11. Abstract:
  12. Light weight lib to support Tiano Sal drivers.
  13. --*/
  14. #include "Tiano.h"
  15. #include "EfiRuntimeLib.h"
  16. #include EFI_PROTOCOL_DEFINITION (ExtendedSalBootService)
  17. #include EFI_PROTOCOL_DEFINITION (ExtendedSalGuid)
  18. #include "IpfDefines.h"
  19. #include "SalApi.h"
  20. //
  21. // Worker functions in EsalLib.s
  22. //
  23. SAL_RETURN_REGS
  24. GetEsalEntryPoint (
  25. VOID
  26. );
  27. SAL_RETURN_REGS
  28. SetEsalPhysicalEntryPoint (
  29. IN UINT64 EntryPoint,
  30. IN UINT64 Gp
  31. );
  32. SAL_RETURN_REGS
  33. SetEsalVirtualEntryPoint (
  34. IN UINT64 EntryPoint,
  35. IN UINT64 Gp
  36. );
  37. VOID
  38. SalFlushCache (
  39. IN EFI_PHYSICAL_ADDRESS Start,
  40. IN UINT64 Length
  41. );
  42. //
  43. // Module Globals. It's not valid to use these after the
  44. // EfiRuntimeLibVirtualNotifyEvent has fired.
  45. //
  46. static EFI_EVENT mEfiVirtualNotifyEvent;
  47. static EFI_RUNTIME_SERVICES *mRT;
  48. static EFI_PLABEL mPlabel;
  49. static EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService;
  50. static BOOLEAN mRuntimeLibInitialized = FALSE;
  51. VOID
  52. EFIAPI
  53. EfiRuntimeLibVirtualNotifyEvent (
  54. IN EFI_EVENT Event,
  55. IN VOID *Context
  56. )
  57. /*++
  58. Routine Description:
  59. Fixup internal data so that EFI and SAL can be call in virtual mode.
  60. Call the passed in Child Notify event and convert any pointers in
  61. lib to virtual mode.
  62. Arguments:
  63. Event - The Event that is being processed
  64. Context - Event Context
  65. Returns:
  66. None
  67. --*/
  68. {
  69. EFI_EVENT_NOTIFY ChildNotify;
  70. if (Context != NULL) {
  71. //
  72. // Call child event
  73. //
  74. ChildNotify = (EFI_EVENT_NOTIFY) (UINTN) Context;
  75. ChildNotify (Event, NULL);
  76. }
  77. mRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mPlabel.EntryPoint);
  78. mRT->ConvertPointer (EFI_INTERNAL_POINTER | EFI_IPF_GP_POINTER, (VOID **) &mPlabel.GP);
  79. SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
  80. //
  81. // Clear out BootService globals
  82. //
  83. gBS = NULL;
  84. gST = NULL;
  85. mRT = NULL;
  86. //
  87. // Pointers don't work you must use a direct lib call
  88. //
  89. }
  90. EFI_STATUS
  91. EfiInitializeRuntimeDriverLib (
  92. IN EFI_HANDLE ImageHandle,
  93. IN EFI_SYSTEM_TABLE *SystemTable,
  94. IN EFI_EVENT_NOTIFY GoVirtualChildEvent
  95. )
  96. /*++
  97. Routine Description:
  98. Intialize runtime Driver Lib if it has not yet been initialized.
  99. Arguments:
  100. ImageHandle - The firmware allocated handle for the EFI image.
  101. SystemTable - A pointer to the EFI System Table.
  102. GoVirtualChildEvent - Caller can register a virtual notification event.
  103. Returns:
  104. EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.
  105. --*/
  106. {
  107. EFI_STATUS Status;
  108. EFI_PLABEL *Plabel;
  109. if (mRuntimeLibInitialized) {
  110. return EFI_ALREADY_STARTED;
  111. }
  112. mRuntimeLibInitialized = TRUE;
  113. gST = SystemTable;
  114. gBS = SystemTable->BootServices;
  115. mRT = SystemTable->RuntimeServices;
  116. Status = EfiLibGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
  117. ASSERT_EFI_ERROR (Status);
  118. //
  119. // The protocol contains a function pointer, which is an indirect procedure call.
  120. // An indirect procedure call goes through a plabel, and pointer to a function is
  121. // a pointer to a plabel. To implement indirect procedure calls that can work in
  122. // both physical and virtual mode, two plabels are required (one physical and one
  123. // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it
  124. // away. We cache it in a module global, so we can register the vitrual version.
  125. //
  126. Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, (VOID **) &mEsalBootService);
  127. ASSERT_EFI_ERROR (Status);
  128. Plabel = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;
  129. mPlabel.EntryPoint = Plabel->EntryPoint;
  130. mPlabel.GP = Plabel->GP;
  131. SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
  132. //
  133. // Create a Virtual address change notification event. Pass in the callers
  134. // GoVirtualChildEvent so it's get passed to the event as contex.
  135. //
  136. Status = gBS->CreateEvent (
  137. EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
  138. EFI_TPL_NOTIFY,
  139. EfiRuntimeLibVirtualNotifyEvent,
  140. (VOID *) GoVirtualChildEvent,
  141. &mEfiVirtualNotifyEvent
  142. );
  143. ASSERT_EFI_ERROR (Status);
  144. return EFI_SUCCESS;
  145. }
  146. EFI_STATUS
  147. EfiShutdownRuntimeDriverLib (
  148. VOID
  149. )
  150. /*++
  151. Routine Description:
  152. This routine will free some resources which have been allocated in
  153. EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error,
  154. it must call this routine to free the allocated resource before the exiting.
  155. Arguments:
  156. None
  157. Returns:
  158. EFI_SUCCESS - Shotdown the Runtime Driver Lib successfully
  159. EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all
  160. --*/
  161. {
  162. EFI_STATUS Status;
  163. if (!mRuntimeLibInitialized) {
  164. //
  165. // You must call EfiInitializeRuntimeDriverLib() first
  166. //
  167. return EFI_UNSUPPORTED;
  168. }
  169. mRuntimeLibInitialized = FALSE;
  170. //
  171. // Close SetVirtualAddressMap () notify function
  172. //
  173. Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);
  174. ASSERT_EFI_ERROR (Status);
  175. return EFI_SUCCESS;
  176. }
  177. EFI_STATUS
  178. RegisterEsalFunction (
  179. IN UINT64 FunctionId,
  180. IN EFI_GUID *ClassGuid,
  181. IN SAL_INTERNAL_EXTENDED_SAL_PROC Function,
  182. IN VOID *ModuleGlobal
  183. )
  184. /*++
  185. Routine Description:
  186. Register ESAL Class Function and it's asociated global.
  187. This function is boot service only!
  188. Arguments:
  189. FunctionId - ID of function to register
  190. ClassGuid - GUID of function class
  191. Function - Function to register under ClassGuid/FunctionId pair
  192. ModuleGlobal - Module global for Function.
  193. Returns:
  194. EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.
  195. --*/
  196. {
  197. return mEsalBootService->AddExtendedSalProc (
  198. mEsalBootService,
  199. ClassGuid,
  200. FunctionId,
  201. Function,
  202. ModuleGlobal
  203. );
  204. }
  205. EFI_STATUS
  206. RegisterEsalClass (
  207. IN EFI_GUID *ClassGuid,
  208. IN VOID *ModuleGlobal,
  209. ...
  210. )
  211. /*++
  212. Routine Description:
  213. Register ESAL Class and it's asociated global.
  214. This function is boot service only!
  215. Arguments:
  216. ClassGuid - GUID of function class
  217. ModuleGlobal - Module global for Function.
  218. ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL
  219. indicates the end of the list.
  220. Returns:
  221. EFI_SUCCESS - All members of ClassGuid registered
  222. --*/
  223. {
  224. VA_LIST Args;
  225. EFI_STATUS Status;
  226. SAL_INTERNAL_EXTENDED_SAL_PROC Function;
  227. UINT64 FunctionId;
  228. EFI_HANDLE NewHandle;
  229. VA_START (Args, ModuleGlobal);
  230. Status = EFI_SUCCESS;
  231. while (!EFI_ERROR (Status)) {
  232. Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);
  233. if (Function == NULL) {
  234. break;
  235. }
  236. FunctionId = VA_ARG (Args, UINT64);
  237. Status = RegisterEsalFunction (FunctionId, ClassGuid, Function, ModuleGlobal);
  238. }
  239. if (EFI_ERROR (Status)) {
  240. return Status;
  241. }
  242. NewHandle = NULL;
  243. return gBS->InstallProtocolInterface (
  244. &NewHandle,
  245. ClassGuid,
  246. EFI_NATIVE_INTERFACE,
  247. NULL
  248. );
  249. }
  250. SAL_RETURN_REGS
  251. EfiCallEsalService (
  252. IN EFI_GUID *ClassGuid,
  253. IN UINT64 FunctionId,
  254. IN UINT64 Arg2,
  255. IN UINT64 Arg3,
  256. IN UINT64 Arg4,
  257. IN UINT64 Arg5,
  258. IN UINT64 Arg6,
  259. IN UINT64 Arg7,
  260. IN UINT64 Arg8
  261. )
  262. /*++
  263. Routine Description:
  264. Call module that is not linked direclty to this module. This code is IP
  265. relative and hides the binding issues of virtual or physical calling. The
  266. function that gets dispatched has extra arguments that include the registered
  267. module global and a boolean flag to indicate if the system is in virutal mode.
  268. Arguments:
  269. ClassGuid - GUID of function
  270. FunctionId - Function in ClassGuid to call
  271. Arg2 - Argument 2 ClassGuid/FunctionId defined
  272. Arg3 - Argument 3 ClassGuid/FunctionId defined
  273. Arg4 - Argument 4 ClassGuid/FunctionId defined
  274. Arg5 - Argument 5 ClassGuid/FunctionId defined
  275. Arg6 - Argument 6 ClassGuid/FunctionId defined
  276. Arg7 - Argument 7 ClassGuid/FunctionId defined
  277. Arg8 - Argument 8 ClassGuid/FunctionId defined
  278. Returns:
  279. Status of ClassGuid/FuncitonId
  280. --*/
  281. {
  282. SAL_RETURN_REGS ReturnReg;
  283. SAL_EXTENDED_SAL_PROC EsalProc;
  284. ReturnReg = GetEsalEntryPoint ();
  285. if (ReturnReg.Status != EFI_SAL_SUCCESS) {
  286. return ReturnReg;
  287. }
  288. if (ReturnReg.r11 & PSR_IT_MASK) {
  289. //
  290. // Virtual mode plabel to entry point
  291. //
  292. EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r10;
  293. } else {
  294. //
  295. // Physical mode plabel to entry point
  296. //
  297. EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r9;
  298. }
  299. return EsalProc (
  300. ClassGuid,
  301. FunctionId,
  302. Arg2,
  303. Arg3,
  304. Arg4,
  305. Arg5,
  306. Arg6,
  307. Arg7,
  308. Arg8
  309. );
  310. }
  311. EFI_STATUS
  312. EfiConvertPointer (
  313. IN UINTN DebugDisposition,
  314. IN OUT VOID *Address
  315. )
  316. /*++
  317. Routine Description:
  318. Determines the new virtual address that is to be used on subsequent memory accesses.
  319. Arguments:
  320. DebugDisposition - Supplies type information for the pointer being converted.
  321. Address - A pointer to a pointer that is to be fixed to be the value needed
  322. for the new virtual address mappings being applied.
  323. Returns:
  324. Status code
  325. --*/
  326. {
  327. return mRT->ConvertPointer (DebugDisposition, Address);
  328. }
  329. BOOLEAN
  330. EfiGoneVirtual (
  331. VOID
  332. )
  333. /*++
  334. Routine Description:
  335. Return TRUE if SetVirtualAddressMap () has been called
  336. Arguments:
  337. NONE
  338. Returns:
  339. TRUE - If SetVirtualAddressMap () has been called
  340. --*/
  341. {
  342. EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;
  343. SAL_RETURN_REGS ReturnReg;
  344. ReturnReg = EfiCallEsalService (&Guid, IsVirtual, 0, 0, 0, 0, 0, 0, 0);
  345. return (BOOLEAN) (ReturnReg.r9 == 1);
  346. }
  347. BOOLEAN
  348. EfiAtRuntime (
  349. VOID
  350. )
  351. /*++
  352. Routine Description:
  353. Return TRUE if ExitBootService () has been called
  354. Arguments:
  355. NONE
  356. Returns:
  357. TRUE - If ExitBootService () has been called
  358. --*/
  359. {
  360. EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;
  361. SAL_RETURN_REGS ReturnReg;
  362. ReturnReg = EfiCallEsalService (&Guid, IsEfiRuntime, 0, 0, 0, 0, 0, 0, 0);
  363. return (BOOLEAN) (ReturnReg.r9 == 1);
  364. }
  365. EFI_STATUS
  366. EfiReportStatusCode (
  367. IN EFI_STATUS_CODE_TYPE CodeType,
  368. IN EFI_STATUS_CODE_VALUE Value,
  369. IN UINT32 Instance,
  370. IN EFI_GUID * CallerId,
  371. IN EFI_STATUS_CODE_DATA * Data OPTIONAL
  372. )
  373. /*++
  374. Routine Description:
  375. Status Code reporter
  376. Arguments:
  377. CodeType - Type of Status Code.
  378. Value - Value to output for Status Code.
  379. Instance - Instance Number of this status code.
  380. CallerId - ID of the caller of this status code.
  381. Data - Optional data associated with this status code.
  382. Returns:
  383. Status code
  384. --*/
  385. {
  386. EFI_GUID Guid = EFI_EXTENDED_SAL_STATUS_CODE_SERVICES_PROTOCOL_GUID;
  387. SAL_RETURN_REGS ReturnReg;
  388. ReturnReg = EfiCallEsalService (
  389. &Guid,
  390. StatusCode,
  391. (UINT64) CodeType,
  392. (UINT64) Value,
  393. (UINT64) Instance,
  394. (UINT64) CallerId,
  395. (UINT64) Data,
  396. 0,
  397. 0
  398. );
  399. return (EFI_STATUS) ReturnReg.Status;
  400. }
  401. //
  402. // Sal Reset Driver Class
  403. //
  404. VOID
  405. EfiResetSystem (
  406. IN EFI_RESET_TYPE ResetType,
  407. IN EFI_STATUS ResetStatus,
  408. IN UINTN DataSize,
  409. IN CHAR16 *ResetData
  410. )
  411. /*++
  412. Routine Description:
  413. Resets the entire platform.
  414. Arguments:
  415. ResetType - The type of reset to perform.
  416. ResetStatus - The status code for the reset.
  417. DataSize - The size, in bytes, of ResetData.
  418. ResetData - A data buffer that includes a Null-terminated Unicode string, optionally
  419. followed by additional binary data.
  420. Returns:
  421. None
  422. --*/
  423. {
  424. EFI_GUID Guid = EFI_EXTENDED_SAL_RESET_SERVICES_PROTOCOL_GUID;
  425. EfiCallEsalService (
  426. &Guid,
  427. ResetSystem,
  428. (UINT64) ResetType,
  429. (UINT64) ResetStatus,
  430. (UINT64) DataSize,
  431. (UINT64) ResetData,
  432. 0,
  433. 0,
  434. 0
  435. );
  436. }
  437. //
  438. // Sal MTC Driver Class
  439. //
  440. EFI_STATUS
  441. EfiGetNextHighMonotonicCount (
  442. OUT UINT32 *HighCount
  443. )
  444. /*++
  445. Routine Description:
  446. Returns the next high 32 bits of the platform's monotonic counter.
  447. Arguments:
  448. HighCount - Pointer to returned value.
  449. Returns:
  450. Status code
  451. --*/
  452. {
  453. SAL_RETURN_REGS ReturnReg;
  454. EFI_GUID Guid = EFI_EXTENDED_SAL_MTC_SERVICES_PROTOCOL_GUID;
  455. ReturnReg = EfiCallEsalService (&Guid, GetNextHighMonotonicCount, (UINT64) HighCount, 0, 0, 0, 0, 0, 0);
  456. return (EFI_STATUS) ReturnReg.Status;
  457. }
  458. //
  459. // Sal Variable Driver Class
  460. //
  461. EFI_STATUS
  462. EfiGetVariable (
  463. IN CHAR16 *VariableName,
  464. IN EFI_GUID * VendorGuid,
  465. OUT UINT32 *Attributes OPTIONAL,
  466. IN OUT UINTN *DataSize,
  467. OUT VOID *Data
  468. )
  469. /*++
  470. Routine Description:
  471. Returns the value of a variable.
  472. Arguments:
  473. VariableName - A Null-terminated Unicode string that is the name of the
  474. vendor's variable.
  475. VendorGuid - A unique identifier for the vendor.
  476. Attributes - If not NULL, a pointer to the memory location to return the
  477. attributes bitmask for the variable.
  478. DataSize - On input, the size in bytes of the return Data buffer.
  479. On output the size of data returned in Data.
  480. Data - The buffer to return the contents of the variable.
  481. Returns:
  482. Status code
  483. --*/
  484. {
  485. SAL_RETURN_REGS ReturnReg;
  486. EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
  487. ReturnReg = EfiCallEsalService (
  488. &Guid,
  489. EsalGetVariable,
  490. (UINT64) VariableName,
  491. (UINT64) VendorGuid,
  492. (UINT64) Attributes,
  493. (UINT64) DataSize,
  494. (UINT64) Data,
  495. 0,
  496. 0
  497. );
  498. return (EFI_STATUS) ReturnReg.Status;
  499. }
  500. EFI_STATUS
  501. EfiGetNextVariableName (
  502. IN OUT UINTN *VariableNameSize,
  503. IN OUT CHAR16 *VariableName,
  504. IN OUT EFI_GUID *VendorGuid
  505. )
  506. /*++
  507. Routine Description:
  508. Enumerates the current variable names.
  509. Arguments:
  510. VariableNameSize - The size of the VariableName buffer.
  511. VariableName - On input, supplies the last VariableName that was returned
  512. by GetNextVariableName().
  513. On output, returns the Nullterminated Unicode string of the
  514. current variable.
  515. VendorGuid - On input, supplies the last VendorGuid that was returned by
  516. GetNextVariableName().
  517. On output, returns the VendorGuid of the current variable.
  518. Returns:
  519. Status code
  520. --*/
  521. {
  522. SAL_RETURN_REGS ReturnReg;
  523. EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
  524. ReturnReg = EfiCallEsalService (
  525. &Guid,
  526. EsalGetNextVariableName,
  527. (UINT64) VariableNameSize,
  528. (UINT64) VariableName,
  529. (UINT64) VendorGuid,
  530. 0,
  531. 0,
  532. 0,
  533. 0
  534. );
  535. return (EFI_STATUS) ReturnReg.Status;
  536. }
  537. EFI_STATUS
  538. EfiSetVariable (
  539. IN CHAR16 *VariableName,
  540. IN EFI_GUID *VendorGuid,
  541. IN UINT32 Attributes,
  542. IN UINTN DataSize,
  543. IN VOID *Data
  544. )
  545. /*++
  546. Routine Description:
  547. Sets the value of a variable.
  548. Arguments:
  549. VariableName - A Null-terminated Unicode string that is the name of the
  550. vendor's variable.
  551. VendorGuid - A unique identifier for the vendor.
  552. Attributes - Attributes bitmask to set for the variable.
  553. DataSize - The size in bytes of the Data buffer.
  554. Data - The contents for the variable.
  555. Returns:
  556. Status code
  557. --*/
  558. {
  559. SAL_RETURN_REGS ReturnReg;
  560. EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
  561. ReturnReg = EfiCallEsalService (
  562. &Guid,
  563. EsalSetVariable,
  564. (UINT64) VariableName,
  565. (UINT64) VendorGuid,
  566. (UINT64) Attributes,
  567. (UINT64) DataSize,
  568. (UINT64) Data,
  569. 0,
  570. 0
  571. );
  572. return (EFI_STATUS) ReturnReg.Status;
  573. }
  574. #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
  575. EFI_STATUS
  576. EfiQueryVariableInfo (
  577. IN UINT32 Attributes,
  578. OUT UINT64 *MaximumVariableStorageSize,
  579. OUT UINT64 *RemainingVariableStorageSize,
  580. OUT UINT64 *MaximumVariableSize
  581. )
  582. /*++
  583. Routine Description:
  584. This code returns information about the EFI variables.
  585. Arguments:
  586. Attributes Attributes bitmask to specify the type of variables
  587. on which to return information.
  588. MaximumVariableStorageSize Pointer to the maximum size of the storage space available
  589. for the EFI variables associated with the attributes specified.
  590. RemainingVariableStorageSize Pointer to the remaining size of the storage space available
  591. for the EFI variables associated with the attributes specified.
  592. MaximumVariableSize Pointer to the maximum size of the individual EFI variables
  593. associated with the attributes specified.
  594. Returns:
  595. Status code
  596. --*/
  597. {
  598. SAL_RETURN_REGS ReturnReg;
  599. EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
  600. ReturnReg = EfiCallEsalService (
  601. &Guid,
  602. EsalQueryVariableInfo,
  603. (UINT64) Attributes,
  604. (UINT64) MaximumVariableStorageSize,
  605. (UINT64) RemainingVariableStorageSize,
  606. (UINT64) MaximumVariableSize,
  607. 0,
  608. 0,
  609. 0
  610. );
  611. return (EFI_STATUS) ReturnReg.Status;
  612. }
  613. #endif
  614. //
  615. // Sal RTC Driver Class.
  616. //
  617. EFI_STATUS
  618. EfiGetTime (
  619. OUT EFI_TIME *Time,
  620. OUT EFI_TIME_CAPABILITIES *Capabilities
  621. )
  622. /*++
  623. Routine Description:
  624. Returns the current time and date information, and the time-keeping
  625. capabilities of the hardware platform.
  626. Arguments:
  627. Time - A pointer to storage to receive a snapshot of the current time.
  628. Capabilities - An optional pointer to a buffer to receive the real time clock device's
  629. capabilities.
  630. Returns:
  631. Status code
  632. --*/
  633. {
  634. SAL_RETURN_REGS ReturnReg;
  635. EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
  636. ReturnReg = EfiCallEsalService (&Guid, GetTime, (UINT64) Time, (UINT64) Capabilities, 0, 0, 0, 0, 0);
  637. return ReturnReg.Status;
  638. }
  639. EFI_STATUS
  640. EfiSetTime (
  641. OUT EFI_TIME *Time
  642. )
  643. /*++
  644. Routine Description:
  645. Sets the current local time and date information.
  646. Arguments:
  647. Time - A pointer to the current time.
  648. Returns:
  649. Status code
  650. --*/
  651. {
  652. SAL_RETURN_REGS ReturnReg;
  653. EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
  654. ReturnReg = EfiCallEsalService (&Guid, SetTime, (UINT64) Time, 0, 0, 0, 0, 0, 0);
  655. return ReturnReg.Status;
  656. }
  657. EFI_STATUS
  658. EfiGetWakeupTime (
  659. OUT BOOLEAN *Enabled,
  660. OUT BOOLEAN *Pending,
  661. OUT EFI_TIME *Time
  662. )
  663. /*++
  664. Routine Description:
  665. Returns the current wakeup alarm clock setting.
  666. Arguments:
  667. Enabled - Indicates if the alarm is currently enabled or disabled.
  668. Pending - Indicates if the alarm signal is pending and requires acknowledgement.
  669. Time - The current alarm setting.
  670. Returns:
  671. Status code
  672. --*/
  673. {
  674. SAL_RETURN_REGS ReturnReg;
  675. EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
  676. ReturnReg = EfiCallEsalService (&Guid, GetWakeupTime, (UINT64) Enabled, (UINT64) Pending, (UINT64) Time, 0, 0, 0, 0);
  677. return ReturnReg.Status;
  678. }
  679. EFI_STATUS
  680. EfiSetWakeupTime (
  681. IN BOOLEAN Enable,
  682. IN EFI_TIME *Time
  683. )
  684. /*++
  685. Routine Description:
  686. Sets the system wakeup alarm clock time.
  687. Arguments:
  688. Enable - Enable or disable the wakeup alarm.
  689. Time - If Enable is TRUE, the time to set the wakeup alarm for.
  690. If Enable is FALSE, then this parameter is optional, and may be NULL.
  691. Returns:
  692. Status code
  693. --*/
  694. {
  695. SAL_RETURN_REGS ReturnReg;
  696. EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
  697. ReturnReg = EfiCallEsalService (&Guid, SetWakeupTime, (UINT64) Enable, (UINT64) Time, 0, 0, 0, 0, 0);
  698. return ReturnReg.Status;
  699. }
  700. //
  701. // Base IO Services
  702. //
  703. EFI_STATUS
  704. EfiIoRead (
  705. IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
  706. IN UINT64 Address,
  707. IN UINTN Count,
  708. IN OUT VOID *Buffer
  709. )
  710. /*++
  711. Routine Description:
  712. Perform an IO read into Buffer.
  713. Arguments:
  714. Width - Width of read transaction, and repeat operation to use
  715. Address - IO address to read
  716. Count - Number of times to read the IO address.
  717. Buffer - Buffer to read data into. size is Width * Count
  718. Returns:
  719. Status code
  720. --*/
  721. {
  722. SAL_RETURN_REGS ReturnReg;
  723. EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
  724. ReturnReg = EfiCallEsalService (&Guid, IoRead, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
  725. ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);
  726. return ReturnReg.Status;
  727. }
  728. EFI_STATUS
  729. EfiIoWrite (
  730. IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
  731. IN UINT64 Address,
  732. IN UINTN Count,
  733. IN OUT VOID *Buffer
  734. )
  735. /*++
  736. Routine Description:
  737. Perform an IO write into Buffer.
  738. Arguments:
  739. Width - Width of write transaction, and repeat operation to use
  740. Address - IO address to write
  741. Count - Number of times to write the IO address.
  742. Buffer - Buffer to write data from. size is Width * Count
  743. Returns:
  744. Status code
  745. --*/
  746. {
  747. SAL_RETURN_REGS ReturnReg;
  748. EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
  749. ReturnReg = EfiCallEsalService (&Guid, IoWrite, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
  750. return ReturnReg.Status;
  751. }
  752. EFI_STATUS
  753. EfiMemRead (
  754. IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
  755. IN UINT64 Address,
  756. IN UINTN Count,
  757. IN OUT VOID *Buffer
  758. )
  759. /*++
  760. Routine Description:
  761. Perform a Memory mapped IO read into Buffer.
  762. Arguments:
  763. Width - Width of each read transaction.
  764. Address - Memory mapped IO address to read
  765. Count - Number of Width quanta to read
  766. Buffer - Buffer to read data into. size is Width * Count
  767. Returns:
  768. Status code
  769. --*/
  770. {
  771. SAL_RETURN_REGS ReturnReg;
  772. EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
  773. ReturnReg = EfiCallEsalService (&Guid, MemRead, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
  774. ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);
  775. return ReturnReg.Status;
  776. }
  777. EFI_STATUS
  778. EfiMemWrite (
  779. IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
  780. IN UINT64 Address,
  781. IN UINTN Count,
  782. IN OUT VOID *Buffer
  783. )
  784. /*++
  785. Routine Description:
  786. Perform a memory mapped IO write into Buffer.
  787. Arguments:
  788. Width - Width of write transaction, and repeat operation to use
  789. Address - IO address to write
  790. Count - Number of times to write the IO address.
  791. Buffer - Buffer to write data from. size is Width * Count
  792. Returns:
  793. Status code
  794. --*/
  795. {
  796. SAL_RETURN_REGS ReturnReg;
  797. EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
  798. ReturnReg = EfiCallEsalService (&Guid, MemWrite, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
  799. return ReturnReg.Status;
  800. }
  801. #define EFI_PCI_ADDRESS_IPF(_seg, _bus, _devfunc, _reg) \
  802. (((_seg) << 24) | ((_bus) << 16) | ((_devfunc) << 8) | (_reg)) & 0xFFFFFFFF
  803. //
  804. // PCI Class Functions
  805. //
  806. UINT8
  807. PciRead8 (
  808. UINT8 Segment,
  809. UINT8 Bus,
  810. UINT8 DevFunc,
  811. UINT8 Register
  812. )
  813. /*++
  814. Routine Description:
  815. Perform an one byte PCI config cycle read
  816. Arguments:
  817. Segment - PCI Segment ACPI _SEG
  818. Bus - PCI Bus
  819. DevFunc - PCI Device(7:3) and Func(2:0)
  820. Register - PCI config space register
  821. Returns:
  822. Data read from PCI config space
  823. --*/
  824. {
  825. EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
  826. UINT64 Address;
  827. SAL_RETURN_REGS Return;
  828. Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
  829. Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 1, 0, 0, 0, 0, 0);
  830. return (UINT8) Return.r9;
  831. }
  832. UINT16
  833. PciRead16 (
  834. UINT8 Segment,
  835. UINT8 Bus,
  836. UINT8 DevFunc,
  837. UINT8 Register
  838. )
  839. /*++
  840. Routine Description:
  841. Perform an two byte PCI config cycle read
  842. Arguments:
  843. Segment - PCI Segment ACPI _SEG
  844. Bus - PCI Bus
  845. DevFunc - PCI Device(7:3) and Func(2:0)
  846. Register - PCI config space register
  847. Returns:
  848. Data read from PCI config space
  849. --*/
  850. {
  851. EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
  852. UINT64 Address;
  853. SAL_RETURN_REGS Return;
  854. Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
  855. Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 2, 0, 0, 0, 0, 0);
  856. return (UINT16) Return.r9;
  857. }
  858. UINT32
  859. PciRead32 (
  860. UINT8 Segment,
  861. UINT8 Bus,
  862. UINT8 DevFunc,
  863. UINT8 Register
  864. )
  865. /*++
  866. Routine Description:
  867. Perform an four byte PCI config cycle read
  868. Arguments:
  869. Segment - PCI Segment ACPI _SEG
  870. Bus - PCI Bus
  871. DevFunc - PCI Device(7:3) and Func(2:0)
  872. Register - PCI config space register
  873. Returns:
  874. Data read from PCI config space
  875. --*/
  876. {
  877. EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
  878. UINT64 Address;
  879. SAL_RETURN_REGS Return;
  880. Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
  881. Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 4, 0, 0, 0, 0, 0);
  882. return (UINT32) Return.r9;
  883. }
  884. VOID
  885. PciWrite8 (
  886. UINT8 Segment,
  887. UINT8 Bus,
  888. UINT8 DevFunc,
  889. UINT8 Register,
  890. UINT8 Data
  891. )
  892. /*++
  893. Routine Description:
  894. Perform an one byte PCI config cycle write
  895. Arguments:
  896. Segment - PCI Segment ACPI _SEG
  897. Bus - PCI Bus
  898. DevFunc - PCI Device(7:3) and Func(2:0)
  899. Register - PCI config space register
  900. Data - Data to write
  901. Returns:
  902. NONE
  903. --*/
  904. {
  905. EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
  906. UINT64 Address;
  907. Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
  908. EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 1, Data, 0, 0, 0, 0);
  909. }
  910. VOID
  911. PciWrite16 (
  912. UINT8 Segment,
  913. UINT8 Bus,
  914. UINT8 DevFunc,
  915. UINT8 Register,
  916. UINT16 Data
  917. )
  918. /*++
  919. Routine Description:
  920. Perform an two byte PCI config cycle write
  921. Arguments:
  922. Segment - PCI Segment ACPI _SEG
  923. Bus - PCI Bus
  924. DevFunc - PCI Device(7:3) and Func(2:0)
  925. Register - PCI config space register
  926. Data - Data to write
  927. Returns:
  928. None.
  929. --*/
  930. {
  931. EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
  932. UINT64 Address;
  933. Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
  934. EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 2, Data, 0, 0, 0, 0);
  935. }
  936. VOID
  937. PciWrite32 (
  938. UINT8 Segment,
  939. UINT8 Bus,
  940. UINT8 DevFunc,
  941. UINT8 Register,
  942. UINT32 Data
  943. )
  944. /*++
  945. Routine Description:
  946. Perform an four byte PCI config cycle write
  947. Arguments:
  948. Segment - PCI Segment ACPI _SEG
  949. Bus - PCI Bus
  950. DevFunc - PCI Device(7:3) and Func(2:0)
  951. Register - PCI config space register
  952. Data - Data to write
  953. Returns:
  954. NONE
  955. --*/
  956. {
  957. EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
  958. UINT64 Address;
  959. Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
  960. EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 4, Data, 0, 0, 0, 0);
  961. }
  962. //
  963. // Stall class functions
  964. //
  965. VOID
  966. EfiStall (
  967. IN UINTN Microseconds
  968. )
  969. /*++
  970. Routine Description:
  971. Delay for at least the request number of microseconds
  972. Arguments:
  973. Microseconds - Number of microseconds to delay.
  974. Returns:
  975. NONE
  976. --*/
  977. {
  978. EFI_GUID Guid = EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID;
  979. if (EfiAtRuntime ()) {
  980. EfiCallEsalService (&Guid, Stall, Microseconds, 4, 0, 0, 0, 0, 0);
  981. } else {
  982. gBS->Stall (Microseconds);
  983. }
  984. }
  985. //
  986. // Cache Flush Routine.
  987. //
  988. EFI_STATUS
  989. EfiCpuFlushCache (
  990. IN EFI_PHYSICAL_ADDRESS Start,
  991. IN UINT64 Length
  992. )
  993. /*++
  994. Routine Description:
  995. Flush cache with specified range.
  996. Arguments:
  997. Start - Start address
  998. Length - Length in bytes
  999. Returns:
  1000. Status code
  1001. EFI_SUCCESS - success
  1002. --*/
  1003. {
  1004. SalFlushCache (Start, Length);
  1005. return EFI_SUCCESS;
  1006. }