I have problem. My method for reading ata doesnt work. It stuck in command "while ( ( (inb(0x1F7) & ATA_SR_DRQ)==1 ) ) {}" . I have detected hard disc on primary master. I use Virtualbox. Please why virtualbox doesnt respond data from hard disc?
Code: Select all
void ata_sector(uint16_t base, uint8_t type, uint64_t addr, uint8_t drive) {
uint16_t tmpword=0;
ata_base=base;
ata_error=UNDETECTED;
drive=inb(ata_base+ATA_PORT_STATUS);
if(drive==0xFF) {
ata_error=DETECTED;
tp("ata is undetected");
return;
}
tmpword=inb(ata_base+ATA_PORT_STATUS);
if(drive==ATA_MASTER) {
outb(ata_base+ATA_PORT_DRV, 0xE0);
}
else { // ATA_SLAVE
outb(ata_base+ATA_PORT_DRV, 0xF0);
}
if ( ( (inb(ATA_PORT_STATUS) & ATA_SR_ERR)==1 ) ) { //error?
tp("ata error 2");
return;
}
//PIO28
outb(ata_base+ATA_PORT_FEATURES, 0x00);
outb(ata_base+ATA_PORT_SCT_COUNT, 0x01);
outb(ata_base+ATA_PORT_SCT_NUMBER, (unsigned char)addr);
outb(ata_base+ATA_PORT_CYL_LOW, (unsigned char)(addr >> 8));
outb(ata_base+ATA_PORT_CYL_HIGH, (unsigned char)(addr >> 16));
if(type==ATA_READ) {
outb(ata_base+ATA_PORT_COMMAND, ATA_CMD_READ_PIO); // Send command
}
else {
outb(ata_base+ATA_PORT_COMMAND, ATA_CMD_WRITE_PIO);
}
// waiting for data
while ( ( (inb(0x1F7) & ATA_SR_DRQ)==1 ) ) {}
for (uint8_t idx = 0; idx < 255; idx++)
{
if(type==ATA_READ) {
buffer[idx] = inw(ata_base + ATA_PORT_DATA);
}
else {
tmpword=(unsigned short)buffer[idx];
outw(ata_base + ATA_PORT_DATA, tmpword);
}
}
}
PS sorry for my bad english