TianoCore EDK2 master
Loading...
Searching...
No Matches
NonDiscoverablePciDeviceIo.c
Go to the documentation of this file.
1
11
13
15
17
18typedef struct {
19 EFI_PHYSICAL_ADDRESS AllocAddress;
20 VOID *HostAddress;
22 UINTN NumberOfBytes;
24
37 IN UINT8 BarIndex,
39 )
40{
42
43 if (BarIndex < Dev->BarOffset) {
44 return EFI_NOT_FOUND;
45 }
46
47 BarIndex -= (UINT8)Dev->BarOffset;
48
49 if (BarIndex >= Dev->BarCount) {
50 return EFI_UNSUPPORTED;
51 }
52
53 for (Desc = Dev->Device->Resources;
54 Desc->Desc != ACPI_END_TAG_DESCRIPTOR;
55 Desc = (VOID *)((UINT8 *)Desc + Desc->Len + 3))
56 {
57 if (BarIndex == 0) {
58 *Descriptor = Desc;
59 return EFI_SUCCESS;
60 }
61
62 BarIndex -= 1;
63 }
64
65 return EFI_NOT_FOUND;
66}
67
85EFIAPI
89 IN UINT8 BarIndex,
90 IN UINT64 Offset,
91 IN UINT64 Mask,
92 IN UINT64 Value,
93 IN UINT64 Delay,
94 OUT UINT64 *Result
95 )
96{
99 UINTN Count;
100 EFI_STATUS Status;
101
102 if ((UINT32)Width > EfiPciIoWidthUint64) {
103 return EFI_INVALID_PARAMETER;
104 }
105
106 if (Result == NULL) {
107 return EFI_INVALID_PARAMETER;
108 }
109
110 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
111 Count = 1;
112
113 Status = GetBarResource (Dev, BarIndex, &Desc);
114 if (EFI_ERROR (Status)) {
115 return Status;
116 }
117
118 if (Offset + (Count << (Width & 0x3)) > Desc->AddrLen) {
119 return EFI_UNSUPPORTED;
120 }
121
122 ASSERT (FALSE);
123 return EFI_UNSUPPORTED;
124}
125
141STATIC
143EFIAPI
147 IN UINT8 BarIndex,
148 IN UINT64 Offset,
149 IN UINT64 Mask,
150 IN UINT64 Value,
151 IN UINT64 Delay,
152 OUT UINT64 *Result
153 )
154{
157 UINTN Count;
158 EFI_STATUS Status;
159
160 if ((UINT32)Width > EfiPciIoWidthUint64) {
161 return EFI_INVALID_PARAMETER;
162 }
163
164 if (Result == NULL) {
165 return EFI_INVALID_PARAMETER;
166 }
167
168 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
169 Count = 1;
170
171 Status = GetBarResource (Dev, BarIndex, &Desc);
172 if (EFI_ERROR (Status)) {
173 return Status;
174 }
175
176 if (Offset + (Count << (Width & 0x3)) > Desc->AddrLen) {
177 return EFI_UNSUPPORTED;
178 }
179
180 ASSERT (FALSE);
181 return EFI_UNSUPPORTED;
182}
183
200STATIC
202EFIAPI
205 IN UINTN Count,
206 IN UINTN DstStride,
207 IN VOID *Dst,
208 IN UINTN SrcStride,
209 OUT CONST VOID *Src
210 )
211{
212 volatile UINT8 *Dst8;
213 volatile UINT16 *Dst16;
214 volatile UINT32 *Dst32;
215 volatile CONST UINT8 *Src8;
216 volatile CONST UINT16 *Src16;
217 volatile CONST UINT32 *Src32;
218
219 //
220 // Loop for each iteration and move the data
221 //
222 switch (Width & 0x3) {
223 case EfiPciWidthUint8:
224 Dst8 = (UINT8 *)Dst;
225 Src8 = (UINT8 *)Src;
226 for ( ; Count > 0; Count--, Dst8 += DstStride, Src8 += SrcStride) {
227 *Dst8 = *Src8;
228 }
229
230 break;
231 case EfiPciWidthUint16:
232 Dst16 = (UINT16 *)Dst;
233 Src16 = (UINT16 *)Src;
234 for ( ; Count > 0; Count--, Dst16 += DstStride, Src16 += SrcStride) {
235 *Dst16 = *Src16;
236 }
237
238 break;
239 case EfiPciWidthUint32:
240 Dst32 = (UINT32 *)Dst;
241 Src32 = (UINT32 *)Src;
242 for ( ; Count > 0; Count--, Dst32 += DstStride, Src32 += SrcStride) {
243 *Dst32 = *Src32;
244 }
245
246 break;
247 default:
248 return EFI_INVALID_PARAMETER;
249 }
250
251 return EFI_SUCCESS;
252}
253
274STATIC
276EFIAPI
280 IN UINT8 BarIndex,
281 IN UINT64 Offset,
282 IN UINTN Count,
283 IN OUT VOID *Buffer
284 )
285{
287 UINTN AlignMask;
288 VOID *Address;
290 EFI_STATUS Status;
291
292 if (Buffer == NULL) {
293 return EFI_INVALID_PARAMETER;
294 }
295
296 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
297
298 //
299 // Only allow accesses to the BARs we emulate
300 //
301 Status = GetBarResource (Dev, BarIndex, &Desc);
302 if (EFI_ERROR (Status)) {
303 return Status;
304 }
305
306 if (Offset + (Count << (Width & 0x3)) > Desc->AddrLen) {
307 return EFI_UNSUPPORTED;
308 }
309
310 Address = (VOID *)(UINTN)(Desc->AddrRangeMin + Offset);
311 AlignMask = (1 << (Width & 0x03)) - 1;
312 if ((UINTN)Address & AlignMask) {
313 return EFI_INVALID_PARAMETER;
314 }
315
316 switch (Width) {
317 case EfiPciIoWidthUint8:
318 case EfiPciIoWidthUint16:
319 case EfiPciIoWidthUint32:
320 case EfiPciIoWidthUint64:
321 return PciIoMemRW (Width, Count, 1, Buffer, 1, Address);
322
323 case EfiPciIoWidthFifoUint8:
324 case EfiPciIoWidthFifoUint16:
325 case EfiPciIoWidthFifoUint32:
326 case EfiPciIoWidthFifoUint64:
327 return PciIoMemRW (Width, Count, 1, Buffer, 0, Address);
328
329 case EfiPciIoWidthFillUint8:
330 case EfiPciIoWidthFillUint16:
331 case EfiPciIoWidthFillUint32:
332 case EfiPciIoWidthFillUint64:
333 return PciIoMemRW (Width, Count, 0, Buffer, 1, Address);
334
335 default:
336 break;
337 }
338
339 return EFI_INVALID_PARAMETER;
340}
341
362STATIC
364EFIAPI
368 IN UINT8 BarIndex,
369 IN UINT64 Offset,
370 IN UINTN Count,
371 IN OUT VOID *Buffer
372 )
373{
375 UINTN AlignMask;
376 VOID *Address;
378 EFI_STATUS Status;
379
380 if (Buffer == NULL) {
381 return EFI_INVALID_PARAMETER;
382 }
383
384 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
385
386 //
387 // Only allow accesses to the BARs we emulate
388 //
389 Status = GetBarResource (Dev, BarIndex, &Desc);
390 if (EFI_ERROR (Status)) {
391 return Status;
392 }
393
394 if (Offset + (Count << (Width & 0x3)) > Desc->AddrLen) {
395 return EFI_UNSUPPORTED;
396 }
397
398 Address = (VOID *)(UINTN)(Desc->AddrRangeMin + Offset);
399 AlignMask = (1 << (Width & 0x03)) - 1;
400 if ((UINTN)Address & AlignMask) {
401 return EFI_INVALID_PARAMETER;
402 }
403
404 switch (Width) {
405 case EfiPciIoWidthUint8:
406 case EfiPciIoWidthUint16:
407 case EfiPciIoWidthUint32:
408 case EfiPciIoWidthUint64:
409 return PciIoMemRW (Width, Count, 1, Address, 1, Buffer);
410
411 case EfiPciIoWidthFifoUint8:
412 case EfiPciIoWidthFifoUint16:
413 case EfiPciIoWidthFifoUint32:
414 case EfiPciIoWidthFifoUint64:
415 return PciIoMemRW (Width, Count, 0, Address, 1, Buffer);
416
417 case EfiPciIoWidthFillUint8:
418 case EfiPciIoWidthFillUint16:
419 case EfiPciIoWidthFillUint32:
420 case EfiPciIoWidthFillUint64:
421 return PciIoMemRW (Width, Count, 1, Address, 0, Buffer);
422
423 default:
424 break;
425 }
426
427 return EFI_INVALID_PARAMETER;
428}
429
443STATIC
445EFIAPI
449 IN UINT8 BarIndex,
450 IN UINT64 Offset,
451 IN UINTN Count,
452 IN OUT VOID *Buffer
453 )
454{
457 EFI_STATUS Status;
458
459 if ((UINT32)Width >= EfiPciIoWidthMaximum) {
460 return EFI_INVALID_PARAMETER;
461 }
462
463 if (Buffer == NULL) {
464 return EFI_INVALID_PARAMETER;
465 }
466
467 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
468
469 Status = GetBarResource (Dev, BarIndex, &Desc);
470 if (EFI_ERROR (Status)) {
471 return Status;
472 }
473
474 if (Offset + (Count << (Width & 0x3)) > Desc->AddrLen) {
475 return EFI_UNSUPPORTED;
476 }
477
478 ASSERT (FALSE);
479 return EFI_UNSUPPORTED;
480}
481
495STATIC
497EFIAPI
501 IN UINT8 BarIndex,
502 IN UINT64 Offset,
503 IN UINTN Count,
504 IN OUT VOID *Buffer
505 )
506{
509 EFI_STATUS Status;
510
511 if ((UINT32)Width >= EfiPciIoWidthMaximum) {
512 return EFI_INVALID_PARAMETER;
513 }
514
515 if (Buffer == NULL) {
516 return EFI_INVALID_PARAMETER;
517 }
518
519 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
520
521 Status = GetBarResource (Dev, BarIndex, &Desc);
522 if (EFI_ERROR (Status)) {
523 return Status;
524 }
525
526 if (Offset + (Count << (Width & 0x3)) > Desc->AddrLen) {
527 return EFI_UNSUPPORTED;
528 }
529
530 ASSERT (FALSE);
531 return EFI_UNSUPPORTED;
532}
533
545STATIC
547EFIAPI
551 IN UINT32 Offset,
552 IN UINTN Count,
553 IN OUT VOID *Buffer
554 )
555{
557 VOID *Address;
558 UINTN Length;
559
560 if ((Width < 0) || (Width >= EfiPciIoWidthMaximum) || (Buffer == NULL)) {
561 return EFI_INVALID_PARAMETER;
562 }
563
564 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
565 Address = (UINT8 *)&Dev->ConfigSpace + Offset;
566 Length = Count << ((UINTN)Width & 0x3);
567
568 if (Offset >= sizeof (Dev->ConfigSpace)) {
569 ZeroMem (Buffer, Length);
570 return EFI_SUCCESS;
571 }
572
573 if (Offset + Length > sizeof (Dev->ConfigSpace)) {
574 //
575 // Read all zeroes for config space accesses beyond the first
576 // 64 bytes
577 //
578 Length -= sizeof (Dev->ConfigSpace) - Offset;
579 ZeroMem ((UINT8 *)Buffer + sizeof (Dev->ConfigSpace) - Offset, Length);
580
581 Count -= Length >> ((UINTN)Width & 0x3);
582 }
583
584 return PciIoMemRW (Width, Count, 1, Buffer, 1, Address);
585}
586
603STATIC
605EFIAPI
609 IN UINT32 Offset,
610 IN UINTN Count,
611 IN OUT VOID *Buffer
612 )
613{
615 VOID *Address;
616
617 if ((Width < 0) || (Width >= EfiPciIoWidthMaximum) || (Buffer == NULL)) {
618 return EFI_INVALID_PARAMETER;
619 }
620
621 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
622 Address = (UINT8 *)&Dev->ConfigSpace + Offset;
623
624 if (Offset + (Count << ((UINTN)Width & 0x3)) > sizeof (Dev->ConfigSpace)) {
625 return EFI_UNSUPPORTED;
626 }
627
628 return PciIoMemRW (Width, Count, 1, Address, 1, Buffer);
629}
630
649STATIC
651EFIAPI
655 IN UINT8 DestBarIndex,
656 IN UINT64 DestOffset,
657 IN UINT8 SrcBarIndex,
658 IN UINT64 SrcOffset,
659 IN UINTN Count
660 )
661{
665 EFI_STATUS Status;
666
667 if ((UINT32)Width > EfiPciIoWidthUint64) {
668 return EFI_INVALID_PARAMETER;
669 }
670
671 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
672
673 Status = GetBarResource (Dev, DestBarIndex, &DestDesc);
674 if (EFI_ERROR (Status)) {
675 return Status;
676 }
677
678 if (DestOffset + (Count << (Width & 0x3)) > DestDesc->AddrLen) {
679 return EFI_UNSUPPORTED;
680 }
681
682 Status = GetBarResource (Dev, SrcBarIndex, &SrcDesc);
683 if (EFI_ERROR (Status)) {
684 return Status;
685 }
686
687 if (SrcOffset + (Count << (Width & 0x3)) > SrcDesc->AddrLen) {
688 return EFI_UNSUPPORTED;
689 }
690
691 ASSERT (FALSE);
692 return EFI_UNSUPPORTED;
693}
694
714STATIC
716EFIAPI
720 IN VOID *HostAddress,
721 IN OUT UINTN *NumberOfBytes,
722 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
723 OUT VOID **Mapping
724 )
725{
727 EFI_STATUS Status;
729
730 if ((Operation != EfiPciIoOperationBusMasterRead) &&
731 (Operation != EfiPciIoOperationBusMasterWrite) &&
733 {
734 return EFI_INVALID_PARAMETER;
735 }
736
737 if ((HostAddress == NULL) ||
738 (NumberOfBytes == NULL) ||
739 (DeviceAddress == NULL) ||
740 (Mapping == NULL))
741 {
742 return EFI_INVALID_PARAMETER;
743 }
744
745 //
746 // If HostAddress exceeds 4 GB, and this device does not support 64-bit DMA
747 // addressing, we need to allocate a bounce buffer and copy over the data.
748 //
749 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
750 if (((Dev->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) &&
751 ((EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress + *NumberOfBytes > SIZE_4GB))
752 {
753 //
754 // Bounce buffering is not possible for consistent mappings
755 //
757 return EFI_UNSUPPORTED;
758 }
759
760 MapInfo = AllocatePool (sizeof *MapInfo);
761 if (MapInfo == NULL) {
762 return EFI_OUT_OF_RESOURCES;
763 }
764
765 MapInfo->AllocAddress = MAX_UINT32;
766 MapInfo->HostAddress = HostAddress;
767 MapInfo->Operation = Operation;
768 MapInfo->NumberOfBytes = *NumberOfBytes;
769
770 Status = gBS->AllocatePages (
773 EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes),
774 &MapInfo->AllocAddress
775 );
776 if (EFI_ERROR (Status)) {
777 //
778 // If we fail here, it is likely because the system has no memory below
779 // 4 GB to begin with. There is not much we can do about that other than
780 // fail the map request.
781 //
782 FreePool (MapInfo);
783 return EFI_DEVICE_ERROR;
784 }
785
786 if (Operation == EfiPciIoOperationBusMasterRead) {
787 gBS->CopyMem (
788 (VOID *)(UINTN)MapInfo->AllocAddress,
789 HostAddress,
790 *NumberOfBytes
791 );
792 }
793
794 *DeviceAddress = MapInfo->AllocAddress;
795 *Mapping = MapInfo;
796 } else {
797 *DeviceAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress;
798 *Mapping = NULL;
799 }
800
801 return EFI_SUCCESS;
802}
803
813STATIC
815EFIAPI
818 IN VOID *Mapping
819 )
820{
822
823 MapInfo = Mapping;
824 if (MapInfo != NULL) {
825 if (MapInfo->Operation == EfiPciIoOperationBusMasterWrite) {
826 gBS->CopyMem (
827 MapInfo->HostAddress,
828 (VOID *)(UINTN)MapInfo->AllocAddress,
829 MapInfo->NumberOfBytes
830 );
831 }
832
833 gBS->FreePages (
834 MapInfo->AllocAddress,
835 EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes)
836 );
837 FreePool (MapInfo);
838 }
839
840 return EFI_SUCCESS;
841}
842
862STATIC
864EFIAPI
868 IN EFI_MEMORY_TYPE MemoryType,
869 IN UINTN Pages,
870 OUT VOID **HostAddress,
871 IN UINT64 Attributes
872 )
873{
875 EFI_PHYSICAL_ADDRESS AllocAddress;
876 EFI_ALLOCATE_TYPE AllocType;
877 EFI_STATUS Status;
878
879 if ((Attributes & ~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE |
880 EFI_PCI_ATTRIBUTE_MEMORY_CACHED)) != 0)
881 {
882 return EFI_UNSUPPORTED;
883 }
884
885 if (HostAddress == NULL) {
886 return EFI_INVALID_PARAMETER;
887 }
888
889 if ((MemoryType != EfiBootServicesData) &&
890 (MemoryType != EfiRuntimeServicesData))
891 {
892 return EFI_INVALID_PARAMETER;
893 }
894
895 //
896 // Allocate below 4 GB if the dual address cycle attribute has not
897 // been set. If the system has no memory available below 4 GB, there
898 // is little we can do except propagate the error.
899 //
900 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
901 if ((Dev->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) {
902 AllocAddress = MAX_UINT32;
903 AllocType = AllocateMaxAddress;
904 } else {
905 AllocType = AllocateAnyPages;
906 }
907
908 Status = gBS->AllocatePages (AllocType, MemoryType, Pages, &AllocAddress);
909 if (!EFI_ERROR (Status)) {
910 *HostAddress = (VOID *)(UINTN)AllocAddress;
911 }
912
913 return Status;
914}
915
926STATIC
928EFIAPI
931 IN UINTN Pages,
932 IN VOID *HostAddress
933 )
934{
935 FreePages (HostAddress, Pages);
936 return EFI_SUCCESS;
937}
938
950STATIC
952EFIAPI
955 IN UINTN Pages,
956 IN VOID *HostAddress
957 )
958{
960 LIST_ENTRY *Entry;
961 EFI_STATUS Status;
965 BOOLEAN Found;
966 UINTN StartPages;
967 UINTN EndPages;
968
969 if (HostAddress != ALIGN_POINTER (HostAddress, EFI_PAGE_SIZE)) {
970 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
971 return EFI_INVALID_PARAMETER;
972 }
973
974 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
975
976 Found = FALSE;
977 Alloc = NULL;
978
979 AllocHead = NULL;
980 AllocTail = NULL;
981
982 //
983 // Find the uncached allocation list entry associated
984 // with this allocation
985 //
986 for (Entry = Dev->UncachedAllocationList.ForwardLink;
987 Entry != &Dev->UncachedAllocationList;
988 Entry = Entry->ForwardLink)
989 {
991
992 StartPages = 0;
993 if (Alloc->HostAddress < HostAddress) {
994 StartPages = EFI_SIZE_TO_PAGES (
995 (UINTN)HostAddress - (UINTN)Alloc->HostAddress
996 );
997 }
998
999 if ((Alloc->HostAddress <= HostAddress) &&
1000 (Alloc->NumPages >= (Pages + StartPages)))
1001 {
1002 //
1003 // We are freeing at least part of what we were given
1004 // before by AllocateBuffer()
1005 //
1006 Found = TRUE;
1007 break;
1008 }
1009 }
1010
1011 if (!Found) {
1012 ASSERT_EFI_ERROR (EFI_NOT_FOUND);
1013 return EFI_NOT_FOUND;
1014 }
1015
1016 EndPages = Alloc->NumPages - (Pages + StartPages);
1017
1018 if (StartPages != 0) {
1019 AllocHead = AllocatePool (sizeof *AllocHead);
1020 if (AllocHead == NULL) {
1021 return EFI_OUT_OF_RESOURCES;
1022 }
1023
1024 AllocHead->HostAddress = Alloc->HostAddress;
1025
1026 AllocHead->NumPages = StartPages;
1027 AllocHead->Attributes = Alloc->Attributes;
1028 }
1029
1030 if (EndPages != 0) {
1031 AllocTail = AllocatePool (sizeof *AllocTail);
1032 if (AllocTail == NULL) {
1033 return EFI_OUT_OF_RESOURCES;
1034 }
1035
1036 AllocTail->HostAddress = (UINT8 *)Alloc->HostAddress +
1037 EFI_PAGES_TO_SIZE (Pages + StartPages);
1038
1039 AllocTail->NumPages = EndPages;
1040 AllocTail->Attributes = Alloc->Attributes;
1041 }
1042
1043 RemoveEntryList (&Alloc->List);
1044 //
1045 // Record this new sub allocations in the linked list, so we
1046 // can restore the memory space attributes later
1047 //
1048 if (AllocHead != NULL) {
1049 InsertHeadList (&Dev->UncachedAllocationList, &AllocHead->List);
1050 }
1051
1052 if (AllocTail != NULL) {
1053 InsertHeadList (&Dev->UncachedAllocationList, &AllocTail->List);
1054 }
1055
1056 Status = gDS->SetMemorySpaceAttributes (
1057 (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress,
1058 EFI_PAGES_TO_SIZE (Pages),
1059 Alloc->Attributes
1060 );
1061 if (EFI_ERROR (Status)) {
1062 goto FreeAlloc;
1063 }
1064
1065 //
1066 // If we fail to restore the original attributes, it is better to leak the
1067 // memory than to return it to the heap
1068 //
1069 FreePages (HostAddress, Pages);
1070
1071FreeAlloc:
1072 FreePool (Alloc);
1073 return Status;
1074}
1075
1095STATIC
1097EFIAPI
1099 IN EFI_PCI_IO_PROTOCOL *This,
1100 IN EFI_ALLOCATE_TYPE Type,
1101 IN EFI_MEMORY_TYPE MemoryType,
1102 IN UINTN Pages,
1103 OUT VOID **HostAddress,
1104 IN UINT64 Attributes
1105 )
1106{
1108 EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
1109 EFI_STATUS Status;
1110 UINT64 MemType;
1112 VOID *AllocAddress;
1113
1114 MemType = EFI_MEMORY_XP;
1115
1116 if (HostAddress == NULL) {
1117 return EFI_INVALID_PARAMETER;
1118 }
1119
1120 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
1121
1123 This,
1124 Type,
1125 MemoryType,
1126 Pages,
1127 &AllocAddress,
1128 Attributes
1129 );
1130 if (EFI_ERROR (Status)) {
1131 return Status;
1132 }
1133
1134 Status = gDS->GetMemorySpaceDescriptor (
1135 (EFI_PHYSICAL_ADDRESS)(UINTN)AllocAddress,
1136 &GcdDescriptor
1137 );
1138 if (EFI_ERROR (Status)) {
1139 goto FreeBuffer;
1140 }
1141
1142 if ((GcdDescriptor.Capabilities & (EFI_MEMORY_WC | EFI_MEMORY_UC)) == 0) {
1143 Status = EFI_UNSUPPORTED;
1144 goto FreeBuffer;
1145 }
1146
1147 //
1148 // Set the preferred memory attributes
1149 //
1150 if (((Attributes & EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE) != 0) ||
1151 ((GcdDescriptor.Capabilities & EFI_MEMORY_UC) == 0))
1152 {
1153 //
1154 // Use write combining if it was requested, or if it is the only
1155 // type supported by the region.
1156 //
1157 MemType |= EFI_MEMORY_WC;
1158 } else {
1159 MemType |= EFI_MEMORY_UC;
1160 }
1161
1162 Alloc = AllocatePool (sizeof *Alloc);
1163 if (Alloc == NULL) {
1164 goto FreeBuffer;
1165 }
1166
1167 Alloc->HostAddress = AllocAddress;
1168 Alloc->NumPages = Pages;
1169 Alloc->Attributes = GcdDescriptor.Attributes;
1170
1171 //
1172 // Record this allocation in the linked list, so we
1173 // can restore the memory space attributes later
1174 //
1175 InsertHeadList (&Dev->UncachedAllocationList, &Alloc->List);
1176
1177 //
1178 // Ensure that EFI_MEMORY_XP is in the capability set
1179 //
1180 if ((GcdDescriptor.Capabilities & EFI_MEMORY_XP) != EFI_MEMORY_XP) {
1181 Status = gDS->SetMemorySpaceCapabilities (
1182 (PHYSICAL_ADDRESS)(UINTN)AllocAddress,
1183 EFI_PAGES_TO_SIZE (Pages),
1184 GcdDescriptor.Capabilities | EFI_MEMORY_XP
1185 );
1186
1187 // if we were to fail setting the capability, this would indicate an internal failure of the GCD code. We should
1188 // assert here to let a platform know something went crazy, but for a release build we can let the allocation occur
1189 // without the EFI_MEMORY_XP bit set, as that was the existing behavior
1190 if (EFI_ERROR (Status)) {
1191 DEBUG ((
1192 DEBUG_ERROR,
1193 "%a failed to set EFI_MEMORY_XP capability on 0x%llx for length 0x%llx. Attempting to allocate without XP set.\n",
1194 __func__,
1195 AllocAddress,
1196 EFI_PAGES_TO_SIZE (Pages)
1197 ));
1198
1199 ASSERT_EFI_ERROR (Status);
1200
1201 MemType &= ~EFI_MEMORY_XP;
1202 }
1203 }
1204
1205 Status = gDS->SetMemorySpaceAttributes (
1206 (EFI_PHYSICAL_ADDRESS)(UINTN)AllocAddress,
1207 EFI_PAGES_TO_SIZE (Pages),
1208 MemType
1209 );
1210 if (EFI_ERROR (Status)) {
1211 goto RemoveList;
1212 }
1213
1214 Status = mCpu->FlushDataCache (
1215 mCpu,
1216 (EFI_PHYSICAL_ADDRESS)(UINTN)AllocAddress,
1217 EFI_PAGES_TO_SIZE (Pages),
1218 EfiCpuFlushTypeInvalidate
1219 );
1220 if (EFI_ERROR (Status)) {
1221 goto RemoveList;
1222 }
1223
1224 *HostAddress = AllocAddress;
1225
1226 return EFI_SUCCESS;
1227
1228RemoveList:
1229 RemoveEntryList (&Alloc->List);
1230 FreePool (Alloc);
1231
1232FreeBuffer:
1233 CoherentPciIoFreeBuffer (This, Pages, AllocAddress);
1234 return Status;
1235}
1236
1256STATIC
1258EFIAPI
1260 IN EFI_PCI_IO_PROTOCOL *This,
1262 IN VOID *HostAddress,
1263 IN OUT UINTN *NumberOfBytes,
1264 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
1265 OUT VOID **Mapping
1266 )
1267{
1269 EFI_STATUS Status;
1271 UINTN AlignMask;
1272 VOID *AllocAddress;
1273 EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
1274 BOOLEAN Bounce;
1275
1276 if ((HostAddress == NULL) ||
1277 (NumberOfBytes == NULL) ||
1278 (DeviceAddress == NULL) ||
1279 (Mapping == NULL))
1280 {
1281 return EFI_INVALID_PARAMETER;
1282 }
1283
1284 if ((Operation != EfiPciIoOperationBusMasterRead) &&
1285 (Operation != EfiPciIoOperationBusMasterWrite) &&
1287 {
1288 return EFI_INVALID_PARAMETER;
1289 }
1290
1291 MapInfo = AllocatePool (sizeof *MapInfo);
1292 if (MapInfo == NULL) {
1293 return EFI_OUT_OF_RESOURCES;
1294 }
1295
1296 MapInfo->HostAddress = HostAddress;
1297 MapInfo->Operation = Operation;
1298 MapInfo->NumberOfBytes = *NumberOfBytes;
1299
1300 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
1301
1302 //
1303 // If this device does not support 64-bit DMA addressing, we need to allocate
1304 // a bounce buffer and copy over the data in case HostAddress >= 4 GB.
1305 //
1306 Bounce = ((Dev->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0 &&
1307 (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress + *NumberOfBytes > SIZE_4GB);
1308
1309 if (!Bounce) {
1310 switch (Operation) {
1313 //
1314 // For streaming DMA, it is sufficient if the buffer is aligned to
1315 // the CPUs DMA buffer alignment.
1316 //
1317 AlignMask = mCpu->DmaBufferAlignment - 1;
1318 if ((((UINTN)HostAddress | *NumberOfBytes) & AlignMask) == 0) {
1319 break;
1320 }
1321
1322 // fall through
1323
1325 //
1326 // Check whether the host address refers to an uncached mapping.
1327 //
1328 Status = gDS->GetMemorySpaceDescriptor (
1329 (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress,
1330 &GcdDescriptor
1331 );
1332 if (EFI_ERROR (Status) ||
1333 ((GcdDescriptor.Attributes & (EFI_MEMORY_WB|EFI_MEMORY_WT)) != 0))
1334 {
1335 Bounce = TRUE;
1336 }
1337
1338 break;
1339
1340 default:
1341 ASSERT (FALSE);
1342 }
1343 }
1344
1345 if (Bounce) {
1346 if (Operation == EfiPciIoOperationBusMasterCommonBuffer) {
1347 Status = EFI_DEVICE_ERROR;
1348 goto FreeMapInfo;
1349 }
1350
1352 This,
1355 EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes),
1356 &AllocAddress,
1357 EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE
1358 );
1359 if (EFI_ERROR (Status)) {
1360 goto FreeMapInfo;
1361 }
1362
1363 MapInfo->AllocAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocAddress;
1364 if (Operation == EfiPciIoOperationBusMasterRead) {
1365 gBS->CopyMem (AllocAddress, HostAddress, *NumberOfBytes);
1366 }
1367
1368 *DeviceAddress = MapInfo->AllocAddress;
1369 } else {
1370 MapInfo->AllocAddress = 0;
1371 *DeviceAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress;
1372
1373 //
1374 // We are not using a bounce buffer: the mapping is sufficiently
1375 // aligned to allow us to simply flush the caches. Note that cleaning
1376 // the caches is necessary for both data directions:
1377 // - for bus master read, we want the latest data to be present
1378 // in main memory
1379 // - for bus master write, we don't want any stale dirty cachelines that
1380 // may be written back unexpectedly, and clobber the data written to
1381 // main memory by the device.
1382 //
1383 mCpu->FlushDataCache (
1384 mCpu,
1385 (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress,
1386 *NumberOfBytes,
1387 EfiCpuFlushTypeWriteBack
1388 );
1389 }
1390
1391 *Mapping = MapInfo;
1392 return EFI_SUCCESS;
1393
1394FreeMapInfo:
1395 FreePool (MapInfo);
1396
1397 return Status;
1398}
1399
1409STATIC
1411EFIAPI
1413 IN EFI_PCI_IO_PROTOCOL *This,
1414 IN VOID *Mapping
1415 )
1416{
1418
1419 if (Mapping == NULL) {
1420 return EFI_DEVICE_ERROR;
1421 }
1422
1423 MapInfo = Mapping;
1424 if (MapInfo->AllocAddress != 0) {
1425 //
1426 // We are using a bounce buffer: copy back the data if necessary,
1427 // and free the buffer.
1428 //
1429 if (MapInfo->Operation == EfiPciIoOperationBusMasterWrite) {
1430 gBS->CopyMem (
1431 MapInfo->HostAddress,
1432 (VOID *)(UINTN)MapInfo->AllocAddress,
1433 MapInfo->NumberOfBytes
1434 );
1435 }
1436
1438 This,
1439 EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes),
1440 (VOID *)(UINTN)MapInfo->AllocAddress
1441 );
1442 } else {
1443 //
1444 // We are *not* using a bounce buffer: if this is a bus master write,
1445 // we have to invalidate the caches so the CPU will see the uncached
1446 // data written by the device.
1447 //
1448 if (MapInfo->Operation == EfiPciIoOperationBusMasterWrite) {
1449 mCpu->FlushDataCache (
1450 mCpu,
1451 (EFI_PHYSICAL_ADDRESS)(UINTN)MapInfo->HostAddress,
1452 MapInfo->NumberOfBytes,
1453 EfiCpuFlushTypeInvalidate
1454 );
1455 }
1456 }
1457
1458 FreePool (MapInfo);
1459 return EFI_SUCCESS;
1460}
1461
1468STATIC
1470EFIAPI
1473 )
1474{
1475 return EFI_SUCCESS;
1476}
1477
1491STATIC
1493EFIAPI
1495 IN EFI_PCI_IO_PROTOCOL *This,
1496 OUT UINTN *SegmentNumber,
1497 OUT UINTN *BusNumber,
1498 OUT UINTN *DeviceNumber,
1499 OUT UINTN *FunctionNumber
1500 )
1501{
1503
1504 if ((SegmentNumber == NULL) ||
1505 (BusNumber == NULL) ||
1506 (DeviceNumber == NULL) ||
1507 (FunctionNumber == NULL))
1508 {
1509 return EFI_INVALID_PARAMETER;
1510 }
1511
1512 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
1513
1514 *SegmentNumber = 0xff;
1515 *BusNumber = Dev->UniqueId >> 5;
1516 *DeviceNumber = Dev->UniqueId & 0x1f;
1517 *FunctionNumber = 0;
1518
1519 return EFI_SUCCESS;
1520}
1521
1541STATIC
1543EFIAPI
1545 IN EFI_PCI_IO_PROTOCOL *This,
1547 IN UINT64 Attributes,
1548 OUT UINT64 *Result OPTIONAL
1549 )
1550{
1552 BOOLEAN Enable;
1553
1554 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
1555
1556 if ((Attributes & (~(DEV_SUPPORTED_ATTRIBUTES))) != 0) {
1557 return EFI_UNSUPPORTED;
1558 }
1559
1560 Enable = FALSE;
1561 switch (Operation) {
1563 if (Result == NULL) {
1564 return EFI_INVALID_PARAMETER;
1565 }
1566
1567 *Result = Dev->Attributes;
1568 break;
1569
1571 if (Result == NULL) {
1572 return EFI_INVALID_PARAMETER;
1573 }
1574
1575 *Result = DEV_SUPPORTED_ATTRIBUTES;
1576 break;
1577
1579 Attributes |= Dev->Attributes;
1581 Enable = ((~Dev->Attributes & Attributes) & EFI_PCI_DEVICE_ENABLE) != 0;
1582 Dev->Attributes = Attributes;
1583 break;
1584
1586 Dev->Attributes &= ~Attributes;
1587 break;
1588
1589 default:
1590 return EFI_INVALID_PARAMETER;
1591 }
1592
1593 //
1594 // If we're setting any of the EFI_PCI_DEVICE_ENABLE bits, perform
1595 // the device specific initialization now.
1596 //
1597 if (Enable && !Dev->Enabled && (Dev->Device->Initialize != NULL)) {
1598 Dev->Device->Initialize (Dev->Device);
1599 Dev->Enabled = TRUE;
1600 }
1601
1602 return EFI_SUCCESS;
1603}
1604
1627STATIC
1629EFIAPI
1631 IN EFI_PCI_IO_PROTOCOL *This,
1632 IN UINT8 BarIndex,
1633 OUT UINT64 *Supports OPTIONAL,
1634 OUT VOID **Resources OPTIONAL
1635 )
1636{
1641 EFI_STATUS Status;
1642
1643 if ((Supports == NULL) && (Resources == NULL)) {
1644 return EFI_INVALID_PARAMETER;
1645 }
1646
1647 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
1648
1649 Status = GetBarResource (Dev, BarIndex, &BarDesc);
1650 if (EFI_ERROR (Status)) {
1651 return Status;
1652 }
1653
1654 //
1655 // Don't expose any configurable attributes for our emulated BAR
1656 //
1657 if (Supports != NULL) {
1658 *Supports = 0;
1659 }
1660
1661 if (Resources != NULL) {
1662 Descriptor = AllocatePool (
1665 );
1666 if (Descriptor == NULL) {
1667 return EFI_OUT_OF_RESOURCES;
1668 }
1669
1670 CopyMem (Descriptor, BarDesc, sizeof *Descriptor);
1671
1672 End = (EFI_ACPI_END_TAG_DESCRIPTOR *)(Descriptor + 1);
1673 End->Desc = ACPI_END_TAG_DESCRIPTOR;
1674 End->Checksum = 0;
1675
1676 *Resources = Descriptor;
1677 }
1678
1679 return EFI_SUCCESS;
1680}
1681
1695STATIC
1697EFIAPI
1699 IN EFI_PCI_IO_PROTOCOL *This,
1700 IN UINT64 Attributes,
1701 IN UINT8 BarIndex,
1702 IN OUT UINT64 *Offset,
1703 IN OUT UINT64 *Length
1704 )
1705{
1709 UINTN Count;
1710 EFI_STATUS Status;
1711
1712 if ((Attributes & (~DEV_SUPPORTED_ATTRIBUTES)) != 0) {
1713 return EFI_UNSUPPORTED;
1714 }
1715
1716 if ((Offset == NULL) || (Length == NULL)) {
1717 return EFI_INVALID_PARAMETER;
1718 }
1719
1720 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
1721 Width = EfiPciIoWidthUint8;
1722 Count = (UINT32)*Length;
1723
1724 Status = GetBarResource (Dev, BarIndex, &Desc);
1725 if (EFI_ERROR (Status)) {
1726 return Status;
1727 }
1728
1729 if (*Offset + (Count << (Width & 0x3)) > Desc->AddrLen) {
1730 return EFI_UNSUPPORTED;
1731 }
1732
1733 ASSERT (FALSE);
1734 return EFI_UNSUPPORTED;
1735}
1736
1737STATIC CONST EFI_PCI_IO_PROTOCOL PciIoTemplate =
1738{
1749 PciIoFlush,
1754 0,
1755 0
1756};
1757
1764VOID
1767 )
1768{
1770 INTN Idx;
1771
1772 InitializeListHead (&Dev->UncachedAllocationList);
1773
1774 Dev->ConfigSpace.Hdr.VendorId = PCI_ID_VENDOR_UNKNOWN;
1775 Dev->ConfigSpace.Hdr.DeviceId = PCI_ID_DEVICE_DONTCARE;
1776
1777 // Copy protocol structure
1778 CopyMem (&Dev->PciIo, &PciIoTemplate, sizeof PciIoTemplate);
1779
1780 if (Dev->Device->DmaType == NonDiscoverableDeviceDmaTypeNonCoherent) {
1781 Dev->PciIo.AllocateBuffer = NonCoherentPciIoAllocateBuffer;
1782 Dev->PciIo.FreeBuffer = NonCoherentPciIoFreeBuffer;
1783 Dev->PciIo.Map = NonCoherentPciIoMap;
1784 Dev->PciIo.Unmap = NonCoherentPciIoUnmap;
1785 }
1786
1787 if (CompareGuid (Dev->Device->Type, &gEdkiiNonDiscoverableAhciDeviceGuid)) {
1788 Dev->ConfigSpace.Hdr.ClassCode[0] = PCI_IF_MASS_STORAGE_AHCI;
1789 Dev->ConfigSpace.Hdr.ClassCode[1] = PCI_CLASS_MASS_STORAGE_SATADPA;
1790 Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_MASS_STORAGE;
1791 Dev->BarOffset = 5;
1792 } else if (CompareGuid (
1793 Dev->Device->Type,
1794 &gEdkiiNonDiscoverableEhciDeviceGuid
1795 ))
1796 {
1797 Dev->ConfigSpace.Hdr.ClassCode[0] = PCI_IF_EHCI;
1798 Dev->ConfigSpace.Hdr.ClassCode[1] = PCI_CLASS_SERIAL_USB;
1799 Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_SERIAL;
1800 Dev->BarOffset = 0;
1801 } else if (CompareGuid (
1802 Dev->Device->Type,
1803 &gEdkiiNonDiscoverableNvmeDeviceGuid
1804 ))
1805 {
1806 Dev->ConfigSpace.Hdr.ClassCode[0] = 0x2; // PCI_IF_NVMHCI
1807 Dev->ConfigSpace.Hdr.ClassCode[1] = 0x8; // PCI_CLASS_MASS_STORAGE_NVM
1808 Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_MASS_STORAGE;
1809 Dev->BarOffset = 0;
1810 } else if (CompareGuid (
1811 Dev->Device->Type,
1812 &gEdkiiNonDiscoverableOhciDeviceGuid
1813 ))
1814 {
1815 Dev->ConfigSpace.Hdr.ClassCode[0] = PCI_IF_OHCI;
1816 Dev->ConfigSpace.Hdr.ClassCode[1] = PCI_CLASS_SERIAL_USB;
1817 Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_SERIAL;
1818 Dev->BarOffset = 0;
1819 } else if (CompareGuid (
1820 Dev->Device->Type,
1821 &gEdkiiNonDiscoverableSdhciDeviceGuid
1822 ))
1823 {
1824 Dev->ConfigSpace.Hdr.ClassCode[0] = 0x0; // don't care
1825 Dev->ConfigSpace.Hdr.ClassCode[1] = PCI_SUBCLASS_SD_HOST_CONTROLLER;
1826 Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_SYSTEM_PERIPHERAL;
1827 Dev->BarOffset = 0;
1828 } else if (CompareGuid (
1829 Dev->Device->Type,
1830 &gEdkiiNonDiscoverableXhciDeviceGuid
1831 ))
1832 {
1833 Dev->ConfigSpace.Hdr.ClassCode[0] = PCI_IF_XHCI;
1834 Dev->ConfigSpace.Hdr.ClassCode[1] = PCI_CLASS_SERIAL_USB;
1835 Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_SERIAL;
1836 Dev->BarOffset = 0;
1837 } else if (CompareGuid (
1838 Dev->Device->Type,
1839 &gEdkiiNonDiscoverableUhciDeviceGuid
1840 ))
1841 {
1842 Dev->ConfigSpace.Hdr.ClassCode[0] = PCI_IF_UHCI;
1843 Dev->ConfigSpace.Hdr.ClassCode[1] = PCI_CLASS_SERIAL_USB;
1844 Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_SERIAL;
1845 Dev->BarOffset = 0;
1846 } else if (CompareGuid (
1847 Dev->Device->Type,
1848 &gEdkiiNonDiscoverableUfsDeviceGuid
1849 ))
1850 {
1851 Dev->ConfigSpace.Hdr.ClassCode[0] = 0x0; // don't care
1852 Dev->ConfigSpace.Hdr.ClassCode[1] = 0x9; // UFS controller subclass;
1853 Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_MASS_STORAGE;
1854 Dev->BarOffset = 0;
1855 } else {
1856 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
1857 }
1858
1859 //
1860 // Iterate over the resources to populate the virtual BARs
1861 //
1862 Idx = Dev->BarOffset;
1863 for (Desc = Dev->Device->Resources, Dev->BarCount = 0;
1864 Desc->Desc != ACPI_END_TAG_DESCRIPTOR;
1865 Desc = (VOID *)((UINT8 *)Desc + Desc->Len + 3))
1866 {
1867 ASSERT (Desc->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR);
1868 ASSERT (Desc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM);
1869
1870 if ((Idx >= PCI_MAX_BAR) ||
1871 ((Idx == PCI_MAX_BAR - 1) && (Desc->AddrSpaceGranularity == 64)))
1872 {
1873 DEBUG ((
1874 DEBUG_ERROR,
1875 "%a: resource count exceeds number of emulated BARs\n",
1876 __func__
1877 ));
1878 ASSERT (FALSE);
1879 break;
1880 }
1881
1882 Dev->ConfigSpace.Device.Bar[Idx] = (UINT32)Desc->AddrRangeMin;
1883 Dev->BarCount++;
1884
1885 if (Desc->AddrSpaceGranularity == 64) {
1886 Dev->ConfigSpace.Device.Bar[Idx] |= 0x4;
1887 Dev->ConfigSpace.Device.Bar[++Idx] = (UINT32)RShiftU64 (
1888 Desc->AddrRangeMin,
1889 32
1890 );
1891 }
1892 }
1893}
UINT64 UINTN
INT64 INTN
PACKED struct @89 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:218
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_DXE_SERVICES * gDS
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define ALIGN_POINTER(Pointer, Alignment)
Definition: Base.h:963
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define BASE_CR(Record, TYPE, Field)
Definition: Base.h:891
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_PCI_IO_PROTOCOL_WIDTH
Definition: PciIo.h:28
#define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
Clear for PCI controllers that can not genrate a DAC.
Definition: PciIo.h:64
EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION
Definition: PciIo.h:99
@ EfiPciIoAttributeOperationDisable
Definition: PciIo.h:115
@ EfiPciIoAttributeOperationGet
Definition: PciIo.h:103
@ EfiPciIoAttributeOperationEnable
Definition: PciIo.h:111
@ EfiPciIoAttributeOperationSet
Definition: PciIo.h:107
@ EfiPciIoAttributeOperationSupported
Definition: PciIo.h:119
EFI_PCI_IO_PROTOCOL_OPERATION
Definition: PciIo.h:77
@ EfiPciIoOperationBusMasterWrite
Definition: PciIo.h:85
@ EfiPciIoOperationBusMasterRead
Definition: PciIo.h:81
@ EfiPciIoOperationBusMasterCommonBuffer
Definition: PciIo.h:90
STATIC EFI_STATUS EFIAPI CoherentPciIoFreeBuffer(IN EFI_PCI_IO_PROTOCOL *This, IN UINTN Pages, IN VOID *HostAddress)
STATIC EFI_STATUS GetBarResource(IN NON_DISCOVERABLE_PCI_DEVICE *Dev, IN UINT8 BarIndex, OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptor)
STATIC EFI_STATUS EFIAPI CoherentPciIoAllocateBuffer(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, OUT VOID **HostAddress, IN UINT64 Attributes)
STATIC EFI_STATUS EFIAPI PciIoGetBarAttributes(IN EFI_PCI_IO_PROTOCOL *This, IN UINT8 BarIndex, OUT UINT64 *Supports OPTIONAL, OUT VOID **Resources OPTIONAL)
STATIC EFI_STATUS EFIAPI PciIoCopyMem(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 DestBarIndex, IN UINT64 DestOffset, IN UINT8 SrcBarIndex, IN UINT64 SrcOffset, IN UINTN Count)
VOID InitializePciIoProtocol(NON_DISCOVERABLE_PCI_DEVICE *Dev)
STATIC EFI_STATUS EFIAPI PciIoIoWrite(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 BarIndex, IN UINT64 Offset, IN UINTN Count, IN OUT VOID *Buffer)
STATIC EFI_STATUS EFIAPI CoherentPciIoMap(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
STATIC EFI_STATUS EFIAPI PciIoGetLocation(IN EFI_PCI_IO_PROTOCOL *This, OUT UINTN *SegmentNumber, OUT UINTN *BusNumber, OUT UINTN *DeviceNumber, OUT UINTN *FunctionNumber)
STATIC EFI_STATUS EFIAPI PciIoMemRW(IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINTN Count, IN UINTN DstStride, IN VOID *Dst, IN UINTN SrcStride, OUT CONST VOID *Src)
STATIC EFI_STATUS EFIAPI PciIoFlush(IN EFI_PCI_IO_PROTOCOL *This)
STATIC EFI_STATUS EFIAPI CoherentPciIoUnmap(IN EFI_PCI_IO_PROTOCOL *This, IN VOID *Mapping)
STATIC EFI_STATUS EFIAPI PciIoPciWrite(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT32 Offset, IN UINTN Count, IN OUT VOID *Buffer)
STATIC EFI_STATUS EFIAPI PciIoAttributes(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, IN UINT64 Attributes, OUT UINT64 *Result OPTIONAL)
STATIC EFI_STATUS EFIAPI NonCoherentPciIoMap(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
STATIC EFI_STATUS EFIAPI PciIoPciRead(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT32 Offset, IN UINTN Count, IN OUT VOID *Buffer)
STATIC EFI_STATUS EFIAPI PciIoIoRead(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 BarIndex, IN UINT64 Offset, IN UINTN Count, IN OUT VOID *Buffer)
STATIC EFI_STATUS EFIAPI PciIoPollMem(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 BarIndex, IN UINT64 Offset, IN UINT64 Mask, IN UINT64 Value, IN UINT64 Delay, OUT UINT64 *Result)
STATIC EFI_STATUS EFIAPI PciIoMemWrite(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 BarIndex, IN UINT64 Offset, IN UINTN Count, IN OUT VOID *Buffer)
STATIC EFI_STATUS EFIAPI NonCoherentPciIoFreeBuffer(IN EFI_PCI_IO_PROTOCOL *This, IN UINTN Pages, IN VOID *HostAddress)
STATIC EFI_STATUS EFIAPI PciIoMemRead(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 BarIndex, IN UINT64 Offset, IN UINTN Count, IN OUT VOID *Buffer)
STATIC EFI_STATUS EFIAPI PciIoSetBarAttributes(IN EFI_PCI_IO_PROTOCOL *This, IN UINT64 Attributes, IN UINT8 BarIndex, IN OUT UINT64 *Offset, IN OUT UINT64 *Length)
STATIC EFI_STATUS EFIAPI NonCoherentPciIoUnmap(IN EFI_PCI_IO_PROTOCOL *This, IN VOID *Mapping)
STATIC EFI_STATUS EFIAPI NonCoherentPciIoAllocateBuffer(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, OUT VOID **HostAddress, IN UINT64 Attributes)
STATIC EFI_STATUS EFIAPI PciIoPollIo(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 BarIndex, IN UINT64 Offset, IN UINT64 Mask, IN UINT64 Value, IN UINT64 Delay, OUT UINT64 *Result)
#define PCI_IF_EHCI
Definition: Pci23.h:53
#define PCI_CLASS_MASS_STORAGE_SATADPA
Definition: Pci30.h:18
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_MEMORY_TYPE
@ EfiBootServicesData
@ EfiRuntimeServicesData
EFI_ALLOCATE_TYPE
Definition: UefiSpec.h:29
@ AllocateMaxAddress
Definition: UefiSpec.h:38
@ AllocateAnyPages
Definition: UefiSpec.h:33
UINT32 DmaBufferAlignment
Definition: Cpu.h:281