ATA DMA data arriving late

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
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

ATA DMA data arriving late

Post by Octacone »

Hello, I'm back after a long break and I gotta say this new forum theme is quite hard to get used to.
It needs a better contrast.

Anyways, I've been having this problem for years: whenever I receive an interrupt, I have to wait approx. 37 * 400ns in order to be able to see the data in memory, otherwise the buffer is empty.
Inside the interrupt handler, everything checks out, bus master status register bit 2 is set, bit 0 and 1 are clear.
I also read the status register to acknowledge the interrupt and I stop the DMA transfer.

I experience this behavior in all emulators.
Has anybody ever encountered a similar issue?
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: ATA DMA data arriving late

Post by Octacone »

Interrupt: This bit is set by the rising edge of the IDE interrupt line. This bit is cleared when a
'1' is written to it by software. Software can use this bit to determine if an IDE device has
asserted its interrupt line. When this bit is read as a one, all data transfered from the drive is
visible in system memory.


Yeah, that is not happening...
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: ATA DMA data arriving late

Post by Octocontrabass »

I've never heard of anyone else having that problem, so I can only assume it's a bug in your code, but I can't think of anything that would cause the exact behavior you're seeing.

QEMU can log some events that might help you find the problem.
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: ATA DMA data arriving late

Post by Octacone »

My FAT 32 code uses malloc all around.
Could this thing be caused by crossing the 64 KB boundary.
Let's say my malloc returned 0x24F202C, and I needed to read 8 sectors 512 bytes each.
The resulting address would be 0x24F302C which would not be compliant with this:

"The data buffers cannot cross a 64K boundary, and must be contiguous in physical memory (ie. they can't be "virtual" data buffers). The byte count on the data buffers must match the number of sectors transferred by the disk. If not, the controller will error out in various ways."

Right?

Edit:
This is ridiculous!
It sometimes randomly works. Like every 50 times.
I also fixed the boundary issue, but it didn't help.

Edit 2:
When I start Qemu for the first time it doesn't work, but when I tell Qemu to reboot it works almost every time.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: ATA DMA data arriving late

Post by Octocontrabass »

Octacone wrote: Sat Jul 20, 2024 8:39 amCould this thing be caused by crossing the 64 KB boundary.
Probably not. I would expect either memory corruption or no problem at all, data arriving late just doesn't make sense.
Octacone wrote: Sat Jul 20, 2024 8:39 amWhen I start Qemu for the first time it doesn't work, but when I tell Qemu to reboot it works almost every time.
Sounds like the problem is timing-related, but I still can't imagine what it could be if it only affects IDE DMA and nothing else.
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: ATA DMA data arriving late

Post by Octacone »

This driver might as well be a random number generator. :D
I think the interrupts are to blame.
I always get a spurious interrupt on Qemu and a fake one (interrupt bit clear) on Bochs.

Reading or not reading the command register when stopping the transfer appears to have a big impact...
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: ATA DMA data arriving late

Post by Octocontrabass »

Octacone wrote: Mon Jul 22, 2024 8:29 amI think the interrupts are to blame.
I always get a spurious interrupt on Qemu and a fake one (interrupt bit clear) on Bochs.
Well, that definitely points to a bug in your code.

Spurious IDE interrupts can be caused by polling a drive when you should be waiting for an interrupt, or by switching between drives that share an interface without waiting for command completion and acknowledging the interrupt. Spurious interrupts of any kind can be caused by polling a device when you should be waiting for an interrupt, or by incorrectly configuring an interrupt controller, or (if it's something like the PIT) by not responding to the interrupt before the device cancels its interrupt request.

VMs aren't bound by the limits of physical hardware, so I could see how the bug causing spurious interrupts might also cause DMA to appear to complete late instead of aborting the transfer.
Post Reply