Page 1 of 1

PCI bus + IDE DMA

Posted: Fri Jan 30, 2009 8:59 am
by captainwiggles
Hey guys, i'm trying to implement IDE busmaster DMA, so after reading the wiki, I realised i needed to get the base address for the busmaster ide controller, which lead me to write code to enumerate the PCI bus.

So I found the controller I was looking for PIIX3 IDE Interface (Triton II) (device id 0x7010), now I'm a bit stuck on working out how to get the base register still, looking at all the BAR registers in the config space for this device + function, gives me all 0s, except one which is 0x0000C001, so I take that to mean the base address is 0xC000, and its an I/O address. However when I do a inportb(0xC002); //+2 to get the status register, i get all 0s, where i should get bit 5 as a 1 (DMA available on drive 0).

Any ideas about what I'm doing wrong?

Wiggles

edit: sorry, i'm testing with bochs 2.3.6

Re: PCI bus + IDE DMA

Posted: Fri Jan 30, 2009 9:38 am
by jal
captainwiggles wrote:Any ideas about what I'm doing wrong?
I can only guess what you are doing wrong, but getting all 0s in the BAR registers doesn't seem right for an IDE controller.


JAL

Re: PCI bus + IDE DMA

Posted: Fri Jan 30, 2009 9:48 am
by captainwiggles
Ok, its bus 0, device 1, function 1, vendor id 0x8086, device id 0x7010, base class 0x01, sub class 0x01, the first 4 BARs and the 6th are 0x00000000, the 5th is 0xC001.

I'm fairly sure I have the right device.

Re: PCI bus + IDE DMA

Posted: Fri Jan 30, 2009 10:00 am
by jal
captainwiggles wrote:I'm fairly sure I have the right device.
That would seem so. But if the BAR reads 0xC001, why are you assuming it's actual 0xC000? Have you tried reading at 0xC003 instead of 2?


JAL

Re: PCI bus + IDE DMA

Posted: Fri Jan 30, 2009 10:04 am
by captainwiggles
because if you look at the PCI specs for a BAR, bit 0 being 1 means we are talking about I/O ports rather than memory mapped. Also bit 1 is reserved and set to 0, I was unsure whether the base address is the register with those last 2 bits as 0 or just not using those, ie. giving 0xC001 >> 2 = 0x3000, and yes i did try 0x3002.

The wiki suggest you should just 0 the last bit, the PCI spec has the diagram as the last 2 bits being seperate.

edit: So checking the piix3 spec, it suggests that the base address is in fact the low word of the 5th BAR, with the last 4 bits set to 0, which would indicate that the bas address should be 0xC000, so the bus master ide status register should be 0xC002.

edit2: think i've got it, the piix3 spec, suggests that this register defaults to 0, and the device driver should set the relevant bits once its set up DMA ..

Re: PCI bus + IDE DMA

Posted: Fri Jan 30, 2009 2:03 pm
by bewing
It sounds to me like you are doing everything right so far. I think the answer is that the bochs bios is not initializing your controller for DMA mode. So, it sounds like you are going to need to do all the DMA initialization steps yourself ... matching and setting DMA modes, etc.

Re: PCI bus + IDE DMA

Posted: Fri Jan 30, 2009 3:10 pm
by captainwiggles
any chance you have any links for that?

I think i'm doing everything correct, but the irq never arrives (works fine with interrupt driven I/O).

Wiggles

Re: PCI bus + IDE DMA

Posted: Sat Jan 31, 2009 9:01 am
by bewing
IIRC, this Intel manual has pretty extensive instructions on the initialization sequence, but this is all I have:
http://bos.asmhackers.net/docs/ata/docs/29860001.pdf

Re: PCI bus + IDE DMA

Posted: Sat Jan 31, 2009 10:24 am
by Laksen
If the first 4 bar's are 0 that means you have to use the legacy addresses for the IDE controller. The 5th bar is indeed the bus master address. You have to remember to turn bus mastering on though by setting bit 2 in the PCI command register

Re: PCI bus + IDE DMA

Posted: Sat Jan 31, 2009 11:25 am
by captainwiggles
Ok, so I enabled bit 2 of the PCI device command register, but yet still no interrupt.

Here is exactly what I do.

1) loop thhrough each bus, device and function
2) if a device and function is the piix3 ide controller, i get the 5th BAR and save it in a global var
3) I set bit 5 of the busmaster ide status register (drive 0 is DMA capable)
4) I set bit 2 of the PCI device + function command register (the bus master bit)
5) i allocate a page for the prdt
6) i allocate another page for the first entry into the prdt, the first entry is:
0x00 0x30 0x41 0x00 0x00 0x02 0x00 0x80 (individual chars, in little endion, direct from hex dump)
So that gives us 0x413000 as the physical address of the first and only region, that takes 512 bytes (1 sector), and the list bit is set, signifying end of table.
7) send 0 to the bus master ide command register (read mode + don't start)
8) send the physical address of the prdt to the dptr register
9) get the value of the bus master ide status register, and clear bits 1 and 2, writting it back again afterwards (interrupt and error bits)
10) send drive select, the lba28 address and the sector count to the hdd (this is the same function i use for pio and interrupt driven, so i'm sure thats correct)
11) send 0xC8 to the hdd (READ DMA command)
12) write 0x01 to the busmaster ide command register (start bit, the rest of the register is 0 as we wrote 0 to it before)
13) if i read the status register now, i see 0x21 which is: drive 0 is DMA capable as set before, and bus master ide active.
14) I make the thread yield and restore a user mode proc.
15) IRQ 14 does not fire (it does for interrupt driven I/O)

So anyone see anything I missed? also i noticed that in the pci devices config space, there are interrupt line and interrupt pin registers, which are both 0x00 for this device.

Thanks again for any help.

Wiggles

Re: PCI bus + IDE DMA

Posted: Sat Jan 31, 2009 10:27 pm
by david
you want to read/write hard disk using DMA ?

Re: PCI bus + IDE DMA

Posted: Sun Feb 01, 2009 8:34 am
by captainwiggles
erm .. yeah, reading at the moment, but writting would be very similar.

I've been reading the spec bewing posted, it's been helpful, i've added a lot of extra code to initialize other stuff, however everything I've done still fails, in exactly the same way, no interrupt ever arrives.

The extra stuff i've done is:

1) use identify device command, to get fastest mw dma, udma and pio modes.
2)check if we have an 80 connector cable or a 40 connector one (seems to be 40, so i revert to udma 2)
3) use the set features cmd to set the transfer mode to udma mode 2.

anyone got a working dma driver i could look at, specifically the part where you initialize the drive + pci stuff.

Re: PCI bus + IDE DMA

Posted: Wed Jul 22, 2009 4:25 am
by rezoimnadze
So I found the controller I was looking for PIIX3 IDE Interface (Triton II) (device id 0x7010)
How can i find and use this drive in my emulator? (bochs) I need any standard IDE emulation to make Driver using Bus Mastering DMA.

Bochs configuration:

Code: Select all

i440fxsupport: enabled=1, slot1=??
generates error.
All the BARs are 0x0 in my PCI Configuration Space.

----
Problem solved
Tthank you :D

On function 8 and 9 are devices 0x7000 and 0x7010.

Re: PCI bus + IDE DMA

Posted: Sat Jul 25, 2009 8:15 am
by rezoimnadze
This article helped me very much.

I came to this problem and tested it in VMWare too. VMWare has one device 0x7111 PIIX4/4E/4M IDE Controller. BAR5 1051.
As you said Base address will be 1050 and status register port 1052.

I've got 0x20 from status register. Drive 0 DMA Capabe.

I think Bochs doesn't have Bus Master IDE capable drive for default.
Help us, If someone realy knows how to add drive like this.