EFI_STATUS PcatPciRootBridgeParseBars ( IN PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData, IN UINT16 Command, IN UINTN Bus, IN UINTN Device, IN UINTN Function ) /*++ Routine Description: Arguments: Returns: None --*/ { EFI_STATUS Status; UINT64 Address; UINT32 OriginalValue; UINT32 Value; UINT32 OriginalUpperValue; UINT32 UpperValue; UINT64 Mask; UINTN Offset; UINT64 Base; UINT64 Length; UINT64 Limit; for (Offset = 0x10; Offset < 0x28; Offset += 4) { Address = EFI_PCI_ADDRESS (Bus, Device, Function, Offset); Status = PcatPciRootBridgeBarExisted ( PrivateData, Address, &OriginalValue, &Value ); if (!EFI_ERROR (Status )) { if ( Value & 0x01 ) { if (Command & 0x0001) { // //Device I/Os // Mask = 0xfffffffc; Base = OriginalValue & Mask; Length = ((~(Value & Mask)) & Mask) + 0x04; if (!(Value & 0xFFFF0000)){ Length &= 0x0000FFFF; } Limit = Base + Length - 1; if (Base < Limit) { if (PrivateData->IoBase > Base) { PrivateData->IoBase = (UINT32)Base; } if (PrivateData->IoLimit < Limit) { PrivateData->IoLimit = (UINT32)Limit; } } } } else { if (Command & 0x0002) { Mask = 0xfffffff0; Base = OriginalValue & Mask; Length = Value & Mask; if ((Value & 0x07) != 0x04) { Length = ((~Length) + 1) & 0xffffffff; } else { Offset += 4; Address = EFI_PCI_ADDRESS (Bus, Device, Function, Offset); Status = PcatPciRootBridgeBarExisted ( PrivateData, Address, &OriginalUpperValue, &UpperValue ); Base = Base | LShiftU64((UINT64)OriginalUpperValue,32); Length = Length | LShiftU64((UINT64)UpperValue,32); Length = (~Length) + 1; } Limit = Base + Length - 1; if (Base < Limit) { if (PrivateData->MemBase > Base) { PrivateData->MemBase = Base; } if (PrivateData->MemLimit < Limit) { PrivateData->MemLimit = Limit; } switch (Value &0x07) { case 0x00: ////memory space; anywhere in 32 bit address space if (Value & 0x08) { if (PrivateData->Pmem32Base > Base) { PrivateData->Pmem32Base = Base; } if (PrivateData->Pmem32Limit < Limit) { PrivateData->Pmem32Limit = Limit; } } else { if (PrivateData->Mem32Base > Base) { PrivateData->Mem32Base = Base; } if (PrivateData->Mem32Limit < Limit) { PrivateData->Mem32Limit = Limit; } } break; case 0x04: //memory space; anywhere in 64 bit address space if (Value & 0x08) { if (PrivateData->Pmem64Base > Base) { PrivateData->Pmem64Base = Base; } if (PrivateData->Pmem64Limit < Limit) { PrivateData->Pmem64Limit = Limit; } } else { if (PrivateData->Mem64Base > Base) { PrivateData->Mem64Base = Base; } if (PrivateData->Mem64Limit < Limit) { PrivateData->Mem64Limit = Limit; } } break; } } } } } } return EFI_SUCCESS; }
/** Parse PCI bar and collect the assigned PCI resouce information. @param[in] Command Supported attributes. @param[in] Bus PCI bus number. @param[in] Device PCI device number. @param[in] Function PCI function number. @param[in] BarOffsetBase PCI bar start offset. @param[in] BarOffsetEnd PCI bar end offset. @param[in] Io IO aperture. @param[in] Mem MMIO aperture. @param[in] MemAbove4G MMIO aperture above 4G. @param[in] PMem Prefetchable MMIO aperture. @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G. **/ STATIC VOID PcatPciRootBridgeParseBars ( IN UINT16 Command, IN UINTN Bus, IN UINTN Device, IN UINTN Function, IN UINTN BarOffsetBase, IN UINTN BarOffsetEnd, IN PCI_ROOT_BRIDGE_APERTURE *Io, IN PCI_ROOT_BRIDGE_APERTURE *Mem, IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G, IN PCI_ROOT_BRIDGE_APERTURE *PMem, IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G ) { UINT32 OriginalValue; UINT32 Value; UINT32 OriginalUpperValue; UINT32 UpperValue; UINT64 Mask; UINTN Offset; UINTN LowBit; UINT64 Base; UINT64 Length; UINT64 Limit; PCI_ROOT_BRIDGE_APERTURE *MemAperture; for (Offset = BarOffsetBase; Offset < BarOffsetEnd; Offset += sizeof (UINT32)) { PcatPciRootBridgeBarExisted ( PCI_LIB_ADDRESS (Bus, Device, Function, Offset), &OriginalValue, &Value ); if (Value == 0) { continue; } if ((Value & BIT0) == BIT0) { // // IO Bar // if (Command & EFI_PCI_COMMAND_IO_SPACE) { Mask = 0xfffffffc; Base = OriginalValue & Mask; Length = ((~(Value & Mask)) & Mask) + 0x04; if (!(Value & 0xFFFF0000)) { Length &= 0x0000FFFF; } Limit = Base + Length - 1; if ((Base > 0) && (Base < Limit)) { if (Io->Base > Base) { Io->Base = Base; } if (Io->Limit < Limit) { Io->Limit = Limit; } } } } else { // // Mem Bar // if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) { Mask = 0xfffffff0; Base = OriginalValue & Mask; Length = Value & Mask; if ((Value & (BIT1 | BIT2)) == 0) { // // 32bit // Length = ((~Length) + 1) & 0xffffffff; if ((Value & BIT3) == BIT3) { MemAperture = PMem; } else { MemAperture = Mem; } } else { // // 64bit // Offset += 4; PcatPciRootBridgeBarExisted ( PCI_LIB_ADDRESS (Bus, Device, Function, Offset), &OriginalUpperValue, &UpperValue ); Base = Base | LShiftU64 ((UINT64) OriginalUpperValue, 32); Length = Length | LShiftU64 ((UINT64) UpperValue, 32); if (Length != 0) { LowBit = LowBitSet64 (Length); Length = LShiftU64 (1ULL, LowBit); } if ((Value & BIT3) == BIT3) { MemAperture = PMemAbove4G; } else { MemAperture = MemAbove4G; } } Limit = Base + Length - 1; if ((Base > 0) && (Base < Limit)) { if (MemAperture->Base > Base) { MemAperture->Base = Base; } if (MemAperture->Limit < Limit) { MemAperture->Limit = Limit; } } } } } }