Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better power methods, new VMTools class for detecting VMs #2427

Merged
merged 1 commit into from
Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 20 additions & 23 deletions source/Cosmos.System2/Power.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Cosmos.Core;
using sysIO = System.IO;
using System;

namespace Cosmos.System
{
Expand All @@ -13,47 +13,44 @@ public static class Power
/// </summary>
public static void Reboot()
{
/*
* Qemu does not support ACPI at the current moment due to multiboot2 and SeaBios being to old.
* This Provides a Reboot functionality.
*/
if (VMTools.IsQEMU)
{
new IOPort(0x64).Byte = 0xFE;
}

HAL.Power.CPUReboot();
}

/// <summary>
/// Shutdown the ACPI.
/// </summary>
/// <exception cref="sysIO.IOException">Thrown on IO error.</exception>
/// <exception cref="IOException">Thrown on IO error.</exception>
public static void Shutdown()
{
/*
* Detect if the VBOX guest service is present on the PCI bus.
* https://forum.osdev.org/viewtopic.php?f=1&t=30674
*/
if (HAL.PCI.Exists((HAL.VendorID)0x80EE, (HAL.DeviceID)0xCAFE))
if (VMTools.IsVirtualBox)
{
IOPort P = new(0x4004);
P.DWord = 0x3400;
}
/*
* Qemu does not support ACPI at the current moment due to multiboot2 and SeaBios being to old.
* This Provides a shutdown functionality.
*/
if (VMTools.IsQEMU)
{
new IOPort(0x604).Word = 0x2000;
}

// Try Normal Method
HAL.Power.ACPIShutdown();
}

/// <summary>
/// Shutdown Qemu.
/// Qemu does not support ACPI at the current moment due to multiboot2 and SeaBios being to old.
/// This Provides a shutdown functionality.
/// </summary>
public static void QemuShutdown()
{
new IOPort(0x604).Word = 0x2000;
}

/// <summary>
/// Reboot Qemu.
/// Qemu does not support ACPI at the current moment due to multiboot2 and SeaBios being to old.
/// This Provides a Reboot functionality.
/// </summary>
public static void QemuReboot()
{
new IOPort(0x64).Byte = 0xFE;
}
}
}
58 changes: 58 additions & 0 deletions source/Cosmos.System2/VMTools.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Cosmos.HAL;

namespace Cosmos.System
{
/// <summary>
/// A class used to detect if cosmos is being ran in a virtual machine.
/// Usefull for VM specific tasks.
/// </summary>
public static class VMTools
{
/// <summary>
/// A boolean describing whether or not virtualbox has been detected.
/// </summary>
public static bool IsVirtualBox => GetIsVirtualBox();
/// <summary>
/// A boolean describing whether or not VMware has been detected.
/// </summary>
public static bool IsVMWare => GetIsVMWare();
/// <summary>
/// A boolean describing whether or not QEMU has been detected.
/// </summary>
public static bool IsQEMU => GetIsQEMU();

private static bool GetIsVirtualBox()
{
for (int I = 0; I < PCI.Count; I++)
{
if (PCI.Devices[I].VendorID == 0x80EE)
{
return true;
}
}
return false;
}
private static bool GetIsVMWare()
{
for (int I = 0; I < PCI.Count; I++)
{
if (PCI.Devices[I].VendorID == 0x15ad)
{
return true;
}
}
return false;
}
private static bool GetIsQEMU()
{
for (int I = 0; I < PCI.Count; I++)
{
if (PCI.Devices[I].VendorID == 0x1af4)
{
return true;
}
}
return false;
}
}
}