UEFI—— 函数GatherPpbInfo解析

GatherPpbInfo的主要内容还是填充PCI_IO_DEVICE *PciIoDevice 用以保存当前桥设备的信息。因此函数第一步还是创建设备的结构体

  PciIoDevice = CreatePciIoDevice (
                  Bridge,
                  Pci,
                  Bus,
                  Device,
                  Func
                  );

  if (PciIoDevice == NULL) {
    return NULL;
  }

接下来是对设备寄存器进行的一些初始化的操作,这些操作就是向寄存器中写入相应的初始值

  if (gFullEnumeration) {
    PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);

    //
    // Initialize the bridge control register
    //
    PCI_DISABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED);
  }

接下来是对PCI Bridge的Bar寄存器进行解析,由于PCI Bridge 只有两个Bar寄存器,所以只需判断第一次解析后的起始地址是否仍然为Bar寄存器的地址,就可以知道是否需要进行下一次的解析。解析Bar寄存器的函数 PciParseBar 详细分析过了 详见UEFI—— 读取Bar寄存器的实现(函数GatherDeviceInfo 解析)

  //
  // PPB can have two BARs
  //
  if (PciParseBar (PciIoDevice, 0x10, PPB_BAR_0) == 0x14) {
    //
    // Not 64-bit bar
    //
    PciParseBar (PciIoDevice, 0x14, PPB_BAR_1);
  }

接下来需要判断的是当前的桥是否支持32bit 的IO配置

  //
  // Test whether it support 32 decode or not
  //
  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);
  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);
  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value);
  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);

  if (Value != 0) {
    if ((Value & 0x01) != 0) {
      PciIoDevice->Decodes |= EFI_BRIDGE_IO32_DECODE_SUPPORTED;
    } else {
      PciIoDevice->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;
    }
  }

根据PCIe Spec中的定义 如果I/O Base中的bit 3:0 为0 表示当前只支持16bit IO配置,若为1 表示支持32bit IO配置
接下来同样的分析 Prefetchable Memory Base 寄存器的情况


  //
  // Test if it supports 64 memory or not
  //
  // The bottom 4 bits of both the Prefetchable Memory Base and Prefetchable Memory Limit
  // registers:
  //   0 - the bridge supports only 32 bit addresses.
  //   1 - the bridge supports 64-bit addresses.
  //
  PrefetchableMemoryBase  = (UINT16)(PMemBaseLimit & 0xffff);
  PrefetchableMemoryLimit = (UINT16)(PMemBaseLimit >> 16);
  if (!EFI_ERROR (Status) &&
      ((PrefetchableMemoryBase & 0x000f) == 0x0001) &&
      ((PrefetchableMemoryLimit & 0x000f) == 0x0001))
  {
    Status = BarExisted (
               PciIoDevice,
               0x28,
               NULL,
               NULL
               );

    if (!EFI_ERROR (Status)) {
      PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;
      PciIoDevice->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;
    } else {
      PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;
    }
  }

如果PrefetchableMemoryBase & PrefetchableMemoryLimit 两个寄存器的低两位都是01 则表示可以支持 64bit PrefetchableMemory,若是00 则表示只支持32bit的PrefetchableMemory。然后对Prefetchable Base Upper 32 Bits进行判断,如果当前这个寄存器存在有效值,则表示当前桥是 64bit PrefetchableMemory的 否则就是32bit PrefetchableMemory的
接下来对必须要支持的属性进行添加

  //
  // Memory 32 code is required for ppb
  //
  PciIoDevice->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;

以上的操作都是填充 PciIoDevice->Decodes 这一属性
接下来的操作和热插拔相关,目前不在讨论范围内

  GetResourcePaddingPpb (PciIoDevice);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值