public PCIDevice(IPCIController pciController, byte bus, byte slot, byte fun)
{
base.Parent = pciController as Device;
base.Name = base.Parent.Name + "/" + bus.ToString() + "." + slot.ToString() + "." + fun.ToString();
base.DeviceStatus = DeviceStatus.Available;
this.pciController = pciController;
Bus = bus;
Slot = slot;
Function = fun;
ioPortRegionCount = memoryRegionCount = 0;
BaseAddresses = new BaseAddress[8];
for (byte i = 0; i < 6; i++)
{
byte barr = (byte)(PCIConfigurationHeader.BaseAddressRegisterBase + (i * 4));
uint address = pciController.ReadConfig32(bus, slot, fun, barr);
if (address == 0)
continue;
HAL.DisableAllInterrupts();
pciController.WriteConfig32(bus, slot, fun, barr, 0xFFFFFFFF);
uint mask = pciController.ReadConfig32(bus, slot, fun, barr);
pciController.WriteConfig32(bus, slot, fun, barr, address);
HAL.EnableAllInterrupts();
if (address % 2 == 1)
BaseAddresses[i] = new BaseAddress(AddressType.IO, address & 0x0000FFF8, (~(mask & 0xFFF8) + 1) & 0xFFFF, false);
else
BaseAddresses[i] = new BaseAddress(AddressType.Memory, address & 0xFFFFFFF0, ~(mask & 0xFFFFFFF0) + 1, ((address & 0x08) == 1));
}
if ((ClassCode == 0x03) && (SubClassCode == 0x00) && (ProgIF == 0x00))
{
// Special case for generic VGA
BaseAddresses[6] = new BaseAddress(AddressType.Memory, 0xA0000, 0x1FFFF, false);
BaseAddresses[7] = new BaseAddress(AddressType.IO, 0x3B0, 0x0F, false);
}
foreach (var baseAddress in BaseAddresses)
{
if (baseAddress == null)
continue;
switch (baseAddress.Region)
{
case AddressType.IO: ioPortRegionCount++; break;
case AddressType.Memory: memoryRegionCount++; break;
}
}
}