Page 1 of 2
PCI Scanning (continued from Enumarating USB)
Posted: Thu Jun 26, 2008 1:42 am
by naiksidd_85
hi all,
as the most meaningful solution to Enumerating USB is to scan PCI bus (as commented by many OSdevers).
I thought I should create a new topic and start over with PCI first.
I did try many things like outs to 0xcf8 but still the output is 0xff i am not sure why am i not able to read the BARS.
pls help me in it .
Re: PCI Scanning (continued from Enumarating USB)
Posted: Thu Jun 26, 2008 1:57 am
by Laksen
I just used the PCI Bios to do all PCI detection and reading handling. It's pretty easy to use
Re: PCI Scanning (continued from Enumarating USB)
Posted: Thu Jun 26, 2008 2:21 am
by Combuster
do you even get a list of hardware?
Re: PCI Scanning (continued from Enumarating USB)
Posted: Thu Jun 26, 2008 3:11 am
by naiksidd_85
do you even get a list of hardware?
yes i do get it... As i had said in my post, but using SMBIOS.
Re: PCI Scanning (continued from Enumarating USB)
Posted: Thu Jun 26, 2008 3:18 am
by Combuster
You should really test for harware being actually present before even trying to list their BARs.
Any code?
Re: PCI Scanning (continued from Enumarating USB)
Posted: Thu Jun 26, 2008 3:28 am
by naiksidd_85
I am trying the code very similar to what you had posted...
Code: Select all
dword value;
for (int i = 0; i < 32; i++)
{
out32 (0xCF8, (i << 11) | 0x80000000);
value = in32(0xCFC);
if (value != 0xffffffff && value != 0)
{
printf("Device found in slot %i: %x\r\n", i, value);
}
}
just with some changes that is the function names changing but i am not really clear why we outs the value ox80000000 here I have also read that we need to write 0xffffffff to 0xCF8 and read from it.....
will first try to find what hardware is connected as you commented.
sorry for asking such irritating question but I am completely Lost...
Re: PCI Scanning (continued from Enumarating USB)
Posted: Thu Jun 26, 2008 5:59 am
by Combuster
I think you're seeing ghosts.
PCI has all the info you need.
i am not really clear why we outs the value ox80000000
Bit 31 is an enable flag for determining when accesses to CONFIG_DATA should be translated to configuration cycles.
write 0xffffffff to 0xCF8
Ghost #1
0xCF8 and read from it
Ghost #2. Any information comes from the data port - 0xCFC
sorry for asking such irritating question but I am completely Lost...
It helps if you start from point zero. You're like
omg i wrote 5000 lines of code and it doesnt work and i dont know whats happening and it does not work and im lost like a headless chicken help me. Nobody (except psychics, which we aren't) can solve your problem that way. Try imagining why. Begin with the basics. Write 10 lines of code, test it, add a few more, test it, add even more, oops those last 5 lines broke it. Then you know where to look for an answer.
Re: PCI Scanning (continued from Enumarating USB)
Posted: Thu Jun 26, 2008 7:33 am
by Jeko
You can also read source code of other operating systems. It's really useful to understand better how things work.
Re: PCI Scanning (continued from Enumarating USB)
Posted: Fri Jun 27, 2008 5:39 am
by lukem95
Code: Select all
typedef struct
{
unsigned short VendorID;
unsigned short DeviceID;
unsigned short CommandReg;
unsigned short StatusReg;
unsigned char RevisionID;
unsigned char ProgIF;
unsigned char SubClass;
unsigned char ClassCode;
unsigned char CachelineSize;
unsigned char Latency;
unsigned char HeaderType;
unsigned char BIST;
unsigned int BAR0; //Base Address Register
unsigned int BAR1;
unsigned int BAR2;
unsigned int BAR3;
unsigned int BAR4;
unsigned int BAR5;
unsigned int CardbusCISPtr;
unsigned short SubVendorID; //Subsystem
unsigned short SubDeviceID;
unsigned int ExRomAddress; //Expansion ROM
unsigned int Reserved1;
unsigned int Reserved2;
unsigned char IRQ; //IRQ number
unsigned char PIN; //IRQ PIN number
unsigned char MinGrant;
unsigned char MaxLatency;
} PCI_Device_t;
Code: Select all
//Reads DWORD config register
static u32int pci_read(int bus, int dev, int func, int reg)
{
outl(0xCF8,
((unsigned long) 0x80000000 | (bus << 16) | (dev << 11) |
(func << 8) | reg));
return inl(0xCFC);
}
PCI_Device_t* ret;
static PCI_Device_t* pci_readdevice(int bus, int dev, int func)
{
PCI_Device_t* ret;
//THIS FUNCTION HAS BEEN LEFT BLANK
//sorry... but i dont want you just leeching code if you're not going understand
//TODO: get each 32bit value from pci_read() and put it in the correct place in the
//PCI_Device_t struct.
return ret;
}
Code: Select all
PCI_Device_t * dev;
dev = pci_readdevice(bus, device, function);
if(dev->ClassCode == 0x0C && dev->SubClass == 0x03)
{
kprintf("we g0tz our USB controller");
kprintf("IRQ: %d BAR0: 0x%x BAR1: 0x%x ...\n",dev->IRQ,dev->BAR0,dev->BAR1);
}
This is similar to the code i use (the struct is the same, as is pci_read()), i've left one of the functions blank, but if you understand the code (and read the wiki) you will be able to write your own implementation in about 10 minutes (including debugging)... i've actually only removed 3 lines of code.
anyway, hope this helps a bit
Re: PCI Scanning (continued from Enumarating USB)
Posted: Tue Jul 01, 2008 3:49 am
by naiksidd_85
hi all,
I finally found out what was going wrong when i wrote the entire code again..
i was really foolish (or i would say stressed out), i was reading 16bit value and writing 32bit address but now am able to read the pci ,
thanx
Re: PCI Scanning (continued from Enumarating USB)
Posted: Thu Jul 17, 2008 8:20 am
by raistlinthewiz
i try to fill in the code but having strange errors;
Code: Select all
static pci_device_t* pci_read_device(int bus, int dev, int func)
{
pci_device_t* ret;
ret->VendorID=pci_read(bus,dev,func,0);
ret->DeviceID=pci_read(bus,dev,func,2);
//ret->CommandReg=pci_read(bus,dev,func,4);
//ret->ClassCode=pci_read(bus,dev,func,8);
return ret;
}
does not work for DeviceID? any suggestions?
Re: PCI Scanning (continued from Enumarating USB)
Posted: Thu Jul 17, 2008 8:30 am
by Combuster
alignment issues - reading 4 bytes from offset 2 perchance?
Re: PCI Scanning (continued from Enumarating USB)
Posted: Thu Jul 17, 2008 10:13 am
by raistlinthewiz
if u use a dword version,
ret->VendorID=pci_read_dword(bus,dev,func,0);
ret->DeviceID=pci_read_dword(bus,dev,func,2);
vendorid gets corrupted...
can't fix it. any ideas?
Re: PCI Scanning (continued from Enumarating USB)
Posted: Thu Jul 17, 2008 12:55 pm
by Masterkiller
raistlinthewiz wrote:if u use a dword version,
ret->VendorID=pci_read_dword(bus,dev,func,0);
ret->DeviceID=pci_read_dword(bus,dev,func,2);
vendorid gets corrupted...
can't fix it. any ideas?
By Default last two bits are reserved and must be written to zero. The PCI I/O register you read muse be 0x04 aligned and read as a dword. So you read both Vendor and Device ID at once. You must use Arithmetic-Logical function to separate it. Here is the code for C:
Code: Select all
ret->VendorID = (short)((pci_read_dword(bus,dev,func,0)&0xFFFF0000)>>16); //Read VendorID and DeviceID, zero the DeviceID and shift VendorID to the lower word
ret->DeviceID = (short)(pci_read_dword(bus,dev,func,0)&0x0000FFFF); //Read VendorID and DeviceID again and zero the VendorID
Re: PCI Scanning (continued from Enumarating USB)
Posted: Thu Jul 17, 2008 4:30 pm
by raistlinthewiz
thanks a lot it did worked, for future reference, just the correct order is;
Code: Select all
ret->VendorID = (uint16) (pci_read(bus,dev,func,0)&0x0000FFFF); //Read VendorID and DeviceID, zero the DeviceID and shift VendorID to the lower word
ret->DeviceID = (uint16)((pci_read(bus,dev,func,0)&0xFFFF0000) >> 16); //Read VendorID and DeviceID again and zero the VendorID
and pci_read_word did not worked but instead i used uint32 version;
Code: Select all
uint32 pci_read(int bus, int dev, int func, int reg)
{
outl(0xCF8,((unsigned long) 0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | reg ));
return inl(0xCFC);
}