当前位置: 代码迷 >> 驱动开发 >> 使用PCI BIOS来枚举PCI设备,该怎么解决
  详细解决方案

使用PCI BIOS来枚举PCI设备,该怎么解决

热度:25   发布时间:2016-04-28 10:54:14.0
使用PCI BIOS来枚举PCI设备
#include <stdio.h>
#include <conio.h>
#include <dos.h> 

typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD; 

/* PCI设备索引。bus/dev/func 共16位,为了方便处理可放在一个WORD中 */
#define PDI_BUS_SHIFT 8
#define PDI_BUS_SIZE 8
#define PDI_BUS_MAX 0xFF
#define PDI_BUS_MASK 0xFF00 
#define PDI_DEVICE_SHIFT 3
#define PDI_DEVICE_SIZE 5
#define PDI_DEVICE_MAX 0x1F
#define PDI_DEVICE_MASK 0x00F8 
#define PDI_FUNCTION_SHIFT 0
#define PDI_FUNCTION_SIZE 3
#define PDI_FUNCTION_MAX 0x7
#define PDI_FUNCTION_MASK 0x0007 
#define MK_PDI(bus,dev,func) (WORD)((bus&PDI_BUS_MAX)<<PDI_BUS_SHIFT | (dev&PDI_DEVICE_MAX)<<PDI_DEVICE_SHIFT | (func&PDI_FUNCTION_MAX) ) 
int main(void)
{
int bus, dev, func;
int i;

union REGS regs;

WORD wAddr;
FILE* hF;
char szFile[0x10];
printf("\n");
printf("Bus#\tDevice#\tFunc#\tVendor\tDevice\tClass\tIRQ\tIntPin\n"); 
/* 枚举PCI设备 */
for(bus = 0; bus <= PDI_BUS_MAX; ++bus) {
for(dev = 0; dev <= PDI_DEVICE_MAX; ++dev) {
for(func = 0; func <= PDI_FUNCTION_MAX; ++func) {
/* 计算地址 */
wAddr = MK_PDI(bus, dev, func);
/* 获取厂商ID */
regs.x.ax = 0xB109; // PCI BIOS v2.0c+ - READ CONFIGURATION WORD
regs.x.bx = wAddr;
regs.x.di = 0; // Vendor ID
regs.x.cx = 0xFFFF; // 非法的Vendor ID
int86(0x1A, &regs, &regs); 
/* 判断设备是否存在。FFFFh是非法厂商ID */
if (regs.x.cx != 0xFFFF) {
/* bus/dev/func */
printf("%2.2X\t%2.2X\t%1X\t", bus, dev, func); 
/* Vendor */
printf("%4.4X\t", regs.x.cx); 
/* Device */
regs.x.ax = 0xB109; // PCI BIOS v2.0c+ - READ CONFIGURATION WORD
regs.x.bx = wAddr;
regs.x.di = 2; // Device ID
int86(0x1A, &regs, &regs);
printf("%4.4X\t", regs.x.cx); 
/* Class Code */
regs.x.ax = 0xB109; // PCI BIOS v2.0c+ - READ CONFIGURATION WORD
regs.x.bx = wAddr;
regs.x.di = 0xA; // Class/SubClass
int86(0x1A, &regs, &regs);
printf("%4.4X\t", regs.x.cx); 
/* IRQ/intPin */
regs.x.ax = 0xB109; // PCI BIOS v2.0c+ - READ CONFIGURATION WORD
regs.x.bx = wAddr;
regs.x.di = 0x3C; // IRQ/IntPin
int86(0x1A, &regs, &regs);
printf("%d\t", (BYTE)regs.x.cx);
printf("%d", (BYTE)(regs.x.cx>>8)); 
printf("\n"); 
/* 写文件 */
sprintf(szFile, "PCI%2.2X%2.2X%X.bin", bus, dev, func);
hF = fopen(szFile, "wb");
if (hF != NULL) {
/* 256字节的PCI配置空间 */
for (i = 0; i < 0x100; i += 2) {
/* Read */
regs.x.ax = 0xB109; // PCI BIOS v2.0c+ - READ CONFIGURATION WORD
regs.x.bx = wAddr;
regs.x.di = i;
int86(0x1A, &regs, &regs); 
/* Write */
fwrite(&regs.x.cx, 2, 1, hF);
}
fclose(hF);
}
}
  }
}
 } 
 return 0;


这程序小弟运行时在这块union REGS regs;出错, 因为是别人的代码,加上我个人技术不是太好。。 还麻烦大侠,帮忙指点下。 这个REGS共同体如何定义啊。 能让这个程序跑起来。



------解决方案--------------------
直接嵌入汇编吧,这样看起来更乱
------解决方案--------------------
用TC 编译