private void AddDevice(IEnumerable <string> hid_strs, string name, Aml.ACPIObject obj, Aml.Namespace n, Aml.IMachineInterface mi) { StringBuilder sb = new StringBuilder(); int cnt = 0; foreach (var hid_str in hid_strs) { if (cnt != 0) { sb.Append(", "); } sb.Append(hid_str); cnt++; } System.Diagnostics.Debugger.Log(0, "acpipc", name + ": " + sb.ToString()); /* This is a mapping of PNP IDs/ACPI IDs to tysos device driver names */ string tysos_driver = "unknown"; string tysos_subdriver = null; foreach (var hid_str in hid_strs) { if (hid_str == "0A0CD041") { // PNP0C0A ACPI control method battery tysos_driver = "acpipc"; tysos_subdriver = "bat"; } else if (hid_str == "030AD041") { // PNP0A03 PCI bus tysos_driver = "pci"; tysos_subdriver = "hostbridge"; } else if (hid_str == "0001D041") { // PNP0100 AT system timer tysos_driver = "isa"; tysos_subdriver = "pit"; } else if (hid_str == "0F0CD041") { // PNP0C0F PCI interrupt link device tysos_driver = null; /* Dump its IRQ linkage */ Aml.ACPIObject lnk_res = n.Evaluate(name + "._CRS", mi); if (lnk_res != null) { List <File.Property> lnk_props = new List <File.Property>(); InterpretResources(lnk_res, lnk_props); foreach (var lnk_prop in lnk_props) { if (lnk_prop.Name == "interrupt") { System.Diagnostics.Debugger.Log(0, "acpipc", name + " -> " + lnk_prop.Value.ToString()); } } } } else if (hid_str == "ACPI0003") { // ACPI0003 ACPI Power source device tysos_driver = "acpipc"; tysos_subdriver = "power"; } else if (hid_str == "0301D041") { // PNP0103 HPET tysos_driver = "hpet"; } else if (hid_str == "0303D041") { // PNP0303 IBM enhanced keyboard (101/102-key, PS/2 mouse support) tysos_driver = "ps2"; } else if (hid_str == "030FD041") { // PNP0F03 Microsoft PS/2-style Mouse tysos_driver = "ps2"; } else if (hid_str == "0000D041") { // PNP0000 AT programmable interrupt controller tysos_driver = null; } else if (hid_str == "000BD041") { // PNP0B00 AT real-time clock tysos_driver = "isa"; tysos_subdriver = "rtc"; } else if (hid_str == "0105D041") { // PNP0501 16550A-compatible COM port tysos_driver = "isa"; tysos_subdriver = "serial"; } else if (hid_str == "0007D041") { // PNP0700 PC standard floppy disk controller tysos_driver = "fdc"; } else if (name == "0004D041") { // PNP0400 Standard LPT printer port tysos_driver = "isa"; tysos_subdriver = "lpt"; } else if (hid_str == "0002D041") { // PNP0200 AT DMA controller tysos_driver = "isa"; tysos_subdriver = "dma"; } else if (hid_str == "cpu" || hid_str == "ACPI0007") { // ACPI cpu object tysos_driver = "x86_64-cpu"; } if (tysos_driver == null) { return; } if (tysos_driver != "unknown") { break; } } /* Populate the device nodes properties */ List <tysos.lib.File.Property> props = new List <tysos.lib.File.Property>(); props.Add(new tysos.lib.File.Property { Name = "driver", Value = tysos_driver }); foreach (var hid_str in hid_strs) { props.Add(new tysos.lib.File.Property { Name = "acpiid", Value = hid_str }); } props.Add(new tysos.lib.File.Property { Name = "acpiname", Value = name }); ACPIConfiguration dev_conf = new ACPIConfiguration(this, name); props.Add(new tysos.lib.File.Property { Name = "acpiconf", Value = dev_conf }); /* Add PCI specific information */ if (tysos_driver == "pci") { /* Pass PCI IRQ routing information */ foreach (var lnk in lnks) { ACPIConfiguration lnk_conf = new ACPIConfiguration(this, lnk); props.Add(new File.Property { Name = "acpiconf", Value = lnk_conf }); } /* Pass unassigned ISA IRQs */ foreach (var isa_irq in isa_irqs) { if (isa_irq != null && isa_irq.irq != -1) { props.Add(new File.Property { Name = "interrupt", Value = isa_irq }); } } /* Pass a reasonable chunk of the address space */ var vmem = vmems.Alloc(0x1000000000UL, 0x1000UL); if (vmem != null) { props.Add(new File.Property { Name = "vmem", Value = vmem }); } } /* Add CPU specific information */ if (tysos_driver == "x86_64-cpu") { /* See ACPI 8.4 * Get the ACPI ID of the processor so we can match this * with a processor in the MADT table. This may be in two * forms: It can be a _UID object under the processor object, * or can be a field of the Processor object */ Aml.ACPIObject uid = n.Evaluate(name + "._UID", mi); bool found = false; bool enabled = true; if (uid != null && uid.Type == ACPIObject.DataType.Integer) { uint uid_val = (uint)uid.IntegerData; /* LAPIC structures don't contain UIDs and we don't * support Local SAPICs or Local x2APICs yet */ props.Add(new File.Property { Name = "acpiuid", Value = uid_val }); } if (found == false && obj.Type == ACPIObject.DataType.Processor) { /* Try parsing using ACPI ID instead */ var pd = obj.Data as ACPIObject.ProcessorData; foreach (var lapic in lapics) { if (lapic.ACPIProcessorID == pd.ID) { if ((lapic.Flags & 0x1) == 0) { enabled = false; } props.Add(new File.Property { Name = "apicid", Value = lapic.APICID }); tysos_subdriver = "lapic"; found = true; break; } } } if (found == false || enabled == false) { return; } if (obj.Type == ACPIObject.DataType.Processor) { var pd = obj.Data as ACPIObject.ProcessorData; props.Add(new File.Property { Name = "acpiprocid", Value = pd.ID }); if (pd.BlkLen != 0) { props.Add(new File.Property { Name = "io", Value = ios.AllocFixed(pd.BlkAddr, pd.BlkLen, true) }); } } } /* Get resources owned by the device */ Aml.ACPIObject resources = n.Evaluate(name + "._CRS", mi); if (resources != null) { InterpretResources(resources, props); } /* Generate a unique name for the device */ if (tysos_subdriver != null) { props.Add(new tysos.lib.File.Property { Name = "subdriver", Value = tysos_subdriver }); } int dev_no = 0; sb = new StringBuilder(tysos_driver); if (tysos_subdriver != null) { sb.Append("_"); sb.Append(tysos_subdriver); } 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(); /* Link all PS/2 devices together */ if (tysos_driver == "ps2" && children.ContainsKey("ps2_0")) { props.AddRange(children["ps2_0"]); } /* Create a file system node for the device */ children[dev_name] = props; System.Diagnostics.Debugger.Log(0, "acpipc", "AddDevice: created device: " + dev_name); foreach (tysos.lib.File.Property prop in props) { System.Diagnostics.Debugger.Log(0, "acpipc", " " + prop.Name + ": " + prop.Value.ToString()); } }
private void AddDevice(string hid_str, string name, Aml.ACPIObject obj, Aml.Namespace n, Aml.IMachineInterface mi) { AddDevice(new string[] { hid_str }, name, obj, n, mi); }