131 lines
3.1 KiB
C++
131 lines
3.1 KiB
C++
|
#include "atapiDevice.h"
|
||
|
#define IS_BIT_SET(x, bit) ((x >> bit & 0x1) == 1)
|
||
|
|
||
|
void ATA_DEVICE::Soft_Reset(uint8_t DEVICE_CHANNEL,DEVICE_DRIVE drive){
|
||
|
printf("Soft reseting drive...\n");
|
||
|
outb(channels[DEVICE_CHANNEL].base + 7 , 0x4);
|
||
|
// wait a bit..
|
||
|
for(int i = 0 ; i < 1000000; i++){
|
||
|
asm volatile("NOP");
|
||
|
}
|
||
|
outb(channels[DEVICE_CHANNEL].base + 7 , 0x0);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void ATA_DEVICE::Identify(uint8_t DEVICE_CHANNEL,DEVICE_DRIVE drive ){
|
||
|
// lets ignore which port we actually want to check for now !
|
||
|
|
||
|
/*
|
||
|
THE STEPS INVOLVED
|
||
|
|
||
|
1. Select the target drive by sending master (0x0A) or slave (0x0B) to the
|
||
|
drive select IO port
|
||
|
|
||
|
2. Set the Sectorcount, LBAlo, LBAmid and LBAhi IO ports to 0
|
||
|
|
||
|
3. Send the identify command (0xEC) to the command IO port
|
||
|
|
||
|
4. Read the status port
|
||
|
4.2 If the value is 0x0 the drive does not exist
|
||
|
4.3 If it has any other value continue
|
||
|
5. poll the status port until bit 7 is clear.
|
||
|
6. Check if the LBAmid and LBAhi ports are non-zero
|
||
|
6.2. If non-zero stop polling this is not an ATA device
|
||
|
6.3 If zero continue
|
||
|
|
||
|
7. poll status port until bit 3 is set or bit 0 is set
|
||
|
|
||
|
8. if err is clear, read the data from the data port
|
||
|
|
||
|
|
||
|
*/
|
||
|
|
||
|
|
||
|
// Assuming Master here
|
||
|
// Select the target drive
|
||
|
outb(0x176, 0x0A); // on the primary bus select the master drive
|
||
|
|
||
|
// Set the Sectorcount, LBAlo, LBAmid and LBAhi IO ports to 0
|
||
|
outb(0x172, 0);
|
||
|
|
||
|
outb(0x173, 0);
|
||
|
|
||
|
outb(0x174, 0);
|
||
|
|
||
|
outb(0x175, 0);
|
||
|
|
||
|
// send the identify command;
|
||
|
outb(0x177, 0xA1);
|
||
|
|
||
|
// read the status port
|
||
|
uint8_t status = inb(0x177);
|
||
|
if( status == 0x00){
|
||
|
printf("No drive\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
while(true){
|
||
|
status = inb(0x177);
|
||
|
|
||
|
if( status & (~8))
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
printf("Is this an ATA device?\n");
|
||
|
uint8_t LBAmid = inb(0x174);
|
||
|
uint8_t LBAhi = inb(0x175);
|
||
|
|
||
|
printf("LBAmid: 0x%x, LBAhi: 0x%x\n", LBAmid, LBAhi);
|
||
|
|
||
|
|
||
|
if( LBAhi != 0x0 || LBAmid != 0x0){
|
||
|
printf("Not ATA device.. Stopping..\n");
|
||
|
// return;
|
||
|
}
|
||
|
|
||
|
while(true){
|
||
|
status = inb(0x177);
|
||
|
printf( "Status bit: 0x%x\n", status);
|
||
|
if ( IS_BIT_SET(status, 3)){
|
||
|
printf("Status: ready!\n");
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
if( IS_BIT_SET(status, 0)){
|
||
|
printf("Status: error!\n");
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( IS_BIT_SET(status, 0) == false){
|
||
|
// READ DATA
|
||
|
|
||
|
uint16_t deviceIdentify [256];
|
||
|
|
||
|
for (int i= 0; i < 256; i++){
|
||
|
uint8_t data = inb(0x170);
|
||
|
uint8_t data2 = inb(0x170);
|
||
|
|
||
|
deviceIdentify[i] = (uint16_t) ( (uint16_t) data << 8 | (uint16_t) data2 );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
printf("Data received!\n");
|
||
|
}
|
||
|
|
||
|
printf("Error bit was set!\n");
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void ATA_DEVICE::Read(uint8_t DEVICE_CHANNEL, DEVICE_DRIVE drive) {
|
||
|
printf("Not implemented");
|
||
|
}
|
||
|
|
||
|
void ATA_DEVICE::Write(uint8_t DEVICE_CHANNEL, DEVICE_DRIVE drive) {
|
||
|
printf("Not implemented");
|
||
|
}
|