]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkPkg/Library/DxeIoLibCpuIo/IoLib.c
eed26ceaf611620ea35eaf2a1aebdca22dad87f6
[mirror_edk2.git] / IntelFrameworkPkg / Library / DxeIoLibCpuIo / IoLib.c
1 /** @file
2 I/O Library.
3 The implementation of I/O operation for this library instance
4 are based on EFI_CPU_IO_PROTOCOL.
5
6 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
7 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
8
9 SPDX-License-Identifier: BSD-2-Clause-Patent
10
11 Module Name: IoLib.c
12
13 **/
14
15
16 #include "DxeCpuIoLibInternal.h"
17
18 //
19 // Globle varible to cache pointer to CpuIo protocol.
20 //
21 EFI_CPU_IO_PROTOCOL *mCpuIo = NULL;
22
23 /**
24 The constructor function caches the pointer to CpuIo protocol.
25
26 The constructor function locates CpuIo protocol from protocol database.
27 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
28
29 @param ImageHandle The firmware allocated handle for the EFI image.
30 @param SystemTable A pointer to the EFI System Table.
31
32 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
33
34 **/
35 EFI_STATUS
36 EFIAPI
37 IoLibConstructor (
38 IN EFI_HANDLE ImageHandle,
39 IN EFI_SYSTEM_TABLE *SystemTable
40 )
41 {
42 EFI_STATUS Status;
43
44 Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (VOID **) &mCpuIo);
45 ASSERT_EFI_ERROR (Status);
46
47 return Status;
48 }
49
50 /**
51 Reads registers in the EFI CPU I/O space.
52
53 Reads the I/O port specified by Port with registers width specified by Width.
54 The read value is returned. If such operations are not supported, then ASSERT().
55 This function must guarantee that all I/O read and write operations are serialized.
56
57 @param Port The base address of the I/O operation.
58 The caller is responsible for aligning the Address if required.
59 @param Width The width of the I/O operation.
60
61 @return Data read from registers in the EFI CPU I/O space.
62
63 **/
64 UINT64
65 EFIAPI
66 IoReadWorker (
67 IN UINTN Port,
68 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
69 )
70 {
71 EFI_STATUS Status;
72 UINT64 Data;
73
74 Status = mCpuIo->Io.Read (mCpuIo, Width, Port, 1, &Data);
75 ASSERT_EFI_ERROR (Status);
76
77 return Data;
78 }
79
80 /**
81 Writes registers in the EFI CPU I/O space.
82
83 Writes the I/O port specified by Port with registers width and value specified by Width
84 and Data respectively. Data is returned. If such operations are not supported, then ASSERT().
85 This function must guarantee that all I/O read and write operations are serialized.
86
87 @param Port The base address of the I/O operation.
88 The caller is responsible for aligning the Address if required.
89 @param Width The width of the I/O operation.
90 @param Data The value to write to the I/O port.
91
92 @return The parameter of Data.
93
94 **/
95 UINT64
96 EFIAPI
97 IoWriteWorker (
98 IN UINTN Port,
99 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
100 IN UINT64 Data
101 )
102 {
103 EFI_STATUS Status;
104
105 Status = mCpuIo->Io.Write (mCpuIo, Width, Port, 1, &Data);
106 ASSERT_EFI_ERROR (Status);
107
108 return Data;
109 }
110
111 /**
112 Reads registers in the EFI CPU I/O space.
113
114 Reads the I/O port specified by Port with registers width specified by Width.
115 The port is read Count times, and the read data is stored in the provided Buffer.
116
117 This function must guarantee that all I/O read and write operations are serialized.
118 If such operations are not supported, then ASSERT().
119
120 @param Port The base address of the I/O operation.
121 The caller is responsible for aligning the Address if required.
122 @param Width The width of the I/O operation.
123 @param Count The number of times to read I/O port.
124 @param Buffer The buffer to store the read data into.
125
126 **/
127 VOID
128 EFIAPI
129 IoReadFifoWorker (
130 IN UINTN Port,
131 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
132 IN UINTN Count,
133 IN VOID *Buffer
134 )
135 {
136 EFI_STATUS Status;
137
138 Status = mCpuIo->Io.Read (mCpuIo, Width, Port, Count, Buffer);
139 ASSERT_EFI_ERROR (Status);
140 }
141
142 /**
143 Writes registers in the EFI CPU I/O space.
144
145 Writes the I/O port specified by Port with registers width specified by Width.
146 The port is written Count times, and the write data is retrieved from the provided Buffer.
147
148 This function must guarantee that all I/O read and write operations are serialized.
149 If such operations are not supported, then ASSERT().
150
151 @param Port The base address of the I/O operation.
152 The caller is responsible for aligning the Address if required.
153 @param Width The width of the I/O operation.
154 @param Count The number of times to write I/O port.
155 @param Buffer The buffer to store the read data into.
156
157 **/
158 VOID
159 EFIAPI
160 IoWriteFifoWorker (
161 IN UINTN Port,
162 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
163 IN UINTN Count,
164 IN VOID *Buffer
165 )
166 {
167 EFI_STATUS Status;
168
169 Status = mCpuIo->Io.Write (mCpuIo, Width, Port, Count, Buffer);
170 ASSERT_EFI_ERROR (Status);
171 }
172
173 /**
174 Reads memory-mapped registers in the EFI system memory space.
175
176 Reads the MMIO registers specified by Address with registers width specified by Width.
177 The read value is returned. If such operations are not supported, then ASSERT().
178 This function must guarantee that all MMIO read and write operations are serialized.
179
180 @param Address The MMIO register to read.
181 The caller is responsible for aligning the Address if required.
182 @param Width The width of the I/O operation.
183
184 @return Data read from registers in the EFI system memory space.
185
186 **/
187 UINT64
188 EFIAPI
189 MmioReadWorker (
190 IN UINTN Address,
191 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
192 )
193 {
194 EFI_STATUS Status;
195 UINT64 Data;
196
197 Status = mCpuIo->Mem.Read (mCpuIo, Width, Address, 1, &Data);
198 ASSERT_EFI_ERROR (Status);
199
200 return Data;
201 }
202
203 /**
204 Writes memory-mapped registers in the EFI system memory space.
205
206 Writes the MMIO registers specified by Address with registers width and value specified by Width
207 and Data respectively. Data is returned. If such operations are not supported, then ASSERT().
208 This function must guarantee that all MMIO read and write operations are serialized.
209
210 @param Address The MMIO register to read.
211 The caller is responsible for aligning the Address if required.
212 @param Width The width of the I/O operation.
213 @param Data The value to write to the I/O port.
214
215 @return Data read from registers in the EFI system memory space.
216
217 **/
218 UINT64
219 EFIAPI
220 MmioWriteWorker (
221 IN UINTN Address,
222 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
223 IN UINT64 Data
224 )
225 {
226 EFI_STATUS Status;
227
228 Status = mCpuIo->Mem.Write (mCpuIo, Width, Address, 1, &Data);
229 ASSERT_EFI_ERROR (Status);
230
231 return Data;
232 }
233
234 /**
235 Reads an 8-bit I/O port.
236
237 Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
238 This function must guarantee that all I/O read and write operations are
239 serialized.
240
241 If 8-bit I/O port operations are not supported, then ASSERT().
242
243 @param Port The I/O port to read.
244
245 @return The value read.
246
247 **/
248 UINT8
249 EFIAPI
250 IoRead8 (
251 IN UINTN Port
252 )
253 {
254 return (UINT8)IoReadWorker (Port, EfiCpuIoWidthUint8);
255 }
256
257 /**
258 Writes an 8-bit I/O port.
259
260 Writes the 8-bit I/O port specified by Port with the value specified by Value
261 and returns Value. This function must guarantee that all I/O read and write
262 operations are serialized.
263
264 If 8-bit I/O port operations are not supported, then ASSERT().
265
266 @param Port The I/O port to write.
267 @param Value The value to write to the I/O port.
268
269 @return The value written the I/O port.
270
271 **/
272 UINT8
273 EFIAPI
274 IoWrite8 (
275 IN UINTN Port,
276 IN UINT8 Value
277 )
278 {
279 return (UINT8)IoWriteWorker (Port, EfiCpuIoWidthUint8, Value);
280 }
281
282 /**
283 Reads a 16-bit I/O port.
284
285 Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
286 This function must guarantee that all I/O read and write operations are
287 serialized.
288
289 If Port is not aligned on a 16-bit boundary, then ASSERT().
290
291 If 16-bit I/O port operations are not supported, then ASSERT().
292
293 @param Port The I/O port to read.
294
295 @return The value read.
296
297 **/
298 UINT16
299 EFIAPI
300 IoRead16 (
301 IN UINTN Port
302 )
303 {
304 //
305 // Make sure Port is aligned on a 16-bit boundary.
306 //
307 ASSERT ((Port & 1) == 0);
308 return (UINT16)IoReadWorker (Port, EfiCpuIoWidthUint16);
309 }
310
311 /**
312 Writes a 16-bit I/O port.
313
314 Writes the 16-bit I/O port specified by Port with the value specified by Value
315 and returns Value. This function must guarantee that all I/O read and write
316 operations are serialized.
317
318 If Port is not aligned on a 16-bit boundary, then ASSERT().
319
320 If 16-bit I/O port operations are not supported, then ASSERT().
321
322 @param Port The I/O port to write.
323 @param Value The value to write to the I/O port.
324
325 @return The value written the I/O port.
326
327 **/
328 UINT16
329 EFIAPI
330 IoWrite16 (
331 IN UINTN Port,
332 IN UINT16 Value
333 )
334 {
335 //
336 // Make sure Port is aligned on a 16-bit boundary.
337 //
338 ASSERT ((Port & 1) == 0);
339 return (UINT16)IoWriteWorker (Port, EfiCpuIoWidthUint16, Value);
340 }
341
342 /**
343 Reads a 32-bit I/O port.
344
345 Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
346 This function must guarantee that all I/O read and write operations are
347 serialized.
348
349 If Port is not aligned on a 32-bit boundary, then ASSERT().
350
351 If 32-bit I/O port operations are not supported, then ASSERT().
352
353 @param Port The I/O port to read.
354
355 @return The value read.
356
357 **/
358 UINT32
359 EFIAPI
360 IoRead32 (
361 IN UINTN Port
362 )
363 {
364 //
365 // Make sure Port is aligned on a 32-bit boundary.
366 //
367 ASSERT ((Port & 3) == 0);
368 return (UINT32)IoReadWorker (Port, EfiCpuIoWidthUint32);
369 }
370
371 /**
372 Writes a 32-bit I/O port.
373
374 Writes the 32-bit I/O port specified by Port with the value specified by Value
375 and returns Value. This function must guarantee that all I/O read and write
376 operations are serialized.
377
378 If Port is not aligned on a 32-bit boundary, then ASSERT().
379
380 If 32-bit I/O port operations are not supported, then ASSERT().
381
382 @param Port The I/O port to write.
383 @param Value The value to write to the I/O port.
384
385 @return The value written the I/O port.
386
387 **/
388 UINT32
389 EFIAPI
390 IoWrite32 (
391 IN UINTN Port,
392 IN UINT32 Value
393 )
394 {
395 //
396 // Make sure Port is aligned on a 32-bit boundary.
397 //
398 ASSERT ((Port & 3) == 0);
399 return (UINT32)IoWriteWorker (Port, EfiCpuIoWidthUint32, Value);
400 }
401
402 /**
403 Reads a 64-bit I/O port.
404
405 Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.
406 This function must guarantee that all I/O read and write operations are
407 serialized.
408
409 If Port is not aligned on a 64-bit boundary, then ASSERT().
410
411 If 64-bit I/O port operations are not supported, then ASSERT().
412
413 @param Port The I/O port to read.
414
415 @return The value read.
416
417 **/
418 UINT64
419 EFIAPI
420 IoRead64 (
421 IN UINTN Port
422 )
423 {
424 //
425 // Make sure Port is aligned on a 64-bit boundary.
426 //
427 ASSERT ((Port & 7) == 0);
428 return IoReadWorker (Port, EfiCpuIoWidthUint64);
429 }
430
431 /**
432 Writes a 64-bit I/O port.
433
434 Writes the 64-bit I/O port specified by Port with the value specified by Value
435 and returns Value. This function must guarantee that all I/O read and write
436 operations are serialized.
437
438 If Port is not aligned on a 64-bit boundary, then ASSERT().
439
440 If 64-bit I/O port operations are not supported, then ASSERT().
441
442 @param Port The I/O port to write.
443 @param Value The value to write to the I/O port.
444
445 @return The value written the I/O port.
446
447 **/
448 UINT64
449 EFIAPI
450 IoWrite64 (
451 IN UINTN Port,
452 IN UINT64 Value
453 )
454 {
455 //
456 // Make sure Port is aligned on a 64-bit boundary.
457 //
458 ASSERT ((Port & 7) == 0);
459 return IoWriteWorker (Port, EfiCpuIoWidthUint64, Value);
460 }
461
462 /**
463 Reads an 8-bit I/O port fifo into a block of memory.
464
465 Reads the 8-bit I/O fifo port specified by Port.
466 The port is read Count times, and the read data is
467 stored in the provided Buffer.
468
469 This function must guarantee that all I/O read and write operations are
470 serialized.
471
472 If 8-bit I/O port operations are not supported, then ASSERT().
473
474 @param Port The I/O port to read.
475 @param Count The number of times to read I/O port.
476 @param Buffer The buffer to store the read data into.
477
478 **/
479 VOID
480 EFIAPI
481 IoReadFifo8 (
482 IN UINTN Port,
483 IN UINTN Count,
484 OUT VOID *Buffer
485 )
486 {
487 IoReadFifoWorker (Port, EfiCpuIoWidthFifoUint8, Count, Buffer);
488 }
489
490 /**
491 Writes a block of memory into an 8-bit I/O port fifo.
492
493 Writes the 8-bit I/O fifo port specified by Port.
494 The port is written Count times, and the write data is
495 retrieved from the provided Buffer.
496
497 This function must guarantee that all I/O write and write operations are
498 serialized.
499
500 If 8-bit I/O port operations are not supported, then ASSERT().
501
502 @param Port The I/O port to write.
503 @param Count The number of times to write I/O port.
504 @param Buffer The buffer to retrieve the write data from.
505
506 **/
507 VOID
508 EFIAPI
509 IoWriteFifo8 (
510 IN UINTN Port,
511 IN UINTN Count,
512 IN VOID *Buffer
513 )
514 {
515 IoWriteFifoWorker (Port, EfiCpuIoWidthFifoUint8, Count, Buffer);
516 }
517
518 /**
519 Reads a 16-bit I/O port fifo into a block of memory.
520
521 Reads the 16-bit I/O fifo port specified by Port.
522 The port is read Count times, and the read data is
523 stored in the provided Buffer.
524
525 This function must guarantee that all I/O read and write operations are
526 serialized.
527
528 If 16-bit I/O port operations are not supported, then ASSERT().
529
530 @param Port The I/O port to read.
531 @param Count The number of times to read I/O port.
532 @param Buffer The buffer to store the read data into.
533
534 **/
535 VOID
536 EFIAPI
537 IoReadFifo16 (
538 IN UINTN Port,
539 IN UINTN Count,
540 OUT VOID *Buffer
541 )
542 {
543 //
544 // Make sure Port is aligned on a 16-bit boundary.
545 //
546 ASSERT ((Port & 1) == 0);
547 IoReadFifoWorker (Port, EfiCpuIoWidthFifoUint16, Count, Buffer);
548 }
549
550 /**
551 Writes a block of memory into a 16-bit I/O port fifo.
552
553 Writes the 16-bit I/O fifo port specified by Port.
554 The port is written Count times, and the write data is
555 retrieved from the provided Buffer.
556
557 This function must guarantee that all I/O write and write operations are
558 serialized.
559
560 If 16-bit I/O port operations are not supported, then ASSERT().
561
562 @param Port The I/O port to write.
563 @param Count The number of times to write I/O port.
564 @param Buffer The buffer to retrieve the write data from.
565
566 **/
567 VOID
568 EFIAPI
569 IoWriteFifo16 (
570 IN UINTN Port,
571 IN UINTN Count,
572 IN VOID *Buffer
573 )
574 {
575 //
576 // Make sure Port is aligned on a 16-bit boundary.
577 //
578 ASSERT ((Port & 1) == 0);
579 IoWriteFifoWorker (Port, EfiCpuIoWidthFifoUint16, Count, Buffer);
580 }
581
582 /**
583 Reads a 32-bit I/O port fifo into a block of memory.
584
585 Reads the 32-bit I/O fifo port specified by Port.
586 The port is read Count times, and the read data is
587 stored in the provided Buffer.
588
589 This function must guarantee that all I/O read and write operations are
590 serialized.
591
592 If 32-bit I/O port operations are not supported, then ASSERT().
593
594 @param Port The I/O port to read.
595 @param Count The number of times to read I/O port.
596 @param Buffer The buffer to store the read data into.
597
598 **/
599 VOID
600 EFIAPI
601 IoReadFifo32 (
602 IN UINTN Port,
603 IN UINTN Count,
604 OUT VOID *Buffer
605 )
606 {
607 //
608 // Make sure Port is aligned on a 32-bit boundary.
609 //
610 ASSERT ((Port & 3) == 0);
611 IoReadFifoWorker (Port, EfiCpuIoWidthFifoUint32, Count, Buffer);
612 }
613
614 /**
615 Writes a block of memory into a 32-bit I/O port fifo.
616
617 Writes the 32-bit I/O fifo port specified by Port.
618 The port is written Count times, and the write data is
619 retrieved from the provided Buffer.
620
621 This function must guarantee that all I/O write and write operations are
622 serialized.
623
624 If 32-bit I/O port operations are not supported, then ASSERT().
625
626 @param Port The I/O port to write.
627 @param Count The number of times to write I/O port.
628 @param Buffer The buffer to retrieve the write data from.
629
630 **/
631 VOID
632 EFIAPI
633 IoWriteFifo32 (
634 IN UINTN Port,
635 IN UINTN Count,
636 IN VOID *Buffer
637 )
638 {
639 //
640 // Make sure Port is aligned on a 32-bit boundary.
641 //
642 ASSERT ((Port & 3) == 0);
643 IoWriteFifoWorker (Port, EfiCpuIoWidthFifoUint32, Count, Buffer);
644 }
645
646 /**
647 Reads an 8-bit MMIO register.
648
649 Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
650 returned. This function must guarantee that all MMIO read and write
651 operations are serialized.
652
653 If 8-bit MMIO register operations are not supported, then ASSERT().
654
655 @param Address The MMIO register to read.
656
657 @return The value read.
658
659 **/
660 UINT8
661 EFIAPI
662 MmioRead8 (
663 IN UINTN Address
664 )
665 {
666 return (UINT8)MmioReadWorker (Address, EfiCpuIoWidthUint8);
667 }
668
669 /**
670 Writes an 8-bit MMIO register.
671
672 Writes the 8-bit MMIO register specified by Address with the value specified
673 by Value and returns Value. This function must guarantee that all MMIO read
674 and write operations are serialized.
675
676 If 8-bit MMIO register operations are not supported, then ASSERT().
677
678 @param Address The MMIO register to write.
679 @param Value The value to write to the MMIO register.
680
681 **/
682 UINT8
683 EFIAPI
684 MmioWrite8 (
685 IN UINTN Address,
686 IN UINT8 Value
687 )
688 {
689 return (UINT8)MmioWriteWorker (Address, EfiCpuIoWidthUint8, Value);
690 }
691
692 /**
693 Reads a 16-bit MMIO register.
694
695 Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
696 returned. This function must guarantee that all MMIO read and write
697 operations are serialized.
698
699 If Address is not aligned on a 16-bit boundary, then ASSERT().
700
701 If 16-bit MMIO register operations are not supported, then ASSERT().
702
703 @param Address The MMIO register to read.
704
705 @return The value read.
706
707 **/
708 UINT16
709 EFIAPI
710 MmioRead16 (
711 IN UINTN Address
712 )
713 {
714 //
715 // Make sure Address is aligned on a 16-bit boundary.
716 //
717 ASSERT ((Address & 1) == 0);
718 return (UINT16)MmioReadWorker (Address, EfiCpuIoWidthUint16);
719 }
720
721 /**
722 Writes a 16-bit MMIO register.
723
724 Writes the 16-bit MMIO register specified by Address with the value specified
725 by Value and returns Value. This function must guarantee that all MMIO read
726 and write operations are serialized.
727
728 If Address is not aligned on a 16-bit boundary, then ASSERT().
729
730 If 16-bit MMIO register operations are not supported, then ASSERT().
731
732 @param Address The MMIO register to write.
733 @param Value The value to write to the MMIO register.
734
735 **/
736 UINT16
737 EFIAPI
738 MmioWrite16 (
739 IN UINTN Address,
740 IN UINT16 Value
741 )
742 {
743 //
744 // Make sure Address is aligned on a 16-bit boundary.
745 //
746 ASSERT ((Address & 1) == 0);
747 return (UINT16)MmioWriteWorker (Address, EfiCpuIoWidthUint16, Value);
748 }
749
750 /**
751 Reads a 32-bit MMIO register.
752
753 Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
754 returned. This function must guarantee that all MMIO read and write
755 operations are serialized.
756
757 If Address is not aligned on a 32-bit boundary, then ASSERT().
758
759 If 32-bit MMIO register operations are not supported, then ASSERT().
760
761 @param Address The MMIO register to read.
762
763 @return The value read.
764
765 **/
766 UINT32
767 EFIAPI
768 MmioRead32 (
769 IN UINTN Address
770 )
771 {
772 //
773 // Make sure Address is aligned on a 32-bit boundary.
774 //
775 ASSERT ((Address & 3) == 0);
776 return (UINT32)MmioReadWorker (Address, EfiCpuIoWidthUint32);
777 }
778
779 /**
780 Writes a 32-bit MMIO register.
781
782 Writes the 32-bit MMIO register specified by Address with the value specified
783 by Value and returns Value. This function must guarantee that all MMIO read
784 and write operations are serialized.
785
786 If Address is not aligned on a 32-bit boundary, then ASSERT().
787
788 If 32-bit MMIO register operations are not supported, then ASSERT().
789
790 @param Address The MMIO register to write.
791 @param Value The value to write to the MMIO register.
792
793 **/
794 UINT32
795 EFIAPI
796 MmioWrite32 (
797 IN UINTN Address,
798 IN UINT32 Value
799 )
800 {
801 //
802 // Make sure Address is aligned on a 32-bit boundary.
803 //
804 ASSERT ((Address & 3) == 0);
805 return (UINT32)MmioWriteWorker (Address, EfiCpuIoWidthUint32, Value);
806 }
807
808 /**
809 Reads a 64-bit MMIO register.
810
811 Reads the 64-bit MMIO register specified by Address. The 64-bit read value is
812 returned. This function must guarantee that all MMIO read and write
813 operations are serialized.
814
815 If Address is not aligned on a 64-bit boundary, then ASSERT().
816
817 If 64-bit MMIO register operations are not supported, then ASSERT().
818
819 @param Address The MMIO register to read.
820
821 @return The value read.
822
823 **/
824 UINT64
825 EFIAPI
826 MmioRead64 (
827 IN UINTN Address
828 )
829 {
830 //
831 // Make sure Address is aligned on a 64-bit boundary.
832 //
833 ASSERT ((Address & 7) == 0);
834 return (UINT64)MmioReadWorker (Address, EfiCpuIoWidthUint64);
835 }
836
837 /**
838 Writes a 64-bit MMIO register.
839
840 Writes the 64-bit MMIO register specified by Address with the value specified
841 by Value and returns Value. This function must guarantee that all MMIO read
842 and write operations are serialized.
843
844 If Address is not aligned on a 64-bit boundary, then ASSERT().
845
846 If 64-bit MMIO register operations are not supported, then ASSERT().
847
848 @param Address The MMIO register to write.
849 @param Value The value to write to the MMIO register.
850
851 **/
852 UINT64
853 EFIAPI
854 MmioWrite64 (
855 IN UINTN Address,
856 IN UINT64 Value
857 )
858 {
859 //
860 // Make sure Address is aligned on a 64-bit boundary.
861 //
862 ASSERT ((Address & 7) == 0);
863 return (UINT64)MmioWriteWorker (Address, EfiCpuIoWidthUint64, Value);
864 }