OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 3:43 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: ATA drive LBA48 read
PostPosted: Fri Mar 03, 2023 5:13 pm 
Offline
Member
Member

Joined: Mon Jul 30, 2018 2:58 am
Posts: 45
Hello,

I'm having a problem with an ATA LBA48 read funtion. Can you help me solve the issue? Here is the funtion I wrote:
Code:
static int ATA_read48_pio(ATADevice *device, uint32_t LBA, unsigned int count, uint8_t *buffer){
    int ch = device->channel;
    int dr = device->drive;

    outw(channels[ch].base + ATA_REG_HDDEVSEL, (uint8_t []){0x40, 0x50}[dr]);
    io_wait();
    outb(channels[ch].base + ATA_REG_ERROR, 0); // Supposedly it's useless
    io_wait();
    outb(channels[ch].base + ATA_REG_SECCOUNT0, (uint8_t)(count >> 8)); // high sector count byte
    io_wait();
    outb(channels[ch].base + ATA_REG_LBAlo, (uint8_t)(LBA >> 24));
    io_wait();
    outb(channels[ch].base + ATA_REG_LBAmid, 0);
    io_wait();
    outb(channels[ch].base + ATA_REG_LBAhi, 0);
    io_wait();
    outb(channels[ch].base + ATA_REG_SECCOUNT0, (uint8_t)(count)); // low sector count byte
    io_wait();
    outb(channels[ch].base + ATA_REG_LBAlo, (uint8_t)LBA);
    io_wait();
    outb(channels[ch].base + ATA_REG_LBAmid, (uint8_t)(LBA >> 8));
    io_wait();
    outb(channels[ch].base + ATA_REG_LBAhi, (uint8_t)(LBA >> 16));
    io_wait();
    outb(channels[ch].base + ATA_REG_COMMAND, (uint8_t)(ATA_CMD_READ_PIO_EXT));
    long_wait();
   
    for(int i=0; i<count; i++){
        int ret = poll_channel(ch);
        if(ret) // Error code 1: Device not responding!, Error code 2: Unexpected error occured!
            return ret;
        insw(channels[ch].base + ATA_REG_DATA, (uint16_t *)(buffer + i*512), 256);
    }
    long_wait();

    return 0;
}


For some reason I'm getting an "Aborted command" error on bochs. It works on quemu though. The bochs drive should support LBA48 because I'm making sure it does before deciding wheather to use LBA28 or LBA48 like so:
Code:
int ATA_read_pio(ATADevice *device, uint32_t LBA, unsigned int count, uint8_t *buffer){
    if(!device->exists)
        return 3; // Error code 3: Device does not exist
    if(device->commandSets & (1 << 26)){ // Device uses 48-Bit Addressing
        terminal_print(debugTerminal, "[DEBUG] LBA48\n");
        if((LBA + count > device->size) || count > 0xFFFF)
            return 4; // Error code 4: Inapropriate LBA and count
        return ATA_read48_pio(device, LBA, count, buffer);
    }
    else{
        terminal_print(debugTerminal, "[DEBUG] LBA28\n");
        if((LBA + count > device->size) || LBA > 0xfffffff || count > 0xFF)
            return 4; // Error code 4: Inapropriate LBA and count
        return ATA_read28_pio(device, LBA, count, buffer);
    }
}


If you think the problem may lay in polling function here it is:
Code:
static int poll_channel(int channel){
    uint8_t error = 0;
    uint8_t status = 0xff;
    int counter = 0;
    while((status & ATA_SR_BSY) && counter < 10000){
        status = inb(channels[channel].base + ATA_REG_STATUS);
        counter++;
    }
    if(counter >= 10000)
        return 1; // Error code 1: Device not responding!
    counter = 0;
    while(!(status & ATA_SR_DRQ) && counter < 10000){
        status = inb(channels[channel].base + ATA_REG_STATUS);
        if(status & ATA_SR_ERR){
            error = inb(channels[channel].base + ATA_REG_ERROR);
            break;
        }
        counter++;
    }
    if(counter >= 10000)
        return 1; // Error code 1: Device not responding!
    if(error){
        print_error(error);
        soft_reset(channel);
        return 2; // Error code 2: Unexpected error ocured
    }
    return 0;
}


Top
 Profile  
 
 Post subject: Re: ATA drive LBA48 read
PostPosted: Fri Mar 03, 2023 5:37 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
Turn up the log level in Bochs and see what messages it outputs. It might tell you what you're doing wrong that way.

Otherwise, I don't see any obvious problems...


Top
 Profile  
 
 Post subject: Re: ATA drive LBA48 read
PostPosted: Fri Mar 03, 2023 6:08 pm 
Offline
Member
Member

Joined: Mon Jul 30, 2018 2:58 am
Posts: 45
Octocontrabass wrote:
Turn up the log level in Bochs and see what messages it outputs. It might tell you what you're doing wrong that way.

Do you mean I should check out bochsout.txt file? I don't see anything interesting in there... Maybe I just don't know what to look for.


Top
 Profile  
 
 Post subject: Re: ATA drive LBA48 read
PostPosted: Fri Mar 03, 2023 6:17 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
That's where the log will be, once you enable more logging in your bochsrc.


Top
 Profile  
 
 Post subject: Re: ATA drive LBA48 read
PostPosted: Fri Mar 03, 2023 6:44 pm 
Offline
Member
Member

Joined: Mon Jul 30, 2018 2:58 am
Posts: 45
Octocontrabass wrote:
That's where the log will be, once you enable more logging in your bochsrc.

I found the problem. I was getting such message in the log:

12780670378e[DEV ] write to port 0x01f6 with len 2 ignored

Apparently I was using outw instead of outb in one spot.

Thank you for help.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 58 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group