Harddrives not being detected on PCI

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
Tobba
Posts: 21
Joined: Fri Mar 18, 2011 3:24 pm

Harddrives not being detected on PCI

Post by Tobba »

According to this article on the wiki, harddrives should appear on the PCI bus, but for me, all my code finds on the PCI bus is:

Code: Select all

VendorID: 0x00008086 DeviceID: 0x00008086 Class: 0x00000006 Subclass: 0x00000000
VendorID: 0x00008086 DeviceID: 0x00008086 Class: 0x00000006 Subclass: 0x00000001
First is a host bridge and second is a PCI-to-ISA bridge
I've also set bochs to emulate an NE2K NIC and a SB16 sound card
I assume that their all being emulated as ISA, but it makes me think my code for PCI is all wrong, or the article

Code:

Code: Select all

typedef struct
{
	// TODO
	unsigned short vendorID;
	unsigned short deviceID;
} pci_config;

typedef struct
{
	unsigned char bus;
	unsigned char slot;
	unsigned char config[256];
} pci_device;

pci_device *pci_devices;

unsigned char pciConfigReadByte(unsigned short bus, unsigned short slot, unsigned short func, unsigned short offset)
{
	unsigned long address;
	unsigned long lbus = (unsigned long)bus;
	unsigned long lslot = (unsigned long)slot;
	unsigned long lfunc = (unsigned long)func;
	unsigned short tmp = 0;
 
	/* create configuration address as per Figure 1 */
	address = (unsigned long)((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xFC) | 0x80000000);

	outd(0xCF8, address);

	return (unsigned char)((ind(0xCFC) >> ((offset & 3) << 3)) & 0xFF);
}

unsigned short pciConfigReadWord(unsigned short bus, unsigned short slot, unsigned short func, unsigned short offset)
{
	unsigned long address;
	unsigned long lbus = (unsigned long)bus;
	unsigned long lslot = (unsigned long)slot;
	unsigned long lfunc = (unsigned long)func;
	unsigned short tmp = 0;
 
	/* create configuration address as per Figure 1 */
	address = (unsigned long)((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xFC) | 0x80000000);

	outd(0xCF8, address);

	return (unsigned short)((ind(0xCFC) >> ((offset & 2) << 3)) & 0xFFFF);
}

unsigned long pciConfigReadDWord(unsigned short bus, unsigned short slot, unsigned short func, unsigned short offset)
{
	unsigned long address;
	unsigned long lbus = (unsigned long)bus;
	unsigned long lslot = (unsigned long)slot;
	unsigned long lfunc = (unsigned long)func;
	unsigned short tmp = 0;
 
	/* create configuration address as per Figure 1 */
	address = (unsigned long)((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xFC) | 0x80000000);

	outd(0xCF8, address);

	return ind(0xCFC);
}

void init_pci()
{
	unsigned short bus;
	unsigned short slot;
	for (bus = 0; bus < 0xFF; bus++)
	{
		for (slot = 0; slot < 0x20; slot++)
		{
			if (pciConfigReadDWord(bus, slot, 0, 0) != 0xFFFFFFFF)
			{
				pci_device device;
				for (i = 0; i < 0x40; i++)
				{
					((unsigned long*)device.config)[i] = pciConfigReadDWord(bus, slot, 0, i << 2);
				}
				puts("VendorID: ");
				puth(((unsigned short*)device.config)[0]);
				puts(" DeviceID: ");
				puth(((unsigned short*)device.config)[0]);
				puts(" Class: ");
				puth(device.config[0x0B]);
				puts(" Subclass: ");
				puth(device.config[0x0A]);
				putch('\n');
			}
		}
	}
}
(Messy, I know)

Is it my code thats all wrong, the article wrong, or is it something else?
shikhin
Member
Member
Posts: 274
Joined: Sat Oct 09, 2010 3:35 am
Libera.chat IRC: shikhin
Contact:

Re: Harddrives not being detected on PCI

Post by shikhin »

Hi,

I was just wondering whether you are clear what the third argument of the following is meant for:

Code: Select all

unsigned long pciConfigReadDWord(unsigned short bus, unsigned short slot, unsigned short func, unsigned short offset)
unsigned short pciConfigReadWord(unsigned short bus, unsigned short slot, unsigned short func, unsigned short offset)
unsigned char pciConfigReadByte(unsigned short bus, unsigned short slot, unsigned short func, unsigned short offset)


Each PCI Configuration address consists of the following format:
Enable Bit (Bit 31) Reserved (Bit 24-30) Bus Number (Bit 16 - 23) Device Number (Bit 11 - 15) Function Number (Bit 8 - 10) Register Number (Bit 2 - 7) 00 (Bit 0 - 1)
Yes, you guessed that right. This means that the Bus Number can range from 0x00 - 0xFF, the Device number can range from 0x00 - 0x20, and the function number can range from 0x00 - 0x07. But before checking all the 8 functions of the specific device, you should first check if the device even supports functions. This can be found out by checking if bit 7 of the Header Type is set; if set, it supports multiple functions, else only a single function (0x00). [source: http://wiki.osdev.org/PCI#PCI_Device_Structure]

Perhaps you could clear out every doubt using the following: http://wiki.osdev.org/PCI#Configuration_Mechanism_.231 rather than posting back. 8)

Regards,
Shikhin
http://shikhin.in/

Current status: Gandr.
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:

Re: Harddrives not being detected on PCI

Post by Combuster »

It's much simpler:

Code: Select all

            puts("VendorID: ");
            puth(((unsigned short*)device.config)[0]);
            puts(" DeviceID: ");
            puth(((unsigned short*)device.config)[0]);
Since when is the vendor id stored at the same location as the device id? :wink:
"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
Tobba
Posts: 21
Joined: Fri Mar 18, 2011 3:24 pm

Re: Harddrives not being detected on PCI

Post by Tobba »

Combuster wrote:It's much simpler:

Code: Select all

            puts("VendorID: ");
            puth(((unsigned short*)device.config)[0]);
            puts(" DeviceID: ");
            puth(((unsigned short*)device.config)[0]);
Since when is the vendor id stored at the same location as the device id? :wink:
Ever since typos existed

Either way i got it fixed now, I must have missed something about the functions on devices
Post Reply