3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
4 Copyright (c) 2016, Linaro, Ltd. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "NonDiscoverablePciDeviceIo.h"
18 #include <IndustryStandard/Acpi.h>
20 #include <Protocol/PciRootBridgeIo.h>
23 EFI_PHYSICAL_ADDRESS AllocAddress
;
25 EFI_PCI_IO_PROTOCOL_OPERATION Operation
;
27 } NON_DISCOVERABLE_PCI_DEVICE_MAP_INFO
;
30 // Get the resource associated with BAR number 'BarIndex'.
35 IN NON_DISCOVERABLE_PCI_DEVICE
*Dev
,
37 OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
**Descriptor
40 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
42 if (BarIndex
< Dev
->BarOffset
) {
46 BarIndex
-= (UINT8
)Dev
->BarOffset
;
48 for (Desc
= Dev
->Device
->Resources
;
49 Desc
->Desc
!= ACPI_END_TAG_DESCRIPTOR
;
50 Desc
= (VOID
*)((UINT8
*)Desc
+ Desc
->Len
+ 3)) {
66 IN EFI_PCI_IO_PROTOCOL
*This
,
67 IN EFI_PCI_IO_PROTOCOL_WIDTH Width
,
77 return EFI_UNSUPPORTED
;
84 IN EFI_PCI_IO_PROTOCOL
*This
,
85 IN EFI_PCI_IO_PROTOCOL_WIDTH Width
,
95 return EFI_UNSUPPORTED
;
102 IN EFI_PCI_IO_PROTOCOL_WIDTH Width
,
110 volatile UINT8
*Dst8
;
111 volatile UINT16
*Dst16
;
112 volatile UINT32
*Dst32
;
113 volatile CONST UINT8
*Src8
;
114 volatile CONST UINT16
*Src16
;
115 volatile CONST UINT32
*Src32
;
118 // Loop for each iteration and move the data
120 switch (Width
& 0x3) {
121 case EfiPciWidthUint8
:
124 for (;Count
> 0; Count
--, Dst8
+= DstStride
, Src8
+= SrcStride
) {
128 case EfiPciWidthUint16
:
129 Dst16
= (UINT16
*)Dst
;
130 Src16
= (UINT16
*)Src
;
131 for (;Count
> 0; Count
--, Dst16
+= DstStride
, Src16
+= SrcStride
) {
135 case EfiPciWidthUint32
:
136 Dst32
= (UINT32
*)Dst
;
137 Src32
= (UINT32
*)Src
;
138 for (;Count
> 0; Count
--, Dst32
+= DstStride
, Src32
+= SrcStride
) {
143 return EFI_INVALID_PARAMETER
;
153 IN EFI_PCI_IO_PROTOCOL
*This
,
154 IN EFI_PCI_IO_PROTOCOL_WIDTH Width
,
161 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
164 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
167 if (Buffer
== NULL
) {
168 return EFI_INVALID_PARAMETER
;
171 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This
);
174 // Only allow accesses to the BARs we emulate
176 Status
= GetBarResource (Dev
, BarIndex
, &Desc
);
177 if (EFI_ERROR (Status
)) {
181 if (Offset
+ (Count
<< (Width
& 0x3)) > Desc
->AddrLen
) {
182 return EFI_UNSUPPORTED
;
185 Address
= (VOID
*)(UINTN
)(Desc
->AddrRangeMin
+ Offset
);
186 AlignMask
= (1 << (Width
& 0x03)) - 1;
187 if ((UINTN
)Address
& AlignMask
) {
188 return EFI_INVALID_PARAMETER
;
192 case EfiPciIoWidthUint8
:
193 case EfiPciIoWidthUint16
:
194 case EfiPciIoWidthUint32
:
195 case EfiPciIoWidthUint64
:
196 return PciIoMemRW (Width
, Count
, 1, Buffer
, 1, Address
);
198 case EfiPciIoWidthFifoUint8
:
199 case EfiPciIoWidthFifoUint16
:
200 case EfiPciIoWidthFifoUint32
:
201 case EfiPciIoWidthFifoUint64
:
202 return PciIoMemRW (Width
, Count
, 1, Buffer
, 0, Address
);
204 case EfiPciIoWidthFillUint8
:
205 case EfiPciIoWidthFillUint16
:
206 case EfiPciIoWidthFillUint32
:
207 case EfiPciIoWidthFillUint64
:
208 return PciIoMemRW (Width
, Count
, 0, Buffer
, 1, Address
);
213 return EFI_INVALID_PARAMETER
;
220 IN EFI_PCI_IO_PROTOCOL
*This
,
221 IN EFI_PCI_IO_PROTOCOL_WIDTH Width
,
228 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
231 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
234 if (Buffer
== NULL
) {
235 return EFI_INVALID_PARAMETER
;
238 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This
);
241 // Only allow accesses to the BARs we emulate
243 Status
= GetBarResource (Dev
, BarIndex
, &Desc
);
244 if (EFI_ERROR (Status
)) {
248 if (Offset
+ (Count
<< (Width
& 0x3)) > Desc
->AddrLen
) {
249 return EFI_UNSUPPORTED
;
252 Address
= (VOID
*)(UINTN
)(Desc
->AddrRangeMin
+ Offset
);
253 AlignMask
= (1 << (Width
& 0x03)) - 1;
254 if ((UINTN
)Address
& AlignMask
) {
255 return EFI_INVALID_PARAMETER
;
259 case EfiPciIoWidthUint8
:
260 case EfiPciIoWidthUint16
:
261 case EfiPciIoWidthUint32
:
262 case EfiPciIoWidthUint64
:
263 return PciIoMemRW (Width
, Count
, 1, Address
, 1, Buffer
);
265 case EfiPciIoWidthFifoUint8
:
266 case EfiPciIoWidthFifoUint16
:
267 case EfiPciIoWidthFifoUint32
:
268 case EfiPciIoWidthFifoUint64
:
269 return PciIoMemRW (Width
, Count
, 0, Address
, 1, Buffer
);
271 case EfiPciIoWidthFillUint8
:
272 case EfiPciIoWidthFillUint16
:
273 case EfiPciIoWidthFillUint32
:
274 case EfiPciIoWidthFillUint64
:
275 return PciIoMemRW (Width
, Count
, 1, Address
, 0, Buffer
);
280 return EFI_INVALID_PARAMETER
;
287 IN EFI_PCI_IO_PROTOCOL
*This
,
288 IN EFI_PCI_IO_PROTOCOL_WIDTH Width
,
296 return EFI_UNSUPPORTED
;
303 IN EFI_PCI_IO_PROTOCOL
*This
,
304 IN EFI_PCI_IO_PROTOCOL_WIDTH Width
,
312 return EFI_UNSUPPORTED
;
319 IN EFI_PCI_IO_PROTOCOL
*This
,
320 IN EFI_PCI_IO_PROTOCOL_WIDTH Width
,
326 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
330 if (Width
< 0 || Width
>= EfiPciIoWidthMaximum
|| Buffer
== NULL
) {
331 return EFI_INVALID_PARAMETER
;
334 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This
);
335 Address
= (UINT8
*)&Dev
->ConfigSpace
+ Offset
;
336 Length
= Count
<< ((UINTN
)Width
& 0x3);
338 if (Offset
+ Length
> sizeof (Dev
->ConfigSpace
)) {
340 // Read all zeroes for config space accesses beyond the first
343 Length
-= sizeof (Dev
->ConfigSpace
) - Offset
;
344 ZeroMem ((UINT8
*)Buffer
+ sizeof (Dev
->ConfigSpace
) - Offset
, Length
);
346 Count
-= Length
>> ((UINTN
)Width
& 0x3);
348 return PciIoMemRW (Width
, Count
, 1, Buffer
, 1, Address
);
355 IN EFI_PCI_IO_PROTOCOL
*This
,
356 IN EFI_PCI_IO_PROTOCOL_WIDTH Width
,
362 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
365 if (Width
< 0 || Width
>= EfiPciIoWidthMaximum
|| Buffer
== NULL
) {
366 return EFI_INVALID_PARAMETER
;
369 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This
);
370 Address
= (UINT8
*)&Dev
->ConfigSpace
+ Offset
;
372 if (Offset
+ (Count
<< ((UINTN
)Width
& 0x3)) > sizeof (Dev
->ConfigSpace
)) {
373 return EFI_UNSUPPORTED
;
376 return PciIoMemRW (Width
, Count
, 1, Address
, 1, Buffer
);
383 IN EFI_PCI_IO_PROTOCOL
*This
,
384 IN EFI_PCI_IO_PROTOCOL_WIDTH Width
,
385 IN UINT8 DestBarIndex
,
386 IN UINT64 DestOffset
,
387 IN UINT8 SrcBarIndex
,
393 return EFI_UNSUPPORTED
;
400 IN EFI_PCI_IO_PROTOCOL
*This
,
401 IN EFI_PCI_IO_PROTOCOL_OPERATION Operation
,
402 IN VOID
*HostAddress
,
403 IN OUT UINTN
*NumberOfBytes
,
404 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
408 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
410 NON_DISCOVERABLE_PCI_DEVICE_MAP_INFO
*MapInfo
;
413 // If HostAddress exceeds 4 GB, and this device does not support 64-bit DMA
414 // addressing, we need to allocate a bounce buffer and copy over the data.
416 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This
);
417 if ((Dev
->Attributes
& EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
) == 0 &&
418 (UINTN
)HostAddress
+ *NumberOfBytes
> SIZE_4GB
) {
421 // Bounce buffering is not possible for consistent mappings
423 if (Operation
== EfiPciIoOperationBusMasterCommonBuffer
) {
424 return EFI_UNSUPPORTED
;
427 MapInfo
= AllocatePool (sizeof *MapInfo
);
428 if (MapInfo
== NULL
) {
429 return EFI_OUT_OF_RESOURCES
;
432 MapInfo
->AllocAddress
= MAX_UINT32
;
433 MapInfo
->HostAddress
= HostAddress
;
434 MapInfo
->Operation
= Operation
;
435 MapInfo
->NumberOfBytes
= *NumberOfBytes
;
437 Status
= gBS
->AllocatePages (AllocateMaxAddress
, EfiBootServicesData
,
438 EFI_SIZE_TO_PAGES (MapInfo
->NumberOfBytes
),
439 &MapInfo
->AllocAddress
);
440 if (EFI_ERROR (Status
)) {
442 // If we fail here, it is likely because the system has no memory below
443 // 4 GB to begin with. There is not much we can do about that other than
444 // fail the map request.
447 return EFI_DEVICE_ERROR
;
449 if (Operation
== EfiPciIoOperationBusMasterRead
) {
450 gBS
->CopyMem ((VOID
*)(UINTN
)MapInfo
->AllocAddress
, HostAddress
,
453 *DeviceAddress
= MapInfo
->AllocAddress
;
456 *DeviceAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)HostAddress
;
466 IN EFI_PCI_IO_PROTOCOL
*This
,
470 NON_DISCOVERABLE_PCI_DEVICE_MAP_INFO
*MapInfo
;
473 if (MapInfo
!= NULL
) {
474 if (MapInfo
->Operation
== EfiPciIoOperationBusMasterWrite
) {
475 gBS
->CopyMem (MapInfo
->HostAddress
, (VOID
*)(UINTN
)MapInfo
->AllocAddress
,
476 MapInfo
->NumberOfBytes
);
478 gBS
->FreePages (MapInfo
->AllocAddress
,
479 EFI_SIZE_TO_PAGES (MapInfo
->NumberOfBytes
));
488 CoherentPciIoAllocateBuffer (
489 IN EFI_PCI_IO_PROTOCOL
*This
,
490 IN EFI_ALLOCATE_TYPE Type
,
491 IN EFI_MEMORY_TYPE MemoryType
,
493 OUT VOID
**HostAddress
,
497 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
498 EFI_PHYSICAL_ADDRESS AllocAddress
;
499 EFI_ALLOCATE_TYPE AllocType
;
502 if ((Attributes
& ~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE
|
503 EFI_PCI_ATTRIBUTE_MEMORY_CACHED
)) != 0) {
504 return EFI_UNSUPPORTED
;
508 // Allocate below 4 GB if the dual address cycle attribute has not
509 // been set. If the system has no memory available below 4 GB, there
510 // is little we can do except propagate the error.
512 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This
);
513 if ((Dev
->Attributes
& EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
) == 0) {
514 AllocAddress
= MAX_UINT32
;
515 AllocType
= AllocateMaxAddress
;
517 AllocType
= AllocateAnyPages
;
520 Status
= gBS
->AllocatePages (AllocType
, MemoryType
, Pages
, &AllocAddress
);
521 if (!EFI_ERROR (Status
)) {
522 *HostAddress
= (VOID
*)(UINTN
)AllocAddress
;
530 CoherentPciIoFreeBuffer (
531 IN EFI_PCI_IO_PROTOCOL
*This
,
536 FreePages (HostAddress
, Pages
);
545 IN EFI_PCI_IO_PROTOCOL
*This
555 IN EFI_PCI_IO_PROTOCOL
*This
,
556 OUT UINTN
*SegmentNumber
,
557 OUT UINTN
*BusNumber
,
558 OUT UINTN
*DeviceNumber
,
559 OUT UINTN
*FunctionNumber
562 if (SegmentNumber
== NULL
||
564 DeviceNumber
== NULL
||
565 FunctionNumber
== NULL
) {
566 return EFI_INVALID_PARAMETER
;
581 IN EFI_PCI_IO_PROTOCOL
*This
,
582 IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation
,
583 IN UINT64 Attributes
,
584 OUT UINT64
*Result OPTIONAL
587 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
590 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This
);
594 case EfiPciIoAttributeOperationGet
:
595 if (Result
== NULL
) {
596 return EFI_INVALID_PARAMETER
;
598 *Result
= Dev
->Attributes
;
601 case EfiPciIoAttributeOperationSupported
:
602 if (Result
== NULL
) {
603 return EFI_INVALID_PARAMETER
;
605 *Result
= EFI_PCI_DEVICE_ENABLE
| EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
;
608 case EfiPciIoAttributeOperationEnable
:
609 Attributes
|= Dev
->Attributes
;
610 case EfiPciIoAttributeOperationSet
:
611 Enable
= ((~Dev
->Attributes
& Attributes
) & EFI_PCI_DEVICE_ENABLE
) != 0;
612 Dev
->Attributes
= Attributes
;
615 case EfiPciIoAttributeOperationDisable
:
616 Dev
->Attributes
&= ~Attributes
;
620 return EFI_INVALID_PARAMETER
;
624 // If we're setting any of the EFI_PCI_DEVICE_ENABLE bits, perform
625 // the device specific initialization now.
627 if (Enable
&& !Dev
->Enabled
&& Dev
->Device
->Initialize
!= NULL
) {
628 Dev
->Device
->Initialize (Dev
->Device
);
637 PciIoGetBarAttributes (
638 IN EFI_PCI_IO_PROTOCOL
*This
,
640 OUT UINT64
*Supports OPTIONAL
,
641 OUT VOID
**Resources OPTIONAL
644 NON_DISCOVERABLE_PCI_DEVICE
*Dev
;
645 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptor
, *BarDesc
;
646 EFI_ACPI_END_TAG_DESCRIPTOR
*End
;
649 if (Supports
== NULL
&& Resources
== NULL
) {
650 return EFI_INVALID_PARAMETER
;
653 Dev
= NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This
);
655 Status
= GetBarResource (Dev
, BarIndex
, &BarDesc
);
656 if (EFI_ERROR (Status
)) {
661 // Don't expose any configurable attributes for our emulated BAR
663 if (Supports
!= NULL
) {
667 if (Resources
!= NULL
) {
668 Descriptor
= AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
669 sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
));
670 if (Descriptor
== NULL
) {
671 return EFI_OUT_OF_RESOURCES
;
674 CopyMem (Descriptor
, BarDesc
, sizeof *Descriptor
);
676 End
= (EFI_ACPI_END_TAG_DESCRIPTOR
*) (Descriptor
+ 1);
677 End
->Desc
= ACPI_END_TAG_DESCRIPTOR
;
680 *Resources
= Descriptor
;
688 PciIoSetBarAttributes (
689 IN EFI_PCI_IO_PROTOCOL
*This
,
690 IN UINT64 Attributes
,
692 IN OUT UINT64
*Offset
,
693 IN OUT UINT64
*Length
697 return EFI_UNSUPPORTED
;
700 STATIC CONST EFI_PCI_IO_PROTOCOL PciIoTemplate
=
704 { PciIoMemRead
, PciIoMemWrite
},
705 { PciIoIoRead
, PciIoIoWrite
},
706 { PciIoPciRead
, PciIoPciWrite
},
710 CoherentPciIoAllocateBuffer
,
711 CoherentPciIoFreeBuffer
,
715 PciIoGetBarAttributes
,
716 PciIoSetBarAttributes
,
722 InitializePciIoProtocol (
723 NON_DISCOVERABLE_PCI_DEVICE
*Dev
726 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
729 Dev
->ConfigSpace
.Hdr
.VendorId
= PCI_ID_VENDOR_UNKNOWN
;
730 Dev
->ConfigSpace
.Hdr
.DeviceId
= PCI_ID_DEVICE_DONTCARE
;
732 // Copy protocol structure
733 CopyMem(&Dev
->PciIo
, &PciIoTemplate
, sizeof PciIoTemplate
);
735 if (CompareGuid (Dev
->Device
->Type
, &gEdkiiNonDiscoverableAhciDeviceGuid
)) {
736 Dev
->ConfigSpace
.Hdr
.ClassCode
[0] = PCI_IF_MASS_STORAGE_AHCI
;
737 Dev
->ConfigSpace
.Hdr
.ClassCode
[1] = PCI_CLASS_MASS_STORAGE_SATADPA
;
738 Dev
->ConfigSpace
.Hdr
.ClassCode
[2] = PCI_CLASS_MASS_STORAGE
;
740 } else if (CompareGuid (Dev
->Device
->Type
,
741 &gEdkiiNonDiscoverableEhciDeviceGuid
)) {
742 Dev
->ConfigSpace
.Hdr
.ClassCode
[0] = PCI_IF_EHCI
;
743 Dev
->ConfigSpace
.Hdr
.ClassCode
[1] = PCI_CLASS_SERIAL_USB
;
744 Dev
->ConfigSpace
.Hdr
.ClassCode
[2] = PCI_CLASS_SERIAL
;
746 } else if (CompareGuid (Dev
->Device
->Type
,
747 &gEdkiiNonDiscoverableNvmeDeviceGuid
)) {
748 Dev
->ConfigSpace
.Hdr
.ClassCode
[0] = 0x2; // PCI_IF_NVMHCI
749 Dev
->ConfigSpace
.Hdr
.ClassCode
[1] = 0x8; // PCI_CLASS_MASS_STORAGE_NVM
750 Dev
->ConfigSpace
.Hdr
.ClassCode
[2] = PCI_CLASS_MASS_STORAGE
;
752 } else if (CompareGuid (Dev
->Device
->Type
,
753 &gEdkiiNonDiscoverableOhciDeviceGuid
)) {
754 Dev
->ConfigSpace
.Hdr
.ClassCode
[0] = PCI_IF_OHCI
;
755 Dev
->ConfigSpace
.Hdr
.ClassCode
[1] = PCI_CLASS_SERIAL_USB
;
756 Dev
->ConfigSpace
.Hdr
.ClassCode
[2] = PCI_CLASS_SERIAL
;
758 } else if (CompareGuid (Dev
->Device
->Type
,
759 &gEdkiiNonDiscoverableSdhciDeviceGuid
)) {
760 Dev
->ConfigSpace
.Hdr
.ClassCode
[0] = 0x0; // don't care
761 Dev
->ConfigSpace
.Hdr
.ClassCode
[1] = PCI_SUBCLASS_SD_HOST_CONTROLLER
;
762 Dev
->ConfigSpace
.Hdr
.ClassCode
[2] = PCI_CLASS_SYSTEM_PERIPHERAL
;
764 } else if (CompareGuid (Dev
->Device
->Type
,
765 &gEdkiiNonDiscoverableXhciDeviceGuid
)) {
766 Dev
->ConfigSpace
.Hdr
.ClassCode
[0] = PCI_IF_XHCI
;
767 Dev
->ConfigSpace
.Hdr
.ClassCode
[1] = PCI_CLASS_SERIAL_USB
;
768 Dev
->ConfigSpace
.Hdr
.ClassCode
[2] = PCI_CLASS_SERIAL
;
770 } else if (CompareGuid (Dev
->Device
->Type
,
771 &gEdkiiNonDiscoverableUhciDeviceGuid
)) {
772 Dev
->ConfigSpace
.Hdr
.ClassCode
[0] = PCI_IF_UHCI
;
773 Dev
->ConfigSpace
.Hdr
.ClassCode
[1] = PCI_CLASS_SERIAL_USB
;
774 Dev
->ConfigSpace
.Hdr
.ClassCode
[2] = PCI_CLASS_SERIAL
;
776 } else if (CompareGuid (Dev
->Device
->Type
,
777 &gEdkiiNonDiscoverableUfsDeviceGuid
)) {
778 Dev
->ConfigSpace
.Hdr
.ClassCode
[0] = 0x0; // don't care
779 Dev
->ConfigSpace
.Hdr
.ClassCode
[1] = 0x9; // UFS controller subclass;
780 Dev
->ConfigSpace
.Hdr
.ClassCode
[2] = PCI_CLASS_MASS_STORAGE
;
783 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER
);
787 // Iterate over the resources to populate the virtual BARs
789 Idx
= Dev
->BarOffset
;
790 for (Desc
= Dev
->Device
->Resources
, Dev
->BarCount
= 0;
791 Desc
->Desc
!= ACPI_END_TAG_DESCRIPTOR
;
792 Desc
= (VOID
*)((UINT8
*)Desc
+ Desc
->Len
+ 3)) {
794 ASSERT (Desc
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
);
795 ASSERT (Desc
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
);
797 if (Idx
>= PCI_MAX_BARS
||
798 (Idx
== PCI_MAX_BARS
- 1 && Desc
->AddrSpaceGranularity
== 64)) {
800 "%a: resource count exceeds number of emulated BARs\n",
806 Dev
->ConfigSpace
.Device
.Bar
[Idx
] = (UINT32
)Desc
->AddrRangeMin
;
809 if (Desc
->AddrSpaceGranularity
== 64) {
810 Dev
->ConfigSpace
.Device
.Bar
[Idx
] |= 0x4;
811 Dev
->ConfigSpace
.Device
.Bar
[++Idx
] = (UINT32
)RShiftU64 (
812 Desc
->AddrRangeMin
, 32);