From a9eb8c314b14b01483006c3580ecd00442c9dc43 Mon Sep 17 00:00:00 2001 From: Valentin Charbonnier Date: Mon, 19 Jun 2017 22:56:34 +0200 Subject: [PATCH 1/7] Shutdown Reboot with ACPI added --- source/Cosmos.HAL/ACPI.cs | 363 ++++++++++++++++++++++++++++ source/Cosmos.HAL/Cosmos.HAL.csproj | 4 + source/Cosmos.HAL/Power.cs | 12 +- source/Cosmos.System/Power.cs | 10 +- 4 files changed, 386 insertions(+), 3 deletions(-) create mode 100644 source/Cosmos.HAL/ACPI.cs diff --git a/source/Cosmos.HAL/ACPI.cs b/source/Cosmos.HAL/ACPI.cs new file mode 100644 index 000000000..30a22b2cd --- /dev/null +++ b/source/Cosmos.HAL/ACPI.cs @@ -0,0 +1,363 @@ +using Cosmos.Core.Common; +using System; +using System.Runtime.InteropServices; + +namespace Cosmos.HAL +{ + public unsafe class ACPI + { + private static int* SMI_CMD; + private static byte ACPI_ENABLE; + private static byte ACPI_DISABLE; + private static int* PM1a_CNT; + private static int* PM1b_CNT; + private static short SLP_TYPa; + private static short SLP_TYPb; + private static short SLP_EN; + private static short SCI_EN; + private static byte PM1_CNT_LEN; + + + static int Compare(string c1, byte* c2) + { + + for (int i = 0; i < c1.Length; i++) + { + if (c1[i] != (char)c2[i]) { return -1; } + } + return 0; + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct RSDPtr + { + public fixed byte Signature[8]; + public byte CheckSum; + public fixed byte OemID[6]; + public byte Revision; + public int RsdtAddress; + }; + + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct FACP + { + public fixed byte Signature[4]; + public int Length; + + public fixed byte unneded1[40 - 8]; + public int* DSDT; + public fixed byte unneded2[48 - 44]; + public int* SMI_CMD; + public byte ACPI_ENABLE; + public byte ACPI_DISABLE; + public fixed byte unneded3[64 - 54]; + public int* PM1a_CNT_BLK; + public int* PM1b_CNT_BLK; + public fixed byte unneded4[89 - 72]; + public byte PM1_CNT_LEN; + }; + static byte* Facp = null; + static int* facpget(int number) + { + + if (number == 0) { return (int*)*((int*)(Facp + 40)); } + else if (number == 1) { return (int*)*((int*)(Facp + 48)); } + else if (number == 2) { return (int*)*((int*)(Facp + 64)); } + else if (number == 3) { return (int*)*((int*)(Facp + 68)); } + else { return null; } + + } + static byte facpbget(int number) + { + if (number == 0) { return *(Facp + 52); } + else if (number == 1) { return *(Facp + 53); } + else if (number == 2) { return *(Facp + 89); } + else return 0; + } + // check if the given address has a valid header + static uint* acpiCheckRSDPtr(uint* ptr) + { + string sig = "RSD PTR "; + RSDPtr* rsdp = (RSDPtr*)ptr; + byte* bptr; + byte check = 0; + int i; + + if (Compare(sig, (byte*)rsdp) == 0) + { + // check checksum rsdpd + bptr = (byte*)ptr; + for (i = 0; i < 20; i++) + { + check += *bptr; + bptr++; + } + //Console.WriteLine("0x" + check.ToHex()); + // found valid rsdpd + if (check == 0) + { + //string str = rsdp->RsdtAddress.ToHex(); + //Console.WriteLine("seen"); Console.WriteLine(str); + Compare("RSDT", (byte*)rsdp->RsdtAddress); + if (rsdp->RsdtAddress != 0) + return (uint*)rsdp->RsdtAddress; + } + } + Console.WriteLine("Unable to find RSDT. ACPI not available"); + return null; + } + + static uint RSDPAddress() + { + + // check bios + for (uint addr = 0xE0000; addr < 0x100000; addr += 4) + if (Compare("RSD PTR ", (byte*)addr) == 0) + if (Check_RSD(addr)) + return addr; + // 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 (Compare("RSD PTR ", (byte*)addr) == 0) + return addr; + + // not found + return 0; + } + // checks for a given header and validates checksum + static int acpiCheckHeader(byte* ptr, string sig) + { + return Compare(sig, ptr); + } + + static bool Check_RSD(uint address) + { + byte sum = 0; + byte* check = (byte*)address; + + for (int i = 0; i < 20; i++) + sum += *(check++); + + return (sum == 0); + } + private static Core.Common.IOPort smiIO, pm1aIO, pm1bIO; + public static int Enable() + { + // check if acpi is enabled + + if (pm1aIO.Word == 0) + { + // check if acpi can be enabled + if (SMI_CMD != null && ACPI_ENABLE != 0) + { + smiIO.Byte = ACPI_ENABLE; + //CPUBus.Write8((byte)SMI_CMD, ACPI_ENABLE); // send acpi enable command + // give 3 seconds time to enable acpi + int i; + for (i = 0; i < 300; i++) + { + if ((pm1aIO.Word & 1) == 1) + //if ((CPUBus.Read16((ushort)PM1a_CNT) & SCI_EN) == 1) + break; + + } + if (PM1b_CNT != null) + for (; i < 300; i++) + { + //if ((CPUBus.Read16((ushort)PM1b_CNT) & SCI_EN) == 1) + if ((pm1bIO.Word & 1) == 1) + break; + } + if (i < 300) + { + + return 0; + } + else + { + Console.WriteLine("Couldn't enable ACPI."); + return -1; + } + } + else + { + Console.WriteLine("No known way to enable ACPI."); + return -1; + } + } + else + { + + return 0; + } + } + public static void Disable() + { + smiIO.Byte = ACPI_DISABLE; + } + public static int Init() + { + byte* ptr = (byte*)RSDPAddress(); int addr = 0; + + for (int i = 19; i >= 16; i--) + { + addr += (*((byte*)ptr + i)); + addr = (i == 16) ? addr : addr << 8; + } + + ptr = (byte*)addr; + ptr += 4; addr = 0; + for (int i = 3; i >= 0; i--) + { + addr += (*((byte*)ptr + i)); + addr = (i == 0) ? addr : addr << 8; + } + int length = addr; + + ptr -= 4; + // check if address is correct ( if acpi is available on this pc ) + if (ptr != null && acpiCheckHeader((byte*)ptr, "RSDT") == 0) + { + addr = 0; + // the RSDT contains an unknown number of pointers to acpi tables + + int entrys = length; + entrys = (entrys - 36) / 4; + ptr += 36; // skip header information + byte* yeuse; + + while (0 < entrys--) + { + for (int i = 3; i >= 0; i--) + { + addr += (*((byte*)ptr + i)); + addr = (i == 0) ? addr : addr << 8; + } + yeuse = (byte*)addr; + // check if the desired table is reached + Facp = (byte*)yeuse; + if (Compare("FACP", Facp) == 0) + { + if (acpiCheckHeader((byte*)facpget(0), "DSDT") == 0) + { + // search the \_S5 package in the DSDT + byte* S5Addr = (byte*)facpget(0) + 36; // skip header + int dsdtLength = *(facpget(0) + 1) - 36; + while (0 < dsdtLength--) + { + if (Compare("_S5_", (byte*)S5Addr) == 0) + break; + S5Addr++; + } + // check if \_S5 was found + if (dsdtLength > 0) + { + // check for valid AML structure + if ((*(S5Addr - 1) == 0x08 || (*(S5Addr - 2) == 0x08 && *(S5Addr - 1) == '\\')) && *(S5Addr + 4) == 0x12) + { + S5Addr += 5; + S5Addr += ((*S5Addr & 0xC0) >> 6) + 2; // calculate PkgLength size + + if (*S5Addr == 0x0A) + S5Addr++; // skip byteprefix + SLP_TYPa = (short)(*(S5Addr) << 10); + S5Addr++; + + if (*S5Addr == 0x0A) + S5Addr++; // skip byteprefix + SLP_TYPb = (short)(*(S5Addr) << 10); + + SMI_CMD = facpget(1); + + ACPI_ENABLE = facpbget(0); + ACPI_DISABLE = facpbget(1); + + PM1a_CNT = facpget(2); + PM1b_CNT = facpget(3); + + PM1_CNT_LEN = facpbget(3); + + SLP_EN = 1 << 13; + SCI_EN = 1; + smiIO = new IOPort((ushort)SMI_CMD); + pm1aIO = new IOPort((ushort)PM1a_CNT); + pm1bIO = new IOPort((ushort)PM1b_CNT); + return 0; + } + else + { + Console.WriteLine("\\_S5 parse error.\n"); + } + } + else + { + Console.WriteLine("\\_S5 not present.\n"); + } + } + else + { + Console.WriteLine("DSDT invalid.\n"); + } + } + ptr += 4; + } + Console.WriteLine("No valid FACP present.\n"); + } + else + { + Console.WriteLine("No ACPI.\n"); + } + + return -1; + + } + + public static void Reboot() + { + Core.Common.CPU.DisableInterrupts(); + byte good = 0x02; + while ((good & 0x02) != 0) + good = Inb(0x64); + Outb(0x64, 0xFE); + + Cosmos.Core.Global.CPU.Halt(); + } + + static Core.Common.IOPort io = new Core.Common.IOPort(0); + static int PP = 0, D = 0; + public static void Outb(ushort port, byte data) + { + if (io.Port != port) + io = new Core.Common.IOPort(port); + io.Byte = data; + PP = port; + D = data; + + } + public static byte Inb(ushort port) + { + if (io.Port != port) + io = new Core.Common.IOPort(port); + return io.Byte; + + } + + public static void Shutdown() + { + // send the shutdown command + Console.Clear(); + if (PM1a_CNT == null) Init(); + if (pm1aIO != null) + { + pm1aIO.Word = (ushort)(SLP_TYPa | SLP_EN); + if (PM1b_CNT != null) + pm1bIO.Word = (ushort)(SLP_TYPb | SLP_EN); + + } + // Console.WriteLine("It is now safe to turn off your computer"); + } + } +} \ No newline at end of file diff --git a/source/Cosmos.HAL/Cosmos.HAL.csproj b/source/Cosmos.HAL/Cosmos.HAL.csproj index 597a340f6..d75257cfb 100644 --- a/source/Cosmos.HAL/Cosmos.HAL.csproj +++ b/source/Cosmos.HAL/Cosmos.HAL.csproj @@ -8,6 +8,10 @@ Cosmos + + True + + diff --git a/source/Cosmos.HAL/Power.cs b/source/Cosmos.HAL/Power.cs index 8ce01b697..75ecfa681 100644 --- a/source/Cosmos.HAL/Power.cs +++ b/source/Cosmos.HAL/Power.cs @@ -9,9 +9,17 @@ namespace Cosmos.HAL { public class Power { - public static void Reboot() + public static void CPUReboot() { Core.Global.CPU.Reboot(); } + public static void Reboot() + { + ACPI.Reboot(); + } + public static void Shutdown() + { + ACPI.Shutdown(); + } } -} +} \ No newline at end of file diff --git a/source/Cosmos.System/Power.cs b/source/Cosmos.System/Power.cs index ff989d8cd..334bb6cb4 100644 --- a/source/Cosmos.System/Power.cs +++ b/source/Cosmos.System/Power.cs @@ -8,9 +8,17 @@ namespace Cosmos.System { public class Power { + public static void CPUReboot() + { + HAL.Power.CPUReboot(); + } public static void Reboot() { HAL.Power.Reboot(); } + public static void Shutdown() + { + HAL.Power.Shutdown(); + } } -} +} \ No newline at end of file From 78f276aded2dfc07cce42f866b5dcbcbeac1348f Mon Sep 17 00:00:00 2001 From: Valentin Charbonnier Date: Wed, 21 Jun 2017 13:38:40 +0200 Subject: [PATCH 2/7] ACPI.cs moved to Cosmos.Core (From Cosmos.HAL) --- source/{Cosmos.HAL => Cosmos.Core}/ACPI.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename source/{Cosmos.HAL => Cosmos.Core}/ACPI.cs (99%) diff --git a/source/Cosmos.HAL/ACPI.cs b/source/Cosmos.Core/ACPI.cs similarity index 99% rename from source/Cosmos.HAL/ACPI.cs rename to source/Cosmos.Core/ACPI.cs index 30a22b2cd..ab63947bf 100644 --- a/source/Cosmos.HAL/ACPI.cs +++ b/source/Cosmos.Core/ACPI.cs @@ -2,7 +2,7 @@ using System; using System.Runtime.InteropServices; -namespace Cosmos.HAL +namespace Cosmos.Core { public unsafe class ACPI { From b9aba9a17be1e3e4f9d7c36be8b5a797f298ccc4 Mon Sep 17 00:00:00 2001 From: Valentin Charbonnier Date: Wed, 21 Jun 2017 13:40:37 +0200 Subject: [PATCH 3/7] Minor change Set "AllowUnsafeBlocks" to false. --- source/Cosmos.HAL/Cosmos.HAL.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.HAL/Cosmos.HAL.csproj b/source/Cosmos.HAL/Cosmos.HAL.csproj index d75257cfb..8409116a4 100644 --- a/source/Cosmos.HAL/Cosmos.HAL.csproj +++ b/source/Cosmos.HAL/Cosmos.HAL.csproj @@ -9,7 +9,7 @@ - True + False From 1a9e83b632b28821ae07844b3b0463300793d285 Mon Sep 17 00:00:00 2001 From: Valentin Charbonnier Date: Wed, 21 Jun 2017 19:26:08 +0200 Subject: [PATCH 4/7] Some modifications... ACPI class clarified. Start ACPI added when starting a Cosmos Kernel project. (it does not work with remote debugging, the project crash in the VM) --- source/Cosmos.Core/ACPI.cs | 431 ++++++++++++++++-------------------- source/Cosmos.HAL/Global.cs | 9 +- source/Cosmos.HAL/Power.cs | 5 + 3 files changed, 210 insertions(+), 235 deletions(-) diff --git a/source/Cosmos.Core/ACPI.cs b/source/Cosmos.Core/ACPI.cs index ab63947bf..261a6be95 100644 --- a/source/Cosmos.Core/ACPI.cs +++ b/source/Cosmos.Core/ACPI.cs @@ -6,6 +6,22 @@ namespace Cosmos.Core { public unsafe class ACPI { + + //RSD Table + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public unsafe struct RSDPtr + { + public fixed byte Signature[8]; + public byte CheckSum; + public fixed byte OemID[6]; + public byte Revision; + public int RsdtAddress; + }; + + // New Port I/O + private static IOPort smiIO, pm1aIO, pm1bIO; + + // ACPI variables private static int* SMI_CMD; private static byte ACPI_ENABLE; private static byte ACPI_DISABLE; @@ -17,122 +33,26 @@ namespace Cosmos.Core private static short SCI_EN; private static byte PM1_CNT_LEN; + //ACPI Check Header + static int acpiCheckHeader(byte* ptr, string sig) + { + return Compare(sig, ptr); + } + // FACP + private static byte* Facp = null; + + //Compare static int Compare(string c1, byte* c2) { - for (int i = 0; i < c1.Length; i++) { if (c1[i] != (char)c2[i]) { return -1; } } return 0; } - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct RSDPtr - { - public fixed byte Signature[8]; - public byte CheckSum; - public fixed byte OemID[6]; - public byte Revision; - public int RsdtAddress; - }; - - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct FACP - { - public fixed byte Signature[4]; - public int Length; - - public fixed byte unneded1[40 - 8]; - public int* DSDT; - public fixed byte unneded2[48 - 44]; - public int* SMI_CMD; - public byte ACPI_ENABLE; - public byte ACPI_DISABLE; - public fixed byte unneded3[64 - 54]; - public int* PM1a_CNT_BLK; - public int* PM1b_CNT_BLK; - public fixed byte unneded4[89 - 72]; - public byte PM1_CNT_LEN; - }; - static byte* Facp = null; - static int* facpget(int number) - { - - if (number == 0) { return (int*)*((int*)(Facp + 40)); } - else if (number == 1) { return (int*)*((int*)(Facp + 48)); } - else if (number == 2) { return (int*)*((int*)(Facp + 64)); } - else if (number == 3) { return (int*)*((int*)(Facp + 68)); } - else { return null; } - - } - static byte facpbget(int number) - { - if (number == 0) { return *(Facp + 52); } - else if (number == 1) { return *(Facp + 53); } - else if (number == 2) { return *(Facp + 89); } - else return 0; - } - // check if the given address has a valid header - static uint* acpiCheckRSDPtr(uint* ptr) - { - string sig = "RSD PTR "; - RSDPtr* rsdp = (RSDPtr*)ptr; - byte* bptr; - byte check = 0; - int i; - - if (Compare(sig, (byte*)rsdp) == 0) - { - // check checksum rsdpd - bptr = (byte*)ptr; - for (i = 0; i < 20; i++) - { - check += *bptr; - bptr++; - } - //Console.WriteLine("0x" + check.ToHex()); - // found valid rsdpd - if (check == 0) - { - //string str = rsdp->RsdtAddress.ToHex(); - //Console.WriteLine("seen"); Console.WriteLine(str); - Compare("RSDT", (byte*)rsdp->RsdtAddress); - if (rsdp->RsdtAddress != 0) - return (uint*)rsdp->RsdtAddress; - } - } - Console.WriteLine("Unable to find RSDT. ACPI not available"); - return null; - } - - static uint RSDPAddress() - { - - // check bios - for (uint addr = 0xE0000; addr < 0x100000; addr += 4) - if (Compare("RSD PTR ", (byte*)addr) == 0) - if (Check_RSD(addr)) - return addr; - // 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 (Compare("RSD PTR ", (byte*)addr) == 0) - return addr; - - // not found - return 0; - } - // checks for a given header and validates checksum - static int acpiCheckHeader(byte* ptr, string sig) - { - return Compare(sig, ptr); - } + //Check RSD static bool Check_RSD(uint address) { byte sum = 0; @@ -143,221 +63,264 @@ namespace Cosmos.Core return (sum == 0); } - private static Core.Common.IOPort smiIO, pm1aIO, pm1bIO; - public static int Enable() + + //Acpi Initialization :P + public static void Start(bool initialize = true, bool enable = true) { - // check if acpi is enabled + if (initialize) + Init(); - if (pm1aIO.Word == 0) - { - // check if acpi can be enabled - if (SMI_CMD != null && ACPI_ENABLE != 0) - { - smiIO.Byte = ACPI_ENABLE; - //CPUBus.Write8((byte)SMI_CMD, ACPI_ENABLE); // send acpi enable command - // give 3 seconds time to enable acpi - int i; - for (i = 0; i < 300; i++) - { - if ((pm1aIO.Word & 1) == 1) - //if ((CPUBus.Read16((ushort)PM1a_CNT) & SCI_EN) == 1) - break; - - } - if (PM1b_CNT != null) - for (; i < 300; i++) - { - //if ((CPUBus.Read16((ushort)PM1b_CNT) & SCI_EN) == 1) - if ((pm1bIO.Word & 1) == 1) - break; - } - if (i < 300) - { - - return 0; - } - else - { - Console.WriteLine("Couldn't enable ACPI."); - return -1; - } - } - else - { - Console.WriteLine("No known way to enable ACPI."); - return -1; - } - } - else - { - - return 0; - } + if (enable) + Enable(); } - public static void Disable() + + // Shutdown + public static void Shutdown() { - smiIO.Byte = ACPI_DISABLE; + Console.Clear(); + if (PM1a_CNT == null) + Init(); + + pm1aIO.Word = (ushort)(SLP_TYPa | SLP_EN); + + if (PM1b_CNT != null) + pm1bIO.Word = (ushort)(SLP_TYPb | SLP_EN); + + Global.CPU.Halt(); } - public static int Init() + + // Reboot + public static void Reboot() { - byte* ptr = (byte*)RSDPAddress(); int addr = 0; + Console.Clear(); + IOPort port = new IOPort(0x64); + byte good = 0x02; + + while ((good & 0x02) != 0) + good = port.Byte; + + port.Byte = 0xFE; + + // Halt CPU + Global.CPU.Halt(); + } + + // Initializazion + private static bool Init() + { + byte* ptr = (byte*)RSDPAddress(); + int addr = 0; for (int i = 19; i >= 16; i--) { - addr += (*((byte*)ptr + i)); + addr += (*(ptr + i)); addr = (i == 16) ? addr : addr << 8; } ptr = (byte*)addr; ptr += 4; addr = 0; + for (int i = 3; i >= 0; i--) { - addr += (*((byte*)ptr + i)); + addr += (*(ptr + i)); addr = (i == 0) ? addr : addr << 8; } - int length = addr; + int length = addr; ptr -= 4; - // check if address is correct ( if acpi is available on this pc ) - if (ptr != null && acpiCheckHeader((byte*)ptr, "RSDT") == 0) + + if (ptr != null && acpiCheckHeader(ptr, "RSDT") == 0) { addr = 0; - // the RSDT contains an unknown number of pointers to acpi tables - int entrys = length; entrys = (entrys - 36) / 4; - ptr += 36; // skip header information + ptr += 36; byte* yeuse; while (0 < entrys--) { for (int i = 3; i >= 0; i--) { - addr += (*((byte*)ptr + i)); + addr += (*(ptr + i)); addr = (i == 0) ? addr : addr << 8; } + yeuse = (byte*)addr; - // check if the desired table is reached - Facp = (byte*)yeuse; + Facp = yeuse; + if (Compare("FACP", Facp) == 0) { if (acpiCheckHeader((byte*)facpget(0), "DSDT") == 0) { - // search the \_S5 package in the DSDT - byte* S5Addr = (byte*)facpget(0) + 36; // skip header + byte* S5Addr = (byte*)facpget(0) + 36; int dsdtLength = *(facpget(0) + 1) - 36; + while (0 < dsdtLength--) { - if (Compare("_S5_", (byte*)S5Addr) == 0) + if (Compare("_S5_", S5Addr) == 0) break; S5Addr++; } - // check if \_S5 was found + if (dsdtLength > 0) { - // check for valid AML structure if ((*(S5Addr - 1) == 0x08 || (*(S5Addr - 2) == 0x08 && *(S5Addr - 1) == '\\')) && *(S5Addr + 4) == 0x12) { S5Addr += 5; - S5Addr += ((*S5Addr & 0xC0) >> 6) + 2; // calculate PkgLength size - + S5Addr += ((*S5Addr & 0xC0) >> 6) + 2; if (*S5Addr == 0x0A) - S5Addr++; // skip byteprefix + S5Addr++; SLP_TYPa = (short)(*(S5Addr) << 10); S5Addr++; - if (*S5Addr == 0x0A) - S5Addr++; // skip byteprefix + S5Addr++; SLP_TYPb = (short)(*(S5Addr) << 10); - SMI_CMD = facpget(1); - ACPI_ENABLE = facpbget(0); ACPI_DISABLE = facpbget(1); - PM1a_CNT = facpget(2); PM1b_CNT = facpget(3); - PM1_CNT_LEN = facpbget(3); - SLP_EN = 1 << 13; SCI_EN = 1; + smiIO = new IOPort((ushort)SMI_CMD); pm1aIO = new IOPort((ushort)PM1a_CNT); pm1bIO = new IOPort((ushort)PM1b_CNT); - return 0; - } - else - { - Console.WriteLine("\\_S5 parse error.\n"); + + return true; } } - else - { - Console.WriteLine("\\_S5 not present.\n"); - } - } - else - { - Console.WriteLine("DSDT invalid.\n"); } } + ptr += 4; } - Console.WriteLine("No valid FACP present.\n"); } - else + + return false; + } + + // Enable ACPI + private static bool Enable() + { + if (pm1aIO.Word == 0) { - Console.WriteLine("No ACPI.\n"); + if (SMI_CMD != null && ACPI_ENABLE != 0) + { + smiIO.Word = ACPI_ENABLE; + + int i; + for (i = 0; i < 300; i++) + { + if ((pm1aIO.Word & 1) == 1) + break; + } + + if (PM1b_CNT != null) + { + for (; i < 300; i++) + { + if ((pm1bIO.Word & 1) == 1) + break; + } + } + + if (i < 300) return true; + return false; + } + return false; } - - return -1; - + return true; } - public static void Reboot() + // Disable ACPI + public static void Disable() { - Core.Common.CPU.DisableInterrupts(); - byte good = 0x02; - while ((good & 0x02) != 0) - good = Inb(0x64); - Outb(0x64, 0xFE); - - Cosmos.Core.Global.CPU.Halt(); + smiIO.Byte = ACPI_DISABLE; } - static Core.Common.IOPort io = new Core.Common.IOPort(0); - static int PP = 0, D = 0; - public static void Outb(ushort port, byte data) + // Retrieve the RSDP address + private static unsafe uint RSDPAddress() { - if (io.Port != port) - io = new Core.Common.IOPort(port); - io.Byte = data; - PP = port; - D = data; + for (uint addr = 0xE0000; addr < 0x100000; addr += 4) + if (Compare("RSD PTR ", (byte*)addr) == 0) + if (Check_RSD(addr)) + return addr; - } - public static byte Inb(ushort port) - { - if (io.Port != port) - io = new Core.Common.IOPort(port); - return io.Byte; + uint ebda_address = *((uint*)0x040E); + ebda_address = (ebda_address * 0x10) & 0x000fffff; + for (uint addr = ebda_address; addr < ebda_address + 1024; addr += 4) + if (Compare("RSD PTR ", (byte*)addr) == 0) + return addr; + + return 0; } - public static void Shutdown() + // RSDT Table + private static uint* acpiCheckRSDPtr(uint* ptr) { - // send the shutdown command - Console.Clear(); - if (PM1a_CNT == null) Init(); - if (pm1aIO != null) + string sig = "RSD PTR "; + RSDPtr* rsdp = (RSDPtr*)ptr; + + byte* bptr; + byte check = 0; + int i; + + if (Compare(sig, (byte*)rsdp) == 0) { - pm1aIO.Word = (ushort)(SLP_TYPa | SLP_EN); - if (PM1b_CNT != null) - pm1bIO.Word = (ushort)(SLP_TYPb | SLP_EN); + bptr = (byte*)ptr; + for (i = 0; i < 20; i++) + { + check += *bptr; + bptr++; + } + + if (check == 0) + { + Compare("RSDT", (byte*)rsdp->RsdtAddress); + + if (rsdp->RsdtAddress != 0) + return (uint*)rsdp->RsdtAddress; + } + } + + return null; + } + + // FACP Table + private static byte facpbget(int number) + { + switch (number) + { + case 0: + return *(Facp + 52); + case 1: + return *(Facp + 53); + case 2: + return *(Facp + 89); + default: + return 0; + } + } + + private static int* facpget(int number) + { + switch (number) + { + case 0: + return (int*)*((int*)(Facp + 40)); + case 1: + return (int*)*((int*)(Facp + 48)); + case 2: + return (int*)*((int*)(Facp + 64)); + case 3: + return (int*)*((int*)(Facp + 68)); + default: + return null; } - // Console.WriteLine("It is now safe to turn off your computer"); } } } \ No newline at end of file diff --git a/source/Cosmos.HAL/Global.cs b/source/Cosmos.HAL/Global.cs index 48a4b1cfc..e98b5017b 100644 --- a/source/Cosmos.HAL/Global.cs +++ b/source/Cosmos.HAL/Global.cs @@ -105,6 +105,8 @@ namespace Cosmos.HAL InitStaticDevices(); mDebugger.Send("PCI Devices"); InitPciDevices(); + mDebugger.Send("ACPI Init"); + StartACPI(); mDebugger.Send("Done initializing Cosmos.HAL.Global"); mDebugger.Send("ATA Primary Master"); @@ -130,11 +132,16 @@ namespace Cosmos.HAL // system level and not accessible from Core. Need to think about this // for the future. Console.WriteLine("Finding PCI Devices"); - Console.WriteLine(); PCI.Setup(); } + public static void StartACPI() + { + Console.WriteLine("Start ACPI"); + Core.ACPI.Start(); + } + public static void EnableInterrupts() { CPU.EnableInterrupts(); diff --git a/source/Cosmos.HAL/Power.cs b/source/Cosmos.HAL/Power.cs index 75ecfa681..e584043c6 100644 --- a/source/Cosmos.HAL/Power.cs +++ b/source/Cosmos.HAL/Power.cs @@ -9,14 +9,19 @@ namespace Cosmos.HAL { public class Power { + //Reboot with CPU public static void CPUReboot() { Core.Global.CPU.Reboot(); } + + //Reboot with ACPI public static void Reboot() { ACPI.Reboot(); } + + //Shutdown with ACPI public static void Shutdown() { ACPI.Shutdown(); From 4eeb5ce5dbbf32bcfb9180d97455b8563c957d41 Mon Sep 17 00:00:00 2001 From: Valentin Charbonnier Date: Wed, 21 Jun 2017 19:34:31 +0200 Subject: [PATCH 5/7] Update Global.cs "Start ACPI" replaced by "Starting ACPI" --- source/Cosmos.HAL/Global.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Cosmos.HAL/Global.cs b/source/Cosmos.HAL/Global.cs index e98b5017b..ac04cf711 100644 --- a/source/Cosmos.HAL/Global.cs +++ b/source/Cosmos.HAL/Global.cs @@ -138,7 +138,7 @@ namespace Cosmos.HAL public static void StartACPI() { - Console.WriteLine("Start ACPI"); + Console.WriteLine("Starting ACPI"); Core.ACPI.Start(); } From ba65f3b4793bd7f13d6585bd7fcaa40cefcba071 Mon Sep 17 00:00:00 2001 From: Valentin Charbonnier Date: Mon, 3 Jul 2017 20:27:28 +0200 Subject: [PATCH 6/7] Bug fixes and additions. - The user can now Enable and Disable ACPI - Image change in the setup (for a better design) - Bug fixed with Remote Debugging (NRE) --- Setup/images/cosmos_small.bmp | Bin 4158 -> 9294 bytes source/Cosmos.Core/ACPI.cs | 67 +++++++++++++++------------------- source/Cosmos.HAL/Power.cs | 12 ++++++ source/Cosmos.System/Power.cs | 8 ++++ 4 files changed, 49 insertions(+), 38 deletions(-) diff --git a/Setup/images/cosmos_small.bmp b/Setup/images/cosmos_small.bmp index d16bce4f44d1cd15a54f0a391db5800544f84d77..3097d411c0f4551aec97c090ee331512b79407db 100644 GIT binary patch literal 9294 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 literal 4158 zcmd6pZA@F&8OMpV4`VjcEKhe~cISE&d9^)<)G9Vc_GMRWN@ge~V2rzw6+~-?#%^cW zjHn$qp{5}sgz$O+@e+NxESB}&?+b6a(jrhVeWf5+hK7vg;B zhiQN5a-MVV`JLx~o^$RsOupgANt??2K~mB$Nu&v1JCc65^&s}|4$>jlaBma3T73BO z$wSP~3}S4c1q19+-2UqlI-0%Mu_FnZ%vW%Abq<65J^1wFyEx>j!@c#3aKHN|hI)?S z>g5&e`3;Tb#dBzDdJh-ohVifOzQI>tK0*6&58iPcz+iVHDl7KmtvAc@`QyK1xbHX~ z-2VjoUpHa#{8=2XbD-f!9WGy70&UQddFpWgvyX87%0=u_DKS4cjgRi#!o54|m+J_S{$ma!pJ~7+DFvnel$K zHP@rFy%kI60=Rqg8rH8~z>`ORLvLpj#!hu&ptlpl{jC`6X~FFqSJ2NkV{v{G=`W>$ zZEM8J`2Yf=z36CZAZKF)AK$r-k=_>k`~@-DgJE1;m_h2!pJM&`Di-FauyAG^KM@Kr zJ2ilng#gA+wUcx805`5KV|=I=BYiD6dDMfq-}*f|PaMMC^;Mjo9m4cj7xByD&W#n4 za}u}Lma#NHj?)v}m>TK8=-78+tJ;2gyb4Qe^&#B$oUP7lC^Ywh}L6u z=R39!aPUG&4RV<&I0NZ*Pch*+0dSQxq4}d-SKAC3}3ui~k+@qKn zYQ^kC4|>|_3EPX)yss`yle6&%cW>Vy`!!B-bdd2Ym>47;hr962KfWMy z&7j#|OT0{w{huUtox*%u%^!fmW+6OhEblrCP1@ zIX+9XLs&sV%uk+_N+UL7&nLeqs8*}(nF+N^t=4)I*3*_IB$zlMm6>T*s|Bu@osZUq z{1`BdFVh*-?)2i6ii#prS$d|^#4y2{n6nn)Y-vG;VWN=JX%dhdTT<7W8Ae|bEoXFn zI-iXOc82=S{30Du(3QX^l_t>X z_Hk5xx-LBuhl0IiQbul$Cgj#fyBMXiEIF)QQl*oNx7u{2QmKwf$Z^^Yr9v1PYF8+B zMLJu7SfNnL^^t@emn~2z4(4ZsRi#i^xH#PAs}%~ZH&W3sM^%v9R&HprLZK++I$WEg zP%wKUJI`@0hR-ia=fvmp#azs_mJPnr8!;N@Y-u`~%)$+^%Ve@juEVv-g)+Xpnp+^p zxs-(48&(0~xH!@#8)ULzWPuS*A(2=(6-Y?OzNN~_@ZF45iA)gWToC50L665%A{G%cj1tEdo=5UbJyra2+QSwY!ZHz# zXSIq&qJm8{l-A<#codN@TDUGMn@hs7MI2Y)VOciSV72Cn!bu5fXIWVm_bPE5wNJsa zd@%=_2uHv$xtY{nMg}~SPo)o%kz!L=sk{)#a~KT!NzNR*qrhQMvurT(1?BRoXg6)M zX{{V+_1Qua7N%NFJef_fAs{{4tJ_{rm8x1{Ga5OJv|_$7Dv5{0EVHrwJtEW4-q5q+ zC}|b*bYveBm66Fb+0V;IK-wqYN=a#bDS2X|)HI$pT_r9+?nO}$#v0<3s3!gj?106{hxFH1y){=FaQ7m diff --git a/source/Cosmos.Core/ACPI.cs b/source/Cosmos.Core/ACPI.cs index 261a6be95..58b2b942f 100644 --- a/source/Cosmos.Core/ACPI.cs +++ b/source/Cosmos.Core/ACPI.cs @@ -1,4 +1,5 @@ using Cosmos.Core.Common; +using Cosmos.Debug.Kernel; using System; using System.Runtime.InteropServices; @@ -7,6 +8,8 @@ namespace Cosmos.Core public unsafe class ACPI { + public static readonly Debugger mDebugger = new Debugger("System", "Global"); + //RSD Table [StructLayout(LayoutKind.Sequential, Pack = 1)] public unsafe struct RSDPtr @@ -41,13 +44,31 @@ namespace Cosmos.Core // FACP private static byte* Facp = null; + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct FACP + { + public fixed byte Signature[4]; + public int Length; + + public fixed byte unneded1[40 - 8]; + public int* DSDT; + public fixed byte unneded2[48 - 44]; + public int* SMI_CMD; + public byte ACPI_ENABLE; + public byte ACPI_DISABLE; + public fixed byte unneded3[64 - 54]; + public int* PM1a_CNT_BLK; + public int* PM1b_CNT_BLK; + public fixed byte unneded4[89 - 72]; + public byte PM1_CNT_LEN; + }; //Compare static int Compare(string c1, byte* c2) { for (int i = 0; i < c1.Length; i++) { - if (c1[i] != (char)c2[i]) { return -1; } + if (c1[i] != c2[i]) { return -1; } } return 0; } @@ -71,7 +92,7 @@ namespace Cosmos.Core Init(); if (enable) - Enable(); + Enable(); } // Shutdown @@ -148,8 +169,6 @@ namespace Cosmos.Core yeuse = (byte*)addr; Facp = yeuse; - if (Compare("FACP", Facp) == 0) - { if (acpiCheckHeader((byte*)facpget(0), "DSDT") == 0) { byte* S5Addr = (byte*)facpget(0) + 36; @@ -158,7 +177,7 @@ namespace Cosmos.Core while (0 < dsdtLength--) { if (Compare("_S5_", S5Addr) == 0) - break; + break; S5Addr++; } @@ -192,9 +211,7 @@ namespace Cosmos.Core } } } - } - - ptr += 4; + ptr += 4; } } @@ -202,42 +219,16 @@ namespace Cosmos.Core } // Enable ACPI - private static bool Enable() + public static void Enable() { - if (pm1aIO.Word == 0) - { - if (SMI_CMD != null && ACPI_ENABLE != 0) - { - smiIO.Word = ACPI_ENABLE; - - int i; - for (i = 0; i < 300; i++) - { - if ((pm1aIO.Word & 1) == 1) - break; - } - - if (PM1b_CNT != null) - { - for (; i < 300; i++) - { - if ((pm1bIO.Word & 1) == 1) - break; - } - } - - if (i < 300) return true; - return false; - } - return false; - } - return true; + Init(); + smiIO = new IOPort(ACPI_ENABLE); } // Disable ACPI public static void Disable() { - smiIO.Byte = ACPI_DISABLE; + smiIO = new IOPort(ACPI_DISABLE); } // Retrieve the RSDP address diff --git a/source/Cosmos.HAL/Power.cs b/source/Cosmos.HAL/Power.cs index e584043c6..29669136b 100644 --- a/source/Cosmos.HAL/Power.cs +++ b/source/Cosmos.HAL/Power.cs @@ -26,5 +26,17 @@ namespace Cosmos.HAL { ACPI.Shutdown(); } + + //Enable ACPI + public static void ACPIEnable() + { + ACPI.Enable(); + } + + //Disable ACPI + public static void ACPIDisable() + { + ACPI.Disable(); + } } } \ No newline at end of file diff --git a/source/Cosmos.System/Power.cs b/source/Cosmos.System/Power.cs index 334bb6cb4..b741b284c 100644 --- a/source/Cosmos.System/Power.cs +++ b/source/Cosmos.System/Power.cs @@ -20,5 +20,13 @@ namespace Cosmos.System { HAL.Power.Shutdown(); } + public static void ACPIEnable() + { + HAL.Power.ACPIEnable(); + } + public static void ACPIDisable() + { + HAL.Power.ACPIDisable(); + } } } \ No newline at end of file From ffbc1f71be292b22022c93bf5588362e9b97ab51 Mon Sep 17 00:00:00 2001 From: Valentin Charbonnier Date: Tue, 4 Jul 2017 00:10:48 +0200 Subject: [PATCH 7/7] Some changes canceled --- Setup/images/cosmos_small.bmp | Bin 9294 -> 4158 bytes source/Cosmos.HAL/Cosmos.HAL.csproj | 4 ---- 2 files changed, 4 deletions(-) diff --git a/Setup/images/cosmos_small.bmp b/Setup/images/cosmos_small.bmp index 3097d411c0f4551aec97c090ee331512b79407db..d16bce4f44d1cd15a54f0a391db5800544f84d77 100644 GIT binary patch literal 4158 zcmd6pZA@F&8OMpV4`VjcEKhe~cISE&d9^)<)G9Vc_GMRWN@ge~V2rzw6+~-?#%^cW zjHn$qp{5}sgz$O+@e+NxESB}&?+b6a(jrhVeWf5+hK7vg;B zhiQN5a-MVV`JLx~o^$RsOupgANt??2K~mB$Nu&v1JCc65^&s}|4$>jlaBma3T73BO z$wSP~3}S4c1q19+-2UqlI-0%Mu_FnZ%vW%Abq<65J^1wFyEx>j!@c#3aKHN|hI)?S z>g5&e`3;Tb#dBzDdJh-ohVifOzQI>tK0*6&58iPcz+iVHDl7KmtvAc@`QyK1xbHX~ z-2VjoUpHa#{8=2XbD-f!9WGy70&UQddFpWgvyX87%0=u_DKS4cjgRi#!o54|m+J_S{$ma!pJ~7+DFvnel$K zHP@rFy%kI60=Rqg8rH8~z>`ORLvLpj#!hu&ptlpl{jC`6X~FFqSJ2NkV{v{G=`W>$ zZEM8J`2Yf=z36CZAZKF)AK$r-k=_>k`~@-DgJE1;m_h2!pJM&`Di-FauyAG^KM@Kr zJ2ilng#gA+wUcx805`5KV|=I=BYiD6dDMfq-}*f|PaMMC^;Mjo9m4cj7xByD&W#n4 za}u}Lma#NHj?)v}m>TK8=-78+tJ;2gyb4Qe^&#B$oUP7lC^Ywh}L6u z=R39!aPUG&4RV<&I0NZ*Pch*+0dSQxq4}d-SKAC3}3ui~k+@qKn zYQ^kC4|>|_3EPX)yss`yle6&%cW>Vy`!!B-bdd2Ym>47;hr962KfWMy z&7j#|OT0{w{huUtox*%u%^!fmW+6OhEblrCP1@ zIX+9XLs&sV%uk+_N+UL7&nLeqs8*}(nF+N^t=4)I*3*_IB$zlMm6>T*s|Bu@osZUq z{1`BdFVh*-?)2i6ii#prS$d|^#4y2{n6nn)Y-vG;VWN=JX%dhdTT<7W8Ae|bEoXFn zI-iXOc82=S{30Du(3QX^l_t>X z_Hk5xx-LBuhl0IiQbul$Cgj#fyBMXiEIF)QQl*oNx7u{2QmKwf$Z^^Yr9v1PYF8+B zMLJu7SfNnL^^t@emn~2z4(4ZsRi#i^xH#PAs}%~ZH&W3sM^%v9R&HprLZK++I$WEg zP%wKUJI`@0hR-ia=fvmp#azs_mJPnr8!;N@Y-u`~%)$+^%Ve@juEVv-g)+Xpnp+^p zxs-(48&(0~xH!@#8)ULzWPuS*A(2=(6-Y?OzNN~_@ZF45iA)gWToC50L665%A{G%cj1tEdo=5UbJyra2+QSwY!ZHz# zXSIq&qJm8{l-A<#codN@TDUGMn@hs7MI2Y)VOciSV72Cn!bu5fXIWVm_bPE5wNJsa zd@%=_2uHv$xtY{nMg}~SPo)o%kz!L=sk{)#a~KT!NzNR*qrhQMvurT(1?BRoXg6)M zX{{V+_1Qua7N%NFJef_fAs{{4tJ_{rm8x1{Ga5OJv|_$7Dv5{0EVHrwJtEW4-q5q+ zC}|b*bYveBm66Fb+0V;IK-wqYN=a#bDS2X|)HI$pT_r9+?nO}$#v0<3s3!gj?106{hxFH1y){=FaQ7m literal 9294 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 diff --git a/source/Cosmos.HAL/Cosmos.HAL.csproj b/source/Cosmos.HAL/Cosmos.HAL.csproj index 8409116a4..597a340f6 100644 --- a/source/Cosmos.HAL/Cosmos.HAL.csproj +++ b/source/Cosmos.HAL/Cosmos.HAL.csproj @@ -8,10 +8,6 @@ Cosmos - - False - -