ATA PIO Mode: Difference between revisions

Jump to navigation Jump to search
Added table of ATA commands
[unchecked revision][unchecked revision]
(→‎Registers: Added detail to illustrate differences in ports between reads and writes, added table for layout of the Control Register, added description of Error Register and Drive / Head Register)
(Added table of ATA commands)
Line 4:
 
However, when a computer is just beginning to boot there are no other processes. So PIO mode is an excellent and simple interface to utilize during bootup, until the system goes into multitasking mode.
 
 
 
==Hardware==
Line 11 ⟶ 13:
What the original IDE specification did was to detach the disk controller boards from the motherboard, and stick one controller onto each disk drive, permanently. When the CPU accessed a disk IO port, there was a chip that shorted the CPU's IO bus pins directly onto the IDE cable -- so the CPU could directly access the drive's controller board. The data transfer mechanism between the CPU and the controller board remained the same, and is now called PIO mode.
(Nowadays, the disk controller chips just copy the electrical signals between the IO port bus and the IDE cable, until the drive goes into some other mode than PIO.)
 
 
 
==Master/Slave Drives==
 
There is only one wire dedicated to selecting which drive on each bus is active. It is either electrically "high" or "low", which means that there can never be more than two devices operational on any ATA bus. They are called the master and the slave devices, for no particular reason. Their functionality is almost completely identical. There is a special IO port bit that allows a driver to select either drive as the target drive for each command byte.
 
 
 
==Primary/Secondary Bus==
Line 25 ⟶ 31:
 
When the system boots, according to the specs, the PCI disk controller is supposed to be in "Legacy/Compatibility" mode. This means it is supposed to use the standardized IO port settings. You may have no real choice but to rely on that fact.
 
 
 
==400ns delays==
Line 36 ⟶ 44:
 
There is a similar problem after writing the Command Register, with the ERR/DF bits. They are two slightly different kinds of errors that can terminate a command. BSY and DRQ will be cleared, but ERR or DF remain set <i>until just after you write a new command to the Command Register</i>. If you are using polling (see below), you should account for the fact that your first four reads of the Status Register, after sending your command byte, may have the ERR or DF bits still set accidentally. (If you are using IRQs, the Status will always be correct by the time the IRQ is serviced.)
 
 
 
==Cache Flush==
 
On some drives it is necessary to "manually" flush the hardware write cache after every write command. This is done by sending the 0xE7 command to the Command Register (then waiting for BSY to clear). If a driver does not do this, then subsequent write commands can fail invisibly, or "temporary bad sectors" can be created on your disk.
 
 
 
==Bad Sectors==
Line 51 ⟶ 63:
 
As said above, there are also "temporary bad sectors". When you read them you will get a hardware error, just like for a permanently bad sector. If you write to that sector, however, the write will work perfectly and the sector will turn back into a good sector. Temporary bad sectors can happen as a result of unflushed write caches, power spikes, or power failures.
 
 
 
==Detection and Initialization==
Line 59 ⟶ 73:
 
Measuring "float" is a shortcut for detecting that drives do not exist. Reading a non-0xFF value is not completely definitive. The definitive test for detecting drives is the [[#IDENTIFY command]].
 
 
 
===Detecting Controller IO Ports===
 
Detecting controller IO ports is probably a waste of time. During boot, the IO ports assigned to the ATA bus are supposed to be located at standardized addresses. If they are not there, your only chance of finding them is to enumerate the disk controllers on the PCI bus. Alternately, if the ports <i>are</i> at the standard addresses, then "detecting" them gains you nothing. However, you will see controller detection code around, and it is a good thing to be able to recognize it, and know what it is for. If you suspect you know the location of a set of ATA controller IO ports, and there is at least one drive attached to that bus, then you can "detect" those IO ports. ATA controller IO ports are mostly read/write ports. This means that if you write a value to (for example) the "SectorCount" IO port, then you are supposed to be able to read the same value back again, to see what it is set to. This read/write function is performed by the master drive on the bus, unless the slave drive both exists and is selected. One caveat is that if you write a value to a "non-existent" IO port, you may be able to read that value back off the bus, if you read it immediately. So, generally, the way ATA IO port detection software works is to write a byte to one suspected ATA IO port, write a different byte to a different ATA IO port, then read back and verify the two values written to the two ports. If both bytes verify, then the IO ports are read/write ports, and they can be presumed to be ATA controller IO ports. On the Primary bus, ports 0x1F2 through 0x1F5 should all be read/write.
 
 
 
===Standard and Non-standard Detection===
Line 71 ⟶ 89:
 
The other method is to use the Execute Device Diagnostics command (0x90). It supposedly sets bits in the Error Register (0x1F1 on the Primary bus) to show the existence of master and slave devices on the bus.
 
 
 
===IDENTIFY command===
Line 78 ⟶ 98:
 
At that point, if ERR is clear, the data is ready to read from the Data port (0x1F0). Read 256 16-bit values, and store them.
 
 
 
===="Command Aborted"====
Line 84 ⟶ 106:
 
'''However''', at least a few real ATAPI drives do not set the ERR flag after aborting an ATA IDENTIFY command. So do not depend completely on the ERR flag after an IDENTIFY.
 
 
 
====Interesting information returned by IDENTIFY====
Line 98 ⟶ 122:
 
* uint16_t 100 through 103 taken as a uint64_t contain the total number of 48 bit addressable sectors on the drive. (Probably also proof that LBA48 is supported.)
 
 
 
==Addressing Modes==
 
Currently there are three addressing modes to select particular sectors to read or write on a disk. They are 28 bit LBA, 48 bit LBA, and CHS. CHS mode is obsolete, but is discussed quickly below. The number of bits in the LBA modes refer to the number of significant bits in the sector "address", called an LBA. In 28 bit mode, LBAs from 0 to 0x0FFFFFFF are legal. This gives a total of 256M sectors, or 128GB of addressable space. So 28 bit LBA mode is also obsolete for many current drives. However, 28 bit PIO mode is faster than 48 bit addressing, so it may be a better choice for drives or partitions that do not violate the maximum LBA value limitation.
 
 
 
===Absolute/Relative LBA===
 
All the ATA commands that use LBA addressing require "absolute" LBAs (ie. the sector offset from the very beginning of the disk -- completely ignoring [[Partition Table|partition]] boundaries). At first glance, it might seem most efficient to store the LBA values in this same format in your OS. However, this is not the case. It is always necessary to validate the LBAs that are passed into your driver, as truly belonging to the partition that is being accessed. It ends up being smartest to use partition-relative LBA addressing in your code, because you then never need to test if the LBA being accessed is "off the front" of your current partition. So you only need to do half as many tests. This makes up for the fact that you need to add the absolute LBA of the beginning of the current partition to every "relative" LBA value passed to the driver. At the same time, doing this can give you access to one additional LBA address bit. (See the [[#ATA Driver|"33 bit LBA" driver]] code below.)
 
 
 
===Registers===
Line 379 ⟶ 409:
 
All other bits are reserved and should always be clear. In general, you will want to leave HOB, SRST, and nIEN cleared. Set each Device Control Register to 0 once, during boot.
 
 
 
==Resetting a drive / Software Reset==
 
For non-ATAPI drives, the only method a driver has of resetting a drive after a major error is to do a "software reset" on the bus. Set bit 2 (SRST, value = 4) in the proper Control Register for the bus. This will reset <b>both</b> ATA devices on the bus. Then, you have to clear that bit again, yourself. The master drive on the bus is automatically selected. ATAPI drives set values on their LBA_LOW and LBA_HIGH IO ports, but are not supposed to reset or even terminate their current command.
 
 
 
==IRQs==
 
Note: When a command terminates with an error, it does <b>not</b> generate an IRQ. It is smart to check the Alternate Status Register a few times per second to see if the ERR bit has set. Otherwise, you will not know until your command times out.
 
 
 
===Handling an IRQ===
Line 405 ⟶ 441:
 
Note: if you are still in singletasking mode, and polling the Regular Status Register in PIO mode only, then the only thing the IRQ handler needs to do is send EOI to the PICs. You may even want to set the Control Register's nIEN bit, to try to shut off disk IRQs completely.
 
 
 
===Polling the Status vs. IRQs===
Line 417 ⟶ 455:
<b>How to poll</b> (waiting for the drive to be ready to transfer data):
Read the Regular Status port until bit 7 (BSY, value = 0x80) clears, and bit 3 (DRQ, value = 8) sets -- or until bit 0 (ERR, value = 1) or bit 5 (DF, value = 0x20) sets. If neither error bit is set, the device is ready right then.
 
 
 
===Preempting/Preventing IRQs from firing:===
Line 423 ⟶ 463:
A much more complete way to prevent ATA IRQs from happening is to set the nIEN bit in the Control Register of a particular <i>selected drive</i>. This should prevent the drive on the bus from sending any IRQs at all, until you clear the bit again. <b>However, it may not always work!</b> Several programmers have reported problems making nIEN work.
Drives only respond to <i>newly written values</i> of nIEN when they are the selected drive on the bus. That is, if a drive is selected, and you set nIEN, then select the other drive with the Drive Select Register, then clear nIEN -- then the first drive should "remember" forever that it was told not to send IRQs -- until you select it again, and write a 0 to the nIEN bit in the Control Register.
 
 
 
===Read/Write Multiple===
Line 429 ⟶ 471:
 
<b>NOTE:</b> Overall, PIO mode is a slow transfer method. Under real working conditions, almost any drive should be controlled by a DMA driver, and should not be using PIO. Trying to speed up PIO mode by preempting IRQs (or any other method) is mostly a waste of time and effort. ATA drives that are 400MB or smaller may not support Multiword DMA mode 0, however. If you want to support drives that size, then perhaps a <i>little</i> effort spent on PIO mode drivers is worthwhile.
 
 
 
==x86 Directions==
Line 456 ⟶ 500:
===Writing 28 bit LBA===
To write sectors in 28 bit PIO mode, send command "WRITE SECTORS" (0x30) to the Command port. Do <b>not</b> use <b>REP</b> OUTSW to transfer data. There must be a tiny delay between each OUTSW output uint16_t. A jmp $+2 size of delay. Make sure to do a Cache Flush (ATA command 0xE7) after each write command completes.
 
 
 
===48 bit PIO===
Line 482 ⟶ 528:
 
After the command byte is sent, transfer each sector of data in exactly the same way as for a 28 bit PIO Read/Write command.
 
 
 
==CHS mode==
Line 512 ⟶ 560:
 
Note on the "magic bits" sent to port 0x1f6: Bit 6 (value = 0x40) is the LBA bit. This must be clear for CHS transfers, as said above. Bits 7 and 5 are obsolete for <b>current</b> ATA drives, but must be set for backwards compatibility with very old (ATA1) drives.
 
 
 
==ATA Commands==
 
And finally, a list of many ATA commands.
 
{| {{wikitable}}
|-
! Command
! Description
|-
| 1x
| Recalibrate
|-
| 20
| Read sectors with retry
|-
| 21
| Read sectors without retry
|-
| 22
| Read long with retry
|-
| 23
| Read long without retry
|-
| 30
| Write sectors with retry
|-
| 31
| Write sectors without retry
|-
| 32
| Write long with retry
|-
| 33
| Write long without retry
|-
| 3C
| Write verify
|-
| 40
| Read verify sectors with retry
|-
| 41
| Read verify sectors without retry
|-
| 50
| Format track
|-
| 7X
| Seek
|-
| 8x
| Vendor unique
|-
| 90
| Execute drive diagnostics
|-
| 91 or E0
| Initialize drive parameters
|-
| 94 or E1
| Standby immediate
|-
| 95 or E2
| Idle immediate
|-
| 96 or E3
| Standby
|-
| 97 or E4
| Idle
|-
| 98 or E5
| Check power mode
|-
| 99 or E6
| Set sleep mode
|-
| 9A
| Vendor unique
|-
| C0 - C3
| Vendor unique
|-
| C4
| Read multiple
|-
| C5
| Write multiple
|-
| C6
| Set multiple mode
|-
| C8
| Read DMA with retry
|-
| C9
| Read DMA without retry
|-
| CA
| Write DMA with retry
|-
| CB
| Write DMA with retry
|-
| E4
| Read buffer
|-
| E8
| Write buffer
|-
| E9
| Write same
|-
| EC
| Identify drive
|-
| EF
| Set features
|-
| F0 - F4
| EATA standard
|-
| F5 - FF
| Vendor unique
|-
|}
 
 
 
==x86 Code Examples==
Line 539 ⟶ 719:
}
</source>
 
 
 
===ATA Driver===
Line 822 ⟶ 1,004:
ret
</source>
 
 
 
==Comments==
ATA Execute Drive Diagnostic command (0x90) may not work right in Bochs.
 
 
 
==See Also==
Line 830 ⟶ 1,016:
* [[MBR_(x86)|Master Boot Record (x86)]]
* [[Partition_Table|Partition Table (x86)]]
 
 
 
===Threads===
Line 835 ⟶ 1,023:
*[http://www.osdev.org/phpBB2/viewtopic.php?t=15314 ATA PIO code library (ASM code from XCHG)]
*[http://forum.osdev.org/viewtopic.php?f=1&p=167798#p167798 IDE Tutorial (C code from ''mostafazizo'')]
 
 
 
===External Links===
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.

Navigation menu