PCI bus + IDE DMA
-
- Posts: 23
- Joined: Tue Nov 11, 2008 3:03 pm
PCI bus + IDE DMA
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
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
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.captainwiggles wrote:Any ideas about what I'm doing wrong?
JAL
-
- Posts: 23
- Joined: Tue Nov 11, 2008 3:03 pm
Re: PCI bus + IDE DMA
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.
I'm fairly sure I have the right device.
Re: PCI bus + IDE DMA
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?captainwiggles wrote:I'm fairly sure I have the right device.
JAL
-
- Posts: 23
- Joined: Tue Nov 11, 2008 3:03 pm
Re: PCI bus + IDE DMA
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 ..
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
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.
-
- Posts: 23
- Joined: Tue Nov 11, 2008 3:03 pm
Re: PCI bus + IDE DMA
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
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
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
http://bos.asmhackers.net/docs/ata/docs/29860001.pdf
Re: PCI bus + IDE DMA
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
http://j-software.dk | JPasKernel - My Object Pascal kernel
-
- Posts: 23
- Joined: Tue Nov 11, 2008 3:03 pm
Re: PCI bus + IDE DMA
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)
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
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)
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
-
- Posts: 23
- Joined: Tue Nov 11, 2008 3:03 pm
Re: PCI bus + IDE DMA
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.
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.
-
- Posts: 8
- Joined: Tue Apr 14, 2009 2:14 am
Re: PCI bus + IDE DMA
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.So I found the controller I was looking for PIIX3 IDE Interface (Triton II) (device id 0x7010)
Bochs configuration:
Code: Select all
i440fxsupport: enabled=1, slot1=??
All the BARs are 0x0 in my PCI Configuration Space.
----
Problem solved
Tthank you
On function 8 and 9 are devices 0x7000 and 0x7010.
-
- Posts: 8
- Joined: Tue Apr 14, 2009 2:14 am
Re: PCI bus + IDE DMA
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.
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.