mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 20:39:01 +00:00
342 lines
No EOL
11 KiB
C#
342 lines
No EOL
11 KiB
C#
|
|
using Cosmos.Kernel;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Cosmos.Hardware2
|
|
{
|
|
public static class ACPIManager
|
|
{
|
|
public static bool Enabled = false;
|
|
public static bool Found = false;
|
|
public static RSD Rsd;
|
|
public static uint[] ACPITable;
|
|
|
|
public static int Version
|
|
{
|
|
get
|
|
{
|
|
if (Found)
|
|
return Rsd.Revision;
|
|
else
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Explicit)] public struct RSD
|
|
{
|
|
[FieldOffset(0)] public int Signature0;
|
|
[FieldOffset(4)] public int Signature1;
|
|
|
|
[FieldOffset(8)] public byte Checksum;
|
|
|
|
[FieldOffset(9)] private byte OemID0;
|
|
[FieldOffset(10)] private byte OemID1;
|
|
[FieldOffset(11)] private byte OemID2;
|
|
[FieldOffset(12)] private byte OemID3;
|
|
[FieldOffset(13)] private byte OemID4;
|
|
[FieldOffset(14)] private byte OemID5;
|
|
|
|
[FieldOffset(15)] public byte Revision;
|
|
[FieldOffset(16)] public uint RsdtAddress;
|
|
|
|
public string Signature
|
|
{
|
|
get
|
|
{
|
|
return ""; // Signature0.ToHex(8) + Signature1.ToHex(8);
|
|
}
|
|
}
|
|
public string OemID
|
|
{
|
|
get
|
|
{
|
|
return "" + (char)OemID0 + (char)OemID1 + (char)OemID2 + (char)OemID3 + (char)OemID4 + (char)OemID5;
|
|
}
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Explicit)] public struct acpi_gen_regaddr
|
|
{
|
|
[FieldOffset(0)] public byte space_id;
|
|
[FieldOffset(1)] public byte bit_width;
|
|
[FieldOffset(2)] public byte bit_offset;
|
|
[FieldOffset(3)] public byte resv;
|
|
[FieldOffset(4)] public uint addrl;
|
|
[FieldOffset(8)] public uint addrh;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Explicit)] public struct acpi_table_header
|
|
{
|
|
[FieldOffset(0)] public byte signature0;
|
|
[FieldOffset(1)] public byte signature1;
|
|
[FieldOffset(2)] public byte signature2;
|
|
[FieldOffset(3)] public byte signature3;
|
|
|
|
[FieldOffset(4)] public uint length;
|
|
[FieldOffset(8)] public byte revision;
|
|
[FieldOffset(9)] public byte checksum;
|
|
|
|
[FieldOffset(10)] byte oem_id0;
|
|
[FieldOffset(11)] byte oem_id1;
|
|
[FieldOffset(12)] byte oem_id2;
|
|
[FieldOffset(13)] byte oem_id3;
|
|
[FieldOffset(14)] byte oem_id4;
|
|
[FieldOffset(15)] byte oem_id5;
|
|
|
|
[FieldOffset(16)] byte oem_table_id0;
|
|
[FieldOffset(17)] byte oem_table_id1;
|
|
[FieldOffset(18)] byte oem_table_id2;
|
|
[FieldOffset(19)] byte oem_table_id3;
|
|
[FieldOffset(20)] byte oem_table_id4;
|
|
[FieldOffset(21)] byte oem_table_id5;
|
|
[FieldOffset(22)] byte oem_table_id6;
|
|
[FieldOffset(23)] byte oem_table_id7;
|
|
|
|
[FieldOffset(24)] public uint oem_revision;
|
|
[FieldOffset(28)] public uint asl_compiler_id;
|
|
[FieldOffset(32)] public uint asl_compiler_revision;
|
|
|
|
|
|
public string Signature
|
|
{
|
|
get
|
|
{
|
|
return "" + (char)signature0 + (char)signature1 + (char)signature2 + (char)signature3;
|
|
}
|
|
}
|
|
public string OemID
|
|
{
|
|
get
|
|
{
|
|
return "" + (char)oem_id0 + (char)oem_id1 + (char)oem_id2 + (char)oem_id3 + (char)oem_id4 + (char)oem_id5;
|
|
}
|
|
}
|
|
public string OemTable
|
|
{
|
|
get
|
|
{
|
|
return "" + (char)oem_table_id0 + (char)oem_table_id1 + (char)oem_table_id2 + (char)oem_table_id3 + (char)oem_table_id4 + (char)oem_table_id5 + (char)oem_table_id6 + (char)oem_table_id7;
|
|
}
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct Fadt
|
|
{
|
|
public acpi_table_header header;
|
|
|
|
public uint firmware_ctrl;
|
|
public uint dsdt;
|
|
public byte model;
|
|
public byte preferred_pm_profile;
|
|
public ushort sci_int;
|
|
public uint smi_cmd;
|
|
public byte acpi_enable;
|
|
public byte acpi_disable;
|
|
public byte s4bios_req;
|
|
public byte pstate_cnt;
|
|
public uint pm1a_evt_blk;
|
|
public uint pm1b_evt_blk;
|
|
public uint pm1a_cnt_blk;
|
|
public uint pm1b_cnt_blk;
|
|
public uint pm2_cnt_blk;
|
|
public uint pm_tmr_blk;
|
|
public uint gpe0_blk;
|
|
public uint gpe1_blk;
|
|
public byte pm1_evt_len;
|
|
public byte pm1_cnt_len;
|
|
public byte pm2_cnt_len;
|
|
public byte pm_tmr_len;
|
|
public byte gpe0_blk_len;
|
|
public byte gpe1_blk_len;
|
|
public byte gpe1_base;
|
|
public byte cst_cnt;
|
|
public ushort p_lvl2_lat;
|
|
public ushort p_lvl3_lat;
|
|
public ushort flush_size;
|
|
public ushort flush_stride;
|
|
public byte duty_offset;
|
|
public byte duty_width;
|
|
public byte day_alrm;
|
|
public byte mon_alrm;
|
|
public byte century;
|
|
public ushort iapc_boot_arch;
|
|
public byte res2;
|
|
public uint flags;
|
|
public acpi_gen_regaddr reset_reg;
|
|
public byte reset_value;
|
|
public byte res3;
|
|
public byte res4;
|
|
public byte res5;
|
|
public uint x_firmware_ctl_l;
|
|
public uint x_firmware_ctl_h;
|
|
public uint x_dsdt_l;
|
|
public uint x_dsdt_h;
|
|
public acpi_gen_regaddr x_pm1a_evt_blk;
|
|
public acpi_gen_regaddr x_pm1b_evt_blk;
|
|
public acpi_gen_regaddr x_pm1a_cnt_blk;
|
|
public acpi_gen_regaddr x_pm1b_cnt_blk;
|
|
public acpi_gen_regaddr x_pm2_cnt_blk;
|
|
public acpi_gen_regaddr x_pm_tmr_blk;
|
|
public acpi_gen_regaddr x_gpe0_blk;
|
|
public acpi_gen_regaddr x_gpe1_blk;
|
|
}
|
|
|
|
public unsafe static void Init()
|
|
{
|
|
Console.Write("Looking for ACPI...");
|
|
|
|
uint rsdp = RSDPAddress();
|
|
|
|
if (rsdp != 0)
|
|
{
|
|
Rsd = *((RSD*)rsdp);
|
|
|
|
|
|
Found = true;
|
|
|
|
//Console.WriteLine("Found Version " + Rsd.Revision + " (" + Rsd.OemID + ") @ " + rsdp.ToHex(8));
|
|
|
|
acpi_table_header* Rsdt = (acpi_table_header*)Rsd.RsdtAddress;
|
|
uint i = Rsdt->length;
|
|
i = (i - 36) / 4;
|
|
|
|
Console.WriteLine(i + " entrys found");
|
|
|
|
ACPITable = new uint[i];
|
|
|
|
uint rsdt = Rsd.RsdtAddress;
|
|
for (int j = 0; j < i; j++)
|
|
{
|
|
ACPITable[j] = *(uint*)(rsdt + 36 +j*4);
|
|
acpi_table_header* header = (acpi_table_header*)ACPITable[j];
|
|
|
|
|
|
}
|
|
Console.Read();
|
|
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Not Found");
|
|
}
|
|
|
|
}
|
|
|
|
public static unsafe uint RSDPAddress()
|
|
{
|
|
Console.Write("searching for acpi...searching BIOS...");
|
|
// check bios
|
|
for (uint addr = 0xE0000; addr < 0x100000; addr += 4)
|
|
if (CheckForRSDP(addr))
|
|
return addr;
|
|
|
|
Console.Write("searching EBD...");
|
|
|
|
// check extended bios
|
|
uint ebda_address = *((uint*)0x040E);
|
|
|
|
ebda_address = (ebda_address * 0x10) & 0x000fffff;
|
|
|
|
for (uint addr = ebda_address; addr < ebda_address + 1024; addr += 4)
|
|
if (CheckForRSDP(addr))
|
|
return addr;
|
|
|
|
// not found
|
|
return 0;
|
|
}
|
|
|
|
public static unsafe bool CheckForRSDP(uint addr)
|
|
{
|
|
// check signature
|
|
byte* ch = (byte*)addr;
|
|
|
|
if (*(ch++) != (byte)'R') return false;
|
|
if (*(ch++) != (byte)'S') return false;
|
|
if (*(ch++) != (byte)'D') return false;
|
|
if (*(ch++) != (byte)' ') return false;
|
|
if (*(ch++) != (byte)'P') return false;
|
|
if (*(ch++) != (byte)'T') return false;
|
|
if (*(ch++) != (byte)'R') return false;
|
|
if (*(ch++) != (byte)' ') return false;
|
|
|
|
// check checksum
|
|
byte sum = 0;
|
|
byte* check = (byte*)addr;
|
|
|
|
for (int i = 0; i < 20; i++)
|
|
sum += *(check++);
|
|
|
|
return (sum == 0);
|
|
}
|
|
|
|
// checks for a given header and validates checksum
|
|
public static unsafe bool acpiCheckHeader(int ptr, string sig)
|
|
{
|
|
byte* b = (byte*)ptr;
|
|
|
|
for (int i = 0; i < sig.Length; i++)
|
|
if (*(b++) != (byte)sig[i])
|
|
return false;
|
|
|
|
byte* checkPtr = (byte*)ptr;
|
|
int len = *(&ptr + 1);
|
|
byte check = 0;
|
|
|
|
while (0 < len--)
|
|
check += *(checkPtr++);
|
|
|
|
return (check == 0);
|
|
}
|
|
|
|
|
|
|
|
public static unsafe bool acpiEnable()
|
|
{
|
|
/*
|
|
// check if acpi is enabled
|
|
if ( (CPUBus.Read16((unsigned int) PM1a_CNT) & SCI_EN) == 0 )
|
|
{
|
|
// check if acpi can be enabled
|
|
if (SMI_CMD != 0 && ACPI_ENABLE != 0)
|
|
{
|
|
outb((unsigned int) SMI_CMD, ACPI_ENABLE); // send acpi enable command
|
|
// give 3 seconds time to enable acpi
|
|
int i;
|
|
for (i=0; i<300; i++ )
|
|
{
|
|
if ( (inw((unsigned int) PM1a_CNT) &SCI_EN) == 1 )
|
|
break;
|
|
sleep(10);
|
|
}
|
|
if (PM1b_CNT != 0)
|
|
for (; i<300; i++ )
|
|
{
|
|
if ( (inw((unsigned int) PM1b_CNT) &SCI_EN) == 1 )
|
|
break;
|
|
sleep(10);
|
|
}
|
|
if (i<300) {
|
|
wrstr("enabled acpi.\n");
|
|
return 0;
|
|
} else {
|
|
wrstr("couldn't enable acpi.\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
wrstr("no known way to enable acpi.\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
//wrstr("acpi was already enabled.\n");
|
|
return 0;
|
|
}*/
|
|
return false;
|
|
}
|
|
|
|
}
|
|
} |