ATA-ATAPI detection
Posted: Wed Aug 12, 2009 3:48 pm
There seems to be nonstandard issues to consider for doing that, and even BIOS functions for that purpose seem difficult to use, and the times I have done this the detection code has proven unstable, working correctly or partially at undetermined times.
I have some textmode DOS assembly code (attached at the end).
It shows 2 main letters in the whole screen: an "M" for Master and an "S" for Slave.
Also shown is the value read from the Status Register.
For example if it reads "M 00 S 00" it would mean that both Master and Slave status registers contain 00h.
Any of those letters should change in color if there's nothing connected to the respective bus (i.e., if status is 0,7F or FF).
For example, if I have disconnected everything from the IDE connectors of the PC, both those letters should change color to demonstrate that reading from the status ports 0x1F7 and 0x177. Unfortunately, every PC that I have, seems to return different "floating bus" values, and worst of all is that none of those values is 0xFF, which is a bad start.
I didn't get the 0x7F value either, which is recommended in this post:
http://forum.osdev.org/viewtopic.php?p=111815#p111815
=====================================================
So, I better start with this from the wiki, since I needed a 100% reliable "floating bus detection":
http://wiki.osdev.org/ATA_PIO_Mode#Dete ... ialization
I tried to comply with that, and it worked unreliably. Here is sort of C code:
======================================================
And here is a small report of what values I got. As you can see, with this values it seems pretty unreliable to scan for a floating bus in this way. So, please tell me if I'm coding things the wrong way.
0x50 == whenever there's at least 1 disk connected to a bus
0x50 == in a Thinkpad 390X, this value appeared in the slave bus (with only one, single Primary Master!!!)
0x51 == in the Thinkpad 390X slave bus when there's nothing connected anywhere!!!
0x00 == in older machines, when there's nothing in a bus
0x20 == a 5-year old PCChips AMD when there's nothing in a bus
0x2A == a 4-year old AMD64 KM88-V when there's nothing in a bus
This would be a table of Master/Slave (MS) results, and see how the {YES/NO} and the {NO/NO} entries differ without pattern between PC's:
ThinkPad 390X:
Old PIII XCel2000:
PCChips:
K8MM-V:
What should or could be done then with this idea of a floating IDE bus if a simple floating 0xFF cannot be scanned consistently but instead you get a 0x00, 0x2A, 0x20 and even 0x50 or 0x51?
I have some textmode DOS assembly code (attached at the end).
It shows 2 main letters in the whole screen: an "M" for Master and an "S" for Slave.
Also shown is the value read from the Status Register.
For example if it reads "M 00 S 00" it would mean that both Master and Slave status registers contain 00h.
Any of those letters should change in color if there's nothing connected to the respective bus (i.e., if status is 0,7F or FF).
For example, if I have disconnected everything from the IDE connectors of the PC, both those letters should change color to demonstrate that reading from the status ports 0x1F7 and 0x177. Unfortunately, every PC that I have, seems to return different "floating bus" values, and worst of all is that none of those values is 0xFF, which is a bad start.
I didn't get the 0x7F value either, which is recommended in this post:
http://forum.osdev.org/viewtopic.php?p=111815#p111815
=====================================================
So, I better start with this from the wiki, since I needed a 100% reliable "floating bus detection":
http://wiki.osdev.org/ATA_PIO_Mode#Dete ... ialization
--------------------------------Floating Bus
The disk that was selected last (by the BIOS, during boot) is supposed to maintain control of the electrical values on each IDE bus. If there is no disk connected to the bus at all, then the electrical values on the bus will all go "high" (to +5 volts). A computer will read this as an 0xFF byte -- this is a condition called a "floating" bus. This is an excellent way to find out if there are no drives on a bus. Before sending any data to the IO ports, read the Regular Status byte. The value 0xFF is an illegal status value, and indicates that the bus has no drives. The reason to read the port before writing anything is that the act of writing can easily cause the voltages of the wires to go screwey for a millisecond (since there may be nothing attached to the wires to control the voltages!), and mess up any attempt to measure "float".
I tried to comply with that, and it worked unreliably. Here is sort of C code:
Code: Select all
//Our delayed loop value. The greater this 32-bit value,
//the less our test loop will last alive:
// ECX == 0x00000000 will last the most (too much time)
// ECX == 0x00000001 will last the least (finishes too fast)
//
ecx=0xFFF00000;
while(1)
{
ecx++; //Increase original ECX value from 0 to 0xFFFFFFFF
//and back to 0 when overflow takes place to control
//the limit of this loop.
//Test the MASTER BUS to see if the
//Status Register (7 + 1F0h) has the
//floating value 0xFF or 0x7F or 0x00:
//
al=inportb(0x1F7);
if( al==0xFF || al==0x00 || al==0x7F )
{
;//If yes, indicate that it's FLOATING
}
//Test the SLAVE BUS to see if the
//Status Register (7 + 170h) has the
//floating value 0xFF or 0x7F or 0x00:
//
al=inportb(0x177);
if( al==0xFF || al==0x00 || al==0x7F )
{
;//If yes, indicate that it's FLOATING
}
if(ecx==0)break;
}
And here is a small report of what values I got. As you can see, with this values it seems pretty unreliable to scan for a floating bus in this way. So, please tell me if I'm coding things the wrong way.
0x50 == whenever there's at least 1 disk connected to a bus
0x50 == in a Thinkpad 390X, this value appeared in the slave bus (with only one, single Primary Master!!!)
0x51 == in the Thinkpad 390X slave bus when there's nothing connected anywhere!!!
0x00 == in older machines, when there's nothing in a bus
0x20 == a 5-year old PCChips AMD when there's nothing in a bus
0x2A == a 4-year old AMD64 KM88-V when there's nothing in a bus
This would be a table of Master/Slave (MS) results, and see how the {YES/NO} and the {NO/NO} entries differ without pattern between PC's:
ThinkPad 390X:
Code: Select all
_____________________________
| M | S | Status (M-S) |
|-----+-----+-----------------|
| No | No | Ma=0x00,Sl=0x51 |
| Yes | No | Ma=0x50,Sl=0x50 |
|_____|_____|_________________|
Old PIII XCel2000:
Code: Select all
_____________________________
| M | S | Status (M-S) |
|-----+-----+-----------------|
| No | No | Ma=0x00,Sl=0x00 |
| No | Yes | Ma=0x00,Sl=0x50 |
| Yes | No | Ma=0x50,Sl=0x00 |
| Yes | Yes | Ma=0x50,Sl=0x50 |
|_____|_____|_________________|
PCChips:
Code: Select all
_____________________________
| M | S | Status (M-S) |
|-----+-----+-----------------|
| No | No | Ma=0x20,Sl=0x20 |
| No | Yes | Ma=0x20,Sl=0x50 |
| Yes | No | Ma=0x50,Sl=0x20 |
| Yes | Yes | Ma=0x50,Sl=0x50 |
|_____|_____|_________________|
K8MM-V:
Code: Select all
_____________________________
| M | S | Status (M-S) |
|-----+-----+-----------------|
| No | No | Ma=0x2A,Sl=0x2A |
| No | Yes | Ma=0x2A,Sl=0x50 |
| Yes | No | Ma=0x50,Sl=0x2A |
| Yes | Yes | Ma=0x50,Sl=0x50 |
|_____|_____|_________________|