private ACPIInterrupt AllocateIRQ(int irq, bool sharable, bool active_low, bool level_trigger) { if (isa_irqs[irq] == null) { return(null); } ACPIInterrupt irq_int = isa_irqs[irq]; irq_int.is_level_trigger = level_trigger; irq_int.is_low_active = active_low; if (sharable == false) { isa_irqs[irq] = null; } return(irq_int); }
public void InterpretResources(ACPIObject resources, List <File.Property> props) { /* The value of _CRS should be a Buffer, i.e. an array of type byte[] */ if (resources.Type != ACPIObject.DataType.Buffer) { System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: WARNING: " + "_CRS output is not of type Package, but rather of type " + resources.Type.ToString()); return; } byte[] rs = resources.Data as byte[]; if (rs == null) { System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: WARNING: " + "_CRS output data is not of type byte[]"); return; } int idx = 0; while (idx < rs.Length) { byte tag = rs[idx]; if ((tag & 0x80) == 0) { /* Small resource */ int len = tag & 0x7; int type = (tag >> 3) & 0xf; //System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: small resource: type: " + type.ToString() + ", len: " + len.ToString()); switch (type) { case 0: case 1: case 2: case 3: System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: small reserved item"); throw new NotSupportedException(); case 4: //System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: small irq format item"); { uint irq_mask_1 = rs[idx + 1]; uint irq_mask_2 = rs[idx + 2]; uint flags = 0x1; // active high edge triggered if (len == 3) { flags = rs[idx + 3]; } bool sharable = ((flags & 0x10) != 0); bool active_low = ((flags & 0x08) != 0); bool level_trigger = ((flags & 0x1) == 0); for (int i = 0; i < 8; i++) { if ((irq_mask_1 & 0x1) != 0) { ACPIInterrupt irq = AllocateIRQ(i, sharable, active_low, level_trigger); if (irq != null) { props.Add(new File.Property { Name = "interrupt", Value = irq }); } } irq_mask_1 >>= 1; } for (int i = 0; i < 8; i++) { if ((irq_mask_2 & 0x1) != 0) { ACPIInterrupt irq = AllocateIRQ(i + 8, sharable, active_low, level_trigger); if (irq != null) { props.Add(new File.Property { Name = "interrupt", Value = irq }); } } irq_mask_2 >>= 1; } } break; case 5: //System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: small dma format item"); { uint dma_mask = rs[idx + 1]; for (int i = 0; i < 8; i++) { if ((dma_mask & 0x1) != 0) { props.Add(new File.Property { Name = "dma", Value = i }); } dma_mask >>= 1; } } break; case 6: System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: small start dependent functions item"); throw new NotImplementedException(); case 7: System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: small end dependent functions item"); throw new NotImplementedException(); case 8: //System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: small io port descriptor item"); { uint io_base = rs[idx + 2]; io_base |= (uint)rs[idx + 3] << 8; uint io_len = rs[idx + 7]; props.Add(new File.Property { Name = "io", Value = ios.AllocFixed(io_base, io_len, true) }); } break; case 9: System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: small fixed location io port descriptor item"); throw new NotImplementedException(); case 0xa: case 0xb: case 0xc: case 0xd: System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: small reserved item"); throw new NotSupportedException(); case 0xe: System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: small vendor defined descriptor item"); throw new NotImplementedException(); } if (type == 0xf) { break; } idx++; idx += len; } else { uint type = tag & 0x7fU; uint len = rs[idx + 1]; len |= (uint)rs[idx + 2] << 8; //System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: large resource: type: " + type.ToString() + ", len: " + len.ToString()); switch (type) { case 0x6: { ulong min = BitConverter.ToUInt32(rs, idx + 4); ulong length = BitConverter.ToUInt32(rs, idx + 8); props.Add(new File.Property { Name = "pmem", Value = pmems.AllocFixed(min, length, true) }); } break; case 0x7: case 0x8: case 0xa: { int res_type = rs[idx + 3]; int gen_flags = rs[idx + 4]; int spec_flags = rs[idx + 5]; ulong gran = 0; ulong min = 0; ulong max = 0; ulong tran = 0; ulong length = 0; switch (type) { case 0x7: gran = BitConverter.ToUInt32(rs, idx + 6); min = BitConverter.ToUInt32(rs, idx + 10); max = BitConverter.ToUInt32(rs, idx + 14); tran = BitConverter.ToUInt32(rs, idx + 18); length = BitConverter.ToUInt32(rs, idx + 22); break; case 0x8: gran = BitConverter.ToUInt16(rs, idx + 6); min = BitConverter.ToUInt16(rs, idx + 8); max = BitConverter.ToUInt16(rs, idx + 10); tran = BitConverter.ToUInt16(rs, idx + 12); length = BitConverter.ToUInt16(rs, idx + 14); break; case 0xa: gran = BitConverter.ToUInt64(rs, idx + 6); min = BitConverter.ToUInt64(rs, idx + 14); max = BitConverter.ToUInt64(rs, idx + 22); tran = BitConverter.ToUInt64(rs, idx + 30); length = BitConverter.ToUInt64(rs, idx + 38); break; } /*System.Diagnostics.Debugger.Log(0, "acpipc", "InterpretResources: large resource: res_type: " + * res_type.ToString("X8") + ", gen_flags: " + gen_flags.ToString("X8") + * ", spec_flags: " + spec_flags.ToString("X8") + * ", gran: " + gran.ToString("X16") + * ", min: " + min.ToString("X16") + * ", max: " + max.ToString("X16") + * ", tran: " + tran.ToString("X16") + * ", length: " + length.ToString("X16"));*/ switch (res_type) { case 0: props.Add(new File.Property { Name = "pmem", Value = pmems.AllocFixed(min, length, true) }); break; case 1: props.Add(new File.Property { Name = "io", Value = ios.AllocFixed((uint)min, (uint)length, true) }); break; } } break; default: throw new NotImplementedException("large descriptor type " + type.ToString()); } idx += 3; idx += (int)len; } } }
public IDictionary <int, ACPIInterrupt[]> GetPRT() { var prt = EvaluateObject("_PRT"); if (prt == null || prt.Type != ACPIObject.DataType.Package) { return(null); } Dictionary <int, ACPIInterrupt[]> prts = new Dictionary <int, ACPIInterrupt[]>( new tysos.Program.MyGenericEqualityComparer <int>()); foreach (var prtentry in (ACPIObject[])prt.Data) { if (prtentry.Type == ACPIObject.DataType.Package) { var prtobj = prtentry.Data as ACPIObject[]; int dev = (int)prtobj[0].IntegerData; if (!prts.ContainsKey(dev)) { prts[dev] = new ACPIInterrupt[4]; } int pin = (int)prtobj[1].IntegerData; /*StringBuilder sb = new StringBuilder(); * sb.Append("_PRT: "); * for (int i = 0; i < prtobj.Length; i++) * { * if (i != 0) * sb.Append(", "); * sb.Append(i.ToString()); * sb.Append(": "); * sb.Append(prtobj[i].Type.ToString()); * sb.Append(": "); * sb.Append(prtobj[i].Data.ToString()); * } * System.Diagnostics.Debugger.Log(0, "pci", sb.ToString()); * * System.Diagnostics.Debugger.Log(0, "pci", "PRT: dev: " + dev.ToString() + ", pin: " + pin.ToString() + ", source.Type: " + prtobj[2].Type.ToString() + ", sourceIndex: " + prtobj[3].IntegerData.ToString());*/ if (prtobj[2].Type == ACPIObject.DataType.ObjectReference) { ACPIObject.ObjRefData ord = prtobj[2].Data as ACPIObject.ObjRefData; System.Diagnostics.Debugger.Log(0, "pci", ord.Object.Name); var crs = acpi.n.Evaluate(ord.Object.Name + "._CRS", acpi.mi); List <File.Property> props = new List <File.Property>(); acpi.InterpretResources(crs, props); if (props.Count == 1) { prts[dev][pin] = props[0].Value as ACPIInterrupt; } } else if (prtobj[2].Type == ACPIObject.DataType.Integer && prtobj[2].IntegerData == 0) { int gsi = (int)prtobj[3].IntegerData; prts[dev][pin] = acpi.GeneratePCIIRQ(gsi); } } } return(prts); }