mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-14 15:06:52 -04:00
ACPI Reset if possible
This commit is contained in:
parent
389e0846fb
commit
57f755bdae
@ -11,10 +11,11 @@
|
||||
namespace acpi {
|
||||
|
||||
void init();
|
||||
void shutdown();
|
||||
|
||||
bool initialized();
|
||||
|
||||
void shutdown();
|
||||
bool reboot();
|
||||
|
||||
} //end of acpi namespace
|
||||
|
||||
#endif
|
||||
|
@ -18,10 +18,13 @@ extern "C" {
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function" //TODO Does not work
|
||||
#include "acpi.h"
|
||||
#include "accommon.h"
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
} //end of extern "C"
|
||||
|
||||
#include <types.hpp>
|
||||
|
||||
constexpr const size_t FADT2_REVISION_ID = 3;
|
||||
|
||||
#endif
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "logging.hpp"
|
||||
#include "scheduler.hpp"
|
||||
#include "arch.hpp"
|
||||
#include "assert.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -105,6 +106,43 @@ void initialize_acpica(){
|
||||
logging::logf(logging::log_level::DEBUG, "acpi:: Finished initialization of ACPICA\n");
|
||||
}
|
||||
|
||||
uint64_t acpi_read(const ACPI_GENERIC_ADDRESS& address){
|
||||
if(address.SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY){
|
||||
UINT64 value = 0;
|
||||
auto status = AcpiOsReadMemory(address.Address, &value, address.BitWidth);
|
||||
if(ACPI_FAILURE(status)){
|
||||
logging::logf(logging::log_level::ERROR, "acpica: Unable to read from memory: error: %s\n", AcpiGbl_ExceptionNames_Env[status].Name);
|
||||
}
|
||||
return value;
|
||||
} else if(address.SpaceId == ACPI_ADR_SPACE_SYSTEM_IO){
|
||||
UINT32 value = 0;
|
||||
auto status = AcpiHwReadPort(address.Address, &value, address.BitWidth);
|
||||
if(ACPI_FAILURE(status)){
|
||||
logging::logf(logging::log_level::ERROR, "acpica: Unable to read from hardware port: error: %s\n", AcpiGbl_ExceptionNames_Env[status].Name);
|
||||
}
|
||||
return value;
|
||||
} else {
|
||||
logging::logf(logging::log_level::ERROR, "acpica: Unimplemented read generic address space id\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void acpi_write(const ACPI_GENERIC_ADDRESS& address, uint64_t value){
|
||||
if(address.SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY){
|
||||
auto status = AcpiOsWriteMemory(address.Address, value, address.BitWidth);
|
||||
if(ACPI_FAILURE(status)){
|
||||
logging::logf(logging::log_level::ERROR, "acpica: Unable to write to memory: error: %s\n", AcpiGbl_ExceptionNames_Env[status].Name);
|
||||
}
|
||||
} else if(address.SpaceId == ACPI_ADR_SPACE_SYSTEM_IO){
|
||||
auto status = AcpiHwWritePort(address.Address, value, address.BitWidth);
|
||||
if(ACPI_FAILURE(status)){
|
||||
logging::logf(logging::log_level::ERROR, "acpica: Unable to write to hardware port: error: %s\n", AcpiGbl_ExceptionNames_Env[status].Name);
|
||||
}
|
||||
} else {
|
||||
logging::logf(logging::log_level::ERROR, "acpica: Unimplemented write generic address space id\n");
|
||||
}
|
||||
}
|
||||
|
||||
} //end of anonymous namespace
|
||||
|
||||
void acpi::init(){
|
||||
@ -112,7 +150,13 @@ void acpi::init(){
|
||||
scheduler::queue_async_init_task(initialize_acpica);
|
||||
}
|
||||
|
||||
bool acpi::initialized(){
|
||||
return acpi_initialized;
|
||||
}
|
||||
|
||||
void acpi::shutdown(){
|
||||
thor_assert(acpi::initialized(), "ACPI must be initialized for acpi::shutdown()");
|
||||
|
||||
auto status = AcpiEnterSleepStatePrep(5);
|
||||
|
||||
if(ACPI_FAILURE(status)){
|
||||
@ -133,6 +177,19 @@ void acpi::shutdown(){
|
||||
arch::enable_hwint(rflags);
|
||||
}
|
||||
|
||||
bool acpi::initialized(){
|
||||
return acpi_initialized;
|
||||
bool acpi::reboot(){
|
||||
thor_assert(acpi::initialized(), "ACPI must be initialized for acpi::reboot()");
|
||||
|
||||
if (AcpiGbl_FADT.Header.Revision < FADT2_REVISION_ID){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER)){
|
||||
return false;
|
||||
}
|
||||
|
||||
auto reset_register = AcpiGbl_FADT.ResetRegister;
|
||||
auto reset_value = AcpiGbl_FADT.ResetValue;
|
||||
|
||||
acpi_write(reset_register, reset_value);
|
||||
}
|
||||
|
@ -13,8 +13,6 @@
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr const size_t FADT2_REVISION_ID = 3;
|
||||
|
||||
#define CURRENT_YEAR 2013
|
||||
#define cmos_address 0x70
|
||||
#define cmos_data 0x71
|
||||
|
@ -91,8 +91,10 @@ void sc_clear(interrupt::syscall_regs*){
|
||||
}
|
||||
|
||||
void sc_reboot(interrupt::syscall_regs*){
|
||||
//TODO Reboot should be done more properly
|
||||
asm volatile("mov al, 0x64; or al, 0xFE; out 0x64, al; mov al, 0xFE; out 0x64, al; " : : );
|
||||
if(!acpi::initialized() || !acpi::reboot()){
|
||||
logging::logf(logging::log_level::ERROR, "ACPI reset not possible, fallback to 8042 reboot\n");
|
||||
asm volatile("mov al, 0x64; or al, 0xFE; out 0x64, al; mov al, 0xFE; out 0x64, al; " : : );
|
||||
}
|
||||
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user