Page 1 of 2
HDD DMA transfers
Posted: Wed May 23, 2007 11:25 am
by XCHG
I can read from and write to my HDD. I was using IN and OUT instructions but I thought I could use INSW and OUTSW instead to speed this process up. Then I thought of using DMA instead. So far, I have not been able to use DMA for HDD transfers. I have set up Channel #3 of the Master 8237A DMA for HDD transfers but I really don't get how the transfer is supposed to be done. How is the HDD going to know what channel I am using? I'd really appreciate it if somebody could tell me the steps that are involved in reading from or writing to the HDD using the 8237A DMA.
Posted: Wed May 23, 2007 12:59 pm
by mathematician
The answer is that the IDE controller has its own on board DMA, and doesn't use the motherboard DMA chips at all. However, it is the devils own job to uncover the relevant documentation, and I haven't managed it yet.
Posted: Wed May 23, 2007 2:18 pm
by xsix
i haven't tried and seen it yet but it is so difficult? i mean, ATA has commands to use with DMA( i think ) so it is so hard to figure out all the things? i'm not arrogant here, i'm just asking
Posted: Wed May 23, 2007 9:35 pm
by XCHG
Unfortunately, I have not seen much documentation about DMA transfers in ATA specifications either. I guess I will try to hunt some source codes that might give us some clue how it is done lol.
Thank you guys, appreciations.
Posted: Wed May 23, 2007 9:49 pm
by exkor
http://www.t13.org/ - get the datasheet
some more goodies: "Programming Interface for Bus Master IDE Controller"
http://www.centrillium-it.com/Projects/idems100.pdf
info in Russian(has example)
http://wasm.ru/article.php?article=atazen02
some russian pdf with example (Latin alphabet ofcaurse)
http://www.argc-argv.relc.com/5_2003/article1.pdf
example with english comments:
http://www.wasm.ru/forum/viewtopic.php?id=20412 - this one has DMA for sure
Posted: Fri May 25, 2007 12:38 am
by XCHG
Thank you guys. I have started writing some HDD functions and procedures in NASM so if anyone is interested, let me know so that I will share it here. Codes are *heavily* commented and have documentations.
I guess I am going to have to get the DMA transfers work, also.
Posted: Fri May 25, 2007 2:05 am
by AJ
Hi,
I just wonder if there would be a place for that in the Wiki? If you go to the ATA article at the moment, you get a short article on ATAPI. The question of HD access comes up quite a bit and the reply is always that "it is easy" - I'm in no position to comment as I haven't got to storage drivers yet.
I'm sure a well commented example on the wiki would go down well.
Cheers,
Adam
Posted: Fri May 25, 2007 2:51 am
by XCHG
Thank you AJ for the feedback. The functions that I have written up to this point are:
Code: Select all
DWORD __IDEProbe (void); StdCall;
Boolean __IDEIdentifyDrive (DWORD Controller, DWORD Drive, IDEDriveInformation* Buffer, DWORD BufferLength); StdCall;
DWORD __IDEDiagnose (DWORD Controller); StdCall;
DWORD __IDEReadFromPortsLBA28 (DWORD Controller, DWORD Drive, DWORD LBA28, DWORD SectorCount, void* Buffer, DWORD MaxBufferLen); StdCall;
DWORD __IDEWriteToPortsLBA28 (DWORD Controller, DWORD Drive, DWORD LBA28, DWORD SectorCount, void* SourceBuffer); StdCall;
I'm now going to start reading about DMA transfers and etc so I guess there should be plenty of more functions/procedures added to the driver. I will put them here as soon as I am finished.
Posted: Fri May 25, 2007 3:01 am
by pcmattman
AJ wrote:I'm sure a well commented example on the wiki would go down well.
I can do a LBA port i/o version...
Posted: Fri May 25, 2007 3:16 am
by AJ
Sounds like a good idea to me. As I say, I haven't started my own drivers yet (and have no intention to for a bit), so can't comment on whether DMA or LBA ports are more useful.
It just strikes me as a fairly common area of questioning on the boards - maybe a wiki article os some sort is needed.
Cheers,
Adam
Posted: Fri May 25, 2007 8:19 am
by jnc100
http://www.ata-atapi.com/atadrvr.htm has some example code on programmed io, isa dma and pci bus mastering dma for both parallel and serial ata/atapi.
I can't comment more as I haven't got to that stage yet.
Regards,
John.
Posted: Sat May 26, 2007 12:04 am
by XCHG
Isn't it ridiculous that ATA specifications state:
Host: Initialize the DMA channel
This action may occur at any point prior to this box.
But nowhere in the specification it is documented how this should be done? I think the best bet is to look at some examples but I'm wondering if it is just me or we can actually find some official specifications and documentations pertaining to DMA transfers on HDDs. I have read ATA-1 ATA-2 and ATA-3 specifications and I don't think I've left any stones unturned. Still no dice!
Posted: Sun May 27, 2007 11:14 am
by JAAman
havent looked, but mabey there is some information at
ATA-ATAPI
dont know why nobody ever mentions this site anymore
Posted: Sun May 27, 2007 5:06 pm
by octavio
On t13.org there are various documents some explain the ata command set and a bit about pio mode and others explain dma modes, search for
ata host adapter standards, y have a document from 2001 about dma and autodma (1510d).will see if i found something more to date.
Posted: Mon May 28, 2007 2:50 am
by XCHG
Maybe there is something with my eyes
but I can not see ANYTHING related to DMA in 2001 documents of T13.
However, I just found out how I should initialize the single/multi word DMA transfers. It took about a week or so by reading all the specifications and etc. I currently have coded 11 procedures/functions for IDE PIO and the whole source file is for now like ~4000 lines of code. I wonder how big the source will get when I am done with it. I will upload it here as soon as I am finished. These are the functions/procedures that I have coded up to this point:
Code: Select all
DWORD __IDEProbe (void); StdCall;
Boolean __IDEIdentifyDrive (DWORD Controller, DWORD Drive,
IDEDriveInformation* Buffer,
DWORD BufferLength); StdCall;
DWORD __IDEDiagnose (DWORD Controller); StdCall;
DWORD __IDEReadFromPortsLBA28 (DWORD Controller, DWORD Drive,
DWORD LBA28, DWORD SectorCount,
void* Buffer, DWORD MaxBufferLen); StdCall;
DWORD __IDEWriteToPortsLBA28 (DWORD Controller, DWORD Drive,
DWORD LBA28, DWORD SectorCount,
void* SourceBuffer); StdCall;
DWORD __IDERecalibrate (DWORD Controller, DWORD Drive); StdCall;
DWORD __IDESleep (DWORD Controller, DWORD Drive); StdCall;
Boolean __IDECheckDriveExistence (DWORD Controller, DWORD Drive); StdCall;
DWORD __IDESetBlockSize (DWORD Controller, DWORD Drive,
DWORD SectorsPerBlock); StdCall;
DWORD __IDEReadBlockFromPortsLBA28 (DWORD Controller, DWORD Drive,
DWORD LBA28, DWORD SectorsPerBlock,
DWORD BlockCount, void* Buffer,
DWORD MaxBufferLen); StdCall;
Boolean __IDECheckControllerExistence (DWORD Controller); StdCall;
DWORD __IDEWriteBlockToPortsLBA28 (DWORD Controller, DWORD Drive,
DWORD LBA28, DWORD SectorsPerBlock,
DWORD BlockCount, void* SourceBuffer);
DWORD __IDESetTransferMode (DWORD Controller, DWORD Drive, DWORD TransferMode); StdCall;
In the meanwhile, I don't think the DMA thing is yet solved so if anybody has any other sources, I'd be thankful if you could give us a link or something.