Page 1 of 1

No ATA Controller in PCI Configuration Space?

Posted: Sat Feb 20, 2016 1:45 pm
by nakst
Hello,
I've created some simple PCI configuration space scanning code for my kernel following the guidance of PCI, although I'm a tad concerned at the lack of an ATA controller (class 1, subclass 5) in the output on Qemu, Bochs and VirtualBox. On VirtualBox I get a SATA controller listed (class 1, subclass 6), but even though I have an IDE controller specified in the machine settings the ATA controller does not show up. I don't get a SATA controller listed in Bochs or Qemu, but I don't think I've told them to make one. I have not tried it yet on real hardware, as I want to make sure it works in emulators first. I know the ports for ATA are pretty much standardised, but according to the DMA page on the wiki I need to know BAR4 of the disk controller, so this is a concern as I am planning to use DMA with ATA.

Here is the code I'm using (C++)

Code: Select all

void pciInit() {
	for (int bus = 0; bus < 256; bus++) 
		for (int device = 0; device < 32; device++) {
			int vendorID = pciConfigRead(bus, device, 0, 0) & 0xFFFF;
			if (vendorID == PCI_INVALID_VENDOR_ID) continue;

			int headerType = 0xFF & (pciConfigRead(bus, device, 0, 0xC) >> 16);
			int functions = (headerType & 0x80) ? 8 : 1;

			for (int function = 0; function < functions; function++)
				if ((pciConfigRead(bus, device, function, 0) & 0xFFFF) != 0xFFFF) {
					int vendorID = pciConfigRead(bus, device, 0, 0) & 0xFFFF;
					int deviceID = (pciConfigRead(bus, device, 0, 0) >> 16) & 0xFFFF;
					int classCode = (pciConfigRead(bus, device, 0, 8) >> 24) & 0xFF;
					int subclassCode = (pciConfigRead(bus, device, 0, 8) >> 16) & 0xFF;

					printf("Detected device: vendor 0x%X\tdevice 0x%X  \tclass 0x%X\tsubclass 0x%X\n",
							vendorID, deviceID, classCode, subclassCode);
				}
		}
}
I run Qemu with: qemu-system-x86_64 -drive file=drive,format=raw,media=disk,index=0 -m 2048

Attached below is a screenshot of the output on Qemu, Bochs and VirtualBox.

My questions:
1. Is my PCI scanning code correct? Should I be initialising something else first?
2. How can I get it to find the ATA controller? It is not listed in emulators?
3. If I can't find the controller, how should I get the information for DMA? ACPI?

Thanks for your help. :D

Re: No ATA Controller in PCI Configuration Space?

Posted: Sat Feb 20, 2016 1:47 pm
by BrightLight
In my ATA code, I search for PCI class/subclass 1/1 (0x0101) and it runs on QEMU, Bochs and VirtualBox.
Although I don't see any class/subclass 1/1 devices in your screenshot... Are you sure there's an IDE controller?
In QEMU, just do:

Code: Select all

qemu-system-x86_64 yourdiskimage.img
If you cannot use DMA in any way, throw an error or fall back to PIO.

Re: No ATA Controller in PCI Configuration Space?

Posted: Sat Feb 20, 2016 1:52 pm
by nakst
omarrx024 wrote:In my ATA code, I search for PCI class/subclass 1/1 (0x0101) and it runs on QEMU, Bochs and VirtualBox.
Although I don't see any class/subclass 1/1 devices in your screenshot... Are you sure there's an IDE controller?
In QEMU, just do:

Code: Select all

qemu-system-x86_64 yourdiskimage.img
If you cannot use DMA in any way, throw an error or fall back to PIO.
Okay, I tried running Qemu with this command but I got exactly the same output as before. Do you know which bus and device you find the controller on with Qemu?

Re: No ATA Controller in PCI Configuration Space?

Posted: Sat Feb 20, 2016 1:55 pm
by BrightLight
Is your PCI code for searching functions correct?
Did you try running QEMU with:

Code: Select all

-monitor stdio
And then running "info pci"? Is there an IDE controller?
From my kernel debug messages:

Code: Select all

[ata] looking for PCI IDE controller...
[ata] done, found IDE controller at PCI slot 00:01:01
So in Bochs, QEMU and VirtualBox, the IDE controller is at bus 0, device 1, function 1.
EDIT: I just noticed: why are you reading the PCI vendor/device/class codes only with the bus and device? Why don't you pass the function?

Re: No ATA Controller in PCI Configuration Space?

Posted: Sat Feb 20, 2016 2:07 pm
by nakst
Ahhhh, I just noticed it in a debugger. I'd gone through the code several times but only just noticed it.
Thanks for your help! I'm getting the correct class and subclass codes now!
Sometimes having someone else proofread you code is really useful!

Re: No ATA Controller in PCI Configuration Space?

Posted: Sat Feb 20, 2016 2:15 pm
by nakst
To anyone who wants it, here is the final (and working!) code:

Code: Select all

	for (int bus = 0; bus < 256; bus++)
		for (int device = 0; device < 32; device++)
			for (int function = 0; function < 8; function++) {
				int vendorID = (pciConfigRead(bus, device, function, 0) & 0xFFFF);
				if (vendorID != PCI_INVALID_VENDOR_ID) {
					int deviceID = (pciConfigRead(bus, device, function, 0) >> 16) & 0xFFFF;
					int classCode = (pciConfigRead(bus, device, function, 8) >> 24) & 0xFF;
					int subclassCode = (pciConfigRead(bus, device, function, 8) >> 16) & 0xFF;

					Device device;
					device.type = DEVICE_TYPE_UNKNOWN;
					device.classCode = classCode;
					device.subclassCode = subclassCode;

					if (classCode == 6)
						device.type = DEVICE_TYPE_BRIDGE_DEVICE;
					else if (classCode == 3 && subclassCode == 0)
						device.type = DEVICE_TYPE_VGA_CONTROLLER;
					else if (classCode == 2 && subclassCode == 0)
						device.type = DEVICE_TYPE_ETHERNET_CONTROLLER;
					else if (classCode == 0xC && subclassCode == 3)
						device.type = DEVICE_TYPE_USB;
					else if (classCode == 1 && subclassCode == 6)
						device.type = DEVICE_TYPE_SATA;
					else if (classCode == 4 && subclassCode == 1)
						device.type = DEVICE_TYPE_AUDIO;
					else if (classCode == 1 && subclassCode == 1)
						device.type = DEVICE_TYPE_IDE;

					ADD_DARRAY(state.devices, device);
				}
			}
And the VirtualBox output is attached below.