TianoCore EDK2 master
Loading...
Searching...
No Matches
PciRootBridgeIo.c
Go to the documentation of this file.
1
10#include "PciHostBridge.h"
11#include "PciRootBridge.h"
12#include "PciHostResource.h"
13
14#define NO_MAPPING (VOID *) (UINTN) -1
15
16#define RESOURCE_VALID(Resource) ((Resource)->Base <= (Resource)->Limit)
17
18//
19// Lookup table for increment values based on transfer widths
20//
21UINT8 mInStride[] = {
22 1, // EfiPciWidthUint8
23 2, // EfiPciWidthUint16
24 4, // EfiPciWidthUint32
25 8, // EfiPciWidthUint64
26 0, // EfiPciWidthFifoUint8
27 0, // EfiPciWidthFifoUint16
28 0, // EfiPciWidthFifoUint32
29 0, // EfiPciWidthFifoUint64
30 1, // EfiPciWidthFillUint8
31 2, // EfiPciWidthFillUint16
32 4, // EfiPciWidthFillUint32
33 8 // EfiPciWidthFillUint64
34};
35
36//
37// Lookup table for increment values based on transfer widths
38//
39UINT8 mOutStride[] = {
40 1, // EfiPciWidthUint8
41 2, // EfiPciWidthUint16
42 4, // EfiPciWidthUint32
43 8, // EfiPciWidthUint64
44 1, // EfiPciWidthFifoUint8
45 2, // EfiPciWidthFifoUint16
46 4, // EfiPciWidthFifoUint32
47 8, // EfiPciWidthFifoUint64
48 0, // EfiPciWidthFillUint8
49 0, // EfiPciWidthFillUint16
50 0, // EfiPciWidthFillUint32
51 0 // EfiPciWidthFillUint64
52};
53
64 IN PCI_ROOT_BRIDGE *Bridge
65 )
66{
67 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
68 PCI_RESOURCE_TYPE Index;
69 CHAR16 *DevicePathStr;
71
72 DevicePathStr = NULL;
73
74 DEBUG ((DEBUG_INFO, "RootBridge: "));
75 DEBUG ((DEBUG_INFO, "%s\n", DevicePathStr = ConvertDevicePathToText (Bridge->DevicePath, FALSE, FALSE)));
76 DEBUG ((DEBUG_INFO, " Support/Attr: %lx / %lx\n", Bridge->Supports, Bridge->Attributes));
77 DEBUG ((DEBUG_INFO, " DmaAbove4G: %s\n", Bridge->DmaAbove4G ? L"Yes" : L"No"));
78 DEBUG ((DEBUG_INFO, "NoExtConfSpace: %s\n", Bridge->NoExtendedConfigSpace ? L"Yes" : L"No"));
79 DEBUG ((
80 DEBUG_INFO,
81 " AllocAttr: %lx (%s%s)\n",
82 Bridge->AllocationAttributes,
83 (Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0 ? L"CombineMemPMem " : L"",
84 (Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) != 0 ? L"Mem64Decode" : L""
85 ));
86 DEBUG ((
87 DEBUG_INFO,
88 " Bus: %lx - %lx Translation=%lx\n",
89 Bridge->Bus.Base,
90 Bridge->Bus.Limit,
91 Bridge->Bus.Translation
92 ));
93 //
94 // Translation for bus is not supported.
95 //
96 ASSERT (Bridge->Bus.Translation == 0);
97 if (Bridge->Bus.Translation != 0) {
98 return NULL;
99 }
100
101 DEBUG ((
102 DEBUG_INFO,
103 " Io: %lx - %lx Translation=%lx\n",
104 Bridge->Io.Base,
105 Bridge->Io.Limit,
106 Bridge->Io.Translation
107 ));
108 DEBUG ((
109 DEBUG_INFO,
110 " Mem: %lx - %lx Translation=%lx\n",
111 Bridge->Mem.Base,
112 Bridge->Mem.Limit,
113 Bridge->Mem.Translation
114 ));
115 DEBUG ((
116 DEBUG_INFO,
117 " MemAbove4G: %lx - %lx Translation=%lx\n",
118 Bridge->MemAbove4G.Base,
119 Bridge->MemAbove4G.Limit,
120 Bridge->MemAbove4G.Translation
121 ));
122 DEBUG ((
123 DEBUG_INFO,
124 " PMem: %lx - %lx Translation=%lx\n",
125 Bridge->PMem.Base,
126 Bridge->PMem.Limit,
127 Bridge->PMem.Translation
128 ));
129 DEBUG ((
130 DEBUG_INFO,
131 " PMemAbove4G: %lx - %lx Translation=%lx\n",
132 Bridge->PMemAbove4G.Base,
133 Bridge->PMemAbove4G.Limit,
134 Bridge->PMemAbove4G.Translation
135 ));
136
137 //
138 // Make sure Mem and MemAbove4G apertures are valid
139 //
140 if (RESOURCE_VALID (&Bridge->Mem)) {
141 ASSERT (Bridge->Mem.Limit < SIZE_4GB);
142 if (Bridge->Mem.Limit >= SIZE_4GB) {
143 return NULL;
144 }
145 }
146
147 if (RESOURCE_VALID (&Bridge->MemAbove4G)) {
148 ASSERT (Bridge->MemAbove4G.Base >= SIZE_4GB);
149 if (Bridge->MemAbove4G.Base < SIZE_4GB) {
150 return NULL;
151 }
152 }
153
154 if (RESOURCE_VALID (&Bridge->PMem)) {
155 ASSERT (Bridge->PMem.Limit < SIZE_4GB);
156 if (Bridge->PMem.Limit >= SIZE_4GB) {
157 return NULL;
158 }
159 }
160
161 if (RESOURCE_VALID (&Bridge->PMemAbove4G)) {
162 ASSERT (Bridge->PMemAbove4G.Base >= SIZE_4GB);
163 if (Bridge->PMemAbove4G.Base < SIZE_4GB) {
164 return NULL;
165 }
166 }
167
168 //
169 // Ignore AllocationAttributes when resources were already assigned.
170 //
171 if (!Bridge->ResourceAssigned) {
172 if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) {
173 //
174 // If this bit is set, then the PCI Root Bridge does not
175 // support separate windows for Non-prefetchable and Prefetchable
176 // memory.
177 //
178 ASSERT (!RESOURCE_VALID (&Bridge->PMem));
179 ASSERT (!RESOURCE_VALID (&Bridge->PMemAbove4G));
180 if (RESOURCE_VALID (&Bridge->PMem) || RESOURCE_VALID (&Bridge->PMemAbove4G)) {
181 return NULL;
182 }
183 }
184
185 if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) == 0) {
186 //
187 // If this bit is not set, then the PCI Root Bridge does not support
188 // 64 bit memory windows.
189 //
190 ASSERT (!RESOURCE_VALID (&Bridge->MemAbove4G));
191 ASSERT (!RESOURCE_VALID (&Bridge->PMemAbove4G));
192 if (RESOURCE_VALID (&Bridge->MemAbove4G) || RESOURCE_VALID (&Bridge->PMemAbove4G)) {
193 return NULL;
194 }
195 }
196 }
197
198 RootBridge = AllocateZeroPool (sizeof (PCI_ROOT_BRIDGE_INSTANCE));
199 ASSERT (RootBridge != NULL);
200
201 RootBridge->Signature = PCI_ROOT_BRIDGE_SIGNATURE;
202 RootBridge->Supports = Bridge->Supports;
203 RootBridge->Attributes = Bridge->Attributes;
204 RootBridge->DmaAbove4G = Bridge->DmaAbove4G;
205 RootBridge->NoExtendedConfigSpace = Bridge->NoExtendedConfigSpace;
206 RootBridge->AllocationAttributes = Bridge->AllocationAttributes;
207 RootBridge->DevicePath = DuplicateDevicePath (Bridge->DevicePath);
208 RootBridge->DevicePathStr = DevicePathStr;
209 RootBridge->ConfigBuffer = AllocatePool (
211 );
212 ASSERT (RootBridge->ConfigBuffer != NULL);
213 InitializeListHead (&RootBridge->Maps);
214
215 CopyMem (&RootBridge->Bus, &Bridge->Bus, sizeof (PCI_ROOT_BRIDGE_APERTURE));
216 CopyMem (&RootBridge->Io, &Bridge->Io, sizeof (PCI_ROOT_BRIDGE_APERTURE));
217 CopyMem (&RootBridge->Mem, &Bridge->Mem, sizeof (PCI_ROOT_BRIDGE_APERTURE));
218 CopyMem (&RootBridge->MemAbove4G, &Bridge->MemAbove4G, sizeof (PCI_ROOT_BRIDGE_APERTURE));
219 CopyMem (&RootBridge->PMem, &Bridge->PMem, sizeof (PCI_ROOT_BRIDGE_APERTURE));
220 CopyMem (&RootBridge->PMemAbove4G, &Bridge->PMemAbove4G, sizeof (PCI_ROOT_BRIDGE_APERTURE));
221
222 for (Index = TypeIo; Index < TypeMax; Index++) {
223 switch (Index) {
224 case TypeBus:
225 Aperture = &RootBridge->Bus;
226 break;
227 case TypeIo:
228 Aperture = &RootBridge->Io;
229 break;
230 case TypeMem32:
231 Aperture = &RootBridge->Mem;
232 break;
233 case TypeMem64:
234 Aperture = &RootBridge->MemAbove4G;
235 break;
236 case TypePMem32:
237 Aperture = &RootBridge->PMem;
238 break;
239 case TypePMem64:
240 Aperture = &RootBridge->PMemAbove4G;
241 break;
242 default:
243 ASSERT (FALSE);
244 Aperture = NULL;
245 break;
246 }
247
248 RootBridge->ResAllocNode[Index].Type = Index;
249 if (Bridge->ResourceAssigned && (Aperture->Limit >= Aperture->Base)) {
250 //
251 // Base in ResAllocNode is a host address, while Base in Aperture is a
252 // device address.
253 //
254 RootBridge->ResAllocNode[Index].Base = TO_HOST_ADDRESS (
255 Aperture->Base,
256 Aperture->Translation
257 );
258 RootBridge->ResAllocNode[Index].Length = Aperture->Limit - Aperture->Base + 1;
259 RootBridge->ResAllocNode[Index].Status = ResAllocated;
260 } else {
261 RootBridge->ResAllocNode[Index].Base = 0;
262 RootBridge->ResAllocNode[Index].Length = 0;
263 RootBridge->ResAllocNode[Index].Status = ResNone;
264 }
265 }
266
267 RootBridge->RootBridgeIo.SegmentNumber = Bridge->Segment;
268 RootBridge->RootBridgeIo.PollMem = RootBridgeIoPollMem;
269 RootBridge->RootBridgeIo.PollIo = RootBridgeIoPollIo;
270 RootBridge->RootBridgeIo.Mem.Read = RootBridgeIoMemRead;
271 RootBridge->RootBridgeIo.Mem.Write = RootBridgeIoMemWrite;
272 RootBridge->RootBridgeIo.Io.Read = RootBridgeIoIoRead;
273 RootBridge->RootBridgeIo.Io.Write = RootBridgeIoIoWrite;
274 RootBridge->RootBridgeIo.CopyMem = RootBridgeIoCopyMem;
275 RootBridge->RootBridgeIo.Pci.Read = RootBridgeIoPciRead;
276 RootBridge->RootBridgeIo.Pci.Write = RootBridgeIoPciWrite;
277 RootBridge->RootBridgeIo.Map = RootBridgeIoMap;
278 RootBridge->RootBridgeIo.Unmap = RootBridgeIoUnmap;
279 RootBridge->RootBridgeIo.AllocateBuffer = RootBridgeIoAllocateBuffer;
280 RootBridge->RootBridgeIo.FreeBuffer = RootBridgeIoFreeBuffer;
281 RootBridge->RootBridgeIo.Flush = RootBridgeIoFlush;
282 RootBridge->RootBridgeIo.GetAttributes = RootBridgeIoGetAttributes;
283 RootBridge->RootBridgeIo.SetAttributes = RootBridgeIoSetAttributes;
284 RootBridge->RootBridgeIo.Configuration = RootBridgeIoConfiguration;
285
286 return RootBridge;
287}
288
331 IN OPERATION_TYPE OperationType,
333 IN UINT64 Address,
334 IN UINTN Count,
335 IN VOID *Buffer
336 )
337{
338 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
340 UINT64 Base;
341 UINT64 Limit;
342 UINT32 Size;
343 UINT64 Length;
344
345 //
346 // Check to see if Buffer is NULL
347 //
348 if (Buffer == NULL) {
349 return EFI_INVALID_PARAMETER;
350 }
351
352 //
353 // Check to see if Width is in the valid range
354 //
355 if ((UINT32)Width >= EfiPciWidthMaximum) {
356 return EFI_INVALID_PARAMETER;
357 }
358
359 //
360 // For FIFO type, the device address won't increase during the access,
361 // so treat Count as 1
362 //
363 if ((Width >= EfiPciWidthFifoUint8) && (Width <= EfiPciWidthFifoUint64)) {
364 Count = 1;
365 }
366
367 Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);
368 Size = 1 << Width;
369
370 //
371 // Make sure (Count * Size) doesn't exceed MAX_UINT64
372 //
373 if (Count > DivU64x32 (MAX_UINT64, Size)) {
374 return EFI_INVALID_PARAMETER;
375 }
376
377 //
378 // Check to see if Address is aligned
379 //
380 if ((Address & (Size - 1)) != 0) {
381 return EFI_UNSUPPORTED;
382 }
383
384 //
385 // Make sure (Address + Count * Size) doesn't exceed MAX_UINT64
386 //
387 Length = MultU64x32 (Count, Size);
388 if (Address > MAX_UINT64 - Length) {
389 return EFI_INVALID_PARAMETER;
390 }
391
392 RootBridge = ROOT_BRIDGE_FROM_THIS (This);
393
394 //
395 // Check to see if any address associated with this transfer exceeds the
396 // maximum allowed address. The maximum address implied by the parameters
397 // passed in is Address + Size * Count. If the following condition is met,
398 // then the transfer is not supported.
399 //
400 // Address + Size * Count > Limit + 1
401 //
402 // Since Limit can be the maximum integer value supported by the CPU and
403 // Count can also be the maximum integer value supported by the CPU, this
404 // range check must be adjusted to avoid all oveflow conditions.
405 //
406 if (OperationType == IoOperation) {
407 //
408 // Allow Legacy IO access
409 //
410 if (Address + Length <= 0x1000) {
411 if ((RootBridge->Attributes & (
412 EFI_PCI_ATTRIBUTE_ISA_IO | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_ATTRIBUTE_VGA_IO |
413 EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |
414 EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16 | EFI_PCI_ATTRIBUTE_VGA_IO_16)) != 0)
415 {
416 return EFI_SUCCESS;
417 }
418 }
419
420 Base = RootBridge->Io.Base;
421 Limit = RootBridge->Io.Limit;
422 } else if (OperationType == MemOperation) {
423 //
424 // Allow Legacy MMIO access
425 //
426 if ((Address >= 0xA0000) && ((Address + Length) <= 0xC0000)) {
427 if ((RootBridge->Attributes & EFI_PCI_ATTRIBUTE_VGA_MEMORY) != 0) {
428 return EFI_SUCCESS;
429 }
430 }
431
432 //
433 // By comparing the Address against Limit we know which range to be used
434 // for checking
435 //
436 if ((Address >= RootBridge->Mem.Base) && (Address + Length <= RootBridge->Mem.Limit + 1)) {
437 Base = RootBridge->Mem.Base;
438 Limit = RootBridge->Mem.Limit;
439 } else if ((Address >= RootBridge->PMem.Base) && (Address + Length <= RootBridge->PMem.Limit + 1)) {
440 Base = RootBridge->PMem.Base;
441 Limit = RootBridge->PMem.Limit;
442 } else if ((Address >= RootBridge->MemAbove4G.Base) && (Address + Length <= RootBridge->MemAbove4G.Limit + 1)) {
443 Base = RootBridge->MemAbove4G.Base;
444 Limit = RootBridge->MemAbove4G.Limit;
445 } else {
446 Base = RootBridge->PMemAbove4G.Base;
447 Limit = RootBridge->PMemAbove4G.Limit;
448 }
449 } else {
450 PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&Address;
451 if ((PciRbAddr->Bus < RootBridge->Bus.Base) ||
452 (PciRbAddr->Bus > RootBridge->Bus.Limit))
453 {
454 return EFI_INVALID_PARAMETER;
455 }
456
457 if ((PciRbAddr->Device > PCI_MAX_DEVICE) ||
458 (PciRbAddr->Function > PCI_MAX_FUNC))
459 {
460 return EFI_INVALID_PARAMETER;
461 }
462
463 if (PciRbAddr->ExtendedRegister != 0) {
464 Address = PciRbAddr->ExtendedRegister;
465 } else {
466 Address = PciRbAddr->Register;
467 }
468
469 Base = 0;
470 Limit = RootBridge->NoExtendedConfigSpace ? 0xFF : 0xFFF;
471 }
472
473 if (Address < Base) {
474 return EFI_INVALID_PARAMETER;
475 }
476
477 if (Address + Length > Limit + 1) {
478 return EFI_INVALID_PARAMETER;
479 }
480
481 return EFI_SUCCESS;
482}
483
498 IN PCI_ROOT_BRIDGE_INSTANCE *RootBridge,
499 IN UINT64 Address,
500 IN OUT UINT64 *Translation
501 )
502{
503 if ((Address >= RootBridge->Mem.Base) && (Address <= RootBridge->Mem.Limit)) {
504 *Translation = RootBridge->Mem.Translation;
505 } else if ((Address >= RootBridge->PMem.Base) && (Address <= RootBridge->PMem.Limit)) {
506 *Translation = RootBridge->PMem.Translation;
507 } else if ((Address >= RootBridge->MemAbove4G.Base) && (Address <= RootBridge->MemAbove4G.Limit)) {
508 *Translation = RootBridge->MemAbove4G.Translation;
509 } else if ((Address >= RootBridge->PMemAbove4G.Base) && (Address <= RootBridge->PMemAbove4G.Limit)) {
510 *Translation = RootBridge->PMemAbove4G.Translation;
511 } else {
512 return EFI_INVALID_PARAMETER;
513 }
514
515 return EFI_SUCCESS;
516}
517
529UINT64
531 IN UINT64 Multiplicand,
532 IN UINT64 Multiplier,
533 IN UINT32 Divisor,
534 OUT UINT32 *Remainder OPTIONAL
535 )
536{
537 UINT64 Uint64;
538 UINT32 LocalRemainder;
539 UINT32 Uint32;
540
541 if (Multiplicand > DivU64x64Remainder (MAX_UINT64, Multiplier, NULL)) {
542 //
543 // Make sure Multiplicand is the bigger one.
544 //
545 if (Multiplicand < Multiplier) {
546 Uint64 = Multiplicand;
547 Multiplicand = Multiplier;
548 Multiplier = Uint64;
549 }
550
551 //
552 // Because Multiplicand * Multiplier overflows,
553 // Multiplicand * Multiplier / Divisor
554 // = (2 * Multiplicand' + 1) * Multiplier / Divisor
555 // = 2 * (Multiplicand' * Multiplier / Divisor) + Multiplier / Divisor
556 //
557 Uint64 = MultThenDivU64x64x32 (RShiftU64 (Multiplicand, 1), Multiplier, Divisor, &LocalRemainder);
558 Uint64 = LShiftU64 (Uint64, 1);
559 Uint32 = 0;
560 if ((Multiplicand & 0x1) == 1) {
561 Uint64 += DivU64x32Remainder (Multiplier, Divisor, &Uint32);
562 }
563
564 return Uint64 + DivU64x32Remainder (Uint32 + LShiftU64 (LocalRemainder, 1), Divisor, Remainder);
565 } else {
566 return DivU64x32Remainder (MultU64x64 (Multiplicand, Multiplier), Divisor, Remainder);
567 }
568}
569
582UINT64
584 UINT64 *CurrentTick,
585 UINT64 StartTick,
586 UINT64 EndTick
587 )
588{
589 UINT64 PreviousTick;
590
591 PreviousTick = *CurrentTick;
592 *CurrentTick = GetPerformanceCounter ();
593 if (StartTick < EndTick) {
594 return *CurrentTick - PreviousTick;
595 } else {
596 return PreviousTick - *CurrentTick;
597 }
598}
599
635EFIAPI
639 IN UINT64 Address,
640 IN UINT64 Mask,
641 IN UINT64 Value,
642 IN UINT64 Delay,
643 OUT UINT64 *Result
644 )
645{
646 EFI_STATUS Status;
647 UINT64 NumberOfTicks;
648 UINT32 Remainder;
649 UINT64 StartTick;
650 UINT64 EndTick;
651 UINT64 CurrentTick;
652 UINT64 ElapsedTick;
653 UINT64 Frequency;
654
655 if (Result == NULL) {
656 return EFI_INVALID_PARAMETER;
657 }
658
659 if ((UINT32)Width > EfiPciWidthUint64) {
660 return EFI_INVALID_PARAMETER;
661 }
662
663 //
664 // No matter what, always do a single poll.
665 //
666 Status = This->Mem.Read (This, Width, Address, 1, Result);
667 if (EFI_ERROR (Status)) {
668 return Status;
669 }
670
671 if ((*Result & Mask) == Value) {
672 return EFI_SUCCESS;
673 }
674
675 if (Delay == 0) {
676 return EFI_SUCCESS;
677 } else {
678 //
679 // NumberOfTicks = Frenquency * Delay / EFI_TIMER_PERIOD_SECONDS(1)
680 //
681 Frequency = GetPerformanceCounterProperties (&StartTick, &EndTick);
682 NumberOfTicks = MultThenDivU64x64x32 (Frequency, Delay, (UINT32)EFI_TIMER_PERIOD_SECONDS (1), &Remainder);
683 if (Remainder >= (UINTN)EFI_TIMER_PERIOD_SECONDS (1) / 2) {
684 NumberOfTicks++;
685 }
686
687 for ( ElapsedTick = 0, CurrentTick = GetPerformanceCounter ()
688 ; ElapsedTick <= NumberOfTicks
689 ; ElapsedTick += GetElapsedTick (&CurrentTick, StartTick, EndTick)
690 )
691 {
692 Status = This->Mem.Read (This, Width, Address, 1, Result);
693 if (EFI_ERROR (Status)) {
694 return Status;
695 }
696
697 if ((*Result & Mask) == Value) {
698 return EFI_SUCCESS;
699 }
700 }
701 }
702
703 return EFI_TIMEOUT;
704}
705
739EFIAPI
743 IN UINT64 Address,
744 IN UINT64 Mask,
745 IN UINT64 Value,
746 IN UINT64 Delay,
747 OUT UINT64 *Result
748 )
749{
750 EFI_STATUS Status;
751 UINT64 NumberOfTicks;
752 UINT32 Remainder;
753 UINT64 StartTick;
754 UINT64 EndTick;
755 UINT64 CurrentTick;
756 UINT64 ElapsedTick;
757 UINT64 Frequency;
758
759 //
760 // No matter what, always do a single poll.
761 //
762
763 if (Result == NULL) {
764 return EFI_INVALID_PARAMETER;
765 }
766
767 if ((UINT32)Width > EfiPciWidthUint64) {
768 return EFI_INVALID_PARAMETER;
769 }
770
771 Status = This->Io.Read (This, Width, Address, 1, Result);
772 if (EFI_ERROR (Status)) {
773 return Status;
774 }
775
776 if ((*Result & Mask) == Value) {
777 return EFI_SUCCESS;
778 }
779
780 if (Delay == 0) {
781 return EFI_SUCCESS;
782 } else {
783 //
784 // NumberOfTicks = Frenquency * Delay / EFI_TIMER_PERIOD_SECONDS(1)
785 //
786 Frequency = GetPerformanceCounterProperties (&StartTick, &EndTick);
787 NumberOfTicks = MultThenDivU64x64x32 (Frequency, Delay, (UINT32)EFI_TIMER_PERIOD_SECONDS (1), &Remainder);
788 if (Remainder >= (UINTN)EFI_TIMER_PERIOD_SECONDS (1) / 2) {
789 NumberOfTicks++;
790 }
791
792 for ( ElapsedTick = 0, CurrentTick = GetPerformanceCounter ()
793 ; ElapsedTick <= NumberOfTicks
794 ; ElapsedTick += GetElapsedTick (&CurrentTick, StartTick, EndTick)
795 )
796 {
797 Status = This->Io.Read (This, Width, Address, 1, Result);
798 if (EFI_ERROR (Status)) {
799 return Status;
800 }
801
802 if ((*Result & Mask) == Value) {
803 return EFI_SUCCESS;
804 }
805 }
806 }
807
808 return EFI_TIMEOUT;
809}
810
839EFIAPI
843 IN UINT64 Address,
844 IN UINTN Count,
845 OUT VOID *Buffer
846 )
847{
848 EFI_STATUS Status;
849 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
850 UINT64 Translation;
851
853 This,
854 MemOperation,
855 Width,
856 Address,
857 Count,
858 Buffer
859 );
860 if (EFI_ERROR (Status)) {
861 return Status;
862 }
863
864 RootBridge = ROOT_BRIDGE_FROM_THIS (This);
865 Status = RootBridgeIoGetMemTranslationByAddress (RootBridge, Address, &Translation);
866 if (EFI_ERROR (Status)) {
867 return Status;
868 }
869
870 // Address passed to CpuIo->Mem.Read needs to be a host address instead of
871 // device address.
872 return mCpuIo->Mem.Read (
873 mCpuIo,
875 TO_HOST_ADDRESS (Address, Translation),
876 Count,
877 Buffer
878 );
879}
880
909EFIAPI
913 IN UINT64 Address,
914 IN UINTN Count,
915 IN VOID *Buffer
916 )
917{
918 EFI_STATUS Status;
919 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
920 UINT64 Translation;
921
923 This,
924 MemOperation,
925 Width,
926 Address,
927 Count,
928 Buffer
929 );
930 if (EFI_ERROR (Status)) {
931 return Status;
932 }
933
934 RootBridge = ROOT_BRIDGE_FROM_THIS (This);
935 Status = RootBridgeIoGetMemTranslationByAddress (RootBridge, Address, &Translation);
936 if (EFI_ERROR (Status)) {
937 return Status;
938 }
939
940 // Address passed to CpuIo->Mem.Write needs to be a host address instead of
941 // device address.
942 return mCpuIo->Mem.Write (
943 mCpuIo,
945 TO_HOST_ADDRESS (Address, Translation),
946 Count,
947 Buffer
948 );
949}
950
973EFIAPI
977 IN UINT64 Address,
978 IN UINTN Count,
979 OUT VOID *Buffer
980 )
981{
982 EFI_STATUS Status;
983 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
984
986 This,
987 IoOperation,
988 Width,
989 Address,
990 Count,
991 Buffer
992 );
993 if (EFI_ERROR (Status)) {
994 return Status;
995 }
996
997 RootBridge = ROOT_BRIDGE_FROM_THIS (This);
998
999 // Address passed to CpuIo->Io.Read needs to be a host address instead of
1000 // device address.
1001 return mCpuIo->Io.Read (
1002 mCpuIo,
1004 TO_HOST_ADDRESS (Address, RootBridge->Io.Translation),
1005 Count,
1006 Buffer
1007 );
1008}
1009
1032EFIAPI
1036 IN UINT64 Address,
1037 IN UINTN Count,
1038 IN VOID *Buffer
1039 )
1040{
1041 EFI_STATUS Status;
1042 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
1043
1045 This,
1046 IoOperation,
1047 Width,
1048 Address,
1049 Count,
1050 Buffer
1051 );
1052 if (EFI_ERROR (Status)) {
1053 return Status;
1054 }
1055
1056 RootBridge = ROOT_BRIDGE_FROM_THIS (This);
1057
1058 // Address passed to CpuIo->Io.Write needs to be a host address instead of
1059 // device address.
1060 return mCpuIo->Io.Write (
1061 mCpuIo,
1063 TO_HOST_ADDRESS (Address, RootBridge->Io.Translation),
1064 Count,
1065 Buffer
1066 );
1067}
1068
1101EFIAPI
1105 IN UINT64 DestAddress,
1106 IN UINT64 SrcAddress,
1107 IN UINTN Count
1108 )
1109{
1110 EFI_STATUS Status;
1111 BOOLEAN Forward;
1112 UINTN Stride;
1113 UINTN Index;
1114 UINT64 Result;
1115
1116 if ((UINT32)Width > EfiPciWidthUint64) {
1117 return EFI_INVALID_PARAMETER;
1118 }
1119
1120 if (DestAddress == SrcAddress) {
1121 return EFI_SUCCESS;
1122 }
1123
1124 Stride = (UINTN)(1 << Width);
1125
1126 Forward = TRUE;
1127 if ((DestAddress > SrcAddress) &&
1128 (DestAddress < (SrcAddress + Count * Stride)))
1129 {
1130 Forward = FALSE;
1131 SrcAddress = SrcAddress + (Count - 1) * Stride;
1132 DestAddress = DestAddress + (Count - 1) * Stride;
1133 }
1134
1135 for (Index = 0; Index < Count; Index++) {
1136 Status = RootBridgeIoMemRead (
1137 This,
1138 Width,
1139 SrcAddress,
1140 1,
1141 &Result
1142 );
1143 if (EFI_ERROR (Status)) {
1144 return Status;
1145 }
1146
1147 Status = RootBridgeIoMemWrite (
1148 This,
1149 Width,
1150 DestAddress,
1151 1,
1152 &Result
1153 );
1154 if (EFI_ERROR (Status)) {
1155 return Status;
1156 }
1157
1158 if (Forward) {
1159 SrcAddress += Stride;
1160 DestAddress += Stride;
1161 } else {
1162 SrcAddress -= Stride;
1163 DestAddress -= Stride;
1164 }
1165 }
1166
1167 return EFI_SUCCESS;
1168}
1169
1186EFIAPI
1189 IN BOOLEAN Read,
1191 IN UINT64 Address,
1192 IN UINTN Count,
1193 IN OUT VOID *Buffer
1194 )
1195{
1196 EFI_STATUS Status;
1197 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
1199 UINT8 *Uint8Buffer;
1200 UINT8 InStride;
1201 UINT8 OutStride;
1202 UINTN Size;
1203
1204 Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer);
1205 if (EFI_ERROR (Status)) {
1206 return Status;
1207 }
1208
1209 //
1210 // Read Pci configuration space
1211 //
1212 RootBridge = ROOT_BRIDGE_FROM_THIS (This);
1213 CopyMem (&PciAddress, &Address, sizeof (PciAddress));
1214
1215 if (PciAddress.ExtendedRegister == 0) {
1216 PciAddress.ExtendedRegister = PciAddress.Register;
1217 }
1218
1219 Address = PCI_SEGMENT_LIB_ADDRESS (
1220 RootBridge->RootBridgeIo.SegmentNumber,
1221 PciAddress.Bus,
1222 PciAddress.Device,
1223 PciAddress.Function,
1224 PciAddress.ExtendedRegister
1225 );
1226
1227 //
1228 // Select loop based on the width of the transfer
1229 //
1230 InStride = mInStride[Width];
1231 OutStride = mOutStride[Width];
1232 Size = (UINTN)(1 << (Width & 0x03));
1233 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
1234 if (Read) {
1235 PciSegmentReadBuffer (Address, Size, Uint8Buffer);
1236 } else {
1237 PciSegmentWriteBuffer (Address, Size, Uint8Buffer);
1238 }
1239 }
1240
1241 //
1242 // If the access was a PCI write, it might have side effects that impact how
1243 // the PCI device decodes its MMIO regions. Issue a barrier to ensure that
1244 // subsequent MMIO accesses to those regions will not be reordered, and will
1245 // not arrive before the PCI write.
1246 //
1247 if (!Read) {
1248 MemoryFence ();
1249 }
1250
1251 return EFI_SUCCESS;
1252}
1253
1269EFIAPI
1273 IN UINT64 Address,
1274 IN UINTN Count,
1275 IN OUT VOID *Buffer
1276 )
1277{
1278 return RootBridgeIoPciAccess (This, TRUE, Width, Address, Count, Buffer);
1279}
1280
1296EFIAPI
1300 IN UINT64 Address,
1301 IN UINTN Count,
1302 IN OUT VOID *Buffer
1303 )
1304{
1305 return RootBridgeIoPciAccess (This, FALSE, Width, Address, Count, Buffer);
1306}
1307
1330EFIAPI
1334 IN VOID *HostAddress,
1335 IN OUT UINTN *NumberOfBytes,
1336 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
1337 OUT VOID **Mapping
1338 )
1339{
1340 EFI_STATUS Status;
1341 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
1342 EFI_PHYSICAL_ADDRESS PhysicalAddress;
1343 MAP_INFO *MapInfo;
1344
1345 if ((HostAddress == NULL) || (NumberOfBytes == NULL) || (DeviceAddress == NULL) ||
1346 (Mapping == NULL))
1347 {
1348 return EFI_INVALID_PARAMETER;
1349 }
1350
1351 //
1352 // Make sure that Operation is valid
1353 //
1354 if ((UINT32)Operation >= EfiPciOperationMaximum) {
1355 return EFI_INVALID_PARAMETER;
1356 }
1357
1358 RootBridge = ROOT_BRIDGE_FROM_THIS (This);
1359
1360 if (mIoMmu != NULL) {
1361 if (!RootBridge->DmaAbove4G) {
1362 //
1363 // Clear 64bit support
1364 //
1365 if (Operation > EfiPciOperationBusMasterCommonBuffer) {
1367 }
1368 }
1369
1370 Status = mIoMmu->Map (
1371 mIoMmu,
1372 (EDKII_IOMMU_OPERATION)Operation,
1373 HostAddress,
1374 NumberOfBytes,
1375 DeviceAddress,
1376 Mapping
1377 );
1378 return Status;
1379 }
1380
1381 PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress;
1382 if ((!RootBridge->DmaAbove4G ||
1383 ((Operation != EfiPciOperationBusMasterRead64) &&
1384 (Operation != EfiPciOperationBusMasterWrite64) &&
1385 (Operation != EfiPciOperationBusMasterCommonBuffer64))) &&
1386 ((PhysicalAddress + *NumberOfBytes) > SIZE_4GB))
1387 {
1388 //
1389 // If the root bridge or the device cannot handle performing DMA above
1390 // 4GB but any part of the DMA transfer being mapped is above 4GB, then
1391 // map the DMA transfer to a buffer below 4GB.
1392 //
1393
1394 if ((Operation == EfiPciOperationBusMasterCommonBuffer) ||
1396 {
1397 //
1398 // Common Buffer operations can not be remapped. If the common buffer
1399 // if above 4GB, then it is not possible to generate a mapping, so return
1400 // an error.
1401 //
1402 return EFI_UNSUPPORTED;
1403 }
1404
1405 //
1406 // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
1407 // called later.
1408 //
1409 MapInfo = AllocatePool (sizeof (MAP_INFO));
1410 if (MapInfo == NULL) {
1411 *NumberOfBytes = 0;
1412 return EFI_OUT_OF_RESOURCES;
1413 }
1414
1415 //
1416 // Initialize the MAP_INFO structure
1417 //
1418 MapInfo->Signature = MAP_INFO_SIGNATURE;
1419 MapInfo->Operation = Operation;
1420 MapInfo->NumberOfBytes = *NumberOfBytes;
1421 MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes);
1422 MapInfo->HostAddress = PhysicalAddress;
1423 MapInfo->MappedHostAddress = SIZE_4GB - 1;
1424
1425 //
1426 // Allocate a buffer below 4GB to map the transfer to.
1427 //
1428 Status = gBS->AllocatePages (
1431 MapInfo->NumberOfPages,
1432 &MapInfo->MappedHostAddress
1433 );
1434 if (EFI_ERROR (Status)) {
1435 FreePool (MapInfo);
1436 *NumberOfBytes = 0;
1437 return Status;
1438 }
1439
1440 //
1441 // If this is a read operation from the Bus Master's point of view,
1442 // then copy the contents of the real buffer into the mapped buffer
1443 // so the Bus Master can read the contents of the real buffer.
1444 //
1445 if ((Operation == EfiPciOperationBusMasterRead) ||
1446 (Operation == EfiPciOperationBusMasterRead64))
1447 {
1448 CopyMem (
1449 (VOID *)(UINTN)MapInfo->MappedHostAddress,
1450 (VOID *)(UINTN)MapInfo->HostAddress,
1451 MapInfo->NumberOfBytes
1452 );
1453 }
1454
1455 InsertTailList (&RootBridge->Maps, &MapInfo->Link);
1456
1457 //
1458 // The DeviceAddress is the address of the maped buffer below 4GB
1459 //
1460 *DeviceAddress = MapInfo->MappedHostAddress;
1461 //
1462 // Return a pointer to the MAP_INFO structure in Mapping
1463 //
1464 *Mapping = MapInfo;
1465 } else {
1466 //
1467 // If the root bridge CAN handle performing DMA above 4GB or
1468 // the transfer is below 4GB, so the DeviceAddress is simply the
1469 // HostAddress
1470 //
1471 *DeviceAddress = PhysicalAddress;
1472 *Mapping = NO_MAPPING;
1473 }
1474
1475 return EFI_SUCCESS;
1476}
1477
1496EFIAPI
1499 IN VOID *Mapping
1500 )
1501{
1502 MAP_INFO *MapInfo;
1503 LIST_ENTRY *Link;
1504 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
1505 EFI_STATUS Status;
1506
1507 if (mIoMmu != NULL) {
1508 Status = mIoMmu->Unmap (
1509 mIoMmu,
1510 Mapping
1511 );
1512 return Status;
1513 }
1514
1515 RootBridge = ROOT_BRIDGE_FROM_THIS (This);
1516
1517 //
1518 // See if the Map() operation associated with this Unmap() required a mapping
1519 // buffer. If a mapping buffer was not required, then this function simply
1520 // returns EFI_SUCCESS.
1521 //
1522 if (Mapping == NO_MAPPING) {
1523 return EFI_SUCCESS;
1524 }
1525
1526 MapInfo = NO_MAPPING;
1527 for (Link = GetFirstNode (&RootBridge->Maps)
1528 ; !IsNull (&RootBridge->Maps, Link)
1529 ; Link = GetNextNode (&RootBridge->Maps, Link)
1530 )
1531 {
1532 MapInfo = MAP_INFO_FROM_LINK (Link);
1533 if (MapInfo == Mapping) {
1534 break;
1535 }
1536 }
1537
1538 //
1539 // Mapping is not a valid value returned by Map()
1540 //
1541 if (MapInfo != Mapping) {
1542 return EFI_INVALID_PARAMETER;
1543 }
1544
1545 RemoveEntryList (&MapInfo->Link);
1546
1547 //
1548 // If this is a write operation from the Bus Master's point of view,
1549 // then copy the contents of the mapped buffer into the real buffer
1550 // so the processor can read the contents of the real buffer.
1551 //
1552 if ((MapInfo->Operation == EfiPciOperationBusMasterWrite) ||
1553 (MapInfo->Operation == EfiPciOperationBusMasterWrite64))
1554 {
1555 CopyMem (
1556 (VOID *)(UINTN)MapInfo->HostAddress,
1557 (VOID *)(UINTN)MapInfo->MappedHostAddress,
1558 MapInfo->NumberOfBytes
1559 );
1560 }
1561
1562 //
1563 // Free the mapped buffer and the MAP_INFO structure.
1564 //
1565 gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
1566 FreePool (Mapping);
1567 return EFI_SUCCESS;
1568}
1569
1597EFIAPI
1600 IN EFI_ALLOCATE_TYPE Type,
1601 IN EFI_MEMORY_TYPE MemoryType,
1602 IN UINTN Pages,
1603 OUT VOID **HostAddress,
1604 IN UINT64 Attributes
1605 )
1606{
1607 EFI_STATUS Status;
1608 EFI_PHYSICAL_ADDRESS PhysicalAddress;
1609 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
1610 EFI_ALLOCATE_TYPE AllocateType;
1611
1612 //
1613 // Validate Attributes
1614 //
1615 if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
1616 return EFI_UNSUPPORTED;
1617 }
1618
1619 //
1620 // Check for invalid inputs
1621 //
1622 if (HostAddress == NULL) {
1623 return EFI_INVALID_PARAMETER;
1624 }
1625
1626 //
1627 // The only valid memory types are EfiBootServicesData and
1628 // EfiRuntimeServicesData
1629 //
1630 if ((MemoryType != EfiBootServicesData) &&
1631 (MemoryType != EfiRuntimeServicesData))
1632 {
1633 return EFI_INVALID_PARAMETER;
1634 }
1635
1636 RootBridge = ROOT_BRIDGE_FROM_THIS (This);
1637
1638 if (mIoMmu != NULL) {
1639 if (!RootBridge->DmaAbove4G) {
1640 //
1641 // Clear DUAL_ADDRESS_CYCLE
1642 //
1643 Attributes &= ~((UINT64)EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE);
1644 }
1645
1646 Status = mIoMmu->AllocateBuffer (
1647 mIoMmu,
1648 Type,
1649 MemoryType,
1650 Pages,
1651 HostAddress,
1652 Attributes
1653 );
1654 return Status;
1655 }
1656
1657 AllocateType = AllocateAnyPages;
1658 if (!RootBridge->DmaAbove4G ||
1659 ((Attributes & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0))
1660 {
1661 //
1662 // Limit allocations to memory below 4GB
1663 //
1664 AllocateType = AllocateMaxAddress;
1665 PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(SIZE_4GB - 1);
1666 }
1667
1668 Status = gBS->AllocatePages (
1669 AllocateType,
1670 MemoryType,
1671 Pages,
1672 &PhysicalAddress
1673 );
1674 if (!EFI_ERROR (Status)) {
1675 *HostAddress = (VOID *)(UINTN)PhysicalAddress;
1676 }
1677
1678 return Status;
1679}
1680
1696EFIAPI
1699 IN UINTN Pages,
1700 OUT VOID *HostAddress
1701 )
1702{
1703 EFI_STATUS Status;
1704
1705 if (mIoMmu != NULL) {
1706 Status = mIoMmu->FreeBuffer (
1707 mIoMmu,
1708 Pages,
1709 HostAddress
1710 );
1711 return Status;
1712 }
1713
1714 return gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, Pages);
1715}
1716
1739EFIAPI
1742 )
1743{
1744 return EFI_SUCCESS;
1745}
1746
1770EFIAPI
1773 OUT UINT64 *Supported,
1774 OUT UINT64 *Attributes
1775 )
1776{
1777 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
1778
1779 if ((Attributes == NULL) && (Supported == NULL)) {
1780 return EFI_INVALID_PARAMETER;
1781 }
1782
1783 RootBridge = ROOT_BRIDGE_FROM_THIS (This);
1784 //
1785 // Set the return value for Supported and Attributes
1786 //
1787 if (Supported != NULL) {
1788 *Supported = RootBridge->Supports;
1789 }
1790
1791 if (Attributes != NULL) {
1792 *Attributes = RootBridge->Attributes;
1793 }
1794
1795 return EFI_SUCCESS;
1796}
1797
1835EFIAPI
1838 IN UINT64 Attributes,
1839 IN OUT UINT64 *ResourceBase,
1840 IN OUT UINT64 *ResourceLength
1841 )
1842{
1843 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
1844
1845 RootBridge = ROOT_BRIDGE_FROM_THIS (This);
1846
1847 if ((Attributes & (~RootBridge->Supports)) != 0) {
1848 return EFI_UNSUPPORTED;
1849 }
1850
1851 RootBridge->Attributes = Attributes;
1852 return EFI_SUCCESS;
1853}
1854
1881EFIAPI
1884 OUT VOID **Resources
1885 )
1886{
1887 PCI_RESOURCE_TYPE Index;
1888 PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
1889 PCI_RES_NODE *ResAllocNode;
1892
1893 //
1894 // Get this instance of the Root Bridge.
1895 //
1896 RootBridge = ROOT_BRIDGE_FROM_THIS (This);
1897 ZeroMem (
1898 RootBridge->ConfigBuffer,
1900 );
1901 Descriptor = RootBridge->ConfigBuffer;
1902 for (Index = TypeIo; Index < TypeMax; Index++) {
1903 ResAllocNode = &RootBridge->ResAllocNode[Index];
1904
1905 if (ResAllocNode->Status != ResAllocated) {
1906 continue;
1907 }
1908
1909 Descriptor->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
1910 Descriptor->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
1911 // According to UEFI 2.7, RootBridgeIo->Configuration should return address
1912 // range in CPU view (host address), and ResAllocNode->Base is already a CPU
1913 // view address (host address).
1914 Descriptor->AddrRangeMin = ResAllocNode->Base;
1915 Descriptor->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;
1916 Descriptor->AddrLen = ResAllocNode->Length;
1917 Descriptor->AddrTranslationOffset = GetTranslationByResourceType (
1918 RootBridge,
1919 ResAllocNode->Type
1920 );
1921
1922 switch (ResAllocNode->Type) {
1923 case TypeIo:
1924 Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
1925 break;
1926
1927 case TypePMem32:
1928 Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
1929 case TypeMem32:
1930 Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
1931 Descriptor->AddrSpaceGranularity = 32;
1932 break;
1933
1934 case TypePMem64:
1935 Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
1936 case TypeMem64:
1937 Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
1938 Descriptor->AddrSpaceGranularity = 64;
1939 break;
1940
1941 case TypeBus:
1942 Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS;
1943 break;
1944
1945 default:
1946 break;
1947 }
1948
1949 Descriptor++;
1950 }
1951
1952 //
1953 // Terminate the entries.
1954 //
1955 End = (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor;
1956 End->Desc = ACPI_END_TAG_DESCRIPTOR;
1957 End->Checksum = 0x0;
1958
1959 *Resources = RootBridge->ConfigBuffer;
1960 return EFI_SUCCESS;
1961}
UINT64 UINTN
PACKED struct @89 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
UINT64 EFIAPI GetPerformanceCounterProperties(OUT UINT64 *StartValue OPTIONAL, OUT UINT64 *EndValue OPTIONAL)
UINT64 EFIAPI GetPerformanceCounter(VOID)
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
UINT64 EFIAPI MultU64x64(IN UINT64 Multiplicand, IN UINT64 Multiplier)
Definition: MultU64x64.c:27
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
VOID EFIAPI MemoryFence(VOID)
Definition: CpuBreakpoint.c:42
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
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
UINT64 EFIAPI DivU64x32Remainder(IN UINT64 Dividend, IN UINT32 Divisor, OUT UINT32 *Remainder OPTIONAL)
UINT64 EFIAPI DivU64x64Remainder(IN UINT64 Dividend, IN UINT64 Divisor, OUT UINT64 *Remainder OPTIONAL)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_CPU_IO_PROTOCOL_WIDTH
Definition: CpuIo2.h:37
CHAR16 *EFIAPI ConvertDevicePathToText(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN BOOLEAN DisplayOnly, IN BOOLEAN AllowShortcuts)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DuplicateDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
UINTN EFIAPI PciSegmentReadBuffer(IN UINT64 StartAddress, IN UINTN Size, OUT VOID *Buffer)
#define PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, Register)
Definition: PciSegmentLib.h:51
UINTN EFIAPI PciSegmentWriteBuffer(IN UINT64 StartAddress, IN UINTN Size, IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#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 DEBUG(Expression)
Definition: DebugLib.h:434
UINT64 GetTranslationByResourceType(IN PCI_ROOT_BRIDGE_INSTANCE *RootBridge, IN PCI_RESOURCE_TYPE ResourceType)
Definition: PciHostBridge.c:36
#define EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
#define EFI_PCI_HOST_BRIDGE_MEM64_DECODE
EFI_STATUS EFIAPI RootBridgeIoPollMem(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINT64 Mask, IN UINT64 Value, IN UINT64 Delay, OUT UINT64 *Result)
EFI_STATUS EFIAPI RootBridgeIoMemRead(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINTN Count, OUT VOID *Buffer)
EFI_STATUS EFIAPI RootBridgeIoUnmap(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN VOID *Mapping)
PCI_ROOT_BRIDGE_INSTANCE * CreateRootBridge(IN PCI_ROOT_BRIDGE *Bridge)
UINT64 GetElapsedTick(UINT64 *CurrentTick, UINT64 StartTick, UINT64 EndTick)
EFI_STATUS EFIAPI RootBridgeIoPciWrite(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN OUT VOID *Buffer)
EFI_STATUS EFIAPI RootBridgeIoIoRead(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINTN Count, OUT VOID *Buffer)
EFI_STATUS EFIAPI RootBridgeIoSetAttributes(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN UINT64 Attributes, IN OUT UINT64 *ResourceBase, IN OUT UINT64 *ResourceLength)
EFI_STATUS EFIAPI RootBridgeIoPciAccess(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN BOOLEAN Read, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN OUT VOID *Buffer)
EFI_STATUS RootBridgeIoGetMemTranslationByAddress(IN PCI_ROOT_BRIDGE_INSTANCE *RootBridge, IN UINT64 Address, IN OUT UINT64 *Translation)
EFI_STATUS EFIAPI RootBridgeIoGetAttributes(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, OUT UINT64 *Supported, OUT UINT64 *Attributes)
UINT64 MultThenDivU64x64x32(IN UINT64 Multiplicand, IN UINT64 Multiplier, IN UINT32 Divisor, OUT UINT32 *Remainder OPTIONAL)
EFI_STATUS EFIAPI RootBridgeIoFreeBuffer(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN UINTN Pages, OUT VOID *HostAddress)
EFI_STATUS EFIAPI RootBridgeIoIoWrite(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer)
EFI_STATUS RootBridgeIoCheckParameter(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN OPERATION_TYPE OperationType, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer)
EFI_STATUS EFIAPI RootBridgeIoCopyMem(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 DestAddress, IN UINT64 SrcAddress, IN UINTN Count)
EFI_STATUS EFIAPI RootBridgeIoAllocateBuffer(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, OUT VOID **HostAddress, IN UINT64 Attributes)
EFI_STATUS EFIAPI RootBridgeIoMemWrite(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer)
EFI_STATUS EFIAPI RootBridgeIoConfiguration(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, OUT VOID **Resources)
EFI_STATUS EFIAPI RootBridgeIoMap(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
EFI_STATUS EFIAPI RootBridgeIoFlush(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This)
EFI_STATUS EFIAPI RootBridgeIoPollIo(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINT64 Mask, IN UINT64 Value, IN UINT64 Delay, OUT UINT64 *Result)
EFI_STATUS EFIAPI RootBridgeIoPciRead(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN OUT VOID *Buffer)
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION
@ EfiPciOperationBusMasterCommonBuffer
@ EfiPciOperationBusMasterWrite
@ EfiPciOperationBusMasterRead64
@ EfiPciOperationBusMasterWrite64
@ EfiPciOperationBusMasterRead
@ EfiPciOperationBusMasterCommonBuffer64
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EDKII_IOMMU_OPERATION
Definition: IoMmu.h:44
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
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
#define EFI_TIMER_PERIOD_SECONDS(Seconds)
Definition: UefiLib.h:98
EFI_MEMORY_TYPE
@ EfiBootServicesData
@ EfiRuntimeServicesData
EFI_ALLOCATE_TYPE
Definition: UefiSpec.h:29
@ AllocateMaxAddress
Definition: UefiSpec.h:38
@ AllocateAnyPages
Definition: UefiSpec.h:33
EFI_CPU_IO_PROTOCOL_ACCESS Io
Definition: CpuIo2.h:131
EFI_CPU_IO_PROTOCOL_ACCESS Mem
Definition: CpuIo2.h:127
EFI_CPU_IO_PROTOCOL_IO_MEM Read
Definition: CpuIo2.h:112
EFI_CPU_IO_PROTOCOL_IO_MEM Write
Definition: CpuIo2.h:116
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Write
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Read