ATA/ATAPI using DMA: Difference between revisions

Added an order of sending DMA commands
[unchecked revision][unchecked revision]
(Added an order of sending DMA commands)
 
(2 intermediate revisions by 2 users not shown)
Line 17:
===Verifying CRC errors===
 
Read the PCI Configuration Space worduint16_t at offset 6 (Device Status) to get the error code.
 
==The PRD Table==
 
You must set up at least one Physical Region Descriptor Table (PRDT) in memory per ATA bus, which contains some number of Physical Region Descriptors (PRDs).
(The PRDT must be dworduint32_t aligned, contiguous in physical memory, and cannot cross a 64K boundary.)
Then you need to store the physical address of the current PRDT in the Bus Master Register, of the Bus Mastering ATA Disk Controller on the PCI bus (see below).
 
===PRD setup===
 
Half of each DMA transfer is encoded in one qworduint64_t PRD entry (8 bytes) in the table.
(Why is it only half of a DMA transfer? Because the PRD does not contain any information about which LBAs to read from/write to the disk.
That information is sent in an entirely separate way to the proper disk -- see below.)
 
The low dworduint32_t is a '''physical''' memory address of a data buffer. (Keep in mind on 64 bit systems that this address must fit in a dworduint32_t!)
The next worduint16_t is a '''byte''' count (not a sector count!) of the transfer size (64K maximum per PRD transfer).
A byte count of 0 means 64K. The next worduint16_t is reserved (should be 0) except for the MSB. If the MSB is set, that indicates that this PRD is the last entry in the PRDT, and the entire set of transfers is complete.
The data buffers cannot cross a 64K boundary, and must be contiguous in physical memory (ie. they can't be "virtual" data buffers).
The byte count on the data buffers must match the number of sectors transferred by the disk. If not, the controller will error out in various ways.
Line 47:
0x0 Command (byte)
0x2 Status (byte)
0x4-0x7 PRDT Address (dworduint32_t)
(Secondary ATA bus)
0x8 Command (byte)
0xA Status (byte)
0xC-0xF PRDT Address (dworduint32_t)
</pre>
 
Line 84:
For ATA, for each PRD entry in the PRDT, the driver must issue a Read/Write DMA command to the disk; specifying a StartLBA and a sector count.
 
When the drive completes each command it sends an IRQ (possibly also when transfer in progress), to let the driver know that it is ready to transfer the next batch of data to/from the disk controller. The driver should then read the Bus Master Register Status byte.
 
The formats of the commands are precisely the same as for the 28 and 48 bit PIO mode Read and Write commands, except for the value sent to the "Command" IO Port.
Line 102:
For any error except a UDMA CRC error, it is recommended to do a Software Reset on the bus, in order to force all the devices to take the bus out of DMA mode.
 
==Standard Order of Sending Commands==
 
* Prepare a PRDT in system memory.
* Send the '''physical''' PRDT address to the Bus Master PRDT Register.
* Set the direction of the data transfer by setting the Read/Write bit in the Bus Master Command Register.
* Clear the Error and Interrupt bit in the Bus Master Status Register.
* Select the drive.
* Send the LBA and sector count to their respective ports.
* Send the DMA transfer command to the ATA controller.
* Set the Start/Stop bit on the Bus Master Command Register.
* When an interrupt arrives (after the transfer is complete), respond by resetting the Start/Stop bit.
* Read the controller and drive status to determine if the transfer completed successfully.
==Comments==
 
Anonymous user