ATA Driver Problem

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

ATA Driver Problem

Post by bigbob »

Hi,

This is my first time on this forum, so I'd like to greet everybody.
I am developing an OS based on the BrokenThorn and osdever.net tutorials:
https://sites.google.com/site/forthoperatingsystem/
Currently I am developing the ATA hard disk driver (hasn't been uploaded yet but the links are below) with PIO according to this page:
http://wiki.osdev.org/ATA_PIO_Mode
My OS is a single task one, so I use polling instead of DMA (IRQ).
The problem is that I can read/write sectors from/to the winchester in emulators (Bochs and QEMU) but on real hardware there is always an interrupt.
According to the osdev.org article (link above) the nIEN bit needs to be set in 0x3F6 (primary bus crtl-register) and 0x376 (secondary bus ctrl-register).
Pseudo code:

Code: Select all

outb(0x3F6, 2)
outb(0x376, 2)
I do this before sending any commands like IDENTIFY to the winchester (which is a Primary Master, IDE, 40GB; there is also a secondary slave DVD in the computer)
but the IRQ kept comming.
I also tried to select the device(it's "Detecting Device Types" in the PIO artile above) and only then set the nIEN bit:

Code: Select all

out(0x1F6, 0xA0)
inb(0x3F6)
inb(0x3F6)
inb(0x3F6)
inb(0x3F6)
outb(0x3F6, 2)
The winchester is a primary master, so no need to set the slave bit.
Unfortunately the IRQ still came.

Maybe I should disable the nIEN-bit on all possible busses (ctrl-ports: 0x3F6, 0x170, 0x0x3E6, 0x366)?
How could I prevent the winchester from firing an IRQ?

The kernel calls hd_detect in hd.asm:
http://pastebin.com/5pCiqW7E
and hd.asm uses ata.asm:
http://pastebin.com/mCK2c8d4

Maybe also delays are missing from the code, but it works with Bochs because it is much slower than real hw.
Can this code work on real hardware after I manage to get rid of the interrupt?

I have wasted so many CDs so far so I decided to ask this question.

Regards,
Rob
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: ATA Driver Problem

Post by mark3094 »

bigbob wrote:My OS is a single task one, so I use polling instead of DMA (IRQ).
The problem is that I can read/write sectors from/to the winchester in emulators (Bochs and QEMU) but on real hardware there is always an interrupt.
In my OS, I have not disabled interrupts, but instead I immediately send an EOI when that interrupt is raised. This may be an alternate solution to this problem.

bigbob wrote:I have wasted so many CDs so far so I decided to ask this question.
Have you considered using rewritable CD's? Or possibly USB?
I don't know a lot about BOCHS, but I think it's an emulator, so you could also try a hypervisor such as VMWARE Player, or Virtual Box for comparison. You may be able to replicate your issue in this environment, troubleshoot it there, and then try again on real hardware when you think you have solved it.
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

Re: ATA Driver Problem

Post by bigbob »

Hi Mark,

You have good ideas. To be honest it didn't occur to me to use rewritable CDs.
The real hardware I am testing on is an old one, there is no USB-boot.
In my opinion it's not a good idea to test it on an expensive laptop or netbook till I have this kind of problems and there are SATA (AHCI) winchesters in those computers.

I will definitely try rewritable CDs and VirtualBox (or WMWARE). Sendig EOI is really an option, I will give it a try.

Rob
Last edited by bigbob on Tue Oct 01, 2013 7:00 am, edited 1 time in total.
User avatar
bwat
Member
Member
Posts: 359
Joined: Fri Jul 03, 2009 6:21 am

Re: ATA Driver Problem

Post by bwat »

bigbob wrote:Hi,
Currently I am developing the ATA hard disk driver (hasn't been uploaded yet but the links are below) with PIO according to this page:
http://wiki.osdev.org/ATA_PIO_Mode
...
Maybe also delays are missing from the code
...
Do you mean the delays mentioned in the article you reference?

Also, are you polling the status BUSY bit? (I can't spend time reading assembly language).
Every universe of discourse has its logical structure --- S. K. Langer.
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

Re: ATA Driver Problem

Post by bigbob »

The delays are there: 2 seconds (it's too much, but it's ok for testing), I use PIT. Of course, I am polling the status bit: It works on Bochs and QEMU, I can read and write sectors. I meant by delay, delays that are not mentioned in the ATA PIO article.
User avatar
bwat
Member
Member
Posts: 359
Joined: Fri Jul 03, 2009 6:21 am

Re: ATA Driver Problem

Post by bwat »

I have a delay in my resetting of the controller which you don't have. I delay after writing the command and then again after clearing the reset bit.
Not sure if it would fix your problem (or is even necessary to tell the truth).
Every universe of discourse has its logical structure --- S. K. Langer.
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

Re: ATA Driver Problem

Post by bigbob »

Even if I get rid of the unnecessary interrupt on real hw, there is the possibility that the code won't work, so any help is appreciated.
I will test the delay you suggested too.
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

Re: ATA Driver Problem

Post by bigbob »

The ATA PIO article mentions using timeouts during polling. That's what I implemented with PIT (pit_ticks).
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

Re: ATA Driver Problem

Post by bigbob »

My OS works with Virual Box too.
I only changed the default SATA (AHCI) hard disk to IDE in VirtualBox, added a floppy image and the OS works just like with Bochs or QEMU: it detects the winchester and so on.
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

Re: ATA Driver Problem

Post by bigbob »

In the ATA PIO article there is an ata_soft_reset call in the "Detecting Device Types" section.
I don't do that and I don't understand why it's necessary because devices are usually detected right after boot.
It seems that the 400ns delays are missing here and there in my code but I still don't understand what sends the interrupt.
The default-interrupt-handler gets called in my code, so the IRQ is greater then 19.
My IDT seems to be working because if I execute e.g. "int 14" in the code then "Page Fault" text will be printed correctly.
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

Re: ATA Driver Problem

Post by bigbob »

I couldn't get the detect_devtype function working (ATA PIO article) on real HW, but using only the primary port and slavebit=0 and after having inserted a few sleep(1) commands as it is recommended in "Detect ATA-ATAPI Devices" in http://wiki.osdev.org/PCI_IDE_Controller the winchester IDENTIFY cmd worked on real HW.
However the unnecessary interrupt sill comes. Maybe EOI or "Detecting a PCI IDE Controller" in this PCI article will help.
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

Re: ATA Driver Problem

Post by bigbob »

On real HW the OS works the same way as on Bochs without setting nIEN.
So if I don't disable the IRQ by setting nIEN on Bochs then the IRQ occurs.
On real HW even if I set nIEN, the IRQ occurs.
This tells me that perhaps on real HW it's not only:

Code: Select all

out(0x3F6, 2)
but I need to read e.g. the status port too in order to get rid of the interrupt.
After setting nIEN, I read(first once then twice) status too with delay.
That didn't help either.
I even changed the zero IRQs in PCI config. Nothing.
Unfortunately EOI wouldn't help because the IRQ46 is sent in both Bochs(if nIEN is not set) and on real HW(with or without nIEN).
As far as I know only IRQs less than 16 can be acknowledged by EOI.
Executing "int 15" in the code prints the correct text, so my IDT seems to be ok.
The same with QEMU.
It's interesting that there is no interrupt in VirtualBox even if I don't set nIEN.

I have no idea.
Post Reply