3 The implementation of I/O operation for this library instance
4 are based on EFI_CPU_IO_PROTOCOL.
6 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
7 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
9 SPDX-License-Identifier: BSD-2-Clause-Patent
16 #include "DxeCpuIoLibInternal.h"
19 // Globle varible to cache pointer to CpuIo protocol.
21 EFI_CPU_IO_PROTOCOL
*mCpuIo
= NULL
;
24 The constructor function caches the pointer to CpuIo protocol.
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.
29 @param ImageHandle The firmware allocated handle for the EFI image.
30 @param SystemTable A pointer to the EFI System Table.
32 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
38 IN EFI_HANDLE ImageHandle
,
39 IN EFI_SYSTEM_TABLE
*SystemTable
44 Status
= gBS
->LocateProtocol (&gEfiCpuIoProtocolGuid
, NULL
, (VOID
**) &mCpuIo
);
45 ASSERT_EFI_ERROR (Status
);
51 Reads registers in the EFI CPU I/O space.
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.
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.
61 @return Data read from registers in the EFI CPU I/O space.
68 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
74 Status
= mCpuIo
->Io
.Read (mCpuIo
, Width
, Port
, 1, &Data
);
75 ASSERT_EFI_ERROR (Status
);
81 Writes registers in the EFI CPU I/O space.
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.
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.
92 @return The parameter of Data.
99 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
105 Status
= mCpuIo
->Io
.Write (mCpuIo
, Width
, Port
, 1, &Data
);
106 ASSERT_EFI_ERROR (Status
);
112 Reads registers in the EFI CPU I/O space.
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.
117 This function must guarantee that all I/O read and write operations are serialized.
118 If such operations are not supported, then ASSERT().
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.
131 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
138 Status
= mCpuIo
->Io
.Read (mCpuIo
, Width
, Port
, Count
, Buffer
);
139 ASSERT_EFI_ERROR (Status
);
143 Writes registers in the EFI CPU I/O space.
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.
148 This function must guarantee that all I/O read and write operations are serialized.
149 If such operations are not supported, then ASSERT().
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.
162 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
169 Status
= mCpuIo
->Io
.Write (mCpuIo
, Width
, Port
, Count
, Buffer
);
170 ASSERT_EFI_ERROR (Status
);
174 Reads memory-mapped registers in the EFI system memory space.
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.
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.
184 @return Data read from registers in the EFI system memory space.
191 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
197 Status
= mCpuIo
->Mem
.Read (mCpuIo
, Width
, Address
, 1, &Data
);
198 ASSERT_EFI_ERROR (Status
);
204 Writes memory-mapped registers in the EFI system memory space.
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.
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.
215 @return Data read from registers in the EFI system memory space.
222 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
228 Status
= mCpuIo
->Mem
.Write (mCpuIo
, Width
, Address
, 1, &Data
);
229 ASSERT_EFI_ERROR (Status
);
235 Reads an 8-bit I/O port.
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
241 If 8-bit I/O port operations are not supported, then ASSERT().
243 @param Port The I/O port to read.
245 @return The value read.
254 return (UINT8
)IoReadWorker (Port
, EfiCpuIoWidthUint8
);
258 Writes an 8-bit I/O port.
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.
264 If 8-bit I/O port operations are not supported, then ASSERT().
266 @param Port The I/O port to write.
267 @param Value The value to write to the I/O port.
269 @return The value written the I/O port.
279 return (UINT8
)IoWriteWorker (Port
, EfiCpuIoWidthUint8
, Value
);
283 Reads a 16-bit I/O port.
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
289 If Port is not aligned on a 16-bit boundary, then ASSERT().
291 If 16-bit I/O port operations are not supported, then ASSERT().
293 @param Port The I/O port to read.
295 @return The value read.
305 // Make sure Port is aligned on a 16-bit boundary.
307 ASSERT ((Port
& 1) == 0);
308 return (UINT16
)IoReadWorker (Port
, EfiCpuIoWidthUint16
);
312 Writes a 16-bit I/O port.
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.
318 If Port is not aligned on a 16-bit boundary, then ASSERT().
320 If 16-bit I/O port operations are not supported, then ASSERT().
322 @param Port The I/O port to write.
323 @param Value The value to write to the I/O port.
325 @return The value written the I/O port.
336 // Make sure Port is aligned on a 16-bit boundary.
338 ASSERT ((Port
& 1) == 0);
339 return (UINT16
)IoWriteWorker (Port
, EfiCpuIoWidthUint16
, Value
);
343 Reads a 32-bit I/O port.
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
349 If Port is not aligned on a 32-bit boundary, then ASSERT().
351 If 32-bit I/O port operations are not supported, then ASSERT().
353 @param Port The I/O port to read.
355 @return The value read.
365 // Make sure Port is aligned on a 32-bit boundary.
367 ASSERT ((Port
& 3) == 0);
368 return (UINT32
)IoReadWorker (Port
, EfiCpuIoWidthUint32
);
372 Writes a 32-bit I/O port.
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.
378 If Port is not aligned on a 32-bit boundary, then ASSERT().
380 If 32-bit I/O port operations are not supported, then ASSERT().
382 @param Port The I/O port to write.
383 @param Value The value to write to the I/O port.
385 @return The value written the I/O port.
396 // Make sure Port is aligned on a 32-bit boundary.
398 ASSERT ((Port
& 3) == 0);
399 return (UINT32
)IoWriteWorker (Port
, EfiCpuIoWidthUint32
, Value
);
403 Reads a 64-bit I/O port.
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
409 If Port is not aligned on a 64-bit boundary, then ASSERT().
411 If 64-bit I/O port operations are not supported, then ASSERT().
413 @param Port The I/O port to read.
415 @return The value read.
425 // Make sure Port is aligned on a 64-bit boundary.
427 ASSERT ((Port
& 7) == 0);
428 return IoReadWorker (Port
, EfiCpuIoWidthUint64
);
432 Writes a 64-bit I/O port.
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.
438 If Port is not aligned on a 64-bit boundary, then ASSERT().
440 If 64-bit I/O port operations are not supported, then ASSERT().
442 @param Port The I/O port to write.
443 @param Value The value to write to the I/O port.
445 @return The value written the I/O port.
456 // Make sure Port is aligned on a 64-bit boundary.
458 ASSERT ((Port
& 7) == 0);
459 return IoWriteWorker (Port
, EfiCpuIoWidthUint64
, Value
);
463 Reads an 8-bit I/O port fifo into a block of memory.
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.
469 This function must guarantee that all I/O read and write operations are
472 If 8-bit I/O port operations are not supported, then ASSERT().
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.
487 IoReadFifoWorker (Port
, EfiCpuIoWidthFifoUint8
, Count
, Buffer
);
491 Writes a block of memory into an 8-bit I/O port fifo.
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.
497 This function must guarantee that all I/O write and write operations are
500 If 8-bit I/O port operations are not supported, then ASSERT().
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.
515 IoWriteFifoWorker (Port
, EfiCpuIoWidthFifoUint8
, Count
, Buffer
);
519 Reads a 16-bit I/O port fifo into a block of memory.
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.
525 This function must guarantee that all I/O read and write operations are
528 If 16-bit I/O port operations are not supported, then ASSERT().
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.
544 // Make sure Port is aligned on a 16-bit boundary.
546 ASSERT ((Port
& 1) == 0);
547 IoReadFifoWorker (Port
, EfiCpuIoWidthFifoUint16
, Count
, Buffer
);
551 Writes a block of memory into a 16-bit I/O port fifo.
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.
557 This function must guarantee that all I/O write and write operations are
560 If 16-bit I/O port operations are not supported, then ASSERT().
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.
576 // Make sure Port is aligned on a 16-bit boundary.
578 ASSERT ((Port
& 1) == 0);
579 IoWriteFifoWorker (Port
, EfiCpuIoWidthFifoUint16
, Count
, Buffer
);
583 Reads a 32-bit I/O port fifo into a block of memory.
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.
589 This function must guarantee that all I/O read and write operations are
592 If 32-bit I/O port operations are not supported, then ASSERT().
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.
608 // Make sure Port is aligned on a 32-bit boundary.
610 ASSERT ((Port
& 3) == 0);
611 IoReadFifoWorker (Port
, EfiCpuIoWidthFifoUint32
, Count
, Buffer
);
615 Writes a block of memory into a 32-bit I/O port fifo.
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.
621 This function must guarantee that all I/O write and write operations are
624 If 32-bit I/O port operations are not supported, then ASSERT().
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.
640 // Make sure Port is aligned on a 32-bit boundary.
642 ASSERT ((Port
& 3) == 0);
643 IoWriteFifoWorker (Port
, EfiCpuIoWidthFifoUint32
, Count
, Buffer
);
647 Reads an 8-bit MMIO register.
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.
653 If 8-bit MMIO register operations are not supported, then ASSERT().
655 @param Address The MMIO register to read.
657 @return The value read.
666 return (UINT8
)MmioReadWorker (Address
, EfiCpuIoWidthUint8
);
670 Writes an 8-bit MMIO register.
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.
676 If 8-bit MMIO register operations are not supported, then ASSERT().
678 @param Address The MMIO register to write.
679 @param Value The value to write to the MMIO register.
689 return (UINT8
)MmioWriteWorker (Address
, EfiCpuIoWidthUint8
, Value
);
693 Reads a 16-bit MMIO register.
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.
699 If Address is not aligned on a 16-bit boundary, then ASSERT().
701 If 16-bit MMIO register operations are not supported, then ASSERT().
703 @param Address The MMIO register to read.
705 @return The value read.
715 // Make sure Address is aligned on a 16-bit boundary.
717 ASSERT ((Address
& 1) == 0);
718 return (UINT16
)MmioReadWorker (Address
, EfiCpuIoWidthUint16
);
722 Writes a 16-bit MMIO register.
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.
728 If Address is not aligned on a 16-bit boundary, then ASSERT().
730 If 16-bit MMIO register operations are not supported, then ASSERT().
732 @param Address The MMIO register to write.
733 @param Value The value to write to the MMIO register.
744 // Make sure Address is aligned on a 16-bit boundary.
746 ASSERT ((Address
& 1) == 0);
747 return (UINT16
)MmioWriteWorker (Address
, EfiCpuIoWidthUint16
, Value
);
751 Reads a 32-bit MMIO register.
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.
757 If Address is not aligned on a 32-bit boundary, then ASSERT().
759 If 32-bit MMIO register operations are not supported, then ASSERT().
761 @param Address The MMIO register to read.
763 @return The value read.
773 // Make sure Address is aligned on a 32-bit boundary.
775 ASSERT ((Address
& 3) == 0);
776 return (UINT32
)MmioReadWorker (Address
, EfiCpuIoWidthUint32
);
780 Writes a 32-bit MMIO register.
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.
786 If Address is not aligned on a 32-bit boundary, then ASSERT().
788 If 32-bit MMIO register operations are not supported, then ASSERT().
790 @param Address The MMIO register to write.
791 @param Value The value to write to the MMIO register.
802 // Make sure Address is aligned on a 32-bit boundary.
804 ASSERT ((Address
& 3) == 0);
805 return (UINT32
)MmioWriteWorker (Address
, EfiCpuIoWidthUint32
, Value
);
809 Reads a 64-bit MMIO register.
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.
815 If Address is not aligned on a 64-bit boundary, then ASSERT().
817 If 64-bit MMIO register operations are not supported, then ASSERT().
819 @param Address The MMIO register to read.
821 @return The value read.
831 // Make sure Address is aligned on a 64-bit boundary.
833 ASSERT ((Address
& 7) == 0);
834 return (UINT64
)MmioReadWorker (Address
, EfiCpuIoWidthUint64
);
838 Writes a 64-bit MMIO register.
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.
844 If Address is not aligned on a 64-bit boundary, then ASSERT().
846 If 64-bit MMIO register operations are not supported, then ASSERT().
848 @param Address The MMIO register to write.
849 @param Value The value to write to the MMIO register.
860 // Make sure Address is aligned on a 64-bit boundary.
862 ASSERT ((Address
& 7) == 0);
863 return (UINT64
)MmioWriteWorker (Address
, EfiCpuIoWidthUint64
, Value
);