/// <summary> /// Create a new PCIDevice instance /// </summary> /// <param name="pciController">The pci controller.</param> /// <param name="bus">The bus.</param> /// <param name="slot">The slot.</param> /// <param name="fun">The fun.</param> 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++) { uint address = pciController.ReadConfig32(bus, slot, fun, (byte)(16 + (i * 4))); if (address != 0) { HAL.DisableAllInterrupts(); pciController.WriteConfig32(bus, slot, fun, (byte)(16 + (i * 4)), 0xFFFFFFFF); uint mask = pciController.ReadConfig32(bus, slot, fun, (byte)(16 + (i * 4))); pciController.WriteConfig32(bus, slot, fun, (byte)(16 + (i * 4)), 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) { switch (baseAddress.Region) { case AddressType.IO: ioPortRegionCount++; break; case AddressType.Memory: memoryRegionCount++; break; } } } }
public override void Initialize() { pciController = Device.Parent.DeviceDriver as IPCIController; var configuration = Device.Configuration as PCIDeviceConfiguration; Bus = configuration.Bus; Slot = configuration.Slot; Function = configuration.Function; Device.Name = Device.Parent.Name + '/' + Bus.ToString() + '.' + Slot.ToString() + '.' + Function.ToString(); 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, Function, barr); if (address == 0) { continue; } HAL.DisableAllInterrupts(); pciController.WriteConfig32(Bus, Slot, Function, barr, 0xFFFFFFFF); uint mask = pciController.ReadConfig32(Bus, Slot, Function, barr); pciController.WriteConfig32(Bus, Slot, Function, barr, address); HAL.EnableAllInterrupts(); if (address % 2 == 1) { BaseAddresses[i] = new BaseAddress(AddressType.IO, new IntPtr(address & 0x0000FFF8), (~(mask & 0xFFF8) + 1) & 0xFFFF, false); } else { BaseAddresses[i] = new BaseAddress(AddressType.Memory, new IntPtr(address & 0xFFFFFFF0), ~(mask & 0xFFFFFFF0) + 1, (address & 0x08) == 1); } } // FIXME: Special case for generic VGA if (ClassCode == 0x03 && SubClassCode == 0x00 && ProgIF == 0x00) { BaseAddresses[6] = new BaseAddress(AddressType.Memory, new IntPtr(0xA0000), 0x1FFFF, false); BaseAddresses[7] = new BaseAddress(AddressType.IO, new IntPtr(0x3B0), 0x0F, false); } foreach (var baseAddress in BaseAddresses) { if (baseAddress == null) { continue; } if (baseAddress.Region == AddressType.Undefined) { continue; } switch (baseAddress.Region) { case AddressType.IO: ioPortRegionCount++; break; case AddressType.Memory: memoryRegionCount++; break; } } }