Issue with INT 13h, AH=48h

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
jlxip
Posts: 10
Joined: Sat Jul 27, 2019 5:47 pm
Location: Granada, Spain
Contact:

Issue with INT 13h, AH=48h

Post by jlxip »

I'm currently trying to improve my ATA and ATAPI drivers (currently PIO) to make them use PCI busmastering DMA. For that, I need to know the PCI tuple (bus, device, function) of the device I'm using to boot. The best way I could think of doing that is using the identifier the BIOS puts in %dl at bootup, which my bootloader saves for the kernel.

In order to get the PCI data, I'm using BIOS interrupt 13h and function AH=48h. I'm doing this from the kernel instead of the bootloader, so I'm using V86 for that. This does not make a difference, see the screenshot below, everything is where it should be.
Image

This is the code I'm using:

Code: Select all

uint32_t base = 0x8000;

regs16_t regs;
regs.ax = 0x4800;
regs.dx = bootDriveID;
regs.ds = 0;
regs.si = base & 0xFFFF;

*(uint16_t*)base = 0x0042;
*(uint16_t*)(base + 0x02) = 0x0000;
*(uint16_t*)(base + 0x1E) = 0xCACA;

printf("AX = %x\n", regs.ax);
V86(0x13, &regs);
printf("AX = %x\n", regs.ax);

printf("Size: %x\n", *(uint16_t*)base);

uint16_t devicePathInfoSignature = *(uint16_t*)(base+0x1E);
if(devicePathInfoSignature == 0xCACA) {
	printf(" {{ devicePathInfoSignature not set at all!  }} ");
	while(true) {}
} else if(devicePathInfoSignature != 0xBEDD) {
	printf(" {{ Device path info not supported! Got: %x }} ", devicePathInfoSignature);
	while(true) {}
}
In all VMs I've tested (Qemu, Bochs, VirtualBox), AX is returned with 0 (no error).

Thing is, I'm setting the size (first word of the buffer) to 0x0042, which according to Ralf Brown's interrupt list, gets the v3.x data (http://www.ctyme.com/intr/rb-0715.htm). On return of the interrupt, however, when testing on VirtualBox, return size is set to 0x001A, and does not set the Device Path signature (0xBEDD), which I don't think makes any sense; see implementation here, it does support v3.x: https://www.virtualbox.org/browser/vbox ... isk.c#L140. Also, Bochs for some reason returns 0x001E as size, even though it does set the Device Path. Qemu also returns 0x001E and sets the device path signature and data.

What am I missing? Thanks :D


Unrelated: is PCI busmastering DMA the «good» way of doing DMA? I mean, Bochs, for instance, returns a buffer that says the host bus is ISA and not PCI (therefore I have no PCI tuple), so I would not be able to use PCI busmastering DMA there, right? Do I have to implement ISA DMA as well? Am I missing theory?
Octocontrabass
Member
Member
Posts: 5575
Joined: Mon Mar 25, 2013 7:01 pm

Re: Issue with INT 13h, AH=48h

Post by Octocontrabass »

jlxip wrote:In order to get the PCI data, I'm using BIOS interrupt 13h and function AH=48h. I'm doing this from the kernel instead of the bootloader, so I'm using V86 for that.
Wouldn't it be easier to do this in the bootloader?
jlxip wrote:Thing is, I'm setting the size (first word of the buffer) to 0x0042, which according to Ralf Brown's interrupt list, gets the v3.x data (http://www.ctyme.com/intr/rb-0715.htm).
All of the EDD 3 drafts I can find say the buffer size is 0x4A, not 0x42.
jlxip wrote:see implementation here, it does support v3.x:

Code: Select all

149	    if (dpt->size >= 0x1a) {
150	        uint64_t    lba;
151	
152	        dpt->size      = 0x1a;

171	    }
172	
173	    /* Fill in EDD 2.x table. */
174	    if (dpt->size >= 0x1e) {
Oops. Maybe their compiler doesn't warn them that the condition in the if statement will always be false?
jlxip wrote:Also, Bochs for some reason returns 0x001E as size, even though it does set the Device Path. Qemu also returns 0x001E and sets the device path signature and data.
That's what the spec says to do. Perhaps it's to avoid bugs in implementations that followed the draft with the 0x42-byte buffer?
jlxip wrote:Unrelated: is PCI busmastering DMA the «good» way of doing DMA?
It's the only way of doing DMA for PCI devices. It's also much faster than legacy DMA, which I'd say is pretty good.
jlxip wrote:I mean, Bochs, for instance, returns a buffer that says the host bus is ISA and not PCI (therefore I have no PCI tuple), so I would not be able to use PCI busmastering DMA there, right?
You can't use PCI bus mastering DMA if the device is not PCI. Some BIOSes don't report correct information though. (Shouldn't Bochs be emulating a PCI IDE controller?)
jlxip wrote:Do I have to implement ISA DMA as well?
Probably not. ISA IDE adapters typically do not support DMA at all. They're also really old - have you ever actually seen one?
User avatar
jlxip
Posts: 10
Joined: Sat Jul 27, 2019 5:47 pm
Location: Granada, Spain
Contact:

Re: Issue with INT 13h, AH=48h

Post by jlxip »

Octocontrabass wrote:Wouldn't it be easier to do this in the bootloader?
Not too much. I had Virtual 8086 already implemented. I know it's not too clean of a solution, but touching the bootloader again scares me.
Octocontrabass wrote:All of the EDD 3 drafts I can find say the buffer size is 0x4A, not 0x42.
Interesting... All I can find say it's 0x42. Ralf Brown's specifies that, same with VirtualBox's implementation.
Octocontrabass wrote:Oops. Maybe their compiler doesn't warn them that the condition in the if statement will always be false?
Looks like it. I've submitted a patch. Issue is, however, that in line 260 ( https://www.virtualbox.org/browser/vbox ... isk.c#L254 ), they haven't even implemented the PCI case :?
I guess I will have to do probing. I'll try using this interrupt to get the number of sectors (which only requires v1.x) or something and check with what I get from PCI probing.If there's a more certain way to check it that you're aware of, please let me know :)
Octocontrabass wrote:It's the only way of doing DMA for PCI devices. It's also much faster than legacy DMA, which I'd say is pretty good.
That explains a lot of things. Thanks!
Octocontrabass wrote:You can't use PCI bus mastering DMA if the device is not PCI. Some BIOSes don't report correct information though. (Shouldn't Bochs be emulating a PCI IDE controller?)
Why wouldn't a BIOS report correct information? :(
Octocontrabass wrote:Probably not. ISA IDE adapters typically do not support DMA at all. They're also really old - have you ever actually seen one?
No, I haven't hahaha.

Thanks for your time :D
Octocontrabass
Member
Member
Posts: 5575
Joined: Mon Mar 25, 2013 7:01 pm

Re: Issue with INT 13h, AH=48h

Post by Octocontrabass »

jlxip wrote:If there's a more certain way to check it that you're aware of, please let me know :)
Linux typically passes the root filesystem UUID on the kernel command line. This works pretty well, as long as you don't copy the entire partition from one disk to another.
jlxip wrote:Why wouldn't a BIOS report correct information? :(
You have some very high expectations from firmware.
Post Reply