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.
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, ®s);
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) {}
}
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
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?