2 I/O Library. The implementations are based on EFI_PEI_SERVICE->CpuIo interface.
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
14 #include <Library/IoLib.h>
15 #include <Library/DebugLib.h>
16 #include <Library/BaseLib.h>
17 #include <Library/PeiServicesTablePointerLib.h>
21 Reads registers in the EFI CPU I/O space.
23 Reads the I/O port specified by Port with registers width specified by Width.
24 The port is read Count times, and the read data is stored in the provided Buffer.
26 This function must guarantee that all I/O read and write operations are serialized.
27 If such operations are not supported, then ASSERT().
29 @param Port The base address of the I/O operation.
30 The caller is responsible for aligning the Address if required.
31 @param Width The width of the I/O operation.
32 @param Count The number of times to read I/O port.
33 @param Buffer The buffer to store the read data into.
40 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
45 CONST EFI_PEI_SERVICES
**PeiServices
;
46 EFI_PEI_CPU_IO_PPI
*CpuIo
;
49 PeiServices
= GetPeiServicesTablePointer ();
50 CpuIo
= (*PeiServices
)->CpuIo
;
51 ASSERT (CpuIo
!= NULL
);
53 Status
= CpuIo
->Io
.Read (PeiServices
, CpuIo
, Width
, Port
, Count
, Buffer
);
54 ASSERT_EFI_ERROR (Status
);
58 Writes registers in the EFI CPU I/O space.
60 Writes the I/O port specified by Port with registers width specified by Width.
61 The port is written Count times, and the write data is retrieved from the provided Buffer.
63 This function must guarantee that all I/O read and write operations are serialized.
64 If such operations are not supported, then ASSERT().
66 @param Port The base address of the I/O operation.
67 The caller is responsible for aligning the Address if required.
68 @param Width The width of the I/O operation.
69 @param Count The number of times to write I/O port.
70 @param Buffer The buffer to store the read data into.
77 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
82 CONST EFI_PEI_SERVICES
**PeiServices
;
83 EFI_PEI_CPU_IO_PPI
*CpuIo
;
86 PeiServices
= GetPeiServicesTablePointer ();
87 CpuIo
= (*PeiServices
)->CpuIo
;
88 ASSERT (CpuIo
!= NULL
);
90 Status
= CpuIo
->Io
.Write (PeiServices
, CpuIo
, Width
, Port
, Count
, Buffer
);
91 ASSERT_EFI_ERROR (Status
);
95 Reads an 8-bit I/O port.
97 Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
98 This function must guarantee that all I/O read and write operations are
101 If 8-bit I/O port operations are not supported, then ASSERT().
103 @param Port The I/O port to read.
105 @return The value read.
114 CONST EFI_PEI_SERVICES
**PeiServices
;
115 EFI_PEI_CPU_IO_PPI
*CpuIo
;
117 PeiServices
= GetPeiServicesTablePointer ();
118 CpuIo
= (*PeiServices
)->CpuIo
;
119 ASSERT (CpuIo
!= NULL
);
121 return CpuIo
->IoRead8 (PeiServices
, CpuIo
, (UINT64
) Port
);
125 Writes an 8-bit I/O port.
127 Writes the 8-bit I/O port specified by Port with the value specified by Value
128 and returns Value. This function must guarantee that all I/O read and write
129 operations are serialized.
131 If 8-bit I/O port operations are not supported, then ASSERT().
133 @param Port The I/O port to write.
134 @param Value The value to write to the I/O port.
136 @return The value written the I/O port.
146 CONST EFI_PEI_SERVICES
**PeiServices
;
147 EFI_PEI_CPU_IO_PPI
*CpuIo
;
149 PeiServices
= GetPeiServicesTablePointer ();
150 CpuIo
= (*PeiServices
)->CpuIo
;
151 ASSERT (CpuIo
!= NULL
);
153 CpuIo
->IoWrite8 (PeiServices
, CpuIo
, (UINT64
) Port
, Value
);
158 Reads a 16-bit I/O port.
160 Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
161 This function must guarantee that all I/O read and write operations are
164 If 16-bit I/O port operations are not supported, then ASSERT().
165 If Port is not aligned on a 16-bit boundary, then ASSERT().
167 @param Port The I/O port to read.
169 @return The value read.
178 CONST EFI_PEI_SERVICES
**PeiServices
;
179 EFI_PEI_CPU_IO_PPI
*CpuIo
;
181 PeiServices
= GetPeiServicesTablePointer ();
182 CpuIo
= (*PeiServices
)->CpuIo
;
183 ASSERT (CpuIo
!= NULL
);
185 // Make sure Port is aligned on a 16-bit boundary.
187 ASSERT ((Port
& 1) == 0);
188 return CpuIo
->IoRead16 (PeiServices
, CpuIo
, (UINT64
) Port
);
192 Writes a 16-bit I/O port.
194 Writes the 16-bit I/O port specified by Port with the value specified by Value
195 and returns Value. This function must guarantee that all I/O read and write
196 operations are serialized.
198 If 16-bit I/O port operations are not supported, then ASSERT().
199 If Port is not aligned on a 16-bit boundary, then ASSERT().
201 @param Port The I/O port to write.
202 @param Value The value to write to the I/O port.
204 @return The value written the I/O port.
214 CONST EFI_PEI_SERVICES
**PeiServices
;
215 EFI_PEI_CPU_IO_PPI
*CpuIo
;
217 PeiServices
= GetPeiServicesTablePointer ();
218 CpuIo
= (*PeiServices
)->CpuIo
;
219 ASSERT (CpuIo
!= NULL
);
221 // Make sure Port is aligned on a 16-bit boundary.
223 ASSERT ((Port
& 1) == 0);
224 CpuIo
->IoWrite16 (PeiServices
, CpuIo
, (UINT64
) Port
, Value
);
229 Reads a 32-bit I/O port.
231 Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
232 This function must guarantee that all I/O read and write operations are
235 If 32-bit I/O port operations are not supported, then ASSERT().
236 If Port is not aligned on a 32-bit boundary, then ASSERT().
238 @param Port The I/O port to read.
240 @return The value read.
249 CONST EFI_PEI_SERVICES
**PeiServices
;
250 EFI_PEI_CPU_IO_PPI
*CpuIo
;
252 PeiServices
= GetPeiServicesTablePointer ();
253 CpuIo
= (*PeiServices
)->CpuIo
;
254 ASSERT (CpuIo
!= NULL
);
256 // Make sure Port is aligned on a 32-bit boundary.
258 ASSERT ((Port
& 3) == 0);
259 return CpuIo
->IoRead32 (PeiServices
, CpuIo
, (UINT64
) Port
);
263 Writes a 32-bit I/O port.
265 Writes the 32-bit I/O port specified by Port with the value specified by Value
266 and returns Value. This function must guarantee that all I/O read and write
267 operations are serialized.
269 If 32-bit I/O port operations are not supported, then ASSERT().
270 If Port is not aligned on a 32-bit boundary, then ASSERT().
272 @param Port The I/O port to write.
273 @param Value The value to write to the I/O port.
275 @return The value written the I/O port.
285 CONST EFI_PEI_SERVICES
**PeiServices
;
286 EFI_PEI_CPU_IO_PPI
*CpuIo
;
288 PeiServices
= GetPeiServicesTablePointer ();
289 CpuIo
= (*PeiServices
)->CpuIo
;
290 ASSERT (CpuIo
!= NULL
);
292 // Make sure Port is aligned on a 32-bit boundary.
294 ASSERT ((Port
& 3) == 0);
295 CpuIo
->IoWrite32 (PeiServices
, CpuIo
, (UINT64
) Port
, Value
);
300 Reads a 64-bit I/O port.
302 Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.
303 This function must guarantee that all I/O read and write operations are
306 If 64-bit I/O port operations are not supported, then ASSERT().
307 If Port is not aligned on a 64-bit boundary, then ASSERT().
309 @param Port The I/O port to read.
311 @return The value read.
320 CONST EFI_PEI_SERVICES
**PeiServices
;
321 EFI_PEI_CPU_IO_PPI
*CpuIo
;
323 PeiServices
= GetPeiServicesTablePointer ();
324 CpuIo
= (*PeiServices
)->CpuIo
;
325 ASSERT (CpuIo
!= NULL
);
327 // Make sure Port is aligned on a 64-bit boundary.
329 ASSERT ((Port
& 7) == 0);
330 return CpuIo
->IoRead64 (PeiServices
, CpuIo
, (UINT64
) Port
);
334 Writes a 64-bit I/O port.
336 Writes the 64-bit I/O port specified by Port with the value specified by Value
337 and returns Value. This function must guarantee that all I/O read and write
338 operations are serialized.
340 If 64-bit I/O port operations are not supported, then ASSERT().
341 If Port is not aligned on a 64-bit boundary, then ASSERT().
343 @param Port The I/O port to write.
344 @param Value The value to write to the I/O port.
346 @return The value written the I/O port.
356 CONST EFI_PEI_SERVICES
**PeiServices
;
357 EFI_PEI_CPU_IO_PPI
*CpuIo
;
359 PeiServices
= GetPeiServicesTablePointer ();
360 CpuIo
= (*PeiServices
)->CpuIo
;
361 ASSERT (CpuIo
!= NULL
);
363 // Make sure Port is aligned on a 64-bit boundary.
365 ASSERT ((Port
& 7) == 0);
366 CpuIo
->IoWrite64 (PeiServices
, CpuIo
, (UINT64
) Port
, Value
);
371 Reads an 8-bit I/O port fifo into a block of memory.
373 Reads the 8-bit I/O fifo port specified by Port.
374 The port is read Count times, and the read data is
375 stored in the provided Buffer.
377 This function must guarantee that all I/O read and write operations are
380 If 8-bit I/O port operations are not supported, then ASSERT().
382 @param Port The I/O port to read.
383 @param Count The number of times to read I/O port.
384 @param Buffer The buffer to store the read data into.
395 IoReadFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint8
, Count
, Buffer
);
399 Writes a block of memory into an 8-bit I/O port fifo.
401 Writes the 8-bit I/O fifo port specified by Port.
402 The port is written Count times, and the write data is
403 retrieved from the provided Buffer.
405 This function must guarantee that all I/O write and write operations are
408 If 8-bit I/O port operations are not supported, then ASSERT().
410 @param Port The I/O port to write.
411 @param Count The number of times to write I/O port.
412 @param Buffer The buffer to retrieve the write data from.
423 IoWriteFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint8
, Count
, Buffer
);
427 Reads a 16-bit I/O port fifo into a block of memory.
429 Reads the 16-bit I/O fifo port specified by Port.
430 The port is read Count times, and the read data is
431 stored in the provided Buffer.
433 This function must guarantee that all I/O read and write operations are
436 If 16-bit I/O port operations are not supported, then ASSERT().
438 @param Port The I/O port to read.
439 @param Count The number of times to read I/O port.
440 @param Buffer The buffer to store the read data into.
452 // Make sure Port is aligned on a 16-bit boundary.
454 ASSERT ((Port
& 1) == 0);
455 IoReadFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint16
, Count
, Buffer
);
459 Writes a block of memory into a 16-bit I/O port fifo.
461 Writes the 16-bit I/O fifo port specified by Port.
462 The port is written Count times, and the write data is
463 retrieved from the provided Buffer.
465 This function must guarantee that all I/O write and write operations are
468 If 16-bit I/O port operations are not supported, then ASSERT().
470 @param Port The I/O port to write.
471 @param Count The number of times to write I/O port.
472 @param Buffer The buffer to retrieve the write data from.
484 // Make sure Port is aligned on a 16-bit boundary.
486 ASSERT ((Port
& 1) == 0);
487 IoWriteFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint16
, Count
, Buffer
);
491 Reads a 32-bit I/O port fifo into a block of memory.
493 Reads the 32-bit I/O fifo port specified by Port.
494 The port is read Count times, and the read data is
495 stored in the provided Buffer.
497 This function must guarantee that all I/O read and write operations are
500 If 32-bit I/O port operations are not supported, then ASSERT().
502 @param Port The I/O port to read.
503 @param Count The number of times to read I/O port.
504 @param Buffer The buffer to store the read data into.
516 // Make sure Port is aligned on a 32-bit boundary.
518 ASSERT ((Port
& 3) == 0);
519 IoReadFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint32
, Count
, Buffer
);
523 Writes a block of memory into a 32-bit I/O port fifo.
525 Writes the 32-bit I/O fifo port specified by Port.
526 The port is written Count times, and the write data is
527 retrieved from the provided Buffer.
529 This function must guarantee that all I/O write and write operations are
532 If 32-bit I/O port operations are not supported, then ASSERT().
534 @param Port The I/O port to write.
535 @param Count The number of times to write I/O port.
536 @param Buffer The buffer to retrieve the write data from.
548 // Make sure Port is aligned on a 32-bit boundary.
550 ASSERT ((Port
& 3) == 0);
551 IoWriteFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint32
, Count
, Buffer
);
555 Reads an 8-bit MMIO register.
557 Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
558 returned. This function must guarantee that all MMIO read and write
559 operations are serialized.
561 If 8-bit MMIO register operations are not supported, then ASSERT().
563 @param Address The MMIO register to read.
565 @return The value read.
574 CONST EFI_PEI_SERVICES
**PeiServices
;
575 EFI_PEI_CPU_IO_PPI
*CpuIo
;
577 PeiServices
= GetPeiServicesTablePointer ();
578 CpuIo
= (*PeiServices
)->CpuIo
;
579 ASSERT (CpuIo
!= NULL
);
581 return CpuIo
->MemRead8 (PeiServices
, CpuIo
, (UINT64
) Address
);
585 Writes an 8-bit MMIO register.
587 Writes the 8-bit MMIO register specified by Address with the value specified
588 by Value and returns Value. This function must guarantee that all MMIO read
589 and write operations are serialized.
591 If 8-bit MMIO register operations are not supported, then ASSERT().
593 @param Address The MMIO register to write.
594 @param Value The value to write to the MMIO register.
606 CONST EFI_PEI_SERVICES
**PeiServices
;
607 EFI_PEI_CPU_IO_PPI
*CpuIo
;
609 PeiServices
= GetPeiServicesTablePointer ();
610 CpuIo
= (*PeiServices
)->CpuIo
;
611 ASSERT (CpuIo
!= NULL
);
613 CpuIo
->MemWrite8 (PeiServices
, CpuIo
, (UINT64
) Address
, Value
);
618 Reads a 16-bit MMIO register.
620 Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
621 returned. This function must guarantee that all MMIO read and write
622 operations are serialized.
624 If 16-bit MMIO register operations are not supported, then ASSERT().
625 If Address is not aligned on a 16-bit boundary, then ASSERT().
627 @param Address The MMIO register to read.
629 @return The value read.
638 CONST EFI_PEI_SERVICES
**PeiServices
;
639 EFI_PEI_CPU_IO_PPI
*CpuIo
;
641 PeiServices
= GetPeiServicesTablePointer ();
642 CpuIo
= (*PeiServices
)->CpuIo
;
643 ASSERT (CpuIo
!= NULL
);
645 // Make sure Address is aligned on a 16-bit boundary.
647 ASSERT ((Address
& 1) == 0);
648 return CpuIo
->MemRead16 (PeiServices
, CpuIo
, (UINT64
) Address
);
653 Writes a 16-bit MMIO register.
655 Writes the 16-bit MMIO register specified by Address with the value specified
656 by Value and returns Value. This function must guarantee that all MMIO read
657 and write operations are serialized.
659 If 16-bit MMIO register operations are not supported, then ASSERT().
660 If Address is not aligned on a 16-bit boundary, then ASSERT().
662 @param Address The MMIO register to write.
663 @param Value The value to write to the MMIO register.
675 CONST EFI_PEI_SERVICES
**PeiServices
;
676 EFI_PEI_CPU_IO_PPI
*CpuIo
;
678 PeiServices
= GetPeiServicesTablePointer ();
679 CpuIo
= (*PeiServices
)->CpuIo
;
680 ASSERT (CpuIo
!= NULL
);
682 // Make sure Address is aligned on a 16-bit boundary.
684 ASSERT ((Address
& 1) == 0);
685 CpuIo
->MemWrite16 (PeiServices
, CpuIo
, (UINT64
) Address
, Value
);
690 Reads a 32-bit MMIO register.
692 Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
693 returned. This function must guarantee that all MMIO read and write
694 operations are serialized.
696 If 32-bit MMIO register operations are not supported, then ASSERT().
697 If Address is not aligned on a 32-bit boundary, then ASSERT().
699 @param Address The MMIO register to read.
701 @return The value read.
710 CONST EFI_PEI_SERVICES
**PeiServices
;
711 EFI_PEI_CPU_IO_PPI
*CpuIo
;
713 PeiServices
= GetPeiServicesTablePointer ();
714 CpuIo
= (*PeiServices
)->CpuIo
;
715 ASSERT (CpuIo
!= NULL
);
717 // Make sure Address is aligned on a 32-bit boundary.
719 ASSERT ((Address
& 3) == 0);
720 return CpuIo
->MemRead32 (PeiServices
, CpuIo
, (UINT64
) Address
);
725 Writes a 32-bit MMIO register.
727 Writes the 32-bit MMIO register specified by Address with the value specified
728 by Value and returns Value. This function must guarantee that all MMIO read
729 and write operations are serialized.
731 If 32-bit MMIO register operations are not supported, then ASSERT().
732 If Address is not aligned on a 32-bit boundary, then ASSERT().
734 @param Address The MMIO register to write.
735 @param Value The value to write to the MMIO register.
747 CONST EFI_PEI_SERVICES
**PeiServices
;
748 EFI_PEI_CPU_IO_PPI
*CpuIo
;
750 PeiServices
= GetPeiServicesTablePointer ();
751 CpuIo
= (*PeiServices
)->CpuIo
;
752 ASSERT (CpuIo
!= NULL
);
754 // Make sure Address is aligned on a 32-bit boundary.
756 ASSERT ((Address
& 3) == 0);
757 CpuIo
->MemWrite32 (PeiServices
, CpuIo
, (UINT64
) Address
, Value
);
762 Reads a 64-bit MMIO register.
764 Reads the 64-bit MMIO register specified by Address. The 64-bit read value is
765 returned. This function must guarantee that all MMIO read and write
766 operations are serialized.
768 If 64-bit MMIO register operations are not supported, then ASSERT().
769 If Address is not aligned on a 64-bit boundary, then ASSERT().
771 @param Address The MMIO register to read.
773 @return The value read.
782 CONST EFI_PEI_SERVICES
**PeiServices
;
783 EFI_PEI_CPU_IO_PPI
*CpuIo
;
785 PeiServices
= GetPeiServicesTablePointer ();
786 CpuIo
= (*PeiServices
)->CpuIo
;
787 ASSERT (CpuIo
!= NULL
);
789 // Make sure Address is aligned on a 64-bit boundary.
791 ASSERT ((Address
& (sizeof (UINT64
) - 1)) == 0);
792 return CpuIo
->MemRead64 (PeiServices
, CpuIo
, (UINT64
) Address
);
797 Writes a 64-bit MMIO register.
799 Writes the 64-bit MMIO register specified by Address with the value specified
800 by Value and returns Value. This function must guarantee that all MMIO read
801 and write operations are serialized.
803 If 64-bit MMIO register operations are not supported, then ASSERT().
804 If Address is not aligned on a 64-bit boundary, then ASSERT().
806 @param Address The MMIO register to write.
807 @param Value The value to write to the MMIO register.
817 CONST EFI_PEI_SERVICES
**PeiServices
;
818 EFI_PEI_CPU_IO_PPI
*CpuIo
;
820 PeiServices
= GetPeiServicesTablePointer ();
821 CpuIo
= (*PeiServices
)->CpuIo
;
822 ASSERT (CpuIo
!= NULL
);
824 // Make sure Address is aligned on a 64-bit boundary.
826 ASSERT ((Address
& 7) == 0);
827 CpuIo
->MemWrite64 (PeiServices
, CpuIo
, (UINT64
) Address
, Value
);