Example #1
0
 public byte ReadIOByte(ulong Addr)
 {
     tysos.x86_64.IOResource io = a.ios.Contains(Addr, 1);
     if (io != null)
     {
         return((byte)io.Read(Addr, 1));
     }
     else
     {
         throw new Exception("Invalid IO port: " + Addr.ToString("X"));
     }
 }
Example #2
0
 internal PCIConfiguration(tysos.x86_64.IOResource config_address,
                           tysos.x86_64.IOResource config_data, int _bus, int _dev, int _func,
                           IHostBridge hostbridge, IList <BAROverride> bar_overrides)
 {
     CONFIG_ADDRESS = config_address;
     CONFIG_DATA    = config_data;
     bus            = _bus;
     dev            = _dev;
     func           = _func;
     hb             = hostbridge;
     bars           = bar_overrides;
 }
Example #3
0
 public ushort ReadIOWord(ulong Addr)
 {
     tysos.x86_64.IOResource io = a.ios.Contains(Addr, 2);
     if (io != null)
     {
         return((ushort)io.Read(Addr, 2));
     }
     else
     {
         throw new Exception("Invalid IO port: " + Addr.ToString("X"));
     }
 }
Example #4
0
 public void WriteIOQWord(ulong Addr, ulong v)
 {
     tysos.x86_64.IOResource io = a.ios.Contains(Addr, 8);
     if (io != null)
     {
         io.Write(Addr, 8, v);
     }
     else
     {
         throw new Exception("Invalid IO port: " + Addr.ToString("X"));
     }
 }
Example #5
0
 public uint ReadIODWord(ulong Addr)
 {
     tysos.x86_64.IOResource io = a.ios.Contains(Addr, 4);
     if (io != null)
     {
         var ret = (uint)io.Read(Addr, 4);
         //System.Diagnostics.Debugger.Log(0, "acpipc", "ReadIODWord: " + ret.ToString("X8") + " from: " + Addr.ToString("X8"));
         return(ret);
     }
     else
     {
         throw new Exception("Invalid IO port: " + Addr.ToString("X"));
     }
 }
Example #6
0
        public void WriteIOWord(ulong Addr, ushort v)
        {
            /* If its a write to the vbox dbg port, log it */
            if (Addr == 0x3000 && is_vbox)
            {
                vbox_write(v);
            }

            tysos.x86_64.IOResource io = a.ios.Contains(Addr, 2);
            if (io != null)
            {
                io.Write(Addr, 2, v);
            }
            else
            {
                throw new Exception("Invalid IO port: " + Addr.ToString("X"));
            }
        }
Example #7
0
        public void WriteIODWord(ulong Addr, uint v)
        {
            /* If its a write to the vbox dbg port, log it */
            if (Addr == 0x3000 && is_vbox)
            {
                vbox_write(v);
            }

            tysos.x86_64.IOResource io = a.ios.Contains(Addr, 4);
            if (io != null)
            {
                //System.Diagnostics.Debugger.Log(0, "acpipc", "WriteIODWord: " + v.ToString("X8") + " to: " + Addr.ToString("X8"));
                io.Write(Addr, 4, v);
            }
            else
            {
                throw new Exception("Invalid IO port: " + Addr.ToString("X"));
            }
        }
Example #8
0
        public override bool InitServer()
        {
            System.Diagnostics.Debugger.Log(0, "pci", "hostbridge started with " + root.Count.ToString() + " properties");

            /* Extract the resources we have been given */
            vmems.Init(root);
            pmems.Init(root);
            ios.Init(root);
            acpiname = GetFirstProperty(root, "acpiname") as string;
            acpiconf = ACPIConfiguration.GetConfiguration(root);
            foreach (var res in root)
            {
                if (res.Name == "interrupt" && (res.Value is ACPIInterrupt))
                {
                    var acpi_int = res.Value as ACPIInterrupt;
                    if (acpi_int.irq != -1)
                    {
                        isa_irqs[acpi_int.irq] = acpi_int;
                    }
                }
            }
            DeviceDB.InitDeviceDB(this);

            /* Get CONFIG_DATA and CONFIG_ADDRESS ports */
            CONFIG_ADDRESS = ios.AllocFixed(0xcf8, 4);
            CONFIG_DATA    = ios.AllocFixed(0xcfc, 4);
            if (CONFIG_ADDRESS == null)
            {
                throw new Exception("Unable to obtain CONFIG_ADDRESS");
            }
            if (CONFIG_DATA == null)
            {
                throw new Exception("Unable to obtain CONFIG_DATA");
            }

            /* Get extra details from ACPI if available */
            if (acpiname != null && acpiconf.ContainsKey(acpiname))
            {
                /* Get a list of subdevices */
                IList <ACPIName> subdevs = acpiconf[acpiname].GetDevices(1);
                foreach (var subdev in subdevs)
                {
                    System.Diagnostics.Debugger.Log(0, "pci", "acpi reported subdevice: " + subdev);
                    var adr = acpiconf[acpiname].EvaluateObject(subdev + "._ADR", ACPIObject.DataType.Integer);
                    if (adr != null)
                    {
                        System.Diagnostics.Debugger.Log(0, "pci", "on device " + adr.IntegerData.ToString());
                        acpinames[(int)adr.IntegerData] = subdev;
                    }
                }

                /* Evaluate _PRT object */
                prts = acpiconf[acpiname].GetPRT();
            }

            /* Enumerate the devices on this bus */
            for (int dev = 0; dev < 32; dev++)
            {
                CheckDevice(0, dev, 0);
            }

            root.Add(new tysos.lib.File.Property {
                Name = "class", Value = "bus"
            });
            Tags.Add("class");

            return(true);
        }
Example #9
0
        public RPCResult <tysos.RangeResource> GetBAR(PCIConfiguration conf, int bar_no)
        {
            /* Get the requested BAR of the device passed.
             * If its base is zero, but length is not, we have to allocate it
             * somewhere */

            /* Ensure the device is enumerated by this bridge */
            if (conf.hb != this)
            {
                return(null);
            }

            /* Ensure its a valid BAR index.  For header type 0, max_bar is 6,
             * for header 1 its 2 and for others its 0 */
            uint header_type = ReadConfig(conf.bus, conf.dev, conf.func,
                                          0xc);

            header_type >>= 16;
            header_type  &= 0xffU;
            int max_bar = 0;

            if (header_type == 0)
            {
                max_bar = 6;
            }
            else if (header_type == 1)
            {
                max_bar = 2;
            }

            if (bar_no >= max_bar)
            {
                return(null);
            }

            /* See if we have a valid bar override */
            if (conf.bars != null && bar_no < conf.bars.Count)
            {
                BAROverride bar_override = conf.bars[bar_no];
                switch (bar_override.Type)
                {
                case 0:
                    return(pmems.AllocFixed(bar_override.Value, bar_override.Length, true));

                case 1:
                    return(ios.AllocFixed(bar_override.Value, bar_override.Length, true));
                }
            }

            /* If bar_no >= 1, read the previous BAR to ensure we're not
             * trying to read half way into a 64-bit one */
            if (bar_no >= 1)
            {
                uint prev_bar = ReadConfig(conf.bus, conf.dev, conf.func,
                                           (bar_no - 1) * 4 + 0x10);

                if ((prev_bar & 0x7) == 0x4)
                {
                    /* Previous bar is a 64 bit memory register */
                    return(null);
                }
            }

            /* Read the current value of the bar */
            int  bar_addr = bar_no * 4 + 0x10;
            uint bar      = ReadConfig(conf.bus, conf.dev, conf.func, bar_addr);

            if ((bar & 0x1) == 0)
            {
                // Memory register
                ulong base_addr = 0;
                ulong length    = 0;
                switch (bar & 0x7)
                {
                case 0:
                    // 32 bit address
                    base_addr = bar & 0xfffffff0U;

                    /* To get length, write all 1s, read length, mask out type bits
                     * and write the original value back */
                    WriteConfig(conf.bus, conf.dev, conf.func, bar_addr, 0xffffffffU);
                    length  = ReadConfig(conf.bus, conf.dev, conf.func, bar_addr);
                    length &= 0xfffffff0U;
                    WriteConfig(conf.bus, conf.dev, conf.func, bar_addr, bar);
                    unchecked { length = ~length; length++; }
                    length &= 0xffffffffU;

                    break;

                case 2:
                    // 16 bit address
                    base_addr = bar & 0xfff0U;

                    WriteConfig(conf.bus, conf.dev, conf.func, bar_addr, 0xffffU);
                    length  = ReadConfig(conf.bus, conf.dev, conf.func, bar_addr);
                    length &= 0xfff0U;
                    WriteConfig(conf.bus, conf.dev, conf.func, bar_addr, bar);
                    unchecked { length = ~length; length++; }
                    length &= 0xffffU;

                    break;

                case 4:
                    // 64 bit address
                    int next_bar      = bar_no + 1;
                    int next_bar_addr = next_bar * 4 + 0x10;
                    if (next_bar >= max_bar)
                    {
                        return(null);
                    }
                    ulong next_bar_val = ReadConfig(conf.bus, conf.dev,
                                                    conf.func, next_bar_addr);
                    base_addr  = bar & 0xfffffff0U;
                    base_addr |= (next_bar_val << 32);

                    WriteConfig(conf.bus, conf.dev, conf.func, bar_addr, 0xffffffffU);
                    length  = ReadConfig(conf.bus, conf.dev, conf.func, bar_addr);
                    length &= 0xfffffff0U;
                    WriteConfig(conf.bus, conf.dev, conf.func, bar_addr, bar);

                    WriteConfig(conf.bus, conf.dev, conf.func, next_bar_addr, 0xffffffffU);
                    ulong next_length = ReadConfig(conf.bus, conf.dev, conf.func, next_bar_addr);
                    length |= (next_length << 32);
                    WriteConfig(conf.bus, conf.dev, conf.func, next_bar_addr, (uint)next_bar_val);

                    unchecked { length = ~length; length++; }

                    break;
                }

                if (length == 0)
                {
                    return(null);
                }

                tysos.PhysicalMemoryResource64 pmem = pmems.AllocFixed(base_addr, length, true);
                if (pmem != null)
                {
                    return(pmem);
                }

                // TODO: allocate a chunk of physical address space for the device
                pmem = pmems.Alloc(length, 0x1000, (bar & 0x7) != 0x4);
                if (pmem == null)
                {
                    System.Diagnostics.Debugger.Log(0, "pci", "could not allocate physical memory for BAR");
                    return(null);
                }
                System.Diagnostics.Debugger.Log(0, "pci", "allocated " + pmem.ToString() + " for BAR " + bar_no.ToString());
                throw new NotImplementedException();
            }
            else
            {
                // IO register
                uint base_addr = bar & 0xfffffffcU;

                /* To get length, write all 1s, read length, mask out type bits
                 * and write the original value back */
                WriteConfig(conf.bus, conf.dev, conf.func, bar_addr, 0xffffffffU);
                uint length = ReadConfig(conf.bus, conf.dev, conf.func, bar_addr);
                length &= 0xfffffffcU;
                WriteConfig(conf.bus, conf.dev, conf.func, bar_addr, bar);
                unchecked { length = ~length; length++; }
                length &= 0xffffffffU;

                tysos.x86_64.IOResource io = ios.AllocFixed(base_addr, length, true);
                if (io != null)
                {
                    return(io);
                }

                if (length == 0)
                {
                    return(null);
                }

                // TODO: allocate a chunk of IO space for the device
                throw new NotImplementedException();
            }
        }
Example #10
0
        public override bool InitServer()
        {
            System.Diagnostics.Debugger.Log(0, "bga", "BGA driver started");

            // Interpret properties
            pciconf = pci.PCIConfiguration.GetPCIConf(root);
            ios.Init(root);
            index = ios.Contains(VBE_DISPI_IOPORT_INDEX, 2);
            data  = ios.Contains(VBE_DISPI_IOPORT_DATA, 2);
            foreach (var prop in root)
            {
                if (prop.Name == "vmem" && (prop.Value is tysos.VirtualMemoryResource64))
                {
                    vmem = prop.Value as tysos.VirtualMemoryResource64;
                    break;
                }
            }

            if (pciconf == null)
            {
                System.Diagnostics.Debugger.Log(0, "bga", "no pci configuration provided");
                return(false);
            }
            if (vmem == null)
            {
                System.Diagnostics.Debugger.Log(0, "bga", "no virtual memory space provided");
                return(false);
            }
            if (index == null)
            {
                System.Diagnostics.Debugger.Log(0, "bga", "index port not provided");
                return(false);
            }
            if (data == null)
            {
                System.Diagnostics.Debugger.Log(0, "bga", "data port not provided");
                return(false);
            }

            /* Determine the version of the BGA */
            ushort ver = ReadRegister(VBE_DISPI_INDEX_ID);

            System.Diagnostics.Debugger.Log(0, "bga", "BGA version " + ver.ToString("X4") + " detected");
            if (ver < 0xb0c2)
            {
                System.Diagnostics.Debugger.Log(0, null, "Unsupported BGA version");
                return(false);
            }

            /* Set a reasonable resolution */
            if (SetMode(1024, 768, 32) == false)
            {
                System.Diagnostics.Debugger.Log(0, "bga", "failed to set 1024x768x32");
                return(false);
            }

            /* Identify ourselves as a framebuffer device */
            root.Add(new tysos.lib.File.Property {
                Name = "class", Value = "framebuffer"
            });
            Tags.Add("class");

            read_fbd();

            return(true);
        }