summaryrefslogtreecommitdiffhomepage
path: root/src/kernel/HALKit/AMD64/HalACPIFactoryInterface.cpp
blob: 7368ea10d1673d5b7eb0d81b16848c028fee4b8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org)
// Licensed under the Apache License, Version 2.0 (see LICENSE file)
// Official repository: https://github.com/nekernel-org/nekernel

#include <ArchKit/ArchKit.h>
#include <HALKit/AMD64/Processor.h>
#include <KernelKit/HeapMgr.h>
#include <NeKit/KString.h>
#include <modules/ACPI/ACPIFactoryInterface.h>

namespace Kernel {
namespace Detail {
  struct FADT final : public SDT {
    UInt32 FirmwareCtrl;
    UInt32 Dsdt;

    // field used in ACPI 1.0; no longer in use, for compatibility only
    UInt8 Reserved;

    UInt8  PreferredPowerManagementProfile;
    UInt16 SCI_Interrupt;
    UInt32 SMI_CommandPort;
    UInt8  AcpiEnable;
    UInt8  AcpiDisable;
    UInt8  S4BIOS_REQ;
    UInt8  PSTATE_Control;
    UInt32 PM1aEventBlock;
    UInt32 PM1bEventBlock;
    UInt32 PM1aControlBlock;
    UInt32 PM1bControlBlock;
    UInt32 PM2ControlBlock;
    UInt32 PMTimerBlock;
    UInt32 GPE0Block;
    UInt32 GPE1Block;
    UInt8  PM1EventLength;
    UInt8  PM1ControlLength;
    UInt8  PM2ControlLength;
    UInt8  PMTimerLength;
    UInt8  GPE0Length;
    UInt8  GPE1Length;
    UInt8  GPE1Base;
    UInt8  CStateControl;
    UInt16 WorstC2Latency;
    UInt16 WorstC3Latency;
    UInt16 FlushSize;
    UInt16 FlushStride;
    UInt8  DutyOffset;
    UInt8  DutyWidth;
    UInt8  DayAlarm;
    UInt8  MonthAlarm;
    UInt8  Century;

    // reserved in ACPI 1.0; used since ACPI 2.0+
    UInt16 BootArchitecturkMMFlags;

    UInt8  Reserved2;
    UInt32 Flags;

    // 12 byte structure; see below for details
    ACPI_ADDRESS ResetReg;

    UInt8 ResetValue;
    UInt8 Reserved3[3];

    // 64bit pointers - Available on ACPI 2.0+
    UInt64 X_FirmwareControl;
    UInt64 X_Dsdt;

    ACPI_ADDRESS X_PM1aEventBlock;
    ACPI_ADDRESS X_PM1bEventBlock;
    ACPI_ADDRESS X_PM1aControlBlock;
    ACPI_ADDRESS X_PM1bControlBlock;
    ACPI_ADDRESS X_PM2ControlBlock;
    ACPI_ADDRESS X_PMTimerBlock;
    ACPI_ADDRESS X_GPE0Block;
    ACPI_ADDRESS X_GPE1Block;
  };
}  // namespace Detail

ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) : fRsdp(rsp_ptr), fEntries(0) {}

Bool ACPIFactoryInterface::Shutdown() {
  return NO;
}

/// @brief Reboot machine in either ACPI or by triple faulting.
/// @return nothing it's a reboot.
Void ACPIFactoryInterface::Reboot() {
  asm volatile(
      ".intel_syntax noprefix; "
      "rt_reset_hardware:; "
      "cli; "
      "wait_gate1: ; "
      "in al,0x64 ; "
      "and al,2 ; "
      "jnz wait_gate1 ; "
      "mov al,0x0D1 ; "
      "out 0x64,al ; "
      "wait_gate2: ; "
      "in al,0x64 ; "
      "and al,2 ; "
      "jnz wait_gate2 ; "
      "mov al,0x0FE ; "
      "out 0x60,al ; "
      "xor rax,rax ; "
      "lidt [rax] ; "
      "reset_wait: ; "
      "jmp reset_wait ; "
      ".att_syntax; ");
}
}  // namespace Kernel