1
0

fatdev.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976
  1. /*++
  2. Copyright (c) 2012 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. fatdev.c
  5. Abstract:
  6. This module implements the underlying device support for the FAT library
  7. in the firmware environment
  8. Author:
  9. Evan Green 23-Sep-2012
  10. Environment:
  11. Firmware
  12. --*/
  13. //
  14. // ------------------------------------------------------------------- Includes
  15. //
  16. #include <minoca/kernel/kernel.h>
  17. #include <minoca/lib/fat/fat.h>
  18. #include <uefifw.h>
  19. #include <minoca/uefi/protocol/diskio.h>
  20. #include <minoca/uefi/protocol/blockio.h>
  21. #include <minoca/uefi/protocol/sfilesys.h>
  22. #include "fatfs.h"
  23. //
  24. // ---------------------------------------------------------------- Definitions
  25. //
  26. //
  27. // ------------------------------------------------------ Data Type Definitions
  28. //
  29. /*++
  30. Structure Description:
  31. This structure defines an I/O buffer in the firmware environment.
  32. Members:
  33. Data - Stores a pointer to the I/O buffer's data buffer.
  34. Size - Stores the size of the memory buffer, in bytes.
  35. CurrentOffset - Stores the current offset into the I/O buffer. All I/O will
  36. begin at the current offset.
  37. --*/
  38. typedef struct _EFI_FAT_IO_BUFFER {
  39. VOID *Data;
  40. UINTN Size;
  41. UINTN CurrentOffset;
  42. } EFI_FAT_IO_BUFFER, *PEFI_FAT_IO_BUFFER;
  43. //
  44. // ----------------------------------------------- Internal Function Prototypes
  45. //
  46. //
  47. // -------------------------------------------------------------------- Globals
  48. //
  49. //
  50. // ------------------------------------------------------------------ Functions
  51. //
  52. PFAT_IO_BUFFER
  53. FatAllocateIoBuffer (
  54. PVOID DeviceToken,
  55. UINTN Size
  56. )
  57. /*++
  58. Routine Description:
  59. This routine allocates memory for device I/O use.
  60. Arguments:
  61. DeviceToken - Supplies an opaque token identifying the underlying device.
  62. Size - Supplies the size of the required allocation, in bytes.
  63. Return Value:
  64. Returns a pointer to the FAT I/O buffer, or NULL on failure.
  65. --*/
  66. {
  67. PEFI_FAT_IO_BUFFER IoBuffer;
  68. EFI_STATUS Status;
  69. Status = EfiAllocatePool(EfiBootServicesData,
  70. sizeof(EFI_FAT_IO_BUFFER) + Size,
  71. (VOID **)&IoBuffer);
  72. if (EFI_ERROR(Status)) {
  73. return NULL;
  74. }
  75. IoBuffer->Data = (VOID *)IoBuffer + sizeof(EFI_FAT_IO_BUFFER);
  76. IoBuffer->Size = Size;
  77. IoBuffer->CurrentOffset = 0;
  78. return IoBuffer;
  79. }
  80. PFAT_IO_BUFFER
  81. FatCreateIoBuffer (
  82. PVOID Buffer,
  83. UINTN Size
  84. )
  85. /*++
  86. Routine Description:
  87. This routine creates a FAT I/O buffer from the given buffer.
  88. Arguments:
  89. Buffer - Supplies a pointer to the memory buffer on which to base the FAT
  90. I/O buffer.
  91. Size - Supplies the size of the memory buffer, in bytes.
  92. Return Value:
  93. Returns an pointer to the FAT I/O buffer, or NULL on failure.
  94. --*/
  95. {
  96. PEFI_FAT_IO_BUFFER IoBuffer;
  97. EFI_STATUS Status;
  98. Status = EfiAllocatePool(EfiBootServicesData,
  99. sizeof(EFI_FAT_IO_BUFFER),
  100. (VOID **)&IoBuffer);
  101. if (EFI_ERROR(Status)) {
  102. return NULL;
  103. }
  104. IoBuffer->Data = Buffer;
  105. IoBuffer->Size = Size;
  106. IoBuffer->CurrentOffset = 0;
  107. return IoBuffer;
  108. }
  109. VOID
  110. FatIoBufferUpdateOffset (
  111. PFAT_IO_BUFFER FatIoBuffer,
  112. UINTN OffsetUpdate,
  113. BOOL Decrement
  114. )
  115. /*++
  116. Routine Description:
  117. This routine increments the given FAT I/O buffer's current offset by the
  118. given amount.
  119. Arguments:
  120. FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
  121. OffsetUpdate - Supplies the number of bytes by which the offset will be
  122. updated.
  123. Decrement - Supplies a boolean indicating whether the update will be a
  124. decrement (TRUE) or an increment (FALSE).
  125. Return Value:
  126. None.
  127. --*/
  128. {
  129. if (Decrement == FALSE) {
  130. ((PEFI_FAT_IO_BUFFER)FatIoBuffer)->CurrentOffset += OffsetUpdate;
  131. } else {
  132. ((PEFI_FAT_IO_BUFFER)FatIoBuffer)->CurrentOffset -= OffsetUpdate;
  133. }
  134. ASSERT(((PEFI_FAT_IO_BUFFER)FatIoBuffer)->CurrentOffset <=
  135. ((PEFI_FAT_IO_BUFFER)FatIoBuffer)->Size);
  136. return;
  137. }
  138. VOID
  139. FatIoBufferSetOffset (
  140. PFAT_IO_BUFFER FatIoBuffer,
  141. UINTN Offset
  142. )
  143. /*++
  144. Routine Description:
  145. This routine sets the given FAT I/O buffer's current offset.
  146. Arguments:
  147. FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
  148. Offset - Supplies the new offset to set.
  149. Return Value:
  150. None.
  151. --*/
  152. {
  153. PEFI_FAT_IO_BUFFER IoBuffer;
  154. IoBuffer = (PEFI_FAT_IO_BUFFER)FatIoBuffer;
  155. IoBuffer->CurrentOffset = Offset;
  156. ASSERT(IoBuffer->CurrentOffset <= IoBuffer->Size);
  157. return;
  158. }
  159. KSTATUS
  160. FatZeroIoBuffer (
  161. PFAT_IO_BUFFER FatIoBuffer,
  162. UINTN Offset,
  163. UINTN ByteCount
  164. )
  165. /*++
  166. Routine Description:
  167. This routine zeros the contents of the FAT I/O buffer starting at the
  168. offset for the given number of bytes.
  169. Arguments:
  170. FatIoBuffer - Supplies a pointer to the FAT I/O buffer that is to be zeroed.
  171. Offset - Supplies the offset within the I/O buffer where the zeroing should
  172. begin.
  173. ByteCount - Supplies the number of bytes to zero.
  174. Return Value:
  175. Status code.
  176. --*/
  177. {
  178. PEFI_FAT_IO_BUFFER IoBuffer;
  179. IoBuffer = (PEFI_FAT_IO_BUFFER)FatIoBuffer;
  180. EfiSetMem(IoBuffer->Data + IoBuffer->CurrentOffset + Offset, ByteCount, 0);
  181. return STATUS_SUCCESS;
  182. }
  183. KSTATUS
  184. FatCopyIoBuffer (
  185. PFAT_IO_BUFFER Destination,
  186. UINTN DestinationOffset,
  187. PFAT_IO_BUFFER Source,
  188. UINTN SourceOffset,
  189. UINTN ByteCount
  190. )
  191. /*++
  192. Routine Description:
  193. This routine copies the contents of the source I/O buffer starting at the
  194. source offset to the destination I/O buffer starting at the destination
  195. offset. It assumes that the arguments are correct such that the copy can
  196. succeed.
  197. Arguments:
  198. Destination - Supplies a pointer to the destination I/O buffer that is to
  199. be copied into.
  200. DestinationOffset - Supplies the offset into the destination I/O buffer
  201. where the copy should begin.
  202. Source - Supplies a pointer to the source I/O buffer whose contents will be
  203. copied to the destination.
  204. SourceOffset - Supplies the offset into the source I/O buffer where the
  205. copy should begin.
  206. ByteCount - Supplies the size of the requested copy in bytes.
  207. Return Value:
  208. Status code.
  209. --*/
  210. {
  211. VOID *DestinationBuffer;
  212. PEFI_FAT_IO_BUFFER DestinationIoBuffer;
  213. VOID *SourceBuffer;
  214. PEFI_FAT_IO_BUFFER SourceIoBuffer;
  215. DestinationIoBuffer = (PEFI_FAT_IO_BUFFER)Destination;
  216. DestinationBuffer = DestinationIoBuffer->Data +
  217. DestinationIoBuffer->CurrentOffset +
  218. DestinationOffset;
  219. SourceIoBuffer = (PEFI_FAT_IO_BUFFER)Source;
  220. SourceBuffer = SourceIoBuffer->Data +
  221. SourceIoBuffer->CurrentOffset +
  222. SourceOffset;
  223. EfiCopyMem(DestinationBuffer, SourceBuffer, ByteCount);
  224. return STATUS_SUCCESS;
  225. }
  226. KSTATUS
  227. FatCopyIoBufferData (
  228. PFAT_IO_BUFFER FatIoBuffer,
  229. PVOID Buffer,
  230. UINTN Offset,
  231. UINTN Size,
  232. BOOL ToIoBuffer
  233. )
  234. /*++
  235. Routine Description:
  236. This routine copies from a buffer into the given I/O buffer or out of the
  237. given I/O buffer.
  238. Arguments:
  239. FatIoBuffer - Supplies a pointer to the FAT I/O buffer to copy in or out of.
  240. Buffer - Supplies a pointer to the regular linear buffer to copy to or from.
  241. Offset - Supplies an offset in bytes from the beginning of the I/O buffer
  242. to copy to or from.
  243. Size - Supplies the number of bytes to copy.
  244. ToIoBuffer - Supplies a boolean indicating whether data is copied into the
  245. I/O buffer (TRUE) or out of the I/O buffer (FALSE).
  246. Return Value:
  247. Status code.
  248. --*/
  249. {
  250. VOID *Destination;
  251. PEFI_FAT_IO_BUFFER IoBuffer;
  252. VOID *Source;
  253. IoBuffer = (PEFI_FAT_IO_BUFFER)FatIoBuffer;
  254. ASSERT(IoBuffer->CurrentOffset + Offset + Size <= IoBuffer->Size);
  255. Destination = IoBuffer->Data + IoBuffer->CurrentOffset + Offset;
  256. Source = Buffer;
  257. if (ToIoBuffer == FALSE) {
  258. Source = Destination;
  259. Destination = Buffer;
  260. }
  261. EfiCopyMem(Destination, Source, Size);
  262. return STATUS_SUCCESS;
  263. }
  264. PVOID
  265. FatMapIoBuffer (
  266. PFAT_IO_BUFFER FatIoBuffer
  267. )
  268. /*++
  269. Routine Description:
  270. This routine maps the given FAT I/O buffer and returns the base of the
  271. virtually contiguous mapping.
  272. Arguments:
  273. FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
  274. Return Value:
  275. Returns a pointer to the virtual address of the mapping on success, or
  276. NULL on failure.
  277. --*/
  278. {
  279. return ((PEFI_FAT_IO_BUFFER)FatIoBuffer)->Data;
  280. }
  281. VOID
  282. FatFreeIoBuffer (
  283. PFAT_IO_BUFFER FatIoBuffer
  284. )
  285. /*++
  286. Routine Description:
  287. This routine frees a FAT I/O buffer.
  288. Arguments:
  289. FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
  290. Return Value:
  291. None.
  292. --*/
  293. {
  294. EfiFreePool(FatIoBuffer);
  295. return;
  296. }
  297. PVOID
  298. FatAllocatePagedMemory (
  299. PVOID DeviceToken,
  300. ULONG SizeInBytes
  301. )
  302. /*++
  303. Routine Description:
  304. This routine allocates paged memory for the FAT library.
  305. Arguments:
  306. DeviceToken - Supplies an opaque token identifying the underlying device.
  307. SizeInBytes - Supplies the number of bytes to allocate.
  308. Return Value:
  309. Returns a pointer to the allocated memory, or NULL on failure.
  310. --*/
  311. {
  312. VOID *Allocation;
  313. EFI_STATUS Status;
  314. Status = EfiAllocatePool(EfiBootServicesData,
  315. SizeInBytes,
  316. &Allocation);
  317. if (EFI_ERROR(Status)) {
  318. return NULL;
  319. }
  320. return Allocation;
  321. }
  322. PVOID
  323. FatAllocateNonPagedMemory (
  324. PVOID DeviceToken,
  325. ULONG SizeInBytes
  326. )
  327. /*++
  328. Routine Description:
  329. This routine allocates non-paged memory for the FAT library.
  330. Arguments:
  331. DeviceToken - Supplies an opaque token identifying the underlying device.
  332. SizeInBytes - Supplies the number of bytes to allocate.
  333. Return Value:
  334. Returns a pointer to the allocated memory, or NULL on failure.
  335. --*/
  336. {
  337. return FatAllocatePagedMemory(DeviceToken, SizeInBytes);
  338. }
  339. VOID
  340. FatFreePagedMemory (
  341. PVOID DeviceToken,
  342. PVOID Allocation
  343. )
  344. /*++
  345. Routine Description:
  346. This routine frees paged memory for the FAT library.
  347. Arguments:
  348. DeviceToken - Supplies an opaque token identifying the underlying device.
  349. Allocation - Supplies a pointer to the allocation to free.
  350. Return Value:
  351. None.
  352. --*/
  353. {
  354. EfiFreePool(Allocation);
  355. return;
  356. }
  357. VOID
  358. FatFreeNonPagedMemory (
  359. PVOID DeviceToken,
  360. PVOID Allocation
  361. )
  362. /*++
  363. Routine Description:
  364. This routine frees memory for the FAT library.
  365. Arguments:
  366. DeviceToken - Supplies an opaque token identifying the underlying device.
  367. Allocation - Supplies a pointer to the allocation to free.
  368. Return Value:
  369. None.
  370. --*/
  371. {
  372. FatFreePagedMemory(DeviceToken, Allocation);
  373. return;
  374. }
  375. KSTATUS
  376. FatCreateLock (
  377. PVOID *Lock
  378. )
  379. /*++
  380. Routine Description:
  381. This routine creates a lock.
  382. Arguments:
  383. Lock - Supplies a pointer where an opaque pointer will be returned
  384. representing the lock.
  385. Return Value:
  386. STATUS_SUCCESS on success.
  387. STATUS_INSUFFICIENT_RESOURCES if the lock could not be allocated.
  388. --*/
  389. {
  390. *Lock = NULL;
  391. return STATUS_SUCCESS;
  392. }
  393. VOID
  394. FatDestroyLock (
  395. PVOID Lock
  396. )
  397. /*++
  398. Routine Description:
  399. This routine destroys a created lock.
  400. Arguments:
  401. Lock - Supplies a the opaque pointer returned upon creation.
  402. Return Value:
  403. None.
  404. --*/
  405. {
  406. return;
  407. }
  408. VOID
  409. FatAcquireLock (
  410. PVOID Lock
  411. )
  412. /*++
  413. Routine Description:
  414. This routine acquires a lock.
  415. Arguments:
  416. Lock - Supplies a the opaque pointer returned upon creation.
  417. Return Value:
  418. None.
  419. --*/
  420. {
  421. return;
  422. }
  423. VOID
  424. FatReleaseLock (
  425. PVOID Lock
  426. )
  427. /*++
  428. Routine Description:
  429. This routine releases a lock.
  430. Arguments:
  431. Lock - Supplies a the opaque pointer returned upon creation.
  432. Return Value:
  433. None.
  434. --*/
  435. {
  436. return;
  437. }
  438. KSTATUS
  439. FatReadDevice (
  440. PVOID DeviceToken,
  441. ULONGLONG BlockAddress,
  442. UINTN BlockCount,
  443. ULONG Flags,
  444. PVOID Irp,
  445. PFAT_IO_BUFFER FatIoBuffer
  446. )
  447. /*++
  448. Routine Description:
  449. This routine reads data from the underlying disk.
  450. Arguments:
  451. DeviceToken - Supplies an opaque token identifying the underlying device.
  452. BlockAddress - Supplies the block index to read (for physical disks, this is
  453. the LBA).
  454. BlockCount - Supplies the number of blocks to read.
  455. Flags - Supplies flags regarding the I/O operation. See IO_FLAG_*
  456. definitions.
  457. Irp - Supplies an optional pointer to the IRP to pass to the read file
  458. function.
  459. FatIoBuffer - Supplies a pointer to a FAT I/O buffer where the data from
  460. the disk will be returned.
  461. Return Value:
  462. Status code.
  463. --*/
  464. {
  465. VOID *Buffer;
  466. PEFI_FAT_VOLUME Device;
  467. EFI_STATUS EfiStatus;
  468. PEFI_FAT_IO_BUFFER IoBuffer;
  469. KSTATUS Status;
  470. Device = (PEFI_FAT_VOLUME)DeviceToken;
  471. IoBuffer = (PEFI_FAT_IO_BUFFER)FatIoBuffer;
  472. ASSERT(IoBuffer != NULL);
  473. ASSERT(Device->Magic == EFI_FAT_VOLUME_MAGIC);
  474. ASSERT((ULONG)BlockCount == BlockCount);
  475. ASSERT((IoBuffer->Size - IoBuffer->CurrentOffset) >=
  476. (BlockCount * Device->BlockSize));
  477. Status = STATUS_SUCCESS;
  478. Buffer = IoBuffer->Data + IoBuffer->CurrentOffset;
  479. EfiStatus = Device->DiskIo->ReadDisk(Device->DiskIo,
  480. Device->MediaId,
  481. BlockAddress * Device->BlockSize,
  482. BlockCount * Device->BlockSize,
  483. Buffer);
  484. if (EfiStatus == EFI_MEDIA_CHANGED) {
  485. Status = STATUS_DEVICE_IO_ERROR;
  486. } else if (EfiStatus == EFI_NO_MEDIA) {
  487. Status = STATUS_NO_MEDIA;
  488. } else if (EFI_ERROR(EfiStatus)) {
  489. Status = STATUS_DEVICE_IO_ERROR;
  490. }
  491. if (!KSUCCESS(Status)) {
  492. goto ReadDeviceEnd;
  493. }
  494. Status = STATUS_SUCCESS;
  495. ReadDeviceEnd:
  496. return Status;
  497. }
  498. KSTATUS
  499. FatWriteDevice (
  500. PVOID DeviceToken,
  501. ULONGLONG BlockAddress,
  502. UINTN BlockCount,
  503. ULONG Flags,
  504. PVOID Irp,
  505. PFAT_IO_BUFFER FatIoBuffer
  506. )
  507. /*++
  508. Routine Description:
  509. This routine writes data to the underlying disk.
  510. Arguments:
  511. DeviceToken - Supplies an opaque token identifying the underlying device.
  512. BlockAddress - Supplies the block index to write to (for physical disks,
  513. this is the LBA).
  514. BlockCount - Supplies the number of blocks to write.
  515. Flags - Supplies flags regarding the I/O operation. See IO_FLAG_*
  516. definitions.
  517. Irp - Supplies an optional pointer to an IRP to use for the disk operation.
  518. FatIoBuffer - Supplies a pointer to a FAT I/O buffer containing the data to
  519. write.
  520. Return Value:
  521. Status code.
  522. --*/
  523. {
  524. VOID *Buffer;
  525. PEFI_FAT_VOLUME Device;
  526. EFI_STATUS EfiStatus;
  527. PEFI_FAT_IO_BUFFER IoBuffer;
  528. KSTATUS Status;
  529. ASSERT(FatIoBuffer != NULL);
  530. Device = (PEFI_FAT_VOLUME)DeviceToken;
  531. IoBuffer = (PEFI_FAT_IO_BUFFER)FatIoBuffer;
  532. Buffer = IoBuffer->Data + IoBuffer->CurrentOffset;
  533. Status = STATUS_SUCCESS;
  534. EfiStatus = Device->DiskIo->WriteDisk(Device->DiskIo,
  535. Device->MediaId,
  536. BlockAddress * Device->BlockSize,
  537. BlockCount * Device->BlockSize,
  538. Buffer);
  539. if (EfiStatus == EFI_MEDIA_CHANGED) {
  540. Status = STATUS_DEVICE_IO_ERROR;
  541. } else if (EfiStatus == EFI_NO_MEDIA) {
  542. Status = STATUS_NO_MEDIA;
  543. } else if (EFI_ERROR(EfiStatus)) {
  544. Status = STATUS_DEVICE_IO_ERROR;
  545. }
  546. if (!KSUCCESS(Status)) {
  547. goto WriteDeviceEnd;
  548. }
  549. WriteDeviceEnd:
  550. return Status;
  551. }
  552. KSTATUS
  553. FatGetDeviceBlockInformation (
  554. PVOID DeviceToken,
  555. PFILE_BLOCK_INFORMATION BlockInformation
  556. )
  557. /*++
  558. Routine Description:
  559. This routine converts a file's block information into disk level block
  560. information by modifying the offsets of each contiguous run.
  561. Arguments:
  562. DeviceToken - Supplies an opaque token identify the underlying device.
  563. BlockInformation - Supplies a pointer to the block information to be
  564. updated.
  565. Return Value:
  566. Status code.
  567. --*/
  568. {
  569. ASSERT(FALSE);
  570. return STATUS_NOT_IMPLEMENTED;
  571. }
  572. ULONG
  573. FatGetIoCacheEntryDataSize (
  574. VOID
  575. )
  576. /*++
  577. Routine Description:
  578. This routine returns the size of data stored in each cache entry.
  579. Arguments:
  580. None.
  581. Return Value:
  582. Returns the size of the data stored in each cache entry, or 0 if there is
  583. no cache.
  584. --*/
  585. {
  586. return 0;
  587. }
  588. ULONG
  589. FatGetPageSize (
  590. VOID
  591. )
  592. /*++
  593. Routine Description:
  594. This routine returns the size of a physical memory page for the current FAT
  595. environment.
  596. Arguments:
  597. None.
  598. Return Value:
  599. Returns the size of a page in the current environment. Returns 0 if the
  600. size is not known.
  601. --*/
  602. {
  603. return EFI_PAGE_SIZE;
  604. }
  605. VOID
  606. FatGetCurrentSystemTime (
  607. PSYSTEM_TIME SystemTime
  608. )
  609. /*++
  610. Routine Description:
  611. This routine returns the current system time.
  612. Arguments:
  613. SystemTime - Supplies a pointer where the current system time will be
  614. returned.
  615. Return Value:
  616. None.
  617. --*/
  618. {
  619. EfiSetMem(SystemTime, sizeof(SYSTEM_TIME), 0);
  620. return;
  621. }
  622. //
  623. // --------------------------------------------------------- Internal Functions
  624. //