[ATA DMA Impl.] Disk controller not detected on PCI bus

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
fiveayem
Member
Member
Posts: 51
Joined: Sun Aug 14, 2011 8:01 am

[ATA DMA Impl.] Disk controller not detected on PCI bus

Post by fiveayem »

Hi,

I have been developping an OS for two months now and today, I intend to implement ATA R/W via DMA. I have read the tutorial on the website, which is quite consistent. However, to configure DMA, I need to access the hard drive controller's PCI Configuration Space and my problem is this device is not detected on the PCI bus.

To be more precise, the only detected devices are the following (and there references do exist, cf. http://www.pcidatabase.com) :

Device 1 :
VendorID : 0x8086
DeviceID : 0x1237
Class code : 0x0006
Subclass : 0x0000

Device 2 :
VendorID : 0x8086
DeviceID : 0x7000
Class code : 0x0006
Subclass : 0x0001

Device 3 :
VendorID : 0x1013
DeviceID : 0x00B8
Class code : 0x0003
Subclass : 0x0000

Device 4 :
VendorID : 0x10EC
DeviceID : 0x8139
Class code : 0x0002
Subclass : 0x0000

Finally, you have here my code. I implemented PCI read/write functions in the same way as in Linux source code, that is to say that the functions belonging to PCIread.../PCIwrite... family work with the following parameters : bus, device, function, offset.

Code: Select all

void PCItest()
{
  u32 bus = 0, dev = 0;
  u16 vendorId = 0;
  while(bus < 2)
  {
    dev = 0;
    while(1)
    {
      vendorId = PCIreadWord(bus, dev, 0, PCI_REG_VENDOR_ID);
      if(vendorId != 0xFFFF)
      {
	print("Bus "); printnumber(bus); print(" device "); printnumber(dev); print("\n");
	print("   Vendor ID : "); printnumber(vendorId); print("\n");
	print("   Device ID : "); printnumber(PCIreadWord(bus, dev, 0, PCI_REG_DEVICE_ID)); print("\n");
	print("   Class code : "); printnumber(PCIreadByte(bus, dev, 0, PCI_REG_CLASS_CODE)); print("\n");
	print("   Subclass : "); printnumber(PCIreadByte(bus, dev, 0, PCI_REG_SUBCLASS)); print("\n");
	dev++;
      }
      else
	break;
    }
    bus++;
  }
}
Maybe this info may be of some help : I run my kernel on QEMU.

Thanks for your help.

PS : My code may be someway wrong. Indeed, it scans bus 0 and 1, but actually, I do not know if there can be more than one PCI bus in a machine.

PS 2 : Sorry if my English is not so good, I am French.
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: [ATA DMA Impl.] Disk controller not detected on PCI bus

Post by Combuster »

It's not unlikely that the harddisk controller is on a multifunctional device, ie function is not 0. You should check function 0 if it has multiple functions to prevent getting duplicate results, and then enumerate functions 1..7 if it happens to be a multifunctional device.

Basically your current listing reads as northbridge, southbridge, pci slot 1 (vga), pci slot 2 (network). The southbridge usually has all the fun stuff to test your PCI detection algorithm, and in my local QEMU version, the primary ATA controller shows up as bus 0 device 1 function 1
"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 ]
fiveayem
Member
Member
Posts: 51
Joined: Sun Aug 14, 2011 8:01 am

Re: [ATA DMA Impl.] Disk controller not detected on PCI bus

Post by fiveayem »

Ok, and with function 1, can I access the device's PCI configuration space in the same way as function 0 ? Actually, why are some devices multifunctional ?
fiveayem
Member
Member
Posts: 51
Joined: Sun Aug 14, 2011 8:01 am

Re: [ATA DMA Impl.] Disk controller not detected on PCI bus

Post by fiveayem »

Thanks, it seems that works. So, if I have understood, for each bus and device, I have to "test" every function in order to gather a complete list of the devices connected to the buses, am I wright ?
Bietje
Member
Member
Posts: 100
Joined: Wed Apr 20, 2011 6:57 am

Re: [ATA DMA Impl.] Disk controller not detected on PCI bus

Post by Bietje »

fiveayem wrote:Thanks, it seems that works. So, if I have understood, for each bus and device, I have to "test" every function in order to gather a complete list of the devices connected to the buses, am I wright ?
Hi.

Almost right.. You should only check other functions of the devices if function 0 says its a multi function device. If you do not do this, several devices might show up 8 times (because they aren't multi function). So in pseudo code you should do something like:

Code: Select all

for(all busses)
{
  for(all devices)
  {
    for(all functions)
    {
      get vendor ID.. check it bla bla;

      if(function is not mf) break;
    }
  }
}
You didn't check all functions before. This is the reason you didn't found your IDE/SATA controller. On every PC I have tested so far was the IDE or SATA controller multi function.

So how do you check that magical multifunction feature thing? You start of with calculating the address specific to the current bus, devices and function:

Code: Select all

dword x = ((1 << 31) | (dev->bus << 16) | 
                (dev->device << 11) | (dev->func << 8) | ((reg & 0x3f) << 2)) & 
                (~3);
For the 'reg' variable you fill in 0x0C. This is the offset of the cache line size byte. On the dword of this offset are also the latency timer, the header type, and the BIST. We are only interested in the header type at this moment.

The layout of the header type is as follows:

Code: Select all

bit 7                  bits 6-0
multifunc              header type
So when you read a dword with offset 0xc you should shift it to the right by 16, this puts the start of the header type at bit 0 and then bitwise and the value with 0x80. If the result != 0, then you device is multi function.

I hope this helped you out,

Greets Bietje
fiveayem
Member
Member
Posts: 51
Joined: Sun Aug 14, 2011 8:01 am

Re: [ATA DMA Impl.] Disk controller not detected on PCI bus

Post by fiveayem »

Ok, thank you very much for your help ! :)
Post Reply