PCI enumeration [solved]

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

PCI enumeration [solved]

Post by lukem95 »

hey, can somebody check my code please. It seems right to me, but i'm trying to enumerate the PCI, and load drivers from the data gathered (Well... print a message and _eventually_ enable the driver).

Code: Select all

static PCI_Device_t* pci_getdevice(int bus, int device, int function)
{
  static PCI_Device_t* pci_device;
  unsigned short vendor = 0, deviceid = 0;
  unsigned char classcode = 0, subclass = 0;
  
  if ((vendor = pci_read(bus,device,0,0)) != 0xFFFF)
  {
       deviceid = pci_read(bus,device,0,2);
       classcode = (pci_read(bus,device,0,10) << 4 );
       subclass = (pci_read(bus,device,0,10) >> 4 );   
       
       pci_device->ClassCode = classcode;
       pci_device->SubClass = subclass;
       pci_device->VendorID = vendor;
       pci_device->DeviceID = deviceid;
  }
  pci_device->VendorID = vendor;
  return pci_device;
}

This is the code i'm using the get the Class code etc, and i then switch this using:

Code: Select all

switch(tmp->ClassCode)
                                   {
                                        //Pre-PCI Items
                                        case 0x00:
                                             if(tmp->SubClass == 0x01)
                                                  //Load VGA driver
                                                  kprintf("VGA driver loading (legacy)... \n");
                                        break;
                                        
                                        //Mass storage devices
                                        case 0x01:
                                             if(tmp->SubClass == 0x01)
                                                  //IDE
                                                  kprintf("ATA (IDE) driver loading... [TODO]\n");
                                             if(tmp->SubClass == 0x02)
                                                  //Floppy
                                                  kprintf("Floppy legacy driver loading... [TODO]\n");
                                                  
                                             if(tmp->SubClass == 0x80)
                                                  kprintf("Mass storage device controller driver loading... [TODO]\n");
                                        break;

...

I get 32 entries in the PCI for Qemu, and 16 for bochs (is this right?), but the Class Code is always 0x00.

any thoughts or obvious errors?

thanks, luke
Last edited by lukem95 on Tue Mar 18, 2008 4:24 pm, edited 1 time in total.
~ Lukem95 [ Cake ]
Release: 0.08b
Image
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

I think one error has to do with this line: (why the left shift?)

Code: Select all

classcode = (pci_read(bus,device,0,10) << 4 ); 
The other error is that you get an power of two amount of devices, which is unrealistic as well. I just ran my own PCI code in QEMU - it gives me 5 devices: 3 intel ones, and two others (I guess they're a cirrus and a creative).

But why it consequently thinks that the classcode is 0, I have no idea. Try printing all vendor:device codes for starters and see if you get meaningful values out of those. You may also want to post your PCI reading code itself.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: PCI enumeration

Post by Brendan »

Hi,
zaleschiemilgabriel wrote:I see you're from "Cambridge, UK"... I thought that place was filled with geniuses. :roll:
Do you think he's in Cambridge University (e.g. studying architecture), or in the city of Cambridge (e.g. working as a doctor of medicine)?
zaleschiemilgabriel wrote:HINT: Avoid asking people to do your homework on Fridays, Mondays or during the weekend. Fridays are the worst. Mondays are really bad too.
Where was homework mentioned, or what led you to assume it was homework?
zaleschiemilgabriel wrote:Well, it's just not enough to say "please" anymore
I'd like to think "please" is more than enough, especially when combined with a polite and detailed request.

Instead of being rude, you might want to consider refraining from replying if you're not interested in helping...


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

Post by lukem95 »

erm.. thankyou brendan for your reply... im actually 15, and although i'd say im fairly smart, i am still in secondary school. This is not quite the same standard as Cambridge Uni.

I'll have another look at my code when i get home from school...

thankyou for your help
~ Lukem95 [ Cake ]
Release: 0.08b
Image
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: PCI enumeration

Post by jal »

lukem_95 wrote:hey, can somebody check my code please. (...) any thoughts or obvious errors?

Code: Select all

       classcode = (pci_read(bus,device,0,10) << 4 ); 
       subclass = (pci_read(bus,device,0,10) >> 4 );  
You read twice the same value. That's rather inefficient, and although I don't know how the PCI handles it, in general it's not a good idea to read the same hardware register twice and expect the same value. Also I don't understand why you put brackets around the statement (though that's obviously not a problem). I'd do something like this:

Code: Select all

class = pci_read(bus, device, 0, 10);
classcode = class << 4;
subclass = class >> 4;
Since that shifting seemed a bit weird to me, I Googled a bit on class codes, and I found e.g. this:
ibm.com wrote:PCI devices also identify themselves with a class code, identifying roughly what type of function they perform, for instance, storage, or networking. The class code is a 16-bit value; the first 8 bits indicate an overall class, such as "mass storage" or "display;" the second 8 bits can indicate subclasses, such as "SCSI" or "IDE" for mass storage, or "Ethernet" or "Token Ring" for network devices.
So it seems the class code is 2x8 bits, not 2x4 as you treat it. That could be the source of your problem.


JAL

Disclaimer: The author has no knowledge of PCI busses and device enumeration. Don't beat him with a stick if Google found the wrong answers.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

*puts in the last nail of the new garden fence*

I don't agree with locking this thread. Instead, tell us wether anything helped you fix the problem in the meantime, or if it still doesn't work.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

Post by lukem95 »

ok, i rewrote my code. My problem was indeed the issue with me treating it as 4 bits instead of 8. The masking was changed to 8 and the data types altered and this worked correctly.

Thankyou everyone for your help ;)

(and thankyou Combbuster for moving the other half of this thread)
~ Lukem95 [ Cake ]
Release: 0.08b
Image
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post by zaleschiemilgabriel »

Sorry I was an @$$. :oops: Please don't feed the troll next time.
Post Reply