From f8dd90dc7cf0dc0147383d8fef79917d586d7812 Mon Sep 17 00:00:00 2001 From: Valentin Charbonnier Date: Tue, 15 Aug 2017 17:52:26 +0200 Subject: [PATCH] First Impl. --- .../Drivers/PCI/Network/AMDPCNetII.cs | 28 +- .../Drivers/PCI/Video/VMWareSVGAII.cs | 12 +- source/Cosmos.HAL2/Global.cs | 129 +++---- source/Cosmos.HAL2/PCI.cs | 131 ++++--- source/Cosmos.HAL2/PCIBaseAddressBar.cs | 55 --- source/Cosmos.HAL2/PciDevice.cs | 341 +++++++----------- 6 files changed, 299 insertions(+), 397 deletions(-) delete mode 100644 source/Cosmos.HAL2/PCIBaseAddressBar.cs diff --git a/source/Cosmos.HAL2/Drivers/PCI/Network/AMDPCNetII.cs b/source/Cosmos.HAL2/Drivers/PCI/Network/AMDPCNetII.cs index 235205210..713c1cb6d 100644 --- a/source/Cosmos.HAL2/Drivers/PCI/Network/AMDPCNetII.cs +++ b/source/Cosmos.HAL2/Drivers/PCI/Network/AMDPCNetII.cs @@ -33,10 +33,10 @@ namespace Cosmos.HAL.Drivers.PCI.Network } this.pciCard = device; - this.pciCard.Claimed = true; + // this.pciCard.Claimed = true; this.pciCard.EnableDevice(); - this.io = new AMDPCNetIIIOGroup((ushort) this.pciCard.BaseAddresses[0].BaseAddress()); + //this.io = new AMDPCNetIIIOGroup((ushort) this.pciCard.BaseAddresses[0].BaseAddress()); this.io.RegisterData.DWord = 0; // Get the EEPROM MAC Address and set it as the devices MAC @@ -97,7 +97,7 @@ namespace Cosmos.HAL.Drivers.PCI.Network mTransmitBuffer = new Queue(); mRecvBuffer = new Queue(); - INTs.SetIrqHandler(device.InterruptLine, HandleNetworkInterrupt); + //INTs.SetIrqHandler(device.InterruptLine, HandleNetworkInterrupt); } protected void HandleNetworkInterrupt(ref INTs.IRQContext aContext) @@ -134,17 +134,17 @@ namespace Cosmos.HAL.Drivers.PCI.Network /// public static void FindAll() { - Console.WriteLine("Scanning for AMD PCNetII cards..."); - PCIDevice device = Cosmos.HAL.PCI.GetDevice(0x1022, 0x2000); - if (device != null) - { - AMDPCNetII nic = new AMDPCNetII((PCIDeviceNormal) device); - - Console.WriteLine("Found AMD PCNetII NIC on PCI " + device.bus + ":" + device.slot + ":" + - device.function); - Console.WriteLine("NIC IRQ: " + device.InterruptLine); - Console.WriteLine("NIC MAC Address: " + nic.MACAddress.ToString()); - } + Console.WriteLine("Scanning for AMD PCNetII cards..."); + // PCIDevice device = Cosmos.HAL.PCI.GetDevice(0x1022, 0x2000); + // if (device != null) + // { + // AMDPCNetII nic = new AMDPCNetII((PCIDeviceNormal) device); + // + // Console.WriteLine("Found AMD PCNetII NIC on PCI " + device.bus + ":" + device.slot + ":" + + // device.function); + // Console.WriteLine("NIC IRQ: " + device.InterruptLine); + // Console.WriteLine("NIC MAC Address: " + nic.MACAddress.ToString()); + // } } #region Register Access Properties diff --git a/source/Cosmos.HAL2/Drivers/PCI/Video/VMWareSVGAII.cs b/source/Cosmos.HAL2/Drivers/PCI/Video/VMWareSVGAII.cs index 9e4432417..f4256f5ef 100644 --- a/source/Cosmos.HAL2/Drivers/PCI/Video/VMWareSVGAII.cs +++ b/source/Cosmos.HAL2/Drivers/PCI/Video/VMWareSVGAII.cs @@ -145,13 +145,13 @@ namespace Cosmos.HAL.Drivers.PCI.Video public VMWareSVGAII() { - device = (PCIDeviceNormal)(HAL.PCI.GetDevice(0x15AD, 0x0405)); + //device = (PCIDeviceNormal)(HAL.PCI.GetDevice(0x15AD, 0x0405)); device.EnableMemory(true); - uint basePort = device.BaseAddresses[0].BaseAddress(); - IndexPort = new IOPort((ushort)(basePort + (uint)IOPortOffset.Index)); - ValuePort = new IOPort((ushort)(basePort + (uint)IOPortOffset.Value)); - BiosPort = new IOPort((ushort)(basePort + (uint)IOPortOffset.Bios)); - IRQPort = new IOPort((ushort)(basePort + (uint)IOPortOffset.IRQ)); + //uint basePort = device.BaseAddresses[0].BaseAddress(); + //IndexPort = new IOPort((ushort)(basePort + (uint)IOPortOffset.Index)); + //ValuePort = new IOPort((ushort)(basePort + (uint)IOPortOffset.Value)); + //BiosPort = new IOPort((ushort)(basePort + (uint)IOPortOffset.Bios)); + // IRQPort = new IOPort((ushort)(basePort + (uint)IOPortOffset.IRQ)); WriteRegister(Register.ID, (uint)ID.V2); if (ReadRegister(Register.ID) != (uint)ID.V2) diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index d4e374a02..aa79337dc 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -12,9 +12,67 @@ namespace Cosmos.HAL //static public PIT PIT = new PIT(); // Must be static init, other static inits rely on it not being null - public static TextScreenBase TextScreen = new TextScreen(); + public static TextScreenBase TextScreen = new TextScreen(); public static PCI Pci; + public static int atamode; + + static public void Init(TextScreenBase textScreen) + { + if (textScreen != null) + { + TextScreen = textScreen; + } + + mDebugger.Send("Before Core.Global.Init"); + Core.Global.Init(); + + //TODO Redo this - Global init should be other. + // Move PCI detection to hardware? Or leave it in core? Is Core PC specific, or deeper? + // If we let hardware do it, we need to protect it from being used by System. + // Probably belongs in hardware, and core is more specific stuff like CPU, memory, etc. + //Core.PCI.OnPCIDeviceFound = PCIDeviceFound; + + //TODO: Since this is FCL, its "common". Otherwise it should be + // system level and not accessible from Core. Need to think about this + // for the future. + + Console.WriteLine("Finding PCI Devices"); + mDebugger.Send("PCI Devices"); + PCI.Setup(); + + Console.WriteLine("Starting ACPI"); + mDebugger.Send("ACPI Init"); + ACPI.Start(); + + mDebugger.Send("Done initializing Cosmos.HAL.Global"); + + if (atamode == 1) + { + //TODO Implement an AHCI Driver + } + else if (atamode == 2) + { + //TODO Implement a RAID Driver + } + else if (atamode == 3) + { + mDebugger.Send("ATA Primary Master"); + InitAta(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); + + //TODO Need to change code to detect if ATA controllers are present or not. How to do this? via PCI enum? + // They do show up in PCI space as well as the fixed space. + // Or is it always here, and was our compiler stack corruption issue? + mDebugger.Send("ATA Secondary Master"); + InitAta(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); + //InitAta(BlockDevice.Ata.ControllerIdEnum.Secondary, BlockDevice.Ata.BusPositionEnum.Slave); + } + } + + public static void EnableInterrupts() + { + CPU.EnableInterrupts(); + } private static void InitAta(Ata.ControllerIdEnum aControllerID, Ata.BusPositionEnum aBusPosition) @@ -76,75 +134,6 @@ namespace Cosmos.HAL } } - // Init devices that are "static"/mostly static. These are devices - // that all PCs are expected to have. Keyboards, screens, ATA hard drives etc. - // Despite them being static, some discovery is required. For example, to see if - // a hard drive is connected or not and if so what type. - internal static void InitStaticDevices() - { - //TextScreen = new TextScreen(); - mDebugger.Send("CLS"); - //TODO: Since this is FCL, its "common". Otherwise it should be - // system level and not accessible from Core. Need to think about this - // for the future. - mDebugger.Send("Finding PCI Devices"); - //PCI.Setup(); - } - - static public void Init(TextScreenBase textScreen) - { - if (textScreen != null) - { - TextScreen = textScreen; - } - - mDebugger.Send("Before Core.Global.Init"); - Core.Global.Init(); - mDebugger.Send("Static Devices"); - InitStaticDevices(); - mDebugger.Send("PCI Devices"); - InitPciDevices(); - mDebugger.Send("ACPI Init"); - StartACPI(); - mDebugger.Send("Done initializing Cosmos.HAL.Global"); - - mDebugger.Send("ATA Primary Master"); - InitAta(Ata.ControllerIdEnum.Primary, Ata.BusPositionEnum.Master); - - //TODO Need to change code to detect if ATA controllers are present or not. How to do this? via PCI enum? - // They do show up in PCI space as well as the fixed space. - // Or is it always here, and was our compiler stack corruption issue? - mDebugger.Send("ATA Secondary Master"); - InitAta(Ata.ControllerIdEnum.Secondary, Ata.BusPositionEnum.Master); - //InitAta(BlockDevice.Ata.ControllerIdEnum.Secondary, BlockDevice.Ata.BusPositionEnum.Slave); - } - - internal static void InitPciDevices() - { - //TODO Redo this - Global init should be other. - // Move PCI detection to hardware? Or leave it in core? Is Core PC specific, or deeper? - // If we let hardware do it, we need to protect it from being used by System. - // Probably belongs in hardware, and core is more specific stuff like CPU, memory, etc. - //Core.PCI.OnPCIDeviceFound = PCIDeviceFound; - - //TODO: Since this is FCL, its "common". Otherwise it should be - // system level and not accessible from Core. Need to think about this - // for the future. - Console.WriteLine("Finding PCI Devices"); - PCI.Setup(); - } - - public static void StartACPI() - { - Console.WriteLine("Starting ACPI"); - ACPI.Start(); - } - - public static void EnableInterrupts() - { - CPU.EnableInterrupts(); - } - public static bool InterruptsEnabled => CPU.mInterruptsEnabled; } } diff --git a/source/Cosmos.HAL2/PCI.cs b/source/Cosmos.HAL2/PCI.cs index d9530bdb5..2b23c6415 100644 --- a/source/Cosmos.HAL2/PCI.cs +++ b/source/Cosmos.HAL2/PCI.cs @@ -8,75 +8,104 @@ namespace Cosmos.HAL { public class PCI { - private static List devices; - internal static Debugger mDebugger = new Debugger("HAL", "PCI"); + private static List Devices; + + public static uint Count + { + get { return (uint)Devices.Count; } + } public static void Setup() { - EnumerateDevices(); - } + Devices = new List(); - public static PCIDevice GetDevice(ushort VendorID, ushort DeviceID) - { - for (int i = 0; i < devices.Count; i++) + if ((PCIDevice.GetHeaderType(0x0, 0x0, 0x0) & 0x80) == 0) { - if (devices[i].VendorID == VendorID && devices[i].DeviceID == DeviceID) - return devices[i]; + CheckBus(0x0); } - return null; - } - - private static void EnumerateDevices() - { - devices = new List(); - //EnumerateBus(0, 0); - } - - private static void EnumerateBus(uint xBus, uint step) - { - for (uint xDevice = 0; xDevice < 32; xDevice++) + else { - PCIDevice xPCIDevice = new PCIDevice(xBus, xDevice, 0x00); - if (xPCIDevice.DeviceExists) + for (ushort fn = 0; fn < 8; fn++) { - if (xPCIDevice.HeaderType == PCIDevice.PCIHeaderType.Bridge) + if (PCIDevice.GetVendorID(0x0, 0x0, fn) != 0xFFFF) + break; + + CheckBus(fn); + } + } + + foreach (PCIDevice device in Devices) + { + + if (device.ClassCode == 0x01 && device.Subclass == 0x06 && device.ProgIF == 0x01) + { + //Serial ATA (AHCI 1.0) + Global.atamode = 1; + } + else if (device.ClassCode == 0x01 && device.Subclass == 0x04 && device.ProgIF == 0x00) + { + //RAID Controller + Global.atamode = 2; + } + else if (device.ClassCode == 0x01 && device.Subclass == 0x01) + { + //IDE Controller + Global.atamode = 3; + } + } + } + + private static void CheckBus(ushort xBus) + { + for (ushort device = 0; device < 32; device++) + { + if (PCIDevice.GetVendorID(xBus, device, 0x0) == 0xFFFF) + continue; + + CheckFunction(new PCIDevice(xBus, device, 0x0)); + if ((PCIDevice.GetHeaderType(xBus, device, 0x0) & 0x80) != 0) + { + for (ushort fn = 1; fn < 8; fn++) { - for (uint xFunction = 0; xFunction < 8; xFunction++) - { - xPCIDevice = new PCIDevice(xBus, xDevice, xFunction); - if (xPCIDevice.DeviceExists) - AddDevice(new PCIDeviceBridge(xBus, xDevice, xFunction), step); - } - } - else if (xPCIDevice.HeaderType == PCIDevice.PCIHeaderType.Cardbus) - { - AddDevice(new PCIDeviceCardbus(xBus, xDevice, 0x00), step); - } - else - { - AddDevice(new PCIDeviceNormal(xBus, xDevice, 0x00), step); + if (PCIDevice.GetVendorID(xBus, device, fn) != 0xFFFF) + CheckFunction(new PCIDevice(xBus, device, fn)); } } } } - private static void AddDevice(PCIDevice device, uint step) + private static void CheckFunction(PCIDevice xPCIDevice) { - Console.WriteLine("Adding PCIDevice"); - string str = ""; - for (int i = 0; i < step; i++) + Devices.Add(xPCIDevice); + + if (xPCIDevice.ClassCode == 0x6 && xPCIDevice.Subclass == 0x4) + CheckBus(xPCIDevice.SecondaryBusNumber); + } + + public static PCIDevice GetDeviceVendorID(ushort VendorID, ushort DeviceID) + { + for (int i = 0; i < Devices.Count; i++) { - str += " "; + var xDevice = Devices[i]; + if (xDevice.VendorID == VendorID && xDevice.DeviceID == DeviceID) + { + return Devices[i]; + } } - var xText = str + device.bus + ":" + device.slot + ":" + device.function + " " + PCIDevice.DeviceClass.GetString(device); - mDebugger.Send(xText); - Console.WriteLine(xText); - devices.Add(device); - if (device is PCIDeviceBridge) + return null; + } + + public static PCIDevice GetDeviceClass(ushort Class, ushort SubClass) + { + for (int i = 0; i < Devices.Count; i++) { - var xDevice = device as PCIDeviceBridge; - EnumerateBus((xDevice).SecondaryBusNumber, step + 1); + var xDevice = Devices[i]; + if (xDevice.ClassCode == Class && xDevice.Subclass == SubClass) + { + return Devices[i]; + } } + return null; } } -} +} \ No newline at end of file diff --git a/source/Cosmos.HAL2/PCIBaseAddressBar.cs b/source/Cosmos.HAL2/PCIBaseAddressBar.cs deleted file mode 100644 index dca9e2706..000000000 --- a/source/Cosmos.HAL2/PCIBaseAddressBar.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Cosmos.HAL -{ - public class PCIBaseAddressBar - { - private uint baseAddress = 0; - private ushort prefetchable = 0; - private byte type = 0; - private bool isIO = false; - - internal PCIBaseAddressBar(uint raw) - { - isIO = (raw & 0x01) == 1; - - if (isIO) - { - baseAddress = raw & 0xFFFFFFFC; - } - else - { - type = (byte)((raw >> 1) & 0x03); - prefetchable = (ushort)((raw >> 3) & 0x01); - switch (type) - { - case 0x00: - baseAddress = raw & 0xFFFFFFF0; - break; - case 0x01: - baseAddress = raw & 0xFFFFFFF0; - break; - } - } - } - private static int pci_size(int b, int mask) - { - int size = mask & b; - size = size & ~(size - 1); - return size; - } - - public uint BaseAddress() - { - return baseAddress; - } - - public bool IsIO() - { - return isIO; - } - } -} diff --git a/source/Cosmos.HAL2/PciDevice.cs b/source/Cosmos.HAL2/PciDevice.cs index 22c7563fc..58157369b 100644 --- a/source/Cosmos.HAL2/PciDevice.cs +++ b/source/Cosmos.HAL2/PciDevice.cs @@ -10,54 +10,21 @@ namespace Cosmos.HAL { public class PCIDevice { + + #region Enums public enum PCIHeaderType : byte { Normal = 0x00, Bridge = 0x01, Cardbus = 0x02 - } + }; - [Flags] public enum PCIBist : byte { - CocdMask = 0x0f, /* Return result */ - Start = 0x40, /* 1 to start BIST, 2 secs or less */ - Capable = 0x80 /* 1 if BIST capable */ - } - - [Flags] - public enum PCICommand : short - { - IO = 0x1, /* Enable response in I/O space */ - Memory = 0x2, /* Enable response in Memory space */ - Master = 0x4, /* Enable bus mastering */ - Special = 0x8, /* Enable response to special cycles */ - Invalidate = 0x10, /* Use memory write and invalidate */ - VGA_Pallete = 0x20, /* Enable palette snooping */ - Parity = 0x40, /* Enable parity checking */ - Wait = 0x80, /* Enable address/data stepping */ - SERR = 0x100, /* Enable SERR */ - Fast_Back = 0x200, /* Enable back-to-back writes */ - } - - [Flags] - public enum PCIStatus : int - { - CAP_LIST = 0x10, /* Support Capability List */ - SUPPORT_66MHZ = 0x20, /* Support 66 Mhz PCI 2.1 bus */ - UDF = 0x40, /* Support User Definable Features [obsolete] */ - FAST_BACK = 0x80, /* Accept fast-back to back */ - PARITY = 0x100, /* Detected parity error */ - DEVSEL_MASK = 0x600, /* DEVSEL timing */ - DEVSEL_FAST = 0x000, - DEVSEL_MEDIUM = 0x200, - DEVSEL_SLOW = 0x400, - SIG_TARGET_ABORT = 0x800, /* Set on target abort */ - REC_TARGET_ABORT = 0x1000, /* Master ack of " */ - REC_MASTER_ABORT = 0x2000, /* Set on master abort */ - SIG_SYSTEM_ERROR = 0x4000, /* Set when we drive SERR */ - DETECTED_PARITY = 0x8000 /* Set on parity error */ - } + CocdMask = 0x0f, + Start = 0x40, + Capable = 0x80 + }; public enum PCIInterruptPIN : byte { @@ -66,95 +33,106 @@ namespace Cosmos.HAL INTB = 0x02, INTC = 0x03, INTD = 0x04 - } + }; - public ushort VendorID { get; private set; } - public ushort DeviceID { get; private set; } + 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 PCICommand Command { get; private set; } - //public PCIStatus Status { get; private set; } - public PCICommand Command { get { return (PCICommand)ReadRegister16(0x04); } set { WriteRegister16(0x04, (ushort)value); } } - public PCIStatus Status { get { return (PCIStatus)ReadRegister16(0x06); } set { WriteRegister16(0x06, (ushort)value); } } + public readonly uint bus; + public readonly uint slot; + public readonly uint function; - public byte RevisionID { get; private set; } - public byte ProgIF { get; private set; } - public byte Subclass { get; private set; } - public byte ClassCode { get; private set; } + public readonly ushort VendorID; + public readonly ushort DeviceID; - public byte CacheLineSize { get; private set; } - public byte LatencyTimer { get; private set; } - public PCIHeaderType HeaderType { get; private set; } - public PCIBist BIST { get; private set; } + public readonly ushort Command; + public readonly ushort Status; - public byte InterruptLine { get; private set; } - public PCIInterruptPIN InterruptPIN { get; private set; } + public readonly byte RevisionID; + public readonly byte ProgIF; + public readonly byte Subclass; + public readonly byte ClassCode; + public readonly byte SecondaryBusNumber; - public bool DeviceExists { get; private set; } + public readonly bool DeviceExists; - /// - /// Has this device been claimed by a driver - /// - public bool Claimed { get; set; } + public readonly PCIHeaderType HeaderType; + public readonly PCIBist BIST; + public readonly PCIInterruptPIN InterruptPIN; - public uint bus = 0; - public uint slot = 0; - public uint function = 0; + public const ushort ConfigAddressPort = 0xCF8; + public const ushort ConfigDataPort = 0xCFC; + + public PCIBaseAddressBar[] BaseAddressBar; + + protected static Core.IOGroup.PCI IO = new Core.IOGroup.PCI(); - protected 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(0x00); - DeviceID = ReadRegister16(0x02); - //Command = (PCICommand)ReadRegister16(0x04); - //Status = (PCIStatus)ReadRegister16(0x06); + VendorID = ReadRegister16((byte)Config.VendorID); + DeviceID = ReadRegister16((byte)Config.DeviceID); - RevisionID = ReadRegister8(0x08); - ProgIF = ReadRegister8(0x09); - Subclass = ReadRegister8(0x0A); - ClassCode = ReadRegister8(0x0B); + Command = ReadRegister16((byte)Config.Command); + Status = ReadRegister16((byte)Config.Status); - CacheLineSize = ReadRegister8(0x0C); - LatencyTimer = ReadRegister8(0x0D); - HeaderType = (PCIHeaderType)ReadRegister8(0x0E); - BIST = (PCIBist)ReadRegister8(0x0F); - InterruptLine = ReadRegister8(0x3C); - InterruptPIN = (PCIInterruptPIN)ReadRegister8(0x3D); + 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); DeviceExists = (uint)VendorID != 0xFFFF && (uint)DeviceID != 0xFFFF; + 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)); + } } - protected UInt32 GetAddressBase(uint aBus, uint aSlot, uint aFunction) + public static ushort GetHeaderType(ushort Bus, ushort Slot, ushort Function) { - // 31 30 - 24 23 - 16 15 - 11 10 - 8 7 - 2 1 - 0 - // Enable Bit Reserved Bus Number Device Number Function Number Register Number 00 - return (UInt32)( - // Enable bit - must be set - 0x80000000 - // Bits 23-16 - | (aBus << 16) - // Bits 15-11 - | ((aSlot & 0x1F) << 11) - // Bits 10-8 - | ((aFunction & 0x07) << 8)); + UInt32 xAddr = GetAddressBase(Bus, Slot, Function) | 0xE & 0xFC; + IO.ConfigAddressPort.DWord = xAddr; + return (byte)(IO.ConfigDataPort.DWord >> ((0xE % 4) * 8) & 0xFF); } - public void EnableMemory(bool enable) + public static UInt16 GetVendorID(ushort Bus, ushort Slot, ushort Function) { - UInt16 command = ReadRegister16(0x04); - - UInt16 flags = 0x0007; - - if (enable) - command |= flags; - else - command &= (ushort)~flags; - - WriteRegister16(0x04, command); + UInt32 xAddr = GetAddressBase(Bus, Slot, Function) | 0x0 & 0xFC; + IO.ConfigAddressPort.DWord = xAddr; + return (UInt16)(IO.ConfigDataPort.DWord >> ((0x0 % 4) * 8) & 0xFFFF); } #region IOReadWrite @@ -176,7 +154,7 @@ namespace Cosmos.HAL { UInt32 xAddr = GetAddressBase(bus, slot, function) | ((UInt32)(aRegister & 0xFC)); IO.ConfigAddressPort.DWord = xAddr; - return (UInt16)(IO.ConfigDataPort.DWord >> ((aRegister % 4) * 8) & 0xFFFF); ; + return (UInt16)(IO.ConfigDataPort.DWord >> ((aRegister % 4) * 8) & 0xFFFF); } protected void WriteRegister16(byte aRegister, ushort value) @@ -201,104 +179,23 @@ namespace Cosmos.HAL } #endregion - public class DeviceClass + protected static UInt32 GetAddressBase(uint aBus, uint aSlot, uint aFunction) { - 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; - } + return 0x80000000 | (aBus << 16) | ((aSlot & 0x1F) << 11) | ((aFunction & 0x07) << 8); + } - 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; - } + public void EnableMemory(bool enable) + { + UInt16 command = ReadRegister16(0x04); + + UInt16 flags = 0x0007; + + if (enable) + command |= flags; + else + command &= (ushort)~flags; + + WriteRegister16(0x04, command); } private static string ToHex(uint aNumber, byte aBits) @@ -306,4 +203,46 @@ namespace Cosmos.HAL 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; } + } + } +} \ No newline at end of file