ATA/ATAPI using DMA: Difference between revisions

Jump to navigation Jump to search
m
s/dword/uint32_t/g
[unchecked revision][unchecked revision]
mNo edit summary
m (s/dword/uint32_t/g)
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>
 
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.

Navigation menu