OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Feb 24, 2020 11:50 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: ATA Status BSY bit never clears
PostPosted: Sun Feb 02, 2020 9:48 pm 
Offline

Joined: Sun Jan 19, 2020 12:25 pm
Posts: 4
Hi all-
I've recently been trying to identify an ATA PIO drive, following the wiki's instructions. Reading the STATUS port works, but the BSY bit of the STATUS port never clears.

My code is in Rust, but it should hopefully be pretty self explanatory.
Code:
pub fn init() {
    unsafe {
        io::outb(DRIVESEL, 0xE0);
        io::outb(SECTOR_COUNT, 0);
        io::outb(LBAL, 0);
        io::outb(LBAM, 0);
        io::outb(LBAH, 0);
        io::outb(COMMAND, ATACommand::IdentifyDevice as u8);

        if io::inb(STATUS) == 0 {
            println!("ATA: master not found");
        } else {
            println!("ATA: master found");
        }

        io::outb(DRIVESEL, 0xF0);
        io::outb(SECTOR_COUNT, 0);
        io::outb(LBAL, 0);
        io::outb(LBAM, 0);
        io::outb(LBAH, 0);
        io::outb(COMMAND, ATACommand::IdentifyDevice as u8);

        if io::inb(STATUS) == 0 {
            println!("ATA: slave not found");
        } else {
            println!("ATA: slave found");
        }

        while io::inb(STATUS).get_bit(BSY) {
            crate::hlt_loop();
        }

        if io::inb(STATUS).get_bit(DRQ) && !io::inb(STATUS).get_bit(ERR) {
            let mut data: [u16; 256] = [0; 256];
            for i in 0..data.len() {
                data[i] = io::inw(DATA);
                print!("{}", data[i]);
            }
        } else {
            println!("ATA: read error");
            return;
        }

    }
}


Top
 Profile  
 
 Post subject: Re: ATA Status BSY bit never clears
PostPosted: Mon Feb 03, 2020 8:13 am 
Offline
Member
Member

Joined: Tue May 13, 2014 3:02 am
Posts: 278
Location: Private, UK
How are you determining that it never clears? Could it not be that "crate::hlt_loop();" never returns? If that function does what its name suggests (the HLT instruction) it definitely won't return unless/until there's a CPU interrupt, so are interrupts enabled and unmasked in the PIC?

Also, surely you should be status-polling after every command you send and before you trust the resulting status value...?

_________________
Image


Top
 Profile  
 
 Post subject: Re: ATA Status BSY bit never clears
PostPosted: Mon Feb 03, 2020 8:16 am 
Online
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 1818
I'm pretty sure hlt_loop() is an infinite loop. It'll never return, even if the BSY bit eventually clears.

With that said, I wouldn't be surprised if it never clears. When no hardware is responding at a particular address, you'll read the open bus value. It's common (but not guaranteed) that open bus will have all bits set; in other words, it will look like the status register is always 0xFF.

Also, keep in mind that IDE is legacy hardware, and most new PCs don't support it at all. The wiki article you're reading was first written almost 12 years ago, and hasn't been updated to take this into account. You should search for IDE-compatible PCI devices before assuming an IDE controller exists and is present at a specific address. (Of course, if you're only using an emulator, you can cheat a little.)


Top
 Profile  
 
 Post subject: Re: ATA Status BSY bit never clears
PostPosted: Mon Feb 03, 2020 10:18 am 
Offline

Joined: Sun Jan 19, 2020 12:25 pm
Posts: 4
Octocontrabass wrote:
With that said, I wouldn't be surprised if it never clears. When no hardware is responding at a particular address, you'll read the open bus value. It's common (but not guaranteed) that open bus will have all bits set; in other words, it will look like the status register is always 0xFF.

It looks like you're right that STATUS is returning 0xFF. I don't know if this is related or not, but I'm running qemu with -machine q35, which seems to function the same as my hardware (Thinkpad X220). When I run regular qemu, I get a double fault when reading status.
Are there any more up to date resources for using ATA PIO, or should I just go with writing an AHCI driver?


Top
 Profile  
 
 Post subject: Re: ATA Status BSY bit never clears
PostPosted: Mon Feb 03, 2020 10:34 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 671
Is it even supported to send a request to one device, while switching to the other device, without waiting for completion?

_________________
managarm: Microkernel-based OS that is capable of running a Wayland desktop
My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions]


Top
 Profile  
 
 Post subject: Re: ATA Status BSY bit never clears
PostPosted: Mon Feb 03, 2020 11:22 am 
Online
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 1818
wsavage wrote:
I don't know if this is related or not, but I'm running qemu with -machine q35, which seems to function the same as my hardware (Thinkpad X220).

QEMU's q35 machine provides an AHCI controller instead of an IDE controller. Your code will only work with an IDE controller.

wsavage wrote:
When I run regular qemu, I get a double fault when reading status.

Reading the status register can't directly cause a double fault. There must be a problem somewhere else. For example, if you've enabled interrupts without configuring the interrupt controllers, the timer will cause IRQ0 which is by default mapped to interrupt 8 which is indistinguishable from a double fault.

wsavage wrote:
Are there any more up to date resources for using ATA PIO, or should I just go with writing an AHCI driver?

This page explains how to search the PCI bus, and this page describes what to look for. In short, you're looking for a device with class 0x01 and subclass 0x01, and if you find it you'll read BAR0 and BAR1 to determine the correct I/O ports.

With QEMU, you can cheat a bit: the default "pc" (i440fx) machine always has an IDE controller mapped at the legacy addresses, so you can skip all of the PCI stuff and keep doing what you're doing now. Then, once you have your driver working, you can add PCI support to make it work with a wider variety of hardware (and make sure it doesn't try to run when there is no IDE controller).


Top
 Profile  
 
 Post subject: Re: ATA Status BSY bit never clears
PostPosted: Mon Feb 03, 2020 9:23 pm 
Offline

Joined: Sun Jan 19, 2020 12:25 pm
Posts: 4
Thanks for the help. The cause of the double fault was a lack of interrupt handlers, as you had said. When I run without
Code:
machine -q35
, status reads 88 for both master and slave. The wiki, as well as other code examples that I have looked at, say to read 256 u16s from the data port to get device information. However, when I do this, only 2/3s of the values are actual numbers, and the rest are zeroes. A screenshot of the output is attached. Am I doing something wrong here? I can't seem to find much about this online.

Here's my read code. Apologies for rust.
Code:
      let mut raw: [u16; 256] = [0; 256];
        if io::inb(STATUS).get_bit(DRQ) && !io::inb(STATUS).get_bit(ERR) {
            for i in 0..raw.len() {
                raw[i] = io::inw(DATA);
                print!("{}", raw[i]);
            }
        } else {
            println!("ATA: read error");
        }


Attachments:
wrong3.png
wrong3.png [ 71.53 KiB | Viewed 361 times ]
Top
 Profile  
 
 Post subject: Re: ATA Status BSY bit never clears
PostPosted: Tue Feb 04, 2020 2:28 am 
Online
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 1818
wsavage wrote:
Am I doing something wrong here?

It looks right to me, although the way you're displaying those numbers makes it very difficult to interpret the results.

Look for the IDENTIFY DEVICE section in the ATA specification if you want to know how to interpret that data. A lot of it is considered obsolete, so you might have to look at several different versions of the ATA specification to understand all of the information the drive gives you.


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: MSN [Bot] and 13 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