2 I/O Library. The implementations are based on EFI_PEI_SERVICE->CpuIo interface.
4 Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php.
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 #include <Library/IoLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/BaseLib.h>
23 #include <Library/PeiServicesTablePointerLib.h>
27 Reads registers in the EFI CPU I/O space.
29 Reads the I/O port specified by Port with registers width specified by Width.
30 The port is read Count times, and the read data is stored in the provided Buffer.
32 This function must guarantee that all I/O read and write operations are serialized.
33 If such operations are not supported, then ASSERT().
35 @param Port The base address of the I/O operation.
36 The caller is responsible for aligning the Address if required.
37 @param Width The width of the I/O operation.
38 @param Count The number of times to read I/O port.
39 @param Buffer The buffer to store the read data into.
46 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
51 CONST EFI_PEI_SERVICES
**PeiServices
;
52 EFI_PEI_CPU_IO_PPI
*CpuIo
;
55 PeiServices
= GetPeiServicesTablePointer ();
56 CpuIo
= (*PeiServices
)->CpuIo
;
57 ASSERT (CpuIo
!= NULL
);
59 Status
= CpuIo
->Io
.Read (PeiServices
, CpuIo
, Width
, Port
, Count
, Buffer
);
60 ASSERT_EFI_ERROR (Status
);
64 Writes registers in the EFI CPU I/O space.
66 Writes the I/O port specified by Port with registers width specified by Width.
67 The port is written Count times, and the write data is retrieved from the provided Buffer.
69 This function must guarantee that all I/O read and write operations are serialized.
70 If such operations are not supported, then ASSERT().
72 @param Port The base address of the I/O operation.
73 The caller is responsible for aligning the Address if required.
74 @param Width The width of the I/O operation.
75 @param Count The number of times to write I/O port.
76 @param Buffer The buffer to store the read data into.
83 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
88 CONST EFI_PEI_SERVICES
**PeiServices
;
89 EFI_PEI_CPU_IO_PPI
*CpuIo
;
92 PeiServices
= GetPeiServicesTablePointer ();
93 CpuIo
= (*PeiServices
)->CpuIo
;
94 ASSERT (CpuIo
!= NULL
);
96 Status
= CpuIo
->Io
.Write (PeiServices
, CpuIo
, Width
, Port
, Count
, Buffer
);
97 ASSERT_EFI_ERROR (Status
);
101 Reads an 8-bit I/O port.
103 Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
104 This function must guarantee that all I/O read and write operations are
107 If 8-bit I/O port operations are not supported, then ASSERT().
109 @param Port The I/O port to read.
111 @return The value read.
120 CONST EFI_PEI_SERVICES
**PeiServices
;
121 EFI_PEI_CPU_IO_PPI
*CpuIo
;
123 PeiServices
= GetPeiServicesTablePointer ();
124 CpuIo
= (*PeiServices
)->CpuIo
;
125 ASSERT (CpuIo
!= NULL
);
127 return CpuIo
->IoRead8 (PeiServices
, CpuIo
, (UINT64
) Port
);
131 Writes an 8-bit I/O port.
133 Writes the 8-bit I/O port specified by Port with the value specified by Value
134 and returns Value. This function must guarantee that all I/O read and write
135 operations are serialized.
137 If 8-bit I/O port operations are not supported, then ASSERT().
139 @param Port The I/O port to write.
140 @param Value The value to write to the I/O port.
142 @return The value written the I/O port.
152 CONST EFI_PEI_SERVICES
**PeiServices
;
153 EFI_PEI_CPU_IO_PPI
*CpuIo
;
155 PeiServices
= GetPeiServicesTablePointer ();
156 CpuIo
= (*PeiServices
)->CpuIo
;
157 ASSERT (CpuIo
!= NULL
);
159 CpuIo
->IoWrite8 (PeiServices
, CpuIo
, (UINT64
) Port
, Value
);
164 Reads a 16-bit I/O port.
166 Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
167 This function must guarantee that all I/O read and write operations are
170 If 16-bit I/O port operations are not supported, then ASSERT().
171 If Port is not aligned on a 16-bit boundary, then ASSERT().
173 @param Port The I/O port to read.
175 @return The value read.
184 CONST EFI_PEI_SERVICES
**PeiServices
;
185 EFI_PEI_CPU_IO_PPI
*CpuIo
;
187 PeiServices
= GetPeiServicesTablePointer ();
188 CpuIo
= (*PeiServices
)->CpuIo
;
189 ASSERT (CpuIo
!= NULL
);
191 // Make sure Port is aligned on a 16-bit boundary.
193 ASSERT ((Port
& 1) == 0);
194 return CpuIo
->IoRead16 (PeiServices
, CpuIo
, (UINT64
) Port
);
198 Writes a 16-bit I/O port.
200 Writes the 16-bit I/O port specified by Port with the value specified by Value
201 and returns Value. This function must guarantee that all I/O read and write
202 operations are serialized.
204 If 16-bit I/O port operations are not supported, then ASSERT().
205 If Port is not aligned on a 16-bit boundary, then ASSERT().
207 @param Port The I/O port to write.
208 @param Value The value to write to the I/O port.
210 @return The value written the I/O port.
220 CONST EFI_PEI_SERVICES
**PeiServices
;
221 EFI_PEI_CPU_IO_PPI
*CpuIo
;
223 PeiServices
= GetPeiServicesTablePointer ();
224 CpuIo
= (*PeiServices
)->CpuIo
;
225 ASSERT (CpuIo
!= NULL
);
227 // Make sure Port is aligned on a 16-bit boundary.
229 ASSERT ((Port
& 1) == 0);
230 CpuIo
->IoWrite16 (PeiServices
, CpuIo
, (UINT64
) Port
, Value
);
235 Reads a 32-bit I/O port.
237 Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
238 This function must guarantee that all I/O read and write operations are
241 If 32-bit I/O port operations are not supported, then ASSERT().
242 If Port is not aligned on a 32-bit boundary, then ASSERT().
244 @param Port The I/O port to read.
246 @return The value read.
255 CONST EFI_PEI_SERVICES
**PeiServices
;
256 EFI_PEI_CPU_IO_PPI
*CpuIo
;
258 PeiServices
= GetPeiServicesTablePointer ();
259 CpuIo
= (*PeiServices
)->CpuIo
;
260 ASSERT (CpuIo
!= NULL
);
262 // Make sure Port is aligned on a 32-bit boundary.
264 ASSERT ((Port
& 3) == 0);
265 return CpuIo
->IoRead32 (PeiServices
, CpuIo
, (UINT64
) Port
);
269 Writes a 32-bit I/O port.
271 Writes the 32-bit I/O port specified by Port with the value specified by Value
272 and returns Value. This function must guarantee that all I/O read and write
273 operations are serialized.
275 If 32-bit I/O port operations are not supported, then ASSERT().
276 If Port is not aligned on a 32-bit boundary, then ASSERT().
278 @param Port The I/O port to write.
279 @param Value The value to write to the I/O port.
281 @return The value written the I/O port.
291 CONST EFI_PEI_SERVICES
**PeiServices
;
292 EFI_PEI_CPU_IO_PPI
*CpuIo
;
294 PeiServices
= GetPeiServicesTablePointer ();
295 CpuIo
= (*PeiServices
)->CpuIo
;
296 ASSERT (CpuIo
!= NULL
);
298 // Make sure Port is aligned on a 32-bit boundary.
300 ASSERT ((Port
& 3) == 0);
301 CpuIo
->IoWrite32 (PeiServices
, CpuIo
, (UINT64
) Port
, Value
);
306 Reads a 64-bit I/O port.
308 Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.
309 This function must guarantee that all I/O read and write operations are
312 If 64-bit I/O port operations are not supported, then ASSERT().
313 If Port is not aligned on a 64-bit boundary, then ASSERT().
315 @param Port The I/O port to read.
317 @return The value read.
326 CONST EFI_PEI_SERVICES
**PeiServices
;
327 EFI_PEI_CPU_IO_PPI
*CpuIo
;
329 PeiServices
= GetPeiServicesTablePointer ();
330 CpuIo
= (*PeiServices
)->CpuIo
;
331 ASSERT (CpuIo
!= NULL
);
333 // Make sure Port is aligned on a 64-bit boundary.
335 ASSERT ((Port
& 7) == 0);
336 return CpuIo
->IoRead64 (PeiServices
, CpuIo
, (UINT64
) Port
);
340 Writes a 64-bit I/O port.
342 Writes the 64-bit I/O port specified by Port with the value specified by Value
343 and returns Value. This function must guarantee that all I/O read and write
344 operations are serialized.
346 If 64-bit I/O port operations are not supported, then ASSERT().
347 If Port is not aligned on a 64-bit boundary, then ASSERT().
349 @param Port The I/O port to write.
350 @param Value The value to write to the I/O port.
352 @return The value written the I/O port.
362 CONST EFI_PEI_SERVICES
**PeiServices
;
363 EFI_PEI_CPU_IO_PPI
*CpuIo
;
365 PeiServices
= GetPeiServicesTablePointer ();
366 CpuIo
= (*PeiServices
)->CpuIo
;
367 ASSERT (CpuIo
!= NULL
);
369 // Make sure Port is aligned on a 64-bit boundary.
371 ASSERT ((Port
& 7) == 0);
372 CpuIo
->IoWrite64 (PeiServices
, CpuIo
, (UINT64
) Port
, Value
);
377 Reads an 8-bit I/O port fifo into a block of memory.
379 Reads the 8-bit I/O fifo port specified by Port.
380 The port is read Count times, and the read data is
381 stored in the provided Buffer.
383 This function must guarantee that all I/O read and write operations are
386 If 8-bit I/O port operations are not supported, then ASSERT().
388 @param Port The I/O port to read.
389 @param Count The number of times to read I/O port.
390 @param Buffer The buffer to store the read data into.
401 IoReadFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint8
, Count
, Buffer
);
405 Writes a block of memory into an 8-bit I/O port fifo.
407 Writes the 8-bit I/O fifo port specified by Port.
408 The port is written Count times, and the write data is
409 retrieved from the provided Buffer.
411 This function must guarantee that all I/O write and write operations are
414 If 8-bit I/O port operations are not supported, then ASSERT().
416 @param Port The I/O port to write.
417 @param Count The number of times to write I/O port.
418 @param Buffer The buffer to retrieve the write data from.
429 IoWriteFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint8
, Count
, Buffer
);
433 Reads a 16-bit I/O port fifo into a block of memory.
435 Reads the 16-bit I/O fifo port specified by Port.
436 The port is read Count times, and the read data is
437 stored in the provided Buffer.
439 This function must guarantee that all I/O read and write operations are
442 If 16-bit I/O port operations are not supported, then ASSERT().
444 @param Port The I/O port to read.
445 @param Count The number of times to read I/O port.
446 @param Buffer The buffer to store the read data into.
458 // Make sure Port is aligned on a 16-bit boundary.
460 ASSERT ((Port
& 1) == 0);
461 IoReadFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint16
, Count
, Buffer
);
465 Writes a block of memory into a 16-bit I/O port fifo.
467 Writes the 16-bit I/O fifo port specified by Port.
468 The port is written Count times, and the write data is
469 retrieved from the provided Buffer.
471 This function must guarantee that all I/O write and write operations are
474 If 16-bit I/O port operations are not supported, then ASSERT().
476 @param Port The I/O port to write.
477 @param Count The number of times to write I/O port.
478 @param Buffer The buffer to retrieve the write data from.
490 // Make sure Port is aligned on a 16-bit boundary.
492 ASSERT ((Port
& 1) == 0);
493 IoWriteFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint16
, Count
, Buffer
);
497 Reads a 32-bit I/O port fifo into a block of memory.
499 Reads the 32-bit I/O fifo port specified by Port.
500 The port is read Count times, and the read data is
501 stored in the provided Buffer.
503 This function must guarantee that all I/O read and write operations are
506 If 32-bit I/O port operations are not supported, then ASSERT().
508 @param Port The I/O port to read.
509 @param Count The number of times to read I/O port.
510 @param Buffer The buffer to store the read data into.
522 // Make sure Port is aligned on a 32-bit boundary.
524 ASSERT ((Port
& 3) == 0);
525 IoReadFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint32
, Count
, Buffer
);
529 Writes a block of memory into a 32-bit I/O port fifo.
531 Writes the 32-bit I/O fifo port specified by Port.
532 The port is written Count times, and the write data is
533 retrieved from the provided Buffer.
535 This function must guarantee that all I/O write and write operations are
538 If 32-bit I/O port operations are not supported, then ASSERT().
540 @param Port The I/O port to write.
541 @param Count The number of times to write I/O port.
542 @param Buffer The buffer to retrieve the write data from.
554 // Make sure Port is aligned on a 32-bit boundary.
556 ASSERT ((Port
& 3) == 0);
557 IoWriteFifoWorker (Port
, EfiPeiCpuIoWidthFifoUint32
, Count
, Buffer
);
561 Reads an 8-bit MMIO register.
563 Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
564 returned. This function must guarantee that all MMIO read and write
565 operations are serialized.
567 If 8-bit MMIO register operations are not supported, then ASSERT().
569 @param Address The MMIO register to read.
571 @return The value read.
580 CONST EFI_PEI_SERVICES
**PeiServices
;
581 EFI_PEI_CPU_IO_PPI
*CpuIo
;
583 PeiServices
= GetPeiServicesTablePointer ();
584 CpuIo
= (*PeiServices
)->CpuIo
;
585 ASSERT (CpuIo
!= NULL
);
587 return CpuIo
->MemRead8 (PeiServices
, CpuIo
, (UINT64
) Address
);
591 Writes an 8-bit MMIO register.
593 Writes the 8-bit MMIO register specified by Address with the value specified
594 by Value and returns Value. This function must guarantee that all MMIO read
595 and write operations are serialized.
597 If 8-bit MMIO register operations are not supported, then ASSERT().
599 @param Address The MMIO register to write.
600 @param Value The value to write to the MMIO register.
612 CONST EFI_PEI_SERVICES
**PeiServices
;
613 EFI_PEI_CPU_IO_PPI
*CpuIo
;
615 PeiServices
= GetPeiServicesTablePointer ();
616 CpuIo
= (*PeiServices
)->CpuIo
;
617 ASSERT (CpuIo
!= NULL
);
619 CpuIo
->MemWrite8 (PeiServices
, CpuIo
, (UINT64
) Address
, Value
);
624 Reads a 16-bit MMIO register.
626 Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
627 returned. This function must guarantee that all MMIO read and write
628 operations are serialized.
630 If 16-bit MMIO register operations are not supported, then ASSERT().
631 If Address is not aligned on a 16-bit boundary, then ASSERT().
633 @param Address The MMIO register to read.
635 @return The value read.
644 CONST EFI_PEI_SERVICES
**PeiServices
;
645 EFI_PEI_CPU_IO_PPI
*CpuIo
;
647 PeiServices
= GetPeiServicesTablePointer ();
648 CpuIo
= (*PeiServices
)->CpuIo
;
649 ASSERT (CpuIo
!= NULL
);
651 // Make sure Address is aligned on a 16-bit boundary.
653 ASSERT ((Address
& 1) == 0);
654 return CpuIo
->MemRead16 (PeiServices
, CpuIo
, (UINT64
) Address
);
659 Writes a 16-bit MMIO register.
661 Writes the 16-bit MMIO register specified by Address with the value specified
662 by Value and returns Value. This function must guarantee that all MMIO read
663 and write operations are serialized.
665 If 16-bit MMIO register operations are not supported, then ASSERT().
666 If Address is not aligned on a 16-bit boundary, then ASSERT().
668 @param Address The MMIO register to write.
669 @param Value The value to write to the MMIO register.
681 CONST EFI_PEI_SERVICES
**PeiServices
;
682 EFI_PEI_CPU_IO_PPI
*CpuIo
;
684 PeiServices
= GetPeiServicesTablePointer ();
685 CpuIo
= (*PeiServices
)->CpuIo
;
686 ASSERT (CpuIo
!= NULL
);
688 // Make sure Address is aligned on a 16-bit boundary.
690 ASSERT ((Address
& 1) == 0);
691 CpuIo
->MemWrite16 (PeiServices
, CpuIo
, (UINT64
) Address
, Value
);
696 Reads a 32-bit MMIO register.
698 Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
699 returned. This function must guarantee that all MMIO read and write
700 operations are serialized.
702 If 32-bit MMIO register operations are not supported, then ASSERT().
703 If Address is not aligned on a 32-bit boundary, then ASSERT().
705 @param Address The MMIO register to read.
707 @return The value read.
716 CONST EFI_PEI_SERVICES
**PeiServices
;
717 EFI_PEI_CPU_IO_PPI
*CpuIo
;
719 PeiServices
= GetPeiServicesTablePointer ();
720 CpuIo
= (*PeiServices
)->CpuIo
;
721 ASSERT (CpuIo
!= NULL
);
723 // Make sure Address is aligned on a 32-bit boundary.
725 ASSERT ((Address
& 3) == 0);
726 return CpuIo
->MemRead32 (PeiServices
, CpuIo
, (UINT64
) Address
);
731 Writes a 32-bit MMIO register.
733 Writes the 32-bit MMIO register specified by Address with the value specified
734 by Value and returns Value. This function must guarantee that all MMIO read
735 and write operations are serialized.
737 If 32-bit MMIO register operations are not supported, then ASSERT().
738 If Address is not aligned on a 32-bit boundary, then ASSERT().
740 @param Address The MMIO register to write.
741 @param Value The value to write to the MMIO register.
753 CONST EFI_PEI_SERVICES
**PeiServices
;
754 EFI_PEI_CPU_IO_PPI
*CpuIo
;
756 PeiServices
= GetPeiServicesTablePointer ();
757 CpuIo
= (*PeiServices
)->CpuIo
;
758 ASSERT (CpuIo
!= NULL
);
760 // Make sure Address is aligned on a 32-bit boundary.
762 ASSERT ((Address
& 3) == 0);
763 CpuIo
->MemWrite32 (PeiServices
, CpuIo
, (UINT64
) Address
, Value
);
768 Reads a 64-bit MMIO register.
770 Reads the 64-bit MMIO register specified by Address. The 64-bit read value is
771 returned. This function must guarantee that all MMIO read and write
772 operations are serialized.
774 If 64-bit MMIO register operations are not supported, then ASSERT().
775 If Address is not aligned on a 64-bit boundary, then ASSERT().
777 @param Address The MMIO register to read.
779 @return The value read.
788 CONST EFI_PEI_SERVICES
**PeiServices
;
789 EFI_PEI_CPU_IO_PPI
*CpuIo
;
791 PeiServices
= GetPeiServicesTablePointer ();
792 CpuIo
= (*PeiServices
)->CpuIo
;
793 ASSERT (CpuIo
!= NULL
);
795 // Make sure Address is aligned on a 64-bit boundary.
797 ASSERT ((Address
& (sizeof (UINT64
) - 1)) == 0);
798 return CpuIo
->MemRead64 (PeiServices
, CpuIo
, (UINT64
) Address
);
803 Writes a 64-bit MMIO register.
805 Writes the 64-bit MMIO register specified by Address with the value specified
806 by Value and returns Value. This function must guarantee that all MMIO read
807 and write operations are serialized.
809 If 64-bit MMIO register operations are not supported, then ASSERT().
810 If Address is not aligned on a 64-bit boundary, then ASSERT().
812 @param Address The MMIO register to write.
813 @param Value The value to write to the MMIO register.
823 CONST EFI_PEI_SERVICES
**PeiServices
;
824 EFI_PEI_CPU_IO_PPI
*CpuIo
;
826 PeiServices
= GetPeiServicesTablePointer ();
827 CpuIo
= (*PeiServices
)->CpuIo
;
828 ASSERT (CpuIo
!= NULL
);
830 // Make sure Address is aligned on a 64-bit boundary.
832 ASSERT ((Address
& 7) == 0);
833 CpuIo
->MemWrite64 (PeiServices
, CpuIo
, (UINT64
) Address
, Value
);