Page 1 of 1

Having difficulty with PCI code

Posted: Sun Jan 24, 2010 4:45 pm
by Barrucadu
edit: Just tried this on real hardware and it found the class for one device.

Hi,

I based my PCI code on the example in the wiki and the address seems to be created correctly, and I get values returned for the vendor and device (though I haven't checked whether they're correct yet), but nothing is returned for the class.
For testing purposes I'm trying to return the class-subclass word with the pciclass() function, when I get that working I'll edit it to return the class and subclass separately… but it's returning 0.

Code: Select all

#include <kernel.h>
#include <hardware/pci.h>

u16int pcireadword(u16int bus, u16int device, u16int func, u16int reg, u16int offset) /* Note: offset is measured in words (ie: offset 0 = bits 0-15, offset 1 = bits 16-31 */
{
    u32int address;
 
    address = (u32int) 0x80000000 | ((u32int) bus << 16) | ((u32int) device << 11) | ((u32int) func << 8) | ((u32int) reg << 2);
    /* kprintf("%s %s %s %s %s\n", itos(address, 16), itos(lbus, 16), itos(ldev, 16), itos(lfunc, 16), itos(lreg, 16)); - For debugging PCI code */

    outportl(0xCF8, address);
    return (u16int) (inportl(0xCFC) >> (offset * 16));
}

u8int pcipolldevice(u16int bus, u16int device)
{
    return !(pcireadword(bus, device, 0, 0, 0) == 0xFFFF);
}

u16int pcivendor(u16int bus, u16int device)
{
    return pcireadword(bus, device, 0, 0, 0);
}

u16int pcidevice(u16int bus, u16int device)
{
    return pcireadword(bus, device, 0, 0, 1);
}

u16int pciclass(u16int bus, u16int device)
{
    return pcireadword(bus, device, 0, 0x08, 0);
}
Thanks

Re: Having difficulty with PCI code

Posted: Sun Jan 24, 2010 5:09 pm
by Combuster
For starters, your documentation is off - PCI can only be accessed as 32-bit words (not 16-bit words!), aligned at 4-byte addresses. Since you use a shift, you are most likely addressing the wrong register in configuration space

The more logical address conversion would read something like:

Code: Select all

if (offset & 3) panic();
address = 0x80000000 + (bus << 16) + (dev << 11) + (fn << 8) + offset;
outport32(0xcf8, address);
return inport32(0xcfc);

Re: Having difficulty with PCI code

Posted: Mon Jan 25, 2010 10:47 am
by Barrucadu
Ok, still not having any luck, but I'll be damned if I can see the cause of the problem…

http://misc.barrucadu.co.uk/pci.c

The value returned by pcivendor() is correct, but the other values are wrong. So it looks like the offsets are wrong, but I can't see where they're going wrong.

Re: Having difficulty with PCI code

Posted: Mon Jan 25, 2010 12:24 pm
by Combuster
I wrote:PCI can only be accessed as 32-bit words (not 16-bit words!), aligned at 4-byte addresses.

Re: Having difficulty with PCI code

Posted: Mon Jan 25, 2010 12:34 pm
by Barrucadu
Argh, I feel stupid now :P
Thanks.