271 lines
8.7 KiB
C#
271 lines
8.7 KiB
C#
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Microsoft Research Singularity
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
// File: AcpiTables.cs
|
||
|
//
|
||
|
// Note:
|
||
|
// Based on ACPI 3.0 Spec.
|
||
|
|
||
|
namespace Microsoft.Singularity.Hal.Acpi
|
||
|
{
|
||
|
using System;
|
||
|
using Microsoft.Singularity.Io;
|
||
|
|
||
|
[ CLSCompliant(false) ]
|
||
|
internal class AcpiTables
|
||
|
{
|
||
|
private static Fadt fadt;
|
||
|
private static Madt madt;
|
||
|
|
||
|
private static Dsdt dsdt;
|
||
|
private static Ssdt ssdt;
|
||
|
|
||
|
private static Srat srat;
|
||
|
|
||
|
private static PMTimer pmTimer;
|
||
|
|
||
|
private static UIntPtr GetRsdpBase()
|
||
|
{
|
||
|
unsafe
|
||
|
{
|
||
|
return BootInfo.GetBootInfo().AcpiRoot32;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static Fadt GetFadt()
|
||
|
{
|
||
|
return fadt;
|
||
|
}
|
||
|
|
||
|
public static Madt GetMadt()
|
||
|
{
|
||
|
return madt;
|
||
|
}
|
||
|
|
||
|
public static Srat GetSrat()
|
||
|
{
|
||
|
return srat;
|
||
|
}
|
||
|
|
||
|
public static PMTimer GetPMTimer()
|
||
|
{
|
||
|
return pmTimer;
|
||
|
}
|
||
|
|
||
|
public static void Parse()
|
||
|
{
|
||
|
UIntPtr rsdpBase = GetRsdpBase();
|
||
|
|
||
|
if (rsdpBase == UIntPtr.Zero) {
|
||
|
DebugStub.Print("ACPI RSDP not found\n");
|
||
|
}
|
||
|
|
||
|
DebugStub.Print("ACPI RSDP address is {0:x8}\n",
|
||
|
__arglist(rsdpBase));
|
||
|
Rsdp rsdp = Rsdp.Parse(rsdpBase, 36u);
|
||
|
|
||
|
DebugStub.Print("ACPI RSDP OemId is {0:x8}\n",
|
||
|
__arglist(rsdp.OemId));
|
||
|
DebugStub.Print("ACPI RSDP revision is {0:x8}\n",
|
||
|
__arglist(rsdp.Revision));
|
||
|
DebugStub.Print("ACPI RSDT address is {0:x8}\n",
|
||
|
__arglist(rsdp.RsdtAddress));
|
||
|
|
||
|
SystemTableHeader rsdtHeader =
|
||
|
SystemTableHeader.Create(rsdp.RsdtAddress);
|
||
|
|
||
|
Rsdt rsdt = Rsdt.Create(rsdtHeader);
|
||
|
|
||
|
|
||
|
DebugStub.Print("RSDT contains:\n");
|
||
|
for (int i = 0; i < rsdt.EntryCount; i++) {
|
||
|
SystemTableHeader header = rsdt.GetTableHeader(i);
|
||
|
DebugStub.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);
|
||
|
}
|
||
|
// haryadi - Srat, Slit
|
||
|
else if (header.Signature == Srat.Signature)
|
||
|
{
|
||
|
srat = Srat.Create(header);
|
||
|
srat.ParseSratStructure();
|
||
|
|
||
|
// srat.DumpSratOffsets();
|
||
|
// srat.DumpSratImportantFields();
|
||
|
// srat.DumpSratStructure();
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (fadt != null) {
|
||
|
pmTimer = PMTimer.Create(fadt);
|
||
|
DebugStub.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);
|
||
|
DebugStub.Print("Read cost {0} ticks\n", __arglist(delta));
|
||
|
|
||
|
if (fadt.DSDT != 0)
|
||
|
{
|
||
|
dsdt = Dsdt.Create(
|
||
|
SystemTableHeader.Create(fadt.DSDT)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
if (dsdt != null) {
|
||
|
DumpRegion("DSDT", dsdt.Region);
|
||
|
}
|
||
|
if (ssdt != null) {
|
||
|
DumpRegion("SSDT", ssdt.Region);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static char Hex(int v)
|
||
|
{
|
||
|
if (v < 10) {
|
||
|
return (char)('0' + v);
|
||
|
}
|
||
|
else {
|
||
|
return (char)('A' + v - 10);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static void DumpRegion(string name, IoMemory region)
|
||
|
{
|
||
|
#if FALSE
|
||
|
// (new NamespaceWalker(region)).Display();
|
||
|
DebugStub.Print("-----------------------------------------------------------------------------\n");
|
||
|
DebugStub.Print("Table {0} dump\n", __arglist(name));
|
||
|
DebugStub.Print("-----------------------------------------------------------------------------\n");
|
||
|
|
||
|
const int step = 16;
|
||
|
|
||
|
byte last = region.Read8(0);
|
||
|
for (int i = 0; i < region.Length - 8; i ++) {
|
||
|
if (region.Read8(i + 0) == (byte)'_' &&
|
||
|
(region.Read8(i + 1) == (byte)'C' ||
|
||
|
region.Read8(i + 1) == (byte)'H') &&
|
||
|
region.Read8(i + 2) == (byte)'I' &&
|
||
|
region.Read8(i + 3) == (byte)'D') {
|
||
|
|
||
|
int o = 1;
|
||
|
byte d0 = region.Read8(i + 4 + o);
|
||
|
byte d1 = region.Read8(i + 5 + o);
|
||
|
byte d2 = region.Read8(i + 6 + o);
|
||
|
byte d3 = region.Read8(i + 7 + o);
|
||
|
char c0 = (char)(((d0 & 0x7f) >> 2) + 0x40);
|
||
|
char c1 = (char)((((d0 & 0x3) << 3) | (d1 >> 5)) + 0x40);
|
||
|
char c2 = (char)((d1 & 0x1f) + 0x40);
|
||
|
char c3 = Hex(d2 >> 4);
|
||
|
char c4 = Hex(d2 & 0xf);
|
||
|
char c5 = Hex(d3 >> 4);
|
||
|
char c6 = Hex(d3 & 0xf);
|
||
|
DebugStub.Print("{0:x8} -> _{8}ID {1}{2}{3}{4}{5}{6}{7}\n",
|
||
|
__arglist(i, c0, c1, c2,
|
||
|
c3, c4, c5, c6,
|
||
|
(char)region.Read8(i + 1)));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < region.Length; i += step) {
|
||
|
DebugStub.Print("{0:x8} : ", __arglist(i));
|
||
|
int n = step;
|
||
|
if (region.Length - i < n) {
|
||
|
n = region.Length - i;
|
||
|
}
|
||
|
for (int j = 0; j < n; j++) {
|
||
|
char c = (char)region.Read8(i + j);
|
||
|
DebugStub.Print("{0:x2} ", __arglist((int)c));
|
||
|
}
|
||
|
for (int j = 0; j < n; j++) {
|
||
|
char c = (char)region.Read8(i + j);
|
||
|
if (c < 32 || c > 127)
|
||
|
c = '.';
|
||
|
DebugStub.Print(c.ToString());
|
||
|
}
|
||
|
DebugStub.Print("\n");
|
||
|
}
|
||
|
DebugStub.Print("\n");
|
||
|
#endif // FALSE
|
||
|
}
|
||
|
|
||
|
internal class NamespaceWalker
|
||
|
{
|
||
|
int cursor = 0;
|
||
|
IoMemory memory;
|
||
|
|
||
|
internal NamespaceWalker(IoMemory m)
|
||
|
{
|
||
|
this.memory = m;
|
||
|
}
|
||
|
|
||
|
byte Read8()
|
||
|
{
|
||
|
return this.memory.Read8(cursor++);
|
||
|
}
|
||
|
|
||
|
ushort Read16()
|
||
|
{
|
||
|
ushort r = this.memory.Read16(cursor);
|
||
|
cursor += 2;
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
uint Read32()
|
||
|
{
|
||
|
uint r = this.memory.Read32(cursor++);
|
||
|
cursor += 4;
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
int GetPackageLength()
|
||
|
{
|
||
|
byte b = Read8();
|
||
|
int length = (int)b & 0x3f;
|
||
|
int following = ((int)b & 0xc) >> 6;
|
||
|
while (following-- > 0) {
|
||
|
length = length << 8;
|
||
|
length += (int)Read8();
|
||
|
}
|
||
|
return length;
|
||
|
}
|
||
|
|
||
|
void Reset()
|
||
|
{
|
||
|
cursor = 0;
|
||
|
}
|
||
|
|
||
|
internal void Display()
|
||
|
{
|
||
|
while (cursor < this.memory.Length) {
|
||
|
DisplayPackage(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DisplayPackage(int depth)
|
||
|
{
|
||
|
int length = GetPackageLength();
|
||
|
int oldCursor = this.cursor;
|
||
|
DebugStub.Print("Package Length {0} Name {1}{2}{3}{4}",
|
||
|
__arglist(length,
|
||
|
(char)Read8(),
|
||
|
(char)Read8(),
|
||
|
(char)Read8(),
|
||
|
(char)Read8()));
|
||
|
cursor = oldCursor + length;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|