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;
}
Esempio n. 2
0
/**
  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;
          }
        }
      }
    }
  }
}