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")); } }
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; }
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")); } }
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")); } }
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")); } }
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")); } }
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")); } }
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); }
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(); } }
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); }