PCIデバイスがあるかどうか確認する。一応それっぽいデバイスが表示はされる。
io_inXとio_outX,Printfが既に定義されているものとする。 io_inとio_outはそれぞれのビット数のin,out命令。
enum PCI_CONFIGURATION_REGISTER
{
VenderID = 0x00, //bit0-15
DeviceID = 0x00, //bit16-32
CommandRegister = 0x04, //bit0-15
StatusRegister = 0x04, //bit16-32
RevisionRegister = 0x08, //bit0-7
ClassCode = 0x08, //bit8-31
CacheLineSize = 0x0C, //bit0-7
MasterLatencyTimer = 0x0C, //bit8-15
HeaderType = 0x0C, //bit16-32
BISTRegister = 0x0C, //bit24-31
};
#define CONFIGURATION_ADDRESS 0x0CF8
#define CONFIGURATION_DATA 0x0CFC
#define CONFIGURATION_DATA1 0x0CFD
#define CONFIGURATION_DATA2 0x0CFE
#define CONFIGURATION_DATA3 0x0CFF
struct PCIConfigHeader{
uint16 venderID;
uint16 deviceID;
uint16 command;
uint16 status;
uint8 revision;
uint8 classCode[3]; //3byte
uint8 chacheLineSize;
uint8 latency;
uint8 header;
uint8 builtInSelftest;
uint32 baseAddrReg0;
uint32 baseAddrReg1;
uint32 baseAddrReg2;
uint32 baseAddrReg3;
uint32 baseAddrReg4;
uint32 baseAddrReg5;
uint32 cardBusCISPointer;
uint16 subSystemVenderID;
uint16 subSystemID;
uint32 expansionRomAddr;
uint32 Reserved0;
uint32 Reserved1;
uint8 irqLine;
uint8 interruptPin;
uint8 minGrant;
uint8 maxLatency;
};
//bus=バス番号 dev=デバイス番号,reg=レジスタ番号(bit0-7) func = 機能番号
int WriteConfigAddr(int bus, int dev, int reg, int func)
{
int data;
data = 0x80000000 |
((bus << 16) & 0xFF0000) |
((dev << 11) & 0xF800) |
((func << 8) & 0x700) |
(((reg/4) << 2) & 0xFC);
io_out32(CONFIGURATION_ADDRESS, data);
return 0;
}
int ReadConfig32(int bus, int dev, int reg, int func)
{
WriteConfigAddr(bus, dev, reg, func);
return io_in32(CONFIGURATION_DATA);
}
int CheckBus(int bus)
{
int dev;
for(dev=0; dev<32; dev++)
{
int vender,devid;
int tmp = ReadConfig32(bus, dev, VenderID, 0);
vender = tmp&0xFFFF;
devid = (tmp>>16)&0xFFFF;
if(vender == 0xFFFF) //デバイスは存在しない
continue;
Printf("PCI bus %d, dev %d Exist. Vender=%x, DevID=%x\n", bus, dev,vender,devid);
}
return 0;
}
int CheckPCI()
{
for(int i = 0; i < 0x0100; i++)
{
CheckBus(i);
}
return 0;
}
qemuでCheckPCIを呼び出したら以下のように表示された。
PCI bus 0, dev 0 Exist. Vender=8086, DevID=1237
PCI bus 0, dev 1 Exist. Vender=8086, DevID=7000
PCI bus 0, dev 2 Exist. Vender=1013, DevID=B8
PCI bus 0, dev 3 Exist. Vender=10EC, DevID=8029
PCI bus 0, dev 4 Exist. Vender=1AF4, DevID=1002