public static DeviceDBEntry GetDeviceDetails(DeviceDBKey id) { /* Try and match on vendor, device and revision, followed by * vendor and device, then class, subclass and progIF followed by * class and subclass */ DeviceDBEntry ret = null; DeviceDBEntry vdr; if (db_vdr.TryGetValue(id, out vdr)) { if (ret == null) { ret = vdr; } System.Diagnostics.Debugger.Log(0, "pci", "matched vendor/device/revision to " + vdr.ToString()); } DeviceDBEntry vd; if (db_vd.TryGetValue(id, out vd)) { if (ret == null) { ret = vd; } System.Diagnostics.Debugger.Log(0, "pci", "matched vendor/device to " + vd.ToString()); } DeviceDBEntry csp; if (db_csp.TryGetValue(id, out csp)) { if (ret == null) { ret = csp; } System.Diagnostics.Debugger.Log(0, "pci", "matched class/subclass/progIF to " + csp.ToString()); } DeviceDBEntry cs; if (db_cs.TryGetValue(id, out cs)) { if (ret == null) { ret = cs; } System.Diagnostics.Debugger.Log(0, "pci", "matched class/subclass to " + cs.ToString()); } if (ret != null) { ret.Key = id; } return(ret); }
private void CheckDevice(int bus, int dev, int func) { uint vendor_devID = ReadConfig(bus, dev, func, 0); uint vendorID = vendor_devID & 0xffff; if (vendorID == 0xffff) { return; } /* Get the basic fields of the device */ uint command_status = ReadConfig(bus, dev, func, 4); uint revID_progIF_subclass_class = ReadConfig(bus, dev, func, 8); uint cacheline_latency_ht_bist = ReadConfig(bus, dev, func, 0xc); /* We have found a valid device */ uint deviceID = vendor_devID >> 16; uint classcode = (revID_progIF_subclass_class >> 24) & 0xffU; uint subclasscode = (revID_progIF_subclass_class >> 16) & 0xffU; uint prog_IF = (revID_progIF_subclass_class >> 8) & 0xffU; uint revisionID = revID_progIF_subclass_class & 0xffU; System.Diagnostics.Debugger.Log(0, "pci", bus.ToString() + ":" + dev.ToString() + ":" + func.ToString() + " : " + vendorID.ToString("X4") + ":" + deviceID.ToString("X4") + " " + classcode.ToString("X2") + ":" + subclasscode.ToString("X2") + ":" + prog_IF.ToString("X2")); DeviceDBEntry details = DeviceDB.GetDeviceDetails(new DeviceDBKey { VendorID = vendorID, DeviceID = deviceID, RevisionID = revisionID, ClassCode = classcode, SubclassCode = subclasscode, ProgIF = prog_IF }); if (details == null) { System.Diagnostics.Debugger.Log(0, "pci", "unknown device"); } else { System.Diagnostics.Debugger.Log(0, "pci", details.ToString()); if (details.DriverName != null) { /* Build a device node */ List <tysos.lib.File.Property> props = new List <tysos.lib.File.Property>(); props.Add(new tysos.lib.File.Property { Name = "driver", Value = details.DriverName }); if (details.SubdriverName != null) { props.Add(new tysos.lib.File.Property { Name = "subdriver", Value = details.SubdriverName }); } if (details.HumanDeviceName != null) { props.Add(new tysos.lib.File.Property { Name = "name", Value = details.HumanDeviceName }); } if (details.HumanManufacturerName != null) { props.Add(new tysos.lib.File.Property { Name = "manufacturer", Value = details.HumanManufacturerName }); } PCIConfiguration conf = new PCIConfiguration(CONFIG_ADDRESS, CONFIG_DATA, bus, dev, func, this, details.BAROverrides); props.Add(new tysos.lib.File.Property { Name = "pciconf", Value = conf }); if (details.ExtraResources != null) { foreach (var res in details.ExtraResources) { if (res is tysos.Resources.InterruptLine) { props.Add(new tysos.lib.File.Property { Name = "interrupt", Value = res }); } else if (res is tysos.PhysicalMemoryResource64) { props.Add(new tysos.lib.File.Property { Name = "pmem", Value = res }); } else if (res is tysos.VirtualMemoryResource64) { props.Add(new tysos.lib.File.Property { Name = "vmem", Value = res }); } else if (res is tysos.x86_64.IOResource) { props.Add(new tysos.lib.File.Property { Name = "io", Value = res }); } } } /* Is the device enumerated in ACPI too? */ int dev_acpi = dev << 16 | func; int dev_acpi_all = dev << 16 | 0xffff; if (acpinames.ContainsKey(dev_acpi)) { props.Add(new tysos.lib.File.Property { Name = "acpiname", Value = acpinames[dev_acpi] }); } if (acpinames.ContainsKey(dev_acpi_all)) { props.Add(new tysos.lib.File.Property { Name = "acpiname", Value = acpinames[dev_acpi_all] }); } // Get interrupt pin number uint conf_3c = conf.ReadConfig(0x3c); uint pin = (conf_3c >> 8) & 0xffU; if (pin != 0) { int int_pin = (int)(pin - 1); if (prts.ContainsKey(dev_acpi)) { props.Add(new tysos.lib.File.Property { Name = "interrupt", Value = prts[dev_acpi][int_pin] }); } if (prts.ContainsKey(dev_acpi_all)) { props.Add(new tysos.lib.File.Property { Name = "interrupt", Value = prts[dev_acpi_all][int_pin] }); } } /* Generate a unique name for the device */ int dev_no = 0; StringBuilder sb = new StringBuilder(details.DriverName); if (details.SubdriverName != null) { sb.Append("_"); sb.Append(details.SubdriverName); } string base_dev = sb.ToString(); if (next_device_id.ContainsKey(base_dev)) { dev_no = next_device_id[base_dev]; } sb.Append("_"); sb.Append(dev_no.ToString()); next_device_id[base_dev] = dev_no + 1; string dev_name = sb.ToString(); children[dev_name] = props; foreach (var prop in props) { System.Diagnostics.Debugger.Log(0, "pci", " " + prop.Name + ": " + prop.Value.ToString()); } } } /* If header type == 0x80, it is a multifunction device */ uint header_type = (cacheline_latency_ht_bist >> 16) & 0xffU; if (header_type == 0x80 && func == 0) { for (int subfunc = 1; subfunc < 8; subfunc++) { CheckDevice(bus, dev, subfunc); } } }
static internal void InitDeviceDB(hostbridge hb) { db_vdr = new Dictionary <DeviceDBKey, DeviceDBEntry>(new VendorDeviceRevisionComparer()); db_vd = new Dictionary <DeviceDBKey, DeviceDBEntry>(new VendorDeviceComparer()); db_csp = new Dictionary <DeviceDBKey, DeviceDBEntry>(new ClassSubclassProgIFComparer()); db_cs = new Dictionary <DeviceDBKey, DeviceDBEntry>(new ClassSubclassComparer()); // Some defines that are used in more than one entry DeviceDBEntry pciide_legacy = new DeviceDBEntry { DriverName = "pciide", HumanManufacturerName = "Generic", HumanDeviceName = "PCI IDE Controller (legacy mode)", BAROverrides = new BAROverride[] { new BAROverride { Value = 0x1f0, Length = 8, Type = 1 }, new BAROverride { Value = 0x3f6, Length = 1, Type = 1 }, new BAROverride { Value = 0x170, Length = 8, Type = 1 }, new BAROverride { Value = 0x376, Length = 1, Type = 1 } }, ExtraResources = new List <tysos.Resource>() }; if (hb.isa_irqs.ContainsKey(14)) { pciide_legacy.ExtraResources.Add(hb.isa_irqs[14]); } if (hb.isa_irqs.ContainsKey(15)) { pciide_legacy.ExtraResources.Add(hb.isa_irqs[15]); } DeviceDBEntry pcnet32 = new DeviceDBEntry() { DriverName = "pcnet32", HumanManufacturerName = "AMD", HumanDeviceName = "79c970 [PCnet32 LANCE]", ExtraResources = new List <tysos.Resource> { hb.vmems.Alloc(0x10000) } }; // Device database // The following match on vendor ID and device ID db_vd.Add(new DeviceDBKey { VendorID = 0x8086, DeviceID = 0x1237 }, new DeviceDBEntry { DriverName = "pci", HumanManufacturerName = "Intel", HumanDeviceName = "440FX - 82441FX PCI and Memory Controller" }); db_vd.Add(new DeviceDBKey { VendorID = 0x8086, DeviceID = 0x2415 }, new DeviceDBEntry { DriverName = "ac97", HumanManufacturerName = "Intel", HumanDeviceName = "82801AA AC'97 Audio Controller" }); db_vd.Add(new DeviceDBKey { VendorID = 0x8086, DeviceID = 0x7000 }, new DeviceDBEntry { DriverName = null, HumanManufacturerName = "Intel", HumanDeviceName = "82371SB PIIX3 ISA" }); db_vd.Add(new DeviceDBKey { VendorID = 0x8086, DeviceID = 0x7113 }, new DeviceDBEntry { DriverName = null, HumanManufacturerName = "Intel", HumanDeviceName = "82371AB/EB/MB PIIX4 ACPI" }); db_vd.Add(new DeviceDBKey { VendorID = 0x80ee, DeviceID = 0xbeef }, new DeviceDBEntry { DriverName = "bga", HumanManufacturerName = "Oracle", HumanDeviceName = "VirtualBox Graphics Adapter", ExtraResources = new tysos.Resource[] { hb.ios.AllocFixed(0x1ce, 2, true), hb.ios.AllocFixed(0x1cf, 2, true), hb.vmems.Alloc(0x2000000) } }); db_vd.Add(new DeviceDBKey { VendorID = 0x1022, DeviceID = 0x2000 }, pcnet32); db_vd.Add(new DeviceDBKey { VendorID = 0x1022, DeviceID = 0x2001 }, pcnet32); // The following match on vendor ID, device ID and revision ID // The following match on class and subclass db_cs.Add(new DeviceDBKey { ClassCode = 0x01, SubclassCode = 0x01 }, new DeviceDBEntry { DriverName = "pciide", HumanManufacturerName = "Generic", HumanDeviceName = "PCI IDE Controller" }); // The following match on class, subclass and progIF db_csp.Add(new DeviceDBKey { ClassCode = 0x01, SubclassCode = 0x01, ProgIF = 0x00 }, pciide_legacy); db_csp.Add(new DeviceDBKey { ClassCode = 0x01, SubclassCode = 0x01, ProgIF = 0x0a }, pciide_legacy); db_csp.Add(new DeviceDBKey { ClassCode = 0x01, SubclassCode = 0x01, ProgIF = 0x80 }, pciide_legacy); db_csp.Add(new DeviceDBKey { ClassCode = 0x01, SubclassCode = 0x01, ProgIF = 0x8a }, pciide_legacy); db_csp.Add(new DeviceDBKey { ClassCode = 0x03, SubclassCode = 0x00, ProgIF = 0x00 }, new DeviceDBEntry { DriverName = "vga", HumanManufacturerName = "Generic", HumanDeviceName = "Standard VGA Controller" }); db_csp.Add(new DeviceDBKey { ClassCode = 0x0c, SubclassCode = 0x03, ProgIF = 0x00 }, new DeviceDBEntry { DriverName = "uhci", HumanManufacturerName = "Generic", HumanDeviceName = "UHCI Controller" }); db_csp.Add(new DeviceDBKey { ClassCode = 0x0c, SubclassCode = 0x03, ProgIF = 0x10 }, new DeviceDBEntry { DriverName = "ohci", HumanManufacturerName = "Generic", HumanDeviceName = "OHCI Controller" }); db_csp.Add(new DeviceDBKey { ClassCode = 0x0c, SubclassCode = 0x03, ProgIF = 0x20 }, new DeviceDBEntry { DriverName = "ehci", HumanManufacturerName = "Generic", HumanDeviceName = "EHCI Controller" }); db_csp.Add(new DeviceDBKey { ClassCode = 0x0c, SubclassCode = 0x03, ProgIF = 0x30 }, new DeviceDBEntry { DriverName = "xhci", HumanManufacturerName = "Generic", HumanDeviceName = "xHCI Controller" }); }