diff --git a/source/Cosmos.HAL2/PCIDevice.cs b/source/Cosmos.HAL2/PCIDevice.cs new file mode 100644 index 000000000..ad50b154b --- /dev/null +++ b/source/Cosmos.HAL2/PCIDevice.cs @@ -0,0 +1,808 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Cosmos.Core.IOGroup; +using Cosmos.Common.Extensions; +using Cosmos.Debug.Kernel; + +namespace Cosmos.HAL +{ + public class PCIDevice + { + + #region Enums + public enum PCIHeaderType : byte + { + Normal = 0x00, + Bridge = 0x01, + Cardbus = 0x02 + }; + + public enum PCIBist : byte + { + CocdMask = 0x0f, + Start = 0x40, + Capable = 0x80 + }; + + public enum PCIInterruptPIN : byte + { + None = 0x00, + INTA = 0x01, + INTB = 0x02, + INTC = 0x03, + INTD = 0x04 + }; + + public enum Config : byte + { + VendorID = 0, DeviceID = 2, + Command = 4, Status = 6, + RevisionID = 8, ProgIF = 9, SubClass = 10, Class = 11, + CacheLineSize = 12, LatencyTimer = 13, HeaderType = 14, BIST = 15, + BAR0 = 16, + BAR1 = 20, + PrimaryBusNo = 24, SecondaryBusNo = 25, SubBusNo = 26, SecondarLT = 27, + IOBase = 28, IOLimit = 29, SecondaryStatus = 30, + MemoryBase = 32, MemoryLimit = 34, + PrefMemoryBase = 36, PrefMemoryLimit = 38, + PrefBase32Upper = 40, + PrefLimit32upper = 44, + PrefBase16Upper = 48, PrefLimit16upper = 50, + CapabilityPointer = 52, Reserved = 53, + ExpROMBaseAddress = 56, + InterruptLine = 60, InterruptPIN = 61, BridgeControl = 62 + }; + #endregion + + public readonly uint bus; + public readonly uint slot; + public readonly uint function; + + public readonly ushort VendorID; + public readonly ushort DeviceID; + + public readonly ushort Command; + public readonly ushort Status; + + public readonly byte RevisionID; + public readonly byte ProgIF; + public readonly byte Subclass; + public readonly byte ClassCode; + public readonly byte SecondaryBusNumber; + + public readonly bool DeviceExists; + + public readonly PCIHeaderType HeaderType; + public readonly PCIBist BIST; + public readonly PCIInterruptPIN InterruptPIN; + + public const ushort ConfigAddressPort = 0xCF8; + public const ushort ConfigDataPort = 0xCFC; + + public PCIBaseAddressBar[] BaseAddressBar; + + protected static Core.IOGroup.PCI IO = new Core.IOGroup.PCI(); + + public PCIDevice(uint bus, uint slot, uint function) + { + this.bus = bus; + this.slot = slot; + this.function = function; + + VendorID = ReadRegister16((byte)Config.VendorID); + DeviceID = ReadRegister16((byte)Config.DeviceID); + + Command = ReadRegister16((byte)Config.Command); + Status = ReadRegister16((byte)Config.Status); + + + RevisionID = ReadRegister8((byte)Config.RevisionID); + ProgIF = ReadRegister8((byte)Config.ProgIF); + Subclass = ReadRegister8((byte)Config.SubClass); + ClassCode = ReadRegister8((byte)Config.Class); + SecondaryBusNumber = ReadRegister8((byte)Config.SecondaryBusNo); + + HeaderType = (PCIHeaderType)ReadRegister8((byte)Config.HeaderType); + BIST = (PCIBist)ReadRegister8((byte)Config.BIST); + InterruptPIN = (PCIInterruptPIN)ReadRegister8((byte)Config.InterruptPIN); + if ((uint)VendorID == 0xFF && (uint)DeviceID == 0xFFFF) + { + DeviceExists = false; + } + else + { + DeviceExists = true; + } + if (HeaderType == PCIHeaderType.Normal) + { + BaseAddressBar = new PCIBaseAddressBar[6]; + BaseAddressBar[0] = new PCIBaseAddressBar(ReadRegister32(0x10)); + BaseAddressBar[1] = new PCIBaseAddressBar(ReadRegister32(0x14)); + BaseAddressBar[2] = new PCIBaseAddressBar(ReadRegister32(0x18)); + BaseAddressBar[3] = new PCIBaseAddressBar(ReadRegister32(0x1C)); + BaseAddressBar[4] = new PCIBaseAddressBar(ReadRegister32(0x20)); + BaseAddressBar[5] = new PCIBaseAddressBar(ReadRegister32(0x24)); + } + } + + public static ushort GetHeaderType(ushort Bus, ushort Slot, ushort Function) + { + UInt32 xAddr = GetAddressBase(Bus, Slot, Function) | 0xE & 0xFC; + IO.ConfigAddressPort.DWord = xAddr; + return (byte)(IO.ConfigDataPort.DWord >> ((0xE % 4) * 8) & 0xFF); + } + + public static UInt16 GetVendorID(ushort Bus, ushort Slot, ushort Function) + { + UInt32 xAddr = GetAddressBase(Bus, Slot, Function) | 0x0 & 0xFC; + IO.ConfigAddressPort.DWord = xAddr; + return (UInt16)(IO.ConfigDataPort.DWord >> ((0x0 % 4) * 8) & 0xFFFF); + } + + #region IOReadWrite + protected byte ReadRegister8(byte aRegister) + { + UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); + IO.ConfigAddressPort.DWord = xAddr; + return (byte)(IO.ConfigDataPort.DWord >> ((aRegister % 4) * 8) & 0xFF); + } + + protected void WriteRegister8(byte aRegister, byte value) + { + UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); + IO.ConfigAddressPort.DWord = xAddr; + IO.ConfigDataPort.Byte = value; + } + + protected UInt16 ReadRegister16(byte aRegister) + { + UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); + IO.ConfigAddressPort.DWord = xAddr; + return (UInt16)(IO.ConfigDataPort.DWord >> ((aRegister % 4) * 8) & 0xFFFF); + } + + protected void WriteRegister16(byte aRegister, ushort value) + { + UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); + IO.ConfigAddressPort.DWord = xAddr; + IO.ConfigDataPort.Word = value; + } + + protected UInt32 ReadRegister32(byte aRegister) + { + UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); + IO.ConfigAddressPort.DWord = xAddr; + return IO.ConfigDataPort.DWord; + } + + protected void WriteRegister32(byte aRegister, uint value) + { + UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); + IO.ConfigAddressPort.DWord = xAddr; + IO.ConfigDataPort.DWord = value; + } + #endregion + + protected static UInt32 GetAddressBase(uint aBus, uint aSlot, uint aFunction) + { + return 0x80000000 | (aBus << 16) | ((aSlot & 0x1F) << 11) | ((aFunction & 0x07) << 8); + } + + public void EnableMemory(bool enable) + { + UInt16 command = ReadRegister16(0x04); + + UInt16 flags = 0x0007; + + if (enable) + command |= flags; + else + command &= (ushort)~flags; + + WriteRegister16(0x04, command); + } + + public void EnableBusMaster(bool enable) + { + UInt16 command = ReadRegister16(0x04); + + UInt16 flags = (1 << 2); + + if (enable) + command |= flags; + else + command &= (ushort)~flags; + + WriteRegister16(0x04, command); + } + + public class DeviceClass + { + public static string GetDeviceString(PCIDevice device) + { + switch (device.VendorID) + { + case 0x1022: //AMD + switch (device.DeviceID) + { + case 0x2000: + return "AMD PCnet LANCE PCI Ethernet Controller"; + default: + return "AMD Unknown device"; + } + case 0x104B: //Sony + switch (device.DeviceID) + { + case 0x1040: + return "Mylex BT958 SCSI Host Adaptor"; + default: + return "Mylex Unknown device"; + } + case 0x1274: //Ensoniq + switch (device.DeviceID) + { + case 0x1371: + return "Ensoniq AudioPCI"; + default: + return "Ensoniq Unknown device"; + } + case 0x15AD: //VMware + switch (device.DeviceID) + { + case 0x0405: + return "VMware NVIDIA 9500MGS"; + case 0x0740: + return "Vmware Virtual Machine Communication Interface"; + case 0x0770: + return "VMware Standard Enhanced PCI to USB Host Controller"; + case 0x0790: + return "VMware 6.0 Virtual USB 2.0 Host Controller"; + case 0x07A0: + return "VMware PCI Express Root Port"; + default: + return "VMware Unknown device"; + } + case 0x8086: //Intel + switch (device.DeviceID) + { + case 0x7190: + return "Intel 440BX/ZX AGPset Host Bridge"; + case 0x7191: + return "Intel 440BX/ZX AGPset PCI-to-PCI bridge"; + case 0x7110: + return "Intel PIIX4/4E/4M ISA Bridge"; + case 0x7111: + return "Intel PIIX4/82371AB/EB/MB IDE"; + case 0x7112: + return "Intel PIIX4/4E/4M USB Interface"; + case 0x7113: + return "Intel PIIX4/82371AB/EB/MB ACPI"; + default: + return "Intel Unknown device"; + } + default: + return "Unknown device"; + } + } + + public static string GetTypeString(PCIDevice device) + { + switch (device.ClassCode) + { + case 0x00: + switch (device.Subclass) + { + case 0x01: + return "VGA-Compatible Device"; + default: + return "0x00 Subclass"; + } + case 0x01: + switch(device.Subclass) + { + case 0x00: + return "SCSI Bus Controller"; + case 0x01: + return "IDE Controller"; + case 0x02: + return "Floppy Disk Controller"; + case 0x03: + return "IPI Bus Controller"; + case 0x04: + return "RAID Controller"; + case 0x05: + return "ATA Controller"; + case 0x06: + return "Serial ATA"; + case 0x80: + return "Unknown Mass Storage Controller"; + default: + return "Mass Storage Controller"; + } + case 0x02: + switch (device.Subclass) + { + case 0x00: + return "Ethernet Controller"; + case 0x01: + return "Token Ring Controller"; + case 0x02: + return "FDDI Controller"; + case 0x03: + return "ATM Controller"; + case 0x04: + return "ISDN Controller"; + case 0x05: + return "WorldFip Controller"; + case 0x06: + return "PICMG 2.14 Multi Computing"; + case 0x80: + return "Unknown Network Controller"; + default: + return "Network Controller"; + } + case 0x03: + switch (device.Subclass) + { + case 0x00: + switch (device.ProgIF) + { + case 0x00: + return "VGA-Compatible Controller"; + case 0x01: + return "8512-Compatible Controller"; + default: + return "Unknown Display Controller"; + } + case 0x01: + return "XGA Controller"; + case 0x02: + return "3D Controller (Not VGA-Compatible)"; + case 0x80: + return "Unknown Display Controller"; + default: + return "Display Controller"; + } + case 0x04: + switch (device.Subclass) + { + case 0x00: + return "Video Device"; + case 0x01: + return "Audio Device"; + case 0x02: + return "Computer Telephony Device"; + case 0x80: + return "Unknown Multimedia Controller"; + default: + return "Multimedia Controller"; + } + case 0x05: + switch (device.Subclass) + { + case 0x00: + return "RAM Controller"; + case 0x01: + return "Flash Controller"; + case 0x80: + return "Unknown Memory Controller"; + default: + return "Memory Controller"; + } + case 0x06: + switch(device.Subclass) + { + case 0x00: + return "Host Bridge"; + case 0x01: + return "ISA Bridge"; + case 0x02: + return "EISA Bridge"; + case 0x03: + return "MCA Bridge"; + case 0x04: + switch (device.ProgIF) + { + case 0x00: + return "PCI-to-PCI Bridge"; + case 0x01: + return "PCI-to-PCI Bridge (Subtractive Decode)"; + default: + return "Unknown PCI-to-PCI Bridge"; + } + case 0x05: + return "PCMCIA Bridge"; + case 0x06: + return "NuBus Bridge"; + case 0x07: + return "CardBus Bridge"; + case 0x08: + return "RACEway Bridge"; + case 0x09: + switch (device.ProgIF) + { + case 0x00: + return "PCI-to-PCI Bridge (Semi-Transparent, Primary)"; + case 0x01: + return "PCI-to-PCI Bridge (Semi-Transparent, Secondary)"; + default: + return "Unknown PCI-to-PCI Bridge"; + } + case 0x0A: + return "InfiniBrand-to-PCI Host Bridge"; + case 0x80: + return "Unknown Bridge Device"; + default: + return "Bridge Device"; + } + case 0x07: + switch (device.Subclass) + { + case 0x00: + switch (device.ProgIF) + { + case 0x00: + return "Generic XT-Compatible Serial Controller"; + case 0x01: + return "16450-Compatible Serial Controller"; + case 0x02: + return "16550-Compatible Serial Controller"; + case 0x03: + return "16650-Compatible Serial Controller"; + case 0x04: + return "16750-Compatible Serial Controller"; + case 0x05: + return "16850-Compatible Serial Controller"; + case 0x06: + return "16950-Compatible Serial Controller"; + default: + return "Simple Communication Controller"; + } + case 0x01: + switch (device.ProgIF) + { + case 0x00: + return "Parallel Port"; + case 0x01: + return "Bi-Directional Parallel Port"; + case 0x02: + return "ECP 1.X Compliant Parallel Port"; + case 0x03: + return "IEEE 1284 Controller"; + case 0xFE: + return "IEEE 1284 Target Device"; + default: + return "Parallel Port"; + } + case 0x02: + return "Multiport Serial Controller"; + case 0x03: + switch (device.ProgIF) + { + case 0x00: + return "Generic Modem"; + case 0x01: + return "Hayes Compatible Modem (16450-Compatible Interface)"; + case 0x02: + return "Hayes Compatible Modem (16550-Compatible Interface)"; + case 0x03: + return "Hayes Compatible Modem (16650-Compatible Interface)"; + case 0x04: + return "Hayes Compatible Modem (16750-Compatible Interface)"; + default: + return "Modem"; + } + case 0x04: + return "IEEE 488.1/2 (GPIB) Controller"; + case 0x05: + return "Smart Card"; + case 0x80: + return "Unknown Communications Device"; + default: + return "Simple Communication Controller"; + } + case 0x08: + switch (device.Subclass) + { + case 0x00: + switch (device.ProgIF) + { + case 0x00: + return "Generic 8259 PIC"; + case 0x01: + return "ISA PIC"; + case 0x02: + return "EISA PIC"; + case 0x10: + return "I/O APIC Interrupt Controller"; + case 0x20: + return "I/O(x) APIC Interrupt Controller"; + default: + return "PIC"; + } + case 0x01: + switch (device.ProgIF) + { + case 0x00: + return "Generic 8237 DMA Controller"; + case 0x01: + return "ISA DMA Controller"; + case 0x02: + return "EISA DMA Controller"; + default: + return "DMA Controller"; + } + case 0x02: + switch (device.ProgIF) + { + case 0x00: + return "Generic 8254 System Timer"; + case 0x01: + return "ISA System Timer"; + case 0x02: + return "EISA System Timer"; + default: + return "System Timer"; + } + case 0x03: + switch (device.ProgIF) + { + case 0x00: + return "Generic RTC Controller"; + case 0x01: + return "ISA RTC Controller"; + default: + return "RTC Controller"; + } + case 0x04: + return "Generic PCI Hot-Plug Controller"; + case 0x80: + return "Unknown System Peripheral"; + default: + return "Base System Peripheral"; + } + case 0x09: + switch (device.Subclass) + { + case 0x00: + return "Keyboard Controller"; + case 0x01: + return "Digitizer"; + case 0x02: + return "Mouse Controller"; + case 0x03: + return "Scanner Controller"; + case 0x04: + switch (device.ProgIF) + { + case 0x00: + return "Gameport Controller (Generic)"; + case 0x10: + return "Gameport Controller (Legacy)"; + default: + return "Gameport Controller"; + } + case 0x80: + return "Unknown Input Controller"; + default: + return "Input Device"; + } + case 0x0A: + switch (device.Subclass) + { + case 0x00: + return "Generic Docking Station"; + case 0x80: + return "Unknown Docking Station"; + default: + return "Docking Station"; + } + case 0x0B: + switch (device.Subclass) + { + case 0x00: + return "386 Processor"; + case 0x01: + return "486 Processor"; + case 0x02: + return "Pentium Processor"; + case 0x10: + return "Alpha Processor"; + case 0x20: + return "PowerPC Processor"; + case 0x30: + return "MIPS Processor"; + case 0x40: + return "Co-Processor"; + default: + return "Processor"; + } + case 0x0C: + switch (device.Subclass) + { + case 0x00: + switch (device.ProgIF) + { + case 0x00: + return "IEEE 1394 Controller (FireWire)"; + case 0x10: + return "IEEE 1394 Controller (1394 OpenHCI Spec)"; + default: + return "IEEE Controller"; + } + case 0x01: + return "ACCESS.bus"; + case 0x02: + return "SSA"; + case 0x03: + switch (device.ProgIF) + { + case 0x00: + return "USB (Universal Host Controller Spec)"; + case 0x10: + return "USB (Open Host Controller Spec)"; + case 0x20: + return "USB2 Host Controller (Intel Enhanced Host Controller Interface)"; + case 0x30: + return "USB3 XHCI Controller"; + case 0x80: + return "Unspecified USB Controller"; + case 0xFE: + return "USB (Not Host Controller)"; + default: + return "USB"; + } + case 0x04: + return "Fibre Channel"; + case 0x05: + return "SMBus"; + case 0x06: + return "InfiniBand"; + case 0x07: + switch (device.ProgIF) + { + case 0x00: + return "IPMI SMIC Interface"; + case 0x01: + return "IPMI Kybd Controller Style Interface"; + case 0x02: + return "IPMI Block Transfer Interface"; + default: + return "IPMI SMIC Interface"; + } + case 0x08: + return "SERCOS Interface Standard (IEC 61491)"; + case 0x09: + return "CANbus"; + default: + return "Serial Bus Controller"; + } + case 0x0D: + switch (device.Subclass) + { + case 0x00: + return "iRDA Compatible Controller"; + case 0x01: + return "Consumer IR Controller"; + case 0x10: + return "RF Controller"; + case 0x11: + return "Bluetooth Controller"; + case 0x12: + return "Broadband Controller"; + case 0x20: + return "Ethernet Controller (802.11a)"; + case 0x21: + return "Ethernet Controller (802.11b)"; + case 0x80: + return "Unknown Wireless Controller"; + default: + return "Wireless Controller"; + } + case 0x0E: + switch (device.Subclass) + { + case 0x00: + return "Message FIFO"; + default: + return "Intelligent I/O Controller"; + } + case 0x0F: + switch (device.Subclass) + { + case 0x01: + return "TV Controller"; + case 0x02: + return "Audio Controller"; + case 0x03: + return "Voice Controller"; + case 0x04: + return "Data Controller"; + default: + return "Satellite Communication Controller"; + } + case 0x10: + switch (device.Subclass) + { + case 0x00: + return "Network and Computing Encrpytion/Decryption"; + case 0x10: + return "Entertainment Encryption/Decryption"; + case 0x80: + return "Unknown Encryption/Decryption"; + default: + return "Encryption/Decryption Controller"; + } + case 0x11: + switch (device.Subclass) + { + case 0x00: + return "DPIO Modules"; + case 0x01: + return "Performance Counters"; + case 0x10: + return "Communications Syncrhonization Plus Time and Frequency Test/Measurment"; + case 0x20: + return "Management Card"; + case 0x80: + return "Unknown Data Acquisition/Signal Processing Controller"; + default: + return "Data Acquisition and Signal Processing Controller"; + } + default: + return "Unknown device type"; + } + } + + } + + private static string ToHex(uint aNumber, byte aBits) + { + return "0x" + aNumber.ToHex(aBits / 4); + } + } + + public class PCIBaseAddressBar + { + private uint baseAddress = 0; + private ushort prefetchable = 0; + private ushort type = 0; + private bool isIO = false; + + public PCIBaseAddressBar(uint raw) + { + isIO = (raw & 0x01) == 1; + + if (isIO) + { + baseAddress = raw & 0xFFFFFFFC; + } + else + { + type = (ushort)((raw >> 1) & 0x03); + prefetchable = (ushort)((raw >> 3) & 0x01); + switch (type) + { + case 0x00: + baseAddress = raw & 0xFFFFFFF0; + break; + case 0x01: + baseAddress = raw & 0xFFFFFFF0; + break; + } + } + } + + public uint BaseAddress + { + get { return baseAddress; } + } + + public bool IsIO + { + get { return isIO; } + } + } +} diff --git a/source/Cosmos.HAL2/PciDevice.cs b/source/Cosmos.HAL2/PciDevice.cs deleted file mode 100644 index 7d6d372ad..000000000 --- a/source/Cosmos.HAL2/PciDevice.cs +++ /dev/null @@ -1,368 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Cosmos.Core.IOGroup; -using Cosmos.Common.Extensions; -using Cosmos.Debug.Kernel; - -namespace Cosmos.HAL -{ - public class PCIDevice - { - - #region Enums - public enum PCIHeaderType : byte - { - Normal = 0x00, - Bridge = 0x01, - Cardbus = 0x02 - }; - - public enum PCIBist : byte - { - CocdMask = 0x0f, - Start = 0x40, - Capable = 0x80 - }; - - public enum PCIInterruptPIN : byte - { - None = 0x00, - INTA = 0x01, - INTB = 0x02, - INTC = 0x03, - INTD = 0x04 - }; - - public enum Config : byte - { - VendorID = 0, DeviceID = 2, - Command = 4, Status = 6, - RevisionID = 8, ProgIF = 9, SubClass = 10, Class = 11, - CacheLineSize = 12, LatencyTimer = 13, HeaderType = 14, BIST = 15, - BAR0 = 16, - BAR1 = 20, - PrimaryBusNo = 24, SecondaryBusNo = 25, SubBusNo = 26, SecondarLT = 27, - IOBase = 28, IOLimit = 29, SecondaryStatus = 30, - MemoryBase = 32, MemoryLimit = 34, - PrefMemoryBase = 36, PrefMemoryLimit = 38, - PrefBase32Upper = 40, - PrefLimit32upper = 44, - PrefBase16Upper = 48, PrefLimit16upper = 50, - CapabilityPointer = 52, Reserved = 53, - ExpROMBaseAddress = 56, - InterruptLine = 60, InterruptPIN = 61, BridgeControl = 62 - }; - #endregion - - public readonly uint bus; - public readonly uint slot; - public readonly uint function; - - public readonly ushort VendorID; - public readonly ushort DeviceID; - - public readonly ushort Command; - public readonly ushort Status; - - public readonly byte RevisionID; - public readonly byte ProgIF; - public readonly byte Subclass; - public readonly byte ClassCode; - public readonly byte SecondaryBusNumber; - - public readonly bool DeviceExists; - - public readonly PCIHeaderType HeaderType; - public readonly PCIBist BIST; - public readonly PCIInterruptPIN InterruptPIN; - - public const ushort ConfigAddressPort = 0xCF8; - public const ushort ConfigDataPort = 0xCFC; - - public PCIBaseAddressBar[] BaseAddressBar; - - protected static Core.IOGroup.PCI IO = new Core.IOGroup.PCI(); - - public PCIDevice(uint bus, uint slot, uint function) - { - this.bus = bus; - this.slot = slot; - this.function = function; - - VendorID = ReadRegister16((byte)Config.VendorID); - DeviceID = ReadRegister16((byte)Config.DeviceID); - - Command = ReadRegister16((byte)Config.Command); - Status = ReadRegister16((byte)Config.Status); - - - RevisionID = ReadRegister8((byte)Config.RevisionID); - ProgIF = ReadRegister8((byte)Config.ProgIF); - Subclass = ReadRegister8((byte)Config.SubClass); - ClassCode = ReadRegister8((byte)Config.Class); - SecondaryBusNumber = ReadRegister8((byte)Config.SecondaryBusNo); - - HeaderType = (PCIHeaderType)ReadRegister8((byte)Config.HeaderType); - BIST = (PCIBist)ReadRegister8((byte)Config.BIST); - InterruptPIN = (PCIInterruptPIN)ReadRegister8((byte)Config.InterruptPIN); - if ((uint)VendorID == 0xFF && (uint)DeviceID == 0xFFFF) - { - DeviceExists = false; - } - else - { - DeviceExists = true; - } - if (HeaderType == PCIHeaderType.Normal) - { - BaseAddressBar = new PCIBaseAddressBar[6]; - BaseAddressBar[0] = new PCIBaseAddressBar(ReadRegister32(0x10)); - BaseAddressBar[1] = new PCIBaseAddressBar(ReadRegister32(0x14)); - BaseAddressBar[2] = new PCIBaseAddressBar(ReadRegister32(0x18)); - BaseAddressBar[3] = new PCIBaseAddressBar(ReadRegister32(0x1C)); - BaseAddressBar[4] = new PCIBaseAddressBar(ReadRegister32(0x20)); - BaseAddressBar[5] = new PCIBaseAddressBar(ReadRegister32(0x24)); - } - } - - public static ushort GetHeaderType(ushort Bus, ushort Slot, ushort Function) - { - UInt32 xAddr = GetAddressBase(Bus, Slot, Function) | 0xE & 0xFC; - IO.ConfigAddressPort.DWord = xAddr; - return (byte)(IO.ConfigDataPort.DWord >> ((0xE % 4) * 8) & 0xFF); - } - - public static UInt16 GetVendorID(ushort Bus, ushort Slot, ushort Function) - { - UInt32 xAddr = GetAddressBase(Bus, Slot, Function) | 0x0 & 0xFC; - IO.ConfigAddressPort.DWord = xAddr; - return (UInt16)(IO.ConfigDataPort.DWord >> ((0x0 % 4) * 8) & 0xFFFF); - } - - #region IOReadWrite - protected byte ReadRegister8(byte aRegister) - { - UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); - IO.ConfigAddressPort.DWord = xAddr; - return (byte)(IO.ConfigDataPort.DWord >> ((aRegister % 4) * 8) & 0xFF); - } - - protected void WriteRegister8(byte aRegister, byte value) - { - UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); - IO.ConfigAddressPort.DWord = xAddr; - IO.ConfigDataPort.Byte = value; - } - - protected UInt16 ReadRegister16(byte aRegister) - { - UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); - IO.ConfigAddressPort.DWord = xAddr; - return (UInt16)(IO.ConfigDataPort.DWord >> ((aRegister % 4) * 8) & 0xFFFF); - } - - protected void WriteRegister16(byte aRegister, ushort value) - { - UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); - IO.ConfigAddressPort.DWord = xAddr; - IO.ConfigDataPort.Word = value; - } - - protected UInt32 ReadRegister32(byte aRegister) - { - UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); - IO.ConfigAddressPort.DWord = xAddr; - return IO.ConfigDataPort.DWord; - } - - protected void WriteRegister32(byte aRegister, uint value) - { - UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); - IO.ConfigAddressPort.DWord = xAddr; - IO.ConfigDataPort.DWord = value; - } - #endregion - - protected static UInt32 GetAddressBase(uint aBus, uint aSlot, uint aFunction) - { - return 0x80000000 | (aBus << 16) | ((aSlot & 0x1F) << 11) | ((aFunction & 0x07) << 8); - } - - public void EnableMemory(bool enable) - { - UInt16 command = ReadRegister16(0x04); - - UInt16 flags = 0x0007; - - if (enable) - command |= flags; - else - command &= (ushort)~flags; - - WriteRegister16(0x04, command); - } - - public void EnableBusMaster(bool enable) - { - UInt16 command = ReadRegister16(0x04); - - UInt16 flags = (1 << 2); - - if (enable) - command |= flags; - else - command &= (ushort)~flags; - - WriteRegister16(0x04, command); - } - - public class DeviceClass - { - public static string GetString(PCIDevice device) - { - switch (device.VendorID) - { - case 0x1022: //AMD - switch (device.DeviceID) - { - case 0x2000: - return "AMD PCnet LANCE PCI Ethernet Controller"; - } - break; - case 0x104B: //Sony - switch (device.DeviceID) - { - case 0x1040: - return "Mylex BT958 SCSI Host Adaptor"; - } - break; - case 0x1274: //Ensoniq - switch (device.DeviceID) - { - case 0x1371: - return "Ensoniq AudioPCI"; - } - break; - case 0x15AD: //VMware - switch (device.DeviceID) - { - case 0x0405: - return "VMware NVIDIA 9500MGS"; - case 0x0770: - return "VMware Standard Enhanced PCI to USB Host Controller"; - case 0x0790: - return "VMware 6.0 Virtual USB 2.0 Host Controller"; - case 0x07A0: - return "VMware PCI Express Root Port"; - } - break; - case 0x8086: //Intel - switch (device.DeviceID) - { - case 0x7190: - return "Intel 440BX/ZX AGPset Host Bridge"; - case 0x7191: - return "Intel 440BX/ZX AGPset PCI-to-PCI bridge"; - case 0x7110: - return "Intel PIIX4/4E/4M ISA Bridge"; - case 0x7112: - return "Intel PIIX4/4E/4M USB Interface"; - } - break; - } - - switch (device.ClassCode) - { - //case 0x00: - // return "Any device"; - case 0x01: - return "Mass Storage Controller"; - case 0x02: - return "Network Controller"; - case 0x03: - return "Display Controller"; - case 0x04: - return "Multimedia Controller"; - case 0x05: - return "Memory Controller"; - case 0x06: - return "Bridge Device"; - case 0x07: - return "Simple Communication Controller"; - case 0x08: - return "Base System Peripheral"; - case 0x09: - return "Input Device"; - case 0x0A: - return "Docking Station"; - case 0x0B: - return "Processor"; - case 0x0C: - return "Serial Bus Controller"; - case 0x0D: - return "Wireless Controller"; - case 0x0E: - return "Intelligent I/O Controller"; - case 0x0F: - return "Satellite Communication Controller"; - case 0x10: - return "Encryption/Decryption Controller"; - case 0x11: - return "Data Acquisition and Signal Processing Controller"; - //case 0xFF: - // return "Unkown device"; - } - return "ClassCode: " + device.ClassCode + " Subclass: " + device.Subclass + " ProgIF: " + device.ProgIF; - } - } - - private static string ToHex(uint aNumber, byte aBits) - { - return "0x" + aNumber.ToHex(aBits / 4); - } - } - - public class PCIBaseAddressBar - { - private uint baseAddress = 0; - private ushort prefetchable = 0; - private ushort type = 0; - private bool isIO = false; - - public PCIBaseAddressBar(uint raw) - { - isIO = (raw & 0x01) == 1; - - if (isIO) - { - baseAddress = raw & 0xFFFFFFFC; - } - else - { - type = (ushort)((raw >> 1) & 0x03); - prefetchable = (ushort)((raw >> 3) & 0x01); - switch (type) - { - case 0x00: - baseAddress = raw & 0xFFFFFFF0; - break; - case 0x01: - baseAddress = raw & 0xFFFFFFF0; - break; - } - } - } - - public uint BaseAddress - { - get { return baseAddress; } - } - - public bool IsIO - { - get { return isIO; } - } - } -}