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
13 #include <Library/IoLib.h>
14 #include <Library/DebugLib.h>
15 #include <Library/BaseLib.h>
16 #include <Library/PeiServicesTablePointerLib.h>
19 Reads registers in the EFI CPU I/O space.
21 Reads the I/O port specified by Port with registers width specified by Width.
22 The port is read Count times, and the read data is stored in the provided Buffer.
24 This function must guarantee that all I/O read and write operations are serialized.
25 If such operations are not supported, then ASSERT().
27 @param Port The base address of the I/O operation.
28 The caller is responsible for aligning the Address if required.
29 @param Width The width of the I/O operation.
30 @param Count The number of times to read I/O port.
31 @param Buffer The buffer to store the read data into.
38 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
43 CONST EFI_PEI_SERVICES
**PeiServices
;
44 EFI_PEI_CPU_IO_PPI
*CpuIo
;
47 PeiServices
= GetPeiServicesTablePointer ();
48 CpuIo
= (*PeiServices
)->CpuIo
;
49 ASSERT (CpuIo
!= NULL
);
51 Status
= CpuIo
->Io
.Read (PeiServices
, CpuIo
, Width
, Port
, Count
, Buffer
);
52 ASSERT_EFI_ERROR (Status
);
56 Writes registers in the EFI CPU I/O space.
58 Writes the I/O port specified by Port with registers width specified by Width.
59 The port is written Count times, and the write data is retrieved from the provided Buffer.
61 This function must guarantee that all I/O read and write operations are serialized.
62 If such operations are not supported, then ASSERT().
64 @param Port The base address of the I/O operation.
65 The caller is responsible for aligning the Address if required.
66 @param Width The width of the I/O operation.
67 @param Count The number of times to write I/O port.
68 @param Buffer The buffer to store the read data into.
75 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
80 CONST EFI_PEI_SERVICES
**PeiServices
;
81 EFI_PEI_CPU_IO_PPI
*CpuIo
;
84 PeiServices
= GetPeiServicesTablePointer ();
85 CpuIo
= (*PeiServices
)->CpuIo
;
86 ASSERT (CpuIo
!= NULL
);
88 Status
= CpuIo
->Io
.Write (PeiServices
, CpuIo
, Width
, Port
, Count
, Buffer
);
89 ASSERT_EFI_ERROR (Status
);
93 Reads an 8-bit I/O port.
95 Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
96 This function must guarantee that all I/O read and write operations are
99 If 8-bit I/O port operations are not supported, then ASSERT().
101 @param Port The I/O port to read.
103 @return The value read.
112 CONST EFI_PEI_SERVICES
**PeiServices
;
113 EFI_PEI_CPU_IO_PPI
*CpuIo
;
115 PeiServices
= GetPeiServicesTablePointer ();
116 CpuIo
= (*PeiServices
)->CpuIo
;
117 ASSERT (CpuIo
!= NULL
);
119 return CpuIo
->IoRead8 (PeiServices
, CpuIo
, (UINT64
)Port
);
123 Writes an 8-bit I/O port.
125 Writes the 8-bit I/O port specified by Port with the value specified by Value
126 and returns Value. This function must guarantee that all I/O read and write
127 operations are serialized.
129 If 8-bit I/O port operations are not supported, then ASSERT().
131 @param Port The I/O port to write.
132 @param Value The value to write to the I/O port.
134 @return The value written the I/O port.
144 CONST EFI_PEI_SERVICES
**PeiServices
;
145 EFI_PEI_CPU_IO_PPI
*CpuIo
;
147 PeiServices
= GetPeiServicesTablePointer ();
148 CpuIo
= (*PeiServices
)->CpuIo
;
149 ASSERT (CpuIo
!= NULL
);
151 CpuIo
->IoWrite8 (PeiServices
, CpuIo
, (UINT64
)Port
, Value
);
156 Reads a 16-bit I/O port.
158 Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
159 This function must guarantee that all I/O read and write operations are
162 If 16-bit I/O port operations are not supported, then ASSERT().
163 If Port is not aligned on a 16-bit boundary, then ASSERT().
165 @param Port The I/O port to read.
167 @return The value read.
176 CONST EFI_PEI_SERVICES
**PeiServices
;
177 EFI_PEI_CPU_IO_PPI
*CpuIo
;
179 PeiServices
= GetPeiServicesTablePointer ();
180 CpuIo
= (*PeiServices
)->CpuIo
;
181 ASSERT (CpuIo
!= NULL
);
183 // Make sure Port is aligned on a 16-bit boundary.
185 ASSERT ((Port
& 1) == 0);
186 return CpuIo
->IoRead16 (PeiServices
, CpuIo
, (UINT64
)Port
);
190 Writes a 16-bit I/O port.
192 Writes the 16-bit I/O port specified by Port with the value specified by Value
193 and returns Value. This function must guarantee that all I/O read and write
194 operations are serialized.
196 If 16-bit I/O port operations are not supported, then ASSERT().
197 If Port is not aligned on a 16-bit boundary, then ASSERT().
199 @param Port The I/O port to write.
200 @param Value The value to write to the I/O port.
202 @return The value written the I/O port.
212 CONST EFI_PEI_SERVICES
**PeiServices
;
213 EFI_PEI_CPU_IO_PPI
*CpuIo
;
215 PeiServices
= GetPeiServicesTablePointer ();
216 CpuIo
= (*PeiServices
)->CpuIo
;
217 ASSERT (CpuIo
!= NULL
);
219 // Make sure Port is aligned on a 16-bit boundary.
221 ASSERT ((Port
& 1) == 0);
222 CpuIo
->IoWrite16 (PeiServices
, CpuIo
, (UINT64
)Port
, Value
);
227 Reads a 32-bit I/O port.
229 Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
230 This function must guarantee that all I/O read and write operations are
233 If 32-bit I/O port operations are not supported, then ASSERT().
234 If Port is not aligned on a 32-bit boundary, then ASSERT().
236 @param Port The I/O port to read.
238 @return The value read.
247 CONST EFI_PEI_SERVICES
**PeiServices
;
248 EFI_PEI_CPU_IO_PPI
*CpuIo
;
250 PeiServices
= GetPeiServicesTablePointer ();
251 CpuIo
= (*PeiServices
)->CpuIo
;
252 ASSERT (CpuIo
!= NULL
);
254 // Make sure Port is aligned on a 32-bit boundary.
256 ASSERT ((Port
& 3) == 0);
257 return CpuIo
->IoRead32 (PeiServices
, CpuIo
, (UINT64
)Port
);
261 Writes a 32-bit I/O port.
263 Writes the 32-bit I/O port specified by Port with the value specified by Value
264 and returns Value. This function must guarantee that all I/O read and write
265 operations are serialized.
267 If 32-bit I/O port operations are not supported, then ASSERT().
268 If Port is not aligned on a 32-bit boundary, then ASSERT().
270 @param Port The I/O port to write.
271 @param Value The value to write to the I/O port.
273 @return The value written the I/O port.
283 CONST EFI_PEI_SERVICES
**PeiServices
;
284 EFI_PEI_CPU_IO_PPI
*CpuIo
;
286 PeiServices
= GetPeiServicesTablePointer ();
287 CpuIo
= (*PeiServices
)->CpuIo
;
288 ASSERT (CpuIo
!= NULL
);
290 // Make sure Port is aligned on a 32-bit boundary.
292 ASSERT ((Port
& 3) == 0);
293 CpuIo
->IoWrite32 (PeiServices
, CpuIo
, (UINT64
)Port
, Value
);
298 Reads a 64-bit I/O port.
300 Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.
301 This function must guarantee that all I/O read and write operations are
304 If 64-bit I/O port operations are not supported, then ASSERT().
305 If Port is not aligned on a 64-bit boundary, then ASSERT().
307 @param Port The I/O port to read.
309 @return The value read.
318 CONST EFI_PEI_SERVICES
**PeiServices
;
319 EFI_PEI_CPU_IO_PPI
*CpuIo
;
321 PeiServices
= GetPeiServicesTablePointer ();
322 CpuIo
= (*PeiServices
)->CpuIo
;
323 ASSERT (CpuIo
!= NULL
);
325 // Make sure Port is aligned on a 64-bit boundary.
327 ASSERT ((Port
& 7) == 0);
328 return CpuIo
->IoRead64 (PeiServices
, CpuIo
, (UINT64
)Port
);
332 Writes a 64-bit I/O port.
334 Writes the 64-bit I/O port specified by Port with the value specified by Value
335 and returns Value. This function must guarantee that all I/O read and write
336 operations are serialized.
338 If 64-bit I/O port operations are not supported, then ASSERT().
339 If Port is not aligned on a 64-bit boundary, then ASSERT().
341 @param Port The I/O port to write.
342 @param Value The value to write to the I/O port.
344 @return The value written the I/O port.
354 CONST EFI_PEI_SERVICES
**PeiServices
;
355 EFI_PEI_CPU_IO_PPI
*CpuIo
;
357 PeiServices
= GetPeiServicesTablePointer ();
358 CpuIo
= (*PeiServices
)->CpuIo
;
359 ASSERT (CpuIo
!= NULL
);
361 // Make sure Port is aligned on a 64-bit boundary.
363 ASSERT ((Port
& 7) == 0);
364 CpuIo
->IoWrite64 (PeiServices
, CpuIo
, (UINT64
)Port
, Value
);
369 Reads an 8-bit I/O port fifo into a block of memory.
371 Reads the 8-bit I/O fifo port specified by Port.
372 The port is read Count times, and the read data is
373 stored in the provided Buffer.
375 This function must guarantee that all I/O read and write operations are
378 If 8-bit I/O port operations are not supported, then ASSERT().
380 @param Port The I/O port to read.
381 @param Count The number of times to read I/O port.
382 @param Buffer The buffer to store the read data into.
393 IoReadFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint8
, Count
, Buffer
);
397 Writes a block of memory into an 8-bit I/O port fifo.
399 Writes the 8-bit I/O fifo port specified by Port.
400 The port is written Count times, and the write data is
401 retrieved from the provided Buffer.
403 This function must guarantee that all I/O write and write operations are
406 If 8-bit I/O port operations are not supported, then ASSERT().
408 @param Port The I/O port to write.
409 @param Count The number of times to write I/O port.
410 @param Buffer The buffer to retrieve the write data from.
421 IoWriteFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint8
, Count
, Buffer
);
425 Reads a 16-bit I/O port fifo into a block of memory.
427 Reads the 16-bit I/O fifo port specified by Port.
428 The port is read Count times, and the read data is
429 stored in the provided Buffer.
431 This function must guarantee that all I/O read and write operations are
434 If 16-bit I/O port operations are not supported, then ASSERT().
436 @param Port The I/O port to read.
437 @param Count The number of times to read I/O port.
438 @param Buffer The buffer to store the read data into.
450 // Make sure Port is aligned on a 16-bit boundary.
452 ASSERT ((Port
& 1) == 0);
453 IoReadFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint16
, Count
, Buffer
);
457 Writes a block of memory into a 16-bit I/O port fifo.
459 Writes the 16-bit I/O fifo port specified by Port.
460 The port is written Count times, and the write data is
461 retrieved from the provided Buffer.
463 This function must guarantee that all I/O write and write operations are
466 If 16-bit I/O port operations are not supported, then ASSERT().
468 @param Port The I/O port to write.
469 @param Count The number of times to write I/O port.
470 @param Buffer The buffer to retrieve the write data from.
482 // Make sure Port is aligned on a 16-bit boundary.
484 ASSERT ((Port
& 1) == 0);
485 IoWriteFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint16
, Count
, Buffer
);
489 Reads a 32-bit I/O port fifo into a block of memory.
491 Reads the 32-bit I/O fifo port specified by Port.
492 The port is read Count times, and the read data is
493 stored in the provided Buffer.
495 This function must guarantee that all I/O read and write operations are
498 If 32-bit I/O port operations are not supported, then ASSERT().
500 @param Port The I/O port to read.
501 @param Count The number of times to read I/O port.
502 @param Buffer The buffer to store the read data into.
514 // Make sure Port is aligned on a 32-bit boundary.
516 ASSERT ((Port
& 3) == 0);
517 IoReadFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint32
, Count
, Buffer
);
521 Writes a block of memory into a 32-bit I/O port fifo.
523 Writes the 32-bit I/O fifo port specified by Port.
524 The port is written Count times, and the write data is
525 retrieved from the provided Buffer.
527 This function must guarantee that all I/O write and write operations are
530 If 32-bit I/O port operations are not supported, then ASSERT().
532 @param Port The I/O port to write.
533 @param Count The number of times to write I/O port.
534 @param Buffer The buffer to retrieve the write data from.
546 // Make sure Port is aligned on a 32-bit boundary.
548 ASSERT ((Port
& 3) == 0);
549 IoWriteFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint32
, Count
, Buffer
);
553 Reads an 8-bit MMIO register.
555 Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
556 returned. This function must guarantee that all MMIO read and write
557 operations are serialized.
559 If 8-bit MMIO register operations are not supported, then ASSERT().
561 @param Address The MMIO register to read.
563 @return The value read.
572 CONST EFI_PEI_SERVICES
**PeiServices
;
573 EFI_PEI_CPU_IO_PPI
*CpuIo
;
575 PeiServices
= GetPeiServicesTablePointer ();
576 CpuIo
= (*PeiServices
)->CpuIo
;
577 ASSERT (CpuIo
!= NULL
);
579 return CpuIo
->MemRead8 (PeiServices
, CpuIo
, (UINT64
)Address
);
583 Writes an 8-bit MMIO register.
585 Writes the 8-bit MMIO register specified by Address with the value specified
586 by Value and returns Value. This function must guarantee that all MMIO read
587 and write operations are serialized.
589 If 8-bit MMIO register operations are not supported, then ASSERT().
591 @param Address The MMIO register to write.
592 @param Value The value to write to the MMIO register.
604 CONST EFI_PEI_SERVICES
**PeiServices
;
605 EFI_PEI_CPU_IO_PPI
*CpuIo
;
607 PeiServices
= GetPeiServicesTablePointer ();
608 CpuIo
= (*PeiServices
)->CpuIo
;
609 ASSERT (CpuIo
!= NULL
);
611 CpuIo
->MemWrite8 (PeiServices
, CpuIo
, (UINT64
)Address
, Value
);
616 Reads a 16-bit MMIO register.
618 Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
619 returned. This function must guarantee that all MMIO read and write
620 operations are serialized.
622 If 16-bit MMIO register operations are not supported, then ASSERT().
623 If Address is not aligned on a 16-bit boundary, then ASSERT().
625 @param Address The MMIO register to read.
627 @return The value read.
636 CONST EFI_PEI_SERVICES
**PeiServices
;
637 EFI_PEI_CPU_IO_PPI
*CpuIo
;
639 PeiServices
= GetPeiServicesTablePointer ();
640 CpuIo
= (*PeiServices
)->CpuIo
;
641 ASSERT (CpuIo
!= NULL
);
643 // Make sure Address is aligned on a 16-bit boundary.
645 ASSERT ((Address
& 1) == 0);
646 return CpuIo
->MemRead16 (PeiServices
, CpuIo
, (UINT64
)Address
);
650 Writes a 16-bit MMIO register.
652 Writes the 16-bit MMIO register specified by Address with the value specified
653 by Value and returns Value. This function must guarantee that all MMIO read
654 and write operations are serialized.
656 If 16-bit MMIO register operations are not supported, then ASSERT().
657 If Address is not aligned on a 16-bit boundary, then ASSERT().
659 @param Address The MMIO register to write.
660 @param Value The value to write to the MMIO register.
672 CONST EFI_PEI_SERVICES
**PeiServices
;
673 EFI_PEI_CPU_IO_PPI
*CpuIo
;
675 PeiServices
= GetPeiServicesTablePointer ();
676 CpuIo
= (*PeiServices
)->CpuIo
;
677 ASSERT (CpuIo
!= NULL
);
679 // Make sure Address is aligned on a 16-bit boundary.
681 ASSERT ((Address
& 1) == 0);
682 CpuIo
->MemWrite16 (PeiServices
, CpuIo
, (UINT64
)Address
, Value
);
687 Reads a 32-bit MMIO register.
689 Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
690 returned. This function must guarantee that all MMIO read and write
691 operations are serialized.
693 If 32-bit MMIO register operations are not supported, then ASSERT().
694 If Address is not aligned on a 32-bit boundary, then ASSERT().
696 @param Address The MMIO register to read.
698 @return The value read.
707 CONST EFI_PEI_SERVICES
**PeiServices
;
708 EFI_PEI_CPU_IO_PPI
*CpuIo
;
710 PeiServices
= GetPeiServicesTablePointer ();
711 CpuIo
= (*PeiServices
)->CpuIo
;
712 ASSERT (CpuIo
!= NULL
);
714 // Make sure Address is aligned on a 32-bit boundary.
716 ASSERT ((Address
& 3) == 0);
717 return CpuIo
->MemRead32 (PeiServices
, CpuIo
, (UINT64
)Address
);
721 Writes a 32-bit MMIO register.
723 Writes the 32-bit MMIO register specified by Address with the value specified
724 by Value and returns Value. This function must guarantee that all MMIO read
725 and write operations are serialized.
727 If 32-bit MMIO register operations are not supported, then ASSERT().
728 If Address is not aligned on a 32-bit boundary, then ASSERT().
730 @param Address The MMIO register to write.
731 @param Value The value to write to the MMIO register.
743 CONST EFI_PEI_SERVICES
**PeiServices
;
744 EFI_PEI_CPU_IO_PPI
*CpuIo
;
746 PeiServices
= GetPeiServicesTablePointer ();
747 CpuIo
= (*PeiServices
)->CpuIo
;
748 ASSERT (CpuIo
!= NULL
);
750 // Make sure Address is aligned on a 32-bit boundary.
752 ASSERT ((Address
& 3) == 0);
753 CpuIo
->MemWrite32 (PeiServices
, CpuIo
, (UINT64
)Address
, Value
);
758 Reads a 64-bit MMIO register.
760 Reads the 64-bit MMIO register specified by Address. The 64-bit read value is
761 returned. This function must guarantee that all MMIO read and write
762 operations are serialized.
764 If 64-bit MMIO register operations are not supported, then ASSERT().
765 If Address is not aligned on a 64-bit boundary, then ASSERT().
767 @param Address The MMIO register to read.
769 @return The value read.
778 CONST EFI_PEI_SERVICES
**PeiServices
;
779 EFI_PEI_CPU_IO_PPI
*CpuIo
;
781 PeiServices
= GetPeiServicesTablePointer ();
782 CpuIo
= (*PeiServices
)->CpuIo
;
783 ASSERT (CpuIo
!= NULL
);
785 // Make sure Address is aligned on a 64-bit boundary.
787 ASSERT ((Address
& (sizeof (UINT64
) - 1)) == 0);
788 return CpuIo
->MemRead64 (PeiServices
, CpuIo
, (UINT64
)Address
);
792 Writes a 64-bit MMIO register.
794 Writes the 64-bit MMIO register specified by Address with the value specified
795 by Value and returns Value. This function must guarantee that all MMIO read
796 and write operations are serialized.
798 If 64-bit MMIO register operations are not supported, then ASSERT().
799 If Address is not aligned on a 64-bit boundary, then ASSERT().
801 @param Address The MMIO register to write.
802 @param Value The value to write to the MMIO register.
812 CONST EFI_PEI_SERVICES
**PeiServices
;
813 EFI_PEI_CPU_IO_PPI
*CpuIo
;
815 PeiServices
= GetPeiServicesTablePointer ();
816 CpuIo
= (*PeiServices
)->CpuIo
;
817 ASSERT (CpuIo
!= NULL
);
819 // Make sure Address is aligned on a 64-bit boundary.
821 ASSERT ((Address
& 7) == 0);
822 CpuIo
->MemWrite64 (PeiServices
, CpuIo
, (UINT64
)Address
, Value
);