public static AcpiDevice[] LoadDevices() { OperationRegionAccessor operationRegionAccessor = new OperationRegionAccessor(); acpiNamespace = new AcpiNamespace(); reservedObjects = new ReservedObjects(acpiNamespace); reservedObjects.CreateReservedObjects(); if (dsdt != null) { if (ParseAndLoadRegion(dsdt.Region, operationRegionAccessor) == AmlParser.ParseSuccess.Failure) { throw new Exception("AML parser failure while parsing DSDT"); } } // From the spec: "SSDTs are a continuation of the DSDT. Multiple SSDTs // can be used as part of a platform description. After the DSDT is loaded // into the ACPI Namespace, each secondary description table listed in the // RSDT/XSDT with a unique OEM Table ID is loaded." - section 2.1, General // ACPI Terminology StringSet visitedOemTableIds = new StringSet(); for (int i = 0; i < rsdt.EntryCount; i++) { SystemTableHeader header = rsdt.GetTableHeader(i); VerboseOut.Print(" {0:x8}\n", __arglist(header.Signature)); string oemTableId = header.OemTableId; if (!visitedOemTableIds.Contains(oemTableId) && header.Signature == Ssdt.Signature) { visitedOemTableIds.Add(oemTableId); ssdt = Ssdt.Create(header); if (ParseAndLoadRegion(ssdt.Region, operationRegionAccessor) == AmlParser.ParseSuccess.Failure) { throw new Exception("AML parser failure while parsing SSDT " + oemTableId); } } } #if DUMP_ACPI_NAMESPACE DebugStub.WriteLine("Dumping ACPI namespace tree..."); acpiNamespace.DumpTree(); #endif return(GetDeviceInfo(operationRegionAccessor)); }
private static AcpiDevice[] GetDeviceInfo(AcpiObject.IOperationRegionAccessor operationRegionAccessor) { ArrayList deviceInfo = new ArrayList(); AmlInterpreter interpreter = new AmlInterpreter(acpiNamespace, operationRegionAccessor); foreach (AcpiNamespace.Node crsNode in acpiNamespace.GetAllNodes()) { if (crsNode.Name != "_CRS") { continue; } VerboseOut.Write("Loading resource descriptors for ACPI device "); foreach (string segment in crsNode.Path.RemoveSegment().NameSegments) { VerboseOut.Write(segment + "\\"); } VerboseOut.WriteLine(); AcpiNamespace.Node hidNode = acpiNamespace.LookupNode(crsNode.Path.RemoveSegmentAbsolute().AddSegmentAbsolute("_HID")); if (hidNode == null) { throw new Exception("Found device with _CRS property but no matching _HID property"); } AcpiObject.AcpiObject hidObject = hidNode.Value; if (hidObject is AcpiObject.BytecodeMethod) { AmlInterpreterThread thread = interpreter.InvokeMethodOnNewThread(null, hidNode.Path, new AcpiObject.AcpiObject[] { }); interpreter.Run(); hidObject = thread.ExitValue; } string deviceId = HidObjectToDeviceId(hidObject); AcpiObject.AcpiObject crsObject = crsNode.Value; if (crsObject is AcpiObject.BytecodeMethod) { AmlInterpreterThread thread = interpreter.InvokeMethodOnNewThread(null, crsNode.Path, new AcpiObject.AcpiObject[] { }); interpreter.Run(); crsObject = thread.ExitValue; } if (crsObject is AcpiObject.Buffer) { byte[] crsBuffer = crsObject.GetAsBuffer().Contents; ResourceDescriptor[] resourceDescriptors = ResourceDescriptorParser.Parse(crsBuffer); VerboseOut.WriteLine("Loaded resource descriptor for device " + deviceId); deviceInfo.Add(new AcpiDevice(deviceId, resourceDescriptors)); } else { VerboseOut.WriteLine("No resource descriptor for device " + deviceId); } } return((AcpiDevice[])deviceInfo.ToArray(typeof(AcpiDevice))); }
public static void Parse() { UIntPtr rsdpBase = GetRsdpBase(); if (rsdpBase == UIntPtr.Zero) { VerboseOut.Print("ACPI RSDP not found\n"); } #if DUMP_ACPI_TABLES_UUENCODED UuencodeDumpRegion("RSDP.dmp", IoMemory.MapPhysicalMemory( rsdpBase, 36u, true, false)); #endif Rsdp rsdp = Rsdp.Parse(rsdpBase, 36u); VerboseOut.Print("ACPI RSDP OemId is {0:x8}\n", __arglist(rsdp.OemId)); VerboseOut.Print("ACPI RSDP revision is {0:x8}\n", __arglist(rsdp.Revision)); if (rsdp.Revision == 2) { rsdtHeader = SystemTableHeader.Create(rsdp.XsdtAddress); #if DUMP_ACPI_TABLES_UUENCODED UuencodeDumpRegion("XSDT.dmp", IoMemory.MapPhysicalMemory( rsdtHeader.Address, rsdtHeader.FullTableLength, true, false)); #endif rsdt = Xsdt.Create(rsdtHeader); } else { rsdtHeader = SystemTableHeader.Create(rsdp.RsdtAddress); #if DUMP_ACPI_TABLES_UUENCODED UuencodeDumpRegion("RSDT.dmp", IoMemory.MapPhysicalMemory( rsdtHeader.Address, rsdtHeader.FullTableLength, true, false)); #endif rsdt = Rsdt.Create(rsdtHeader); } VerboseOut.Print("ACPI RSDT/XSDT OemTableId is {0}\n", __arglist(rsdtHeader.OemTableId)); VerboseOut.Print("ACPI RSDT/XSDT Revision is {0:x8}\n", __arglist(rsdtHeader.Revision)); VerboseOut.Print("ACPI RSDT/XSDT CreatorId is {0:x8}\n", __arglist(rsdtHeader.CreatorId)); VerboseOut.Print("ACPI RSDT/XSDT CreatorRevision is {0:x8}\n", __arglist(rsdtHeader.CreatorRevision)); VerboseOut.Print("RSDT contains:\n"); for (int i = 0; i < rsdt.EntryCount; i++) { SystemTableHeader header = rsdt.GetTableHeader(i); VerboseOut.Print(" {0:x8}\n", __arglist(header.Signature)); if (header.Signature == Fadt.Signature) { fadt = Fadt.Create(header); } else if (header.Signature == Madt.Signature) { madt = Madt.Create(header); } else if (header.Signature == Ssdt.Signature) { ssdt = Ssdt.Create(header); } // Srat, Slit else if (header.Signature == Srat.Signature) { srat = Srat.Create(header); srat.ParseSratStructure(); // srat.DumpSratOffsets(); // srat.DumpSratImportantFields(); // srat.DumpSratStructure(); } } SystemTableHeader dsdtHeader = null; if (fadt != null) { pmTimer = PMTimer.Create(fadt); VerboseOut.Print("PMTimer Value={0} Width={1}\n", __arglist(pmTimer.Value, pmTimer.Width)); uint t0 = pmTimer.Value; uint t1 = pmTimer.Value; uint t2 = pmTimer.Value; uint delta = (t2 >= t1) ? t2 - t1 : ((t1 | 0xff000000) - t2); VerboseOut.Print("Read cost {0} ticks\n", __arglist(delta)); if (fadt.DSDT != 0) { dsdtHeader = SystemTableHeader.Create(fadt.DSDT); dsdt = Dsdt.Create(dsdtHeader); } } VerboseOut.Print("Parsing and loading AML\n"); #if DUMP_ACPI_TABLES_UUENCODED if (dsdtHeader != null) { UuencodeDumpRegion("ACPI.DSDT.dmp", IoMemory.MapPhysicalMemory( dsdtHeader.Address, dsdtHeader.FullTableLength, true, false)); } for (int i = 0; i < rsdt.EntryCount; i++) { SystemTableHeader header = rsdt.GetTableHeader(i); UuencodeDumpRegion("ACPI." + header.Signature + "." + header.OemTableId + ".dmp", IoMemory.MapPhysicalMemory( header.Address, header.FullTableLength, true, false)); } #endif // DUMP_ACPI_TABLES_UUENCODED }