Done the ACPI API

This commit is contained in:
Elia Sulimanov 2020-08-19 16:56:32 +03:00
parent 9505769370
commit b9a652e6c4

View file

@ -5,65 +5,175 @@ using System.Runtime.InteropServices;
namespace Cosmos.Core
{
/// <summary>
/// ACPI (Advanced Configuration and Power Interface) class.
/// </summary>
public unsafe class ACPI
{
/// <summary>
/// Debugger instance at the System ring, of the Global section.
/// </summary>
public static readonly Debugger mDebugger = new Debugger("System", "Global");
//RSD Table
/// <summary>
/// RSD table struct.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct RSDPtr
{
/// <summary>
/// Signature.
/// </summary>
public fixed byte Signature[8];
/// <summary>
/// CheckSum
/// </summary>
public byte CheckSum;
/// <summary>
/// OemID
/// </summary>
public fixed byte OemID[6];
/// <summary>
/// Revision
/// </summary>
public byte Revision;
/// <summary>
/// RSDT Address
/// </summary>
public int RsdtAddress;
};
// New Port I/O
/// <summary>
/// IO port.
/// </summary>
private static IOPort smiIO, pm1aIO, pm1bIO;
// ACPI variables
/// <summary>
/// SMI CMD.
/// </summary>
private static int* SMI_CMD;
/// <summary>
/// ACPI ENABLE.
/// </summary>
private static byte ACPI_ENABLE;
/// <summary>
/// ACPI DISABLE.
/// </summary>
private static byte ACPI_DISABLE;
/// <summary>
/// PM1a CNT
/// </summary>
private static int* PM1a_CNT;
/// <summary>
/// PM1b CNT
/// </summary>
private static int* PM1b_CNT;
/// <summary>
/// SLP TYPa
/// </summary>
private static short SLP_TYPa;
/// <summary>
/// SLP TYPb
/// </summary>
private static short SLP_TYPb;
/// <summary>
/// SLP EN.
/// </summary>
private static short SLP_EN;
/// <summary>
/// SCI EN.
/// </summary>
private static short SCI_EN;
/// <summary>
/// PM1 CNT LEN1
/// </summary>
private static byte PM1_CNT_LEN;
//ACPI Check Header
/// <summary>
/// Check ACPI header.
/// </summary>
/// <param name="ptr"></param>
/// <param name="sig"></param>
/// <returns></returns>
static int acpiCheckHeader(byte* ptr, string sig)
{
return Compare(sig, ptr);
}
// FACP
/// <summary>
/// FACP.
/// </summary>
private static byte* Facp = null;
/// <summary>
/// FACP struct.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct FACP
{
/// <summary>
/// Signature.
/// </summary>
public fixed byte Signature[4];
/// <summary>
/// Length.
/// </summary>
public int Length;
/// <summary>
/// Unused.
/// </summary>
public fixed byte unneded1[40 - 8];
/// <summary>
/// DSDT.
/// </summary>
public int* DSDT;
/// <summary>
/// Unused.
/// </summary>
public fixed byte unneded2[48 - 44];
/// <summary>
/// SMI CMD.
/// </summary>
public int* SMI_CMD;
/// <summary>
/// ACPI ENABLE.
/// </summary>
public byte ACPI_ENABLE;
/// <summary>
/// ACPI DISABLE.
/// </summary>
public byte ACPI_DISABLE;
/// <summary>
/// Unused.
/// </summary>
public fixed byte unneded3[64 - 54];
/// <summary>
/// PM1a CNT BLK.
/// </summary>
public int* PM1a_CNT_BLK;
/// <summary>
/// PM1b CNT BLK.
/// </summary>
public int* PM1b_CNT_BLK;
/// <summary>
/// Unused.
/// </summary>
public fixed byte unneded4[89 - 72];
/// <summary>
/// PM1 CNT LEN.
/// </summary>
public byte PM1_CNT_LEN;
};
//Compare
/// <summary>
/// Compare string to byte array.
/// </summary>
/// <param name="c1">String.</param>
/// <param name="c2">Pointer to the head of the byte array.</param>
/// <returns>0 - identical, -1 different.</returns>
static int Compare(string c1, byte* c2)
{
for (int i = 0; i < c1.Length; i++)
@ -73,7 +183,11 @@ namespace Cosmos.Core
return 0;
}
//Check RSD
/// <summary>
/// Check RSD checksum.
/// </summary>
/// <param name="address">Address to check.</param>
/// <returns>True if RSDT table checksum is good.</returns>
static bool Check_RSD(uint address)
{
byte sum = 0;
@ -85,7 +199,11 @@ namespace Cosmos.Core
return (sum == 0);
}
//Acpi Initialization :P
/// <summary>
/// Start the ACPI.
/// </summary>
/// <param name="initialize">Initialize the ACPI. (default = true)</param>
/// <param name="enable">Enable the ACPI. (default = true)</param>
public static void Start(bool initialize = true, bool enable = true)
{
if (initialize)
@ -95,7 +213,6 @@ namespace Cosmos.Core
Enable();
}
// Shutdown
/// <summary>
/// Shutdown the ACPI.
/// </summary>
@ -114,7 +231,6 @@ namespace Cosmos.Core
Global.CPU.Halt();
}
// Reboot
/// <summary>
/// Reboot ACPI.
/// Not implemented.
@ -125,7 +241,10 @@ namespace Cosmos.Core
throw new NotImplementedException("ACPI Reset not implemented yet."); //TODO
}
// Initializazion
/// <summary>
/// Initialize the ACPI.
/// </summary>
/// <returns>true on success, false on failure.</returns>
private static bool Init()
{
byte* ptr = (byte*)RSDPAddress();
@ -217,19 +336,26 @@ namespace Cosmos.Core
return false;
}
// Enable ACPI
/// <summary>
/// Enable ACPI.
/// </summary>
public static void Enable()
{
smiIO = new IOPort(ACPI_ENABLE);
}
// Disable ACPI
/// <summary>
/// Disable ACPI.
/// </summary>
public static void Disable()
{
smiIO = new IOPort(ACPI_DISABLE);
}
// Retrieve the RSDP address
/// <summary>
/// Get the RSDP address.
/// </summary>
/// <returns>uint value.</returns>
private static unsafe uint RSDPAddress()
{
for (uint addr = 0xE0000; addr < 0x100000; addr += 4)
@ -247,7 +373,11 @@ namespace Cosmos.Core
return 0;
}
// RSDT Table
/// <summary>
/// Check RSDT table
/// </summary>
/// <param name="ptr">A pointer to the RSDT</param>
/// <returns>RSDT table address</returns>
private static uint* acpiCheckRSDPtr(uint* ptr)
{
string sig = "RSD PTR ";
@ -279,7 +409,18 @@ namespace Cosmos.Core
return null;
}
// FACP Table
/// <summary>
/// Get data from the FACP table.
/// </summary>
/// <param name="number">Index number of the data to get.
/// <list type="bullet">
/// <item>0 - ACPI ENABLE</item>
/// <item>1 - ACPI DISABLE</item>
/// <item>2 - PM1 CNT LEN</item>
/// <item>other - 0</item>
/// </list>
/// </param>
/// <returns>byte value.</returns>
private static byte facpbget(int number)
{
switch (number)
@ -295,6 +436,19 @@ namespace Cosmos.Core
}
}
/// <summary>
/// Get pointer to the data on the FACP.
/// </summary>
/// <param name="number">Index number of the data to get.
/// <list type="bullet">
/// <item>0 - DSDT</item>
/// <item>1 - SMI CMD</item>
/// <item>2 - PM1a</item>
/// <item>3 - PM1b</item>
/// <item>other - null</item>
/// </list>
/// </param>
/// <returns>int pointer.</returns>
private static int* facpget(int number)
{
switch (number)