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