IDE drives on emulators
-
- Posts: 7
- Joined: Tue Jan 05, 2010 7:37 pm
- Contact:
IDE drives on emulators
Do emulators (namely Bochs and VirtualBox) support Bus Master IDE and DMA? I have tried to detect IDE drives in my OS project and it always comes up saying that there are none. Are there special settings that need to be set in order to make it work properly? The class code, subclass code, and vendor ID repeatedly come back as xFFFF. I have it loop through each bus and each device with numbers 1 and 2. Is this what I'm doing wrong? I have read through all the wiki articles on the topic and read the Intel specification, but none were any help in the direction of detecting IDEs.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: IDE drives on emulators
Bochs does support PCI IDE, but I couldn't find success stories about DMA even though google suggests it is supported.
In any case, you need to provide bochs with the settings to enable an IDE controller and the i440fx chipset before trying to use PCI otherwise it will indeed shout at you that there are no plug-and-play devices. Check the documentation and sample bochsrc for the settings you want.
In any case, you need to provide bochs with the settings to enable an IDE controller and the i440fx chipset before trying to use PCI otherwise it will indeed shout at you that there are no plug-and-play devices. Check the documentation and sample bochsrc for the settings you want.
-
- Member
- Posts: 391
- Joined: Wed Jul 25, 2007 8:45 am
- Libera.chat IRC: aejsmith
- Location: London, UK
- Contact:
Re: IDE drives on emulators
VirtualBox does, DMA works with my ATA driver on it.KodyKinzel wrote:Do emulators (namely Bochs and VirtualBox) support Bus Master IDE and DMA?
Do you mean you're only looking at 2 devices on each bus? There's a maximum of 32 devices per bus. For me, on VirtualBox the IDE controller is on bus 0, device 1, function 1. Are you sure your PCI detection code is correct?KodyKinzel wrote:I have it loop through each bus and each device with numbers 1 and 2. Is this what I'm doing wrong?
-
- Posts: 7
- Joined: Tue Jan 05, 2010 7:37 pm
- Contact:
Re: IDE drives on emulators
Code: Select all
u32int pciConfigReadDword(u16int bus, u16int device, u16int func, u16int register_number) //read a dword of configuration
{
u32int lbus = (u32int)bus;
u32int ldevice = (u32int)device;
u32int lfunc = (u32int)func;
u32int lregister = (u32int)register_number;
u32int address = ((0x1<<31) | (lbus<<16) | (ldevice<<11) | (lfunc<<8) | (lregister<<2)); //create the address
outl(0xCF8, address); //send it out to port CF8
return inl(0xCFC); //read and return port CFC
}
u8int checkForIDE(u16int bus, u16int device, u16int func) //check if a particular bus, device, function combination is an IDE
{
u32int rawRegister = pciConfigReadDword(bus, device, func, 0x8); //read in the raw data
u16int classword = (u16int)(rawRegister>>16); //get the word with the class information
u8int classcode = (u8int)(classword>>8); //get the class
u8int subclasscode = (u8int)(classword<<8); //get the subclass
if (classcode == 0x1 && subclasscode == 0x1) //check if they are 0x1
return 1; //if so, it's an IDE
}
void detectIDEs() //detect any IDEs present
{
u16int busIndex, deviceIndex, funcIndex; //declar the index variables
for (busIndex; busIndex <= 32; busIndex++) //loop through the buses
{
for (deviceIndex; deviceIndex <= 32; deviceIndex++) //loop through the devices
{
for (funcIndex; funcIndex <= 32; funcIndex++) //loop through the functions
{
if (checkForIDE(busIndex, deviceIndex, funcIndex)) //check for an IDE
{
//for now, print a message if there is one
kprint("IDE detected: ");
kprint_hex(busIndex);
kput(':');
kprint_hex(deviceIndex);
kput(';');
kprint_hex(funcIndex);
kput('\n');
}
}
funcIndex = 0x0; //ready the function number to be used again
}
deviceIndex = 0x0; //ready the device number to be used again
}
}
-
- Member
- Posts: 391
- Joined: Wed Jul 25, 2007 8:45 am
- Libera.chat IRC: aejsmith
- Location: London, UK
- Contact:
Re: IDE drives on emulators
Code: Select all
u32int address = ((0x1<<31) | (lbus<<16) | (ldevice<<11) | (lfunc<<8) | (lregister<<2));
Also, why are you not initialising the indexes variables to 0 in your for loop initialiser?
No need to apologiseI'm sorry if I totally messed it up
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: IDE drives on emulators
Actually, it does not need to be wrong. Both offset << 2 and offset & 0xfc are used in practice. The only difference is that in the first case you will need to supply the index of the word (0-63) instead of the byte (0-255) to read. Downside to the first option is that the offsets will not match the ones you see in official documentation, the second one fails to suggest that you are doing dword reads and you should mask out the correct byte after reading. In any case, I will agree that seeing the opposite of what you are used to can screw with your mind, and in this case it is indeed used wrong.AlexExtreme wrote:The left shift for the register is incorrect - the register must be in the low 8 bits of the address, but the lowest 2 bits must be cleared (4-byte aligned).Code: Select all
u32int address = ((0x1<<31) | (lbus<<16) | (ldevice<<11) | (lfunc<<8) | (lregister<<2));
My personal approach is to have a read byte/word/dword version of this function to hide such murky details. Of course, taste matters. The bottom line is to always check that it works as expected. If you're getting a vendor:device but no classcode, your first place to check is there.
On another note:
Code: Select all
u8int subclasscode = (u8int)(classword<<8); //get the subclass