예제 #1
0
파일: AddDevice.cs 프로젝트: jncronin/tysos
        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());
            }
        }
예제 #2
0
파일: AddDevice.cs 프로젝트: jncronin/tysos
 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);
 }