PCIE Switch设备的Did,Vid,SubDid,SubVid信息获取

问题:W6800卡插在不同的IO模组,SubDid,SubVid会跟随改变,BMC无法正确显示设备

在这里插入图片描述
分析:由图可以看出,W6800是个Switch设备,该设备挂载在rootbridge 01 下面,该Switch下还挂了PCIE设备,提交给BMC的应该为设备Did,Vid,Subdid,subvid。
Switch设备的Header Type 为1,要找到PCIE设备,Header Type 为0,Type1的配置空间如下图所示:
在这里插入图片描述
找到插在Switch卡上的PCIE设备的配置空间
请添加图片描述

                  addr.Addr.Register = PCI_HEADER_TYPE_OFFSET;
                  RbIoProtocol->Pci.Read(RbIoProtocol, EfiPciWidthUint8, addr.ADDR, 1, (VOID*)&HeaderType );
                  if ((HeaderType & HEADER_LAYOUT_CODE) == 1 ) {
                    addr.Addr.Register = 0x19;
                    RbIoProtocol->Pci.Read (RbIoProtocol, EfiPciWidthUint8, addr.ADDR, 1, (VOID*)&SecBus);
                    addr.Addr.Register = 0x1A;
                    RbIoProtocol->Pci.Read (RbIoProtocol, EfiPciWidthUint8, addr.ADDR, 1, (VOID*)&SubBus);
                    for (int BridgeBus = SecBus; BridgeBus <= SubBus; BridgeBus++) {
                      addr.Addr.Bus = (UINT8)BridgeBus;
                      addr.Addr.Register = PCI_HEADER_TYPE_OFFSET;
                      RbIoProtocol->Pci.Read (RbIoProtocol, EfiPciWidthUint8, addr.ADDR, 1, (VOID*)&HeaderType );
                        if ((HeaderType & HEADER_LAYOUT_CODE) == 0 ) {
                          addr.Addr.Register = 0;
                          RbIoProtocol->Pci.Read(RbIoProtocol, EfiPciWidthUint32, addr.ADDR, 1, (VOID*)&PciVidDid);
                          addr.Addr.Register = 0x2C;
                          RbIoProtocol->Pci.Read (RbIoProtocol, EfiPciWidthUint32, addr.ADDR, 1, (VOID*)&SubPciVidDid );
                        }
                    }
                  }

在这里插入图片描述
最终可以正确识别PCIE的设备信息

在PCI Express (PCIe) 设备中,Vendor ID (VID) 和 Device ID (DID) 是两个关键的硬件标识符,用于区分不同的制造商和产品型号。当你从一个PCIe Read Write (R/W) 接口读取这些信息时,通常会在设备描述表 (Device Configuration Space, DCS) 中找到。 DCS位于PCI设备的物理地址0x00000000到0x000000FF处,对于现代设备来说,它包含了VIDDID在内的多个字段。这些信息通常是按照一定的字节顺序存储的: - Vendor ID (8位): 这是十六进制数,代表制造商的ID。你可以将这个值转换成十进制查看对应的产品制造商。 - Device ID (16位): 同样是十六进制数,代表产品的模型ID。可以分为两部分,高八位是功能集号,低八位是子系统设备号。 读取这些信息的具体步骤通常依赖于底层的操作系统和硬件驱动支持。在Linux环境中,你可以使用`ioread`或`ioremap`函数配合PCI设备的 BAR (Base Address Register) 来获取这些数据。在Windows,可以使用`PciReadWrite` API或者其他第三方工具包。 汇总这些信息时,你可能会创建一个结构体或者字典来存储这些数据,示例代码如下(假设使用C语言): ```c typedef struct { uint16_t vendor_id; uint16_t device_id; // 可能还有其他的设备信息... } PcieDeviceInfo; PcieDeviceInfo device_info; // 读取PCIe设备描述表 void read_pci_device_info(void *pci_bar_address) { memcpy(&device_info, pci_bar_address, sizeof(device_info)); } // 示例用法 void main() { uint64_t bar_address = ...; // PCI BAR 地址 read_pci_device_info((void*)bar_address); printf("Vendor ID: %d\n", device_info.vendor_id); printf("Device ID: %d-%d (Function Set: %d, Subsys Dev: %d)\n", device_info.device_id >> 8, device_info.device_id & 0xFF, (device_info.device_id >> 8) & 0xFF, device_info.device_id & 0xFF); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值