Compare commits
2 Commits
7d34bd8f82
...
135ca8395f
Author | SHA1 | Date |
---|---|---|
Bananymous | 135ca8395f | |
Bananymous | e0011d22f2 |
|
@ -10,7 +10,12 @@ endif()
|
||||||
|
|
||||||
set(KERNEL_SOURCES
|
set(KERNEL_SOURCES
|
||||||
font/prefs.psf.o
|
font/prefs.psf.o
|
||||||
kernel/ACPI.cpp
|
kernel/ACPI/ACPI.cpp
|
||||||
|
kernel/ACPI/AML.cpp
|
||||||
|
kernel/ACPI/AML/DataObject.cpp
|
||||||
|
kernel/ACPI/AML/MiscObject.cpp
|
||||||
|
kernel/ACPI/AML/NameObject.cpp
|
||||||
|
kernel/ACPI/AML/TermObject.cpp
|
||||||
kernel/APIC.cpp
|
kernel/APIC.cpp
|
||||||
kernel/BootInfo.cpp
|
kernel/BootInfo.cpp
|
||||||
kernel/CPUID.cpp
|
kernel/CPUID.cpp
|
||||||
|
|
|
@ -54,7 +54,7 @@ bananboot_end:
|
||||||
|
|
||||||
.section .bss, "aw", @nobits
|
.section .bss, "aw", @nobits
|
||||||
boot_stack_bottom:
|
boot_stack_bottom:
|
||||||
.skip 4096 * 4
|
.skip 4096 * 64
|
||||||
boot_stack_top:
|
boot_stack_top:
|
||||||
|
|
||||||
.global g_kernel_cmdline
|
.global g_kernel_cmdline
|
||||||
|
|
|
@ -1,144 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <BAN/Vector.h>
|
|
||||||
#include <kernel/Memory/Types.h>
|
|
||||||
|
|
||||||
namespace Kernel
|
|
||||||
{
|
|
||||||
|
|
||||||
class ACPI
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct GAS
|
|
||||||
{
|
|
||||||
uint8_t address_space_id;
|
|
||||||
uint8_t register_bit_width;
|
|
||||||
uint8_t register_bit_offset;
|
|
||||||
uint8_t access_size;
|
|
||||||
uint64_t address;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct SDTHeader
|
|
||||||
{
|
|
||||||
uint8_t signature[4];
|
|
||||||
uint32_t length;
|
|
||||||
uint8_t revision;
|
|
||||||
uint8_t checksum;
|
|
||||||
uint8_t oemid[6];
|
|
||||||
uint64_t oem_table_id;
|
|
||||||
uint32_t oem_revision;
|
|
||||||
uint32_t creator_id;
|
|
||||||
uint32_t creator_revision;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct FADT : public SDTHeader
|
|
||||||
{
|
|
||||||
uint32_t firmware_ctrl;
|
|
||||||
uint32_t dsdt;
|
|
||||||
uint8_t __reserved;
|
|
||||||
uint8_t preferred_pm_profile;
|
|
||||||
uint16_t sci_int;
|
|
||||||
uint32_t smi_cmd;
|
|
||||||
uint8_t acpi_enable;
|
|
||||||
uint8_t acpi_disable;
|
|
||||||
uint8_t s4bios_req;
|
|
||||||
uint8_t pstate_cnt;
|
|
||||||
uint32_t pm1a_evt_blk;
|
|
||||||
uint32_t pm1b_evt_blk;
|
|
||||||
uint32_t pm1a_cnt_blk;
|
|
||||||
uint32_t pm1b_cnt_blk;
|
|
||||||
uint32_t pm2_cnt_blk;
|
|
||||||
uint32_t pm_tmr_blk;
|
|
||||||
uint32_t gpe0_blk;
|
|
||||||
uint32_t gpe1_blk;
|
|
||||||
uint8_t pm1_evt_len;
|
|
||||||
uint8_t pm1_cnt_len;
|
|
||||||
uint8_t pm2_cnt_len;
|
|
||||||
uint8_t pm_tmr_len;
|
|
||||||
uint8_t gpe0_blk_len;
|
|
||||||
uint8_t gpe1_blk_len;
|
|
||||||
uint8_t gpe1_base;
|
|
||||||
uint8_t cst_cnt;
|
|
||||||
uint16_t p_lvl2_lat;
|
|
||||||
uint16_t p_lvl3_lat;
|
|
||||||
uint16_t flush_size;
|
|
||||||
uint16_t flush_stride;
|
|
||||||
uint8_t duty_offset;
|
|
||||||
uint8_t duty_width;
|
|
||||||
uint8_t day_alrm;
|
|
||||||
uint8_t mon_alrm;
|
|
||||||
uint8_t century;
|
|
||||||
uint16_t iapc_boot_arch;
|
|
||||||
uint8_t __reserved2;
|
|
||||||
uint32_t flags;
|
|
||||||
uint8_t reset_reg[12];
|
|
||||||
uint8_t reset_value;
|
|
||||||
uint16_t arm_boot_arch;
|
|
||||||
uint8_t fadt_minor_version;
|
|
||||||
uint64_t x_firmware_version;
|
|
||||||
uint64_t x_dsdt;
|
|
||||||
uint8_t x_pm1a_evt_blk[12];
|
|
||||||
uint8_t x_pm1b_evt_blk[12];
|
|
||||||
uint8_t x_pm1a_cnt_blk[12];
|
|
||||||
uint8_t x_pm1b_cnt_blk[12];
|
|
||||||
uint8_t x_pm2_cnt_blk[12];
|
|
||||||
uint8_t x_pm_tmr_blk[12];
|
|
||||||
uint8_t x_gpe0_blk[12];
|
|
||||||
uint8_t x_gpe1_blk[12];
|
|
||||||
uint8_t sleep_control_reg[12];
|
|
||||||
uint8_t sleep_status_reg[12];
|
|
||||||
uint64_t hypervison_vendor_identity;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct HPET : public SDTHeader
|
|
||||||
{
|
|
||||||
uint8_t hardware_rev_id;
|
|
||||||
uint8_t comparator_count : 5;
|
|
||||||
uint8_t count_size_cap : 1;
|
|
||||||
uint8_t reserved : 1;
|
|
||||||
uint8_t legacy_replacement_irq_routing_cable : 1;
|
|
||||||
uint16_t pci_vendor_id;
|
|
||||||
GAS base_address;
|
|
||||||
uint8_t hpet_number;
|
|
||||||
uint16_t main_counter_minimum_clock_tick;
|
|
||||||
uint8_t page_protection_and_oem_attribute;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
public:
|
|
||||||
static BAN::ErrorOr<void> initialize();
|
|
||||||
static ACPI& get();
|
|
||||||
|
|
||||||
const SDTHeader* get_header(BAN::StringView signature, uint32_t index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ACPI() = default;
|
|
||||||
BAN::ErrorOr<void> initialize_impl();
|
|
||||||
|
|
||||||
private:
|
|
||||||
paddr_t m_header_table_paddr = 0;
|
|
||||||
vaddr_t m_header_table_vaddr = 0;
|
|
||||||
uint32_t m_entry_size = 0;
|
|
||||||
|
|
||||||
struct MappedPage
|
|
||||||
{
|
|
||||||
Kernel::paddr_t paddr;
|
|
||||||
Kernel::vaddr_t vaddr;
|
|
||||||
|
|
||||||
SDTHeader* as_header() { return (SDTHeader*)vaddr; }
|
|
||||||
};
|
|
||||||
BAN::Vector<MappedPage> m_mapped_headers;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace BAN::Formatter
|
|
||||||
{
|
|
||||||
template<typename F>
|
|
||||||
void print_argument(F putc, const Kernel::ACPI::SDTHeader& header, const ValueFormat& format)
|
|
||||||
{
|
|
||||||
putc(header.signature[0]);
|
|
||||||
putc(header.signature[1]);
|
|
||||||
putc(header.signature[2]);
|
|
||||||
putc(header.signature[3]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <BAN/Vector.h>
|
||||||
|
#include <kernel/ACPI/Headers.h>
|
||||||
|
#include <kernel/Memory/Types.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI
|
||||||
|
{
|
||||||
|
|
||||||
|
class ACPI
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static BAN::ErrorOr<void> initialize();
|
||||||
|
static ACPI& get();
|
||||||
|
|
||||||
|
const SDTHeader* get_header(BAN::StringView signature, uint32_t index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ACPI() = default;
|
||||||
|
BAN::ErrorOr<void> initialize_impl();
|
||||||
|
|
||||||
|
private:
|
||||||
|
paddr_t m_header_table_paddr = 0;
|
||||||
|
vaddr_t m_header_table_vaddr = 0;
|
||||||
|
uint32_t m_entry_size = 0;
|
||||||
|
|
||||||
|
struct MappedPage
|
||||||
|
{
|
||||||
|
Kernel::paddr_t paddr;
|
||||||
|
Kernel::vaddr_t vaddr;
|
||||||
|
|
||||||
|
SDTHeader* as_header() { return (SDTHeader*)vaddr; }
|
||||||
|
};
|
||||||
|
BAN::Vector<MappedPage> m_mapped_headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kernel/ACPI/Headers.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI
|
||||||
|
{
|
||||||
|
|
||||||
|
class AMLParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~AMLParser();
|
||||||
|
|
||||||
|
static AMLParser parse_table(const SDTHeader& header);
|
||||||
|
|
||||||
|
private:
|
||||||
|
AMLParser();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,265 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <BAN/Formatter.h>
|
||||||
|
#include <BAN/Vector.h>
|
||||||
|
#include <BAN/StringView.h>
|
||||||
|
#include <kernel/Debug.h>
|
||||||
|
|
||||||
|
#define DUMP_AML 0
|
||||||
|
|
||||||
|
#if DUMP_AML
|
||||||
|
|
||||||
|
#define AML_DEBUG_CONCAT_IMPL(x, y) x##y
|
||||||
|
#define AML_DEBUG_CONCAT(x, y) AML_DEBUG_CONCAT_IMPL(x, y)
|
||||||
|
#define AML_DEBUG_INDENT_SCOPE() Kernel::ACPI::AML::Indenter AML_DEBUG_CONCAT(indenter, __COUNTER__)
|
||||||
|
|
||||||
|
#define __AML_DEBUG_PRINT_INDENT() \
|
||||||
|
do { \
|
||||||
|
BAN::Formatter::print(Debug::putchar, "{}:{3} ", __BASE_FILE__, __LINE__); \
|
||||||
|
for (size_t i = 1; i < AML::g_depth; i++) \
|
||||||
|
BAN::Formatter::print(Debug::putchar, "│ "); \
|
||||||
|
if (AML::g_depth > 0) \
|
||||||
|
BAN::Formatter::print(Debug::putchar, "├─"); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define AML_DEBUG_PRINT_FN() \
|
||||||
|
__AML_DEBUG_PRINT_INDENT(); \
|
||||||
|
AML_DEBUG_INDENT_SCOPE(); \
|
||||||
|
BAN::Formatter::println(Debug::putchar, "{}", AML::get_class_name(__PRETTY_FUNCTION__))
|
||||||
|
|
||||||
|
#define AML_DEBUG_PRINT(...) \
|
||||||
|
do { \
|
||||||
|
__AML_DEBUG_PRINT_INDENT(); \
|
||||||
|
BAN::Formatter::println(Debug::putchar, __VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define AML_DEBUG_PRINT_FN()
|
||||||
|
#define AML_DEBUG_PRINT(...)
|
||||||
|
#define AML_DEBUG_INDENT_SCOPE()
|
||||||
|
#define __AML_DEBUG_PRINT_INDENT()
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AML_DEBUG_TODO(...) \
|
||||||
|
do { \
|
||||||
|
__AML_DEBUG_PRINT_INDENT(); \
|
||||||
|
BAN::Formatter::print(Debug::putchar, "\e[33mTODO: "); \
|
||||||
|
BAN::Formatter::print(Debug::putchar, __VA_ARGS__); \
|
||||||
|
BAN::Formatter::println(Debug::putchar, "\e[m"); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define AML_DEBUG_ERROR(...) \
|
||||||
|
do { \
|
||||||
|
__AML_DEBUG_PRINT_INDENT(); \
|
||||||
|
BAN::Formatter::print(Debug::putchar, "\e[31m"); \
|
||||||
|
BAN::Formatter::print(Debug::putchar, __VA_ARGS__); \
|
||||||
|
BAN::Formatter::println(Debug::putchar, "\e[m"); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define AML_DEBUG_CANNOT_PARSE(TYPE, SPAN) \
|
||||||
|
do { \
|
||||||
|
__AML_DEBUG_PRINT_INDENT(); \
|
||||||
|
BAN::Formatter::print(Debug::putchar, "\e[31mCannot parse " TYPE " (span {} bytes", SPAN.size()); \
|
||||||
|
if (SPAN.size() > 0) \
|
||||||
|
BAN::Formatter::print(Debug::putchar, ", {2H}", SPAN[0]); \
|
||||||
|
if (SPAN.size() > 1) \
|
||||||
|
BAN::Formatter::print(Debug::putchar, " {2H}", SPAN[1]); \
|
||||||
|
BAN::Formatter::println(Debug::putchar, ")\e[m"); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML
|
||||||
|
{
|
||||||
|
extern size_t g_depth;
|
||||||
|
struct Indenter
|
||||||
|
{
|
||||||
|
Indenter() { g_depth++; }
|
||||||
|
~Indenter() { g_depth--; }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BAN::StringView get_class_name(BAN::StringView pretty_function)
|
||||||
|
{
|
||||||
|
return MUST(MUST(pretty_function.split(' '))[2].split(':'))[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GEN_PARSE_CASE_TODO(NAME) \
|
||||||
|
case AML::Byte::NAME: \
|
||||||
|
AML_DEBUG_TODO(#NAME); \
|
||||||
|
return {};
|
||||||
|
|
||||||
|
#define AML_TRY_PARSE_PACKAGE(NAME) \
|
||||||
|
auto opt_##NAME = AML::PkgLength::parse_package(span); \
|
||||||
|
if (!opt_##NAME.has_value()) \
|
||||||
|
return {}; \
|
||||||
|
auto NAME = opt_##NAME.release_value();
|
||||||
|
|
||||||
|
#define AML_TRY_PARSE(NAME, TYPE, SPAN) \
|
||||||
|
if (!TYPE::can_parse(SPAN)) \
|
||||||
|
{ \
|
||||||
|
AML_DEBUG_CANNOT_PARSE(#TYPE, SPAN); \
|
||||||
|
return {}; \
|
||||||
|
} \
|
||||||
|
auto NAME = TYPE::parse(SPAN); \
|
||||||
|
if (!NAME.has_value()) \
|
||||||
|
return {}
|
||||||
|
|
||||||
|
#define AML_TRY_PARSE_IF_CAN(TYPE) \
|
||||||
|
if (TYPE::can_parse(span)) \
|
||||||
|
{ \
|
||||||
|
if (auto obj = TYPE::parse(span); obj.has_value()) \
|
||||||
|
return obj.release_value(); \
|
||||||
|
return {}; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML {
|
||||||
|
|
||||||
|
enum class Byte : uint8_t
|
||||||
|
{
|
||||||
|
ExtOpPrefix = 0x5B,
|
||||||
|
|
||||||
|
// NamePath
|
||||||
|
DualNamePrefix = 0x2E,
|
||||||
|
MultiNamePrefix = 0x2F,
|
||||||
|
|
||||||
|
// NameSpaceModifierObj
|
||||||
|
AliasOp = 0x06,
|
||||||
|
NameOp = 0x08,
|
||||||
|
ScopeOp = 0x10,
|
||||||
|
|
||||||
|
// ConstObj
|
||||||
|
ZeroOp = 0x00,
|
||||||
|
OneOp = 0x01,
|
||||||
|
OnesOp = 0xFF,
|
||||||
|
|
||||||
|
// ComputationalData
|
||||||
|
BytePrefix = 0x0A,
|
||||||
|
WordPrefix = 0x0B,
|
||||||
|
DWordPrefix = 0x0C,
|
||||||
|
StringPrefix = 0x0D,
|
||||||
|
QWordPrefix = 0x0E,
|
||||||
|
BufferOp = 0x11,
|
||||||
|
ExtRevisionOp = 0x30,
|
||||||
|
|
||||||
|
// DataObject
|
||||||
|
PackageOp = 0x12,
|
||||||
|
VarPackageOp = 0x13,
|
||||||
|
|
||||||
|
// NamedObj
|
||||||
|
ExternalOp = 0x15,
|
||||||
|
CreateDWordFieldOp = 0x8A,
|
||||||
|
CreateWordFieldOp = 0x8B,
|
||||||
|
CreateByteFieldOp = 0x8C,
|
||||||
|
CreateBitFieldOp = 0x8D,
|
||||||
|
CreateQWordFieldOp = 0x8F,
|
||||||
|
ExtCreateFieldOp = 0x13,
|
||||||
|
ExtOpRegionOp = 0x80,
|
||||||
|
ExtProcessorOp = 0x83, // deprecated
|
||||||
|
ExtPowerResOp = 0x84,
|
||||||
|
ExtThermalZoneOp = 0x85,
|
||||||
|
ExtBankFieldOp = 0x87,
|
||||||
|
ExtDataRegionOp = 0x88,
|
||||||
|
// ... not specified
|
||||||
|
MethodOp = 0x14,
|
||||||
|
ExtMutexOp = 0x01,
|
||||||
|
ExtEventOp = 0x02,
|
||||||
|
ExtFieldOp = 0x81,
|
||||||
|
ExtDeviceOp = 0x82,
|
||||||
|
ExtIndexFieldOp = 0x86,
|
||||||
|
|
||||||
|
// StatementOpcode
|
||||||
|
BreakOp = 0xA5,
|
||||||
|
BreakPointOp = 0xCC,
|
||||||
|
ContinueOp = 0x9F,
|
||||||
|
ElseOp = 0xA1,
|
||||||
|
IfOp = 0xA0,
|
||||||
|
NoopOp = 0xA3,
|
||||||
|
NotifyOp = 0x86,
|
||||||
|
ReturnOp = 0xA4,
|
||||||
|
WhileOp = 0xA2,
|
||||||
|
ExtFatalOp = 0x32,
|
||||||
|
ExtReleaseOp = 0x27,
|
||||||
|
ExtResetOp = 0x26,
|
||||||
|
ExtSignalOp = 0x24,
|
||||||
|
ExtSleepOp = 0x22,
|
||||||
|
ExtStallOp = 0x21,
|
||||||
|
|
||||||
|
// ExpressionOpcode
|
||||||
|
//PackageOp = 0x12,
|
||||||
|
//VarPackageOp = 0x13,
|
||||||
|
//BufferOp = 0x11,
|
||||||
|
StoreOp = 0x70,
|
||||||
|
RefOfOp = 0x71,
|
||||||
|
AddOp = 0x72,
|
||||||
|
ConcatOp = 0x73,
|
||||||
|
SubtractOp = 0x74,
|
||||||
|
IncrementOp = 0x75,
|
||||||
|
DecrementOp = 0x76,
|
||||||
|
MultiplyOp = 0x77,
|
||||||
|
DivideOp = 0x78,
|
||||||
|
ShiftLeftOp = 0x79,
|
||||||
|
ShiftRightOp = 0x7A,
|
||||||
|
AndOp = 0x7B,
|
||||||
|
NAndOp = 0x7C,
|
||||||
|
OrOp = 0x7D,
|
||||||
|
NOrOp = 0x7E,
|
||||||
|
XOrOp = 0x7F,
|
||||||
|
NotOp = 0x80,
|
||||||
|
FindSetLeftBitOp = 0x81,
|
||||||
|
FindSetRightBitOp = 0x82,
|
||||||
|
DerefOfOp = 0x83,
|
||||||
|
ConcatResOp = 0x84,
|
||||||
|
ModOp = 0x85,
|
||||||
|
SizeOfOp = 0x87,
|
||||||
|
IndexOp = 0x88,
|
||||||
|
MatchOp = 0x89,
|
||||||
|
ObjectTypeOp = 0x8E,
|
||||||
|
LAndOp = 0x90,
|
||||||
|
LOrOp = 0x91,
|
||||||
|
LNotOp = 0x92,
|
||||||
|
LEqualOp = 0x93,
|
||||||
|
LGreaterOp = 0x94,
|
||||||
|
LLessOp = 0x95,
|
||||||
|
ToBufferOp = 0x96,
|
||||||
|
ToDecimalStringOp = 0x97,
|
||||||
|
ToHexStringOp = 0x98,
|
||||||
|
ToIntegerOp = 0x99,
|
||||||
|
ToStringOp = 0x9C,
|
||||||
|
CopyObjectOp = 0x9D,
|
||||||
|
MidOp = 0x9E,
|
||||||
|
ExtCondRefOfOp = 0x12,
|
||||||
|
ExtLoadTableOp = 0x1F,
|
||||||
|
ExtLoadOp = 0x20,
|
||||||
|
ExtAcquireOp = 0x23,
|
||||||
|
ExtWaitOp = 0x25,
|
||||||
|
ExtFromBCDOp = 0x28,
|
||||||
|
ExtToBCDOp = 0x29,
|
||||||
|
ExtTimerOp = 0x33,
|
||||||
|
|
||||||
|
// LocalObj
|
||||||
|
Local0Op = 0x60,
|
||||||
|
Local1Op = 0x61,
|
||||||
|
Local2Op = 0x62,
|
||||||
|
Local3Op = 0x63,
|
||||||
|
Local4Op = 0x64,
|
||||||
|
Local5Op = 0x65,
|
||||||
|
Local6Op = 0x66,
|
||||||
|
Local7Op = 0x67,
|
||||||
|
|
||||||
|
// ArgObj
|
||||||
|
Arg0Op = 0x68,
|
||||||
|
Arg1Op = 0x69,
|
||||||
|
Arg2Op = 0x6A,
|
||||||
|
Arg3Op = 0x6B,
|
||||||
|
Arg4Op = 0x6C,
|
||||||
|
Arg5Op = 0x6D,
|
||||||
|
Arg6Op = 0x6E,
|
||||||
|
|
||||||
|
// DebugObj
|
||||||
|
ExtDebugOp = 0x31,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <BAN/ByteSpan.h>
|
||||||
|
#include <BAN/Optional.h>
|
||||||
|
#include <BAN/String.h>
|
||||||
|
#include <BAN/UniqPtr.h>
|
||||||
|
#include <BAN/Variant.h>
|
||||||
|
#include <BAN/Vector.h>
|
||||||
|
#include <kernel/ACPI/AML/NameObject.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML
|
||||||
|
{
|
||||||
|
// ACPI Spec 6.4, Section 20.2.3
|
||||||
|
|
||||||
|
// Integer := ByteConst | WordConst | DWordConst | QWordConst
|
||||||
|
// Not actually defined in the spec...
|
||||||
|
struct Integer
|
||||||
|
{
|
||||||
|
uint64_t value;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<Integer> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Buffer := BufferOp PkgLength BufferSize ByteList
|
||||||
|
struct Buffer
|
||||||
|
{
|
||||||
|
Integer buffer_size;
|
||||||
|
BAN::Vector<uint8_t> data;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<Buffer> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ComputationalData := Integer | String | ConstObj | RevisionOp | DefBuffer
|
||||||
|
struct ComputationalData
|
||||||
|
{
|
||||||
|
struct String
|
||||||
|
{
|
||||||
|
BAN::String value;
|
||||||
|
};
|
||||||
|
struct ConstObj
|
||||||
|
{
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
Zero,
|
||||||
|
One,
|
||||||
|
Ones
|
||||||
|
};
|
||||||
|
Type type;
|
||||||
|
};
|
||||||
|
struct RevisionOp {};
|
||||||
|
|
||||||
|
BAN::Variant<Integer, String, ConstObj, RevisionOp, Buffer> data;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<ComputationalData> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DataRefObject;
|
||||||
|
|
||||||
|
// PackageElement := DataRefObject | NameString
|
||||||
|
using PackageElement = BAN::Variant<BAN::UniqPtr<DataRefObject>, NameString>;
|
||||||
|
|
||||||
|
// DefPackage := PackageOp PkgLength NumElements PackageElementList
|
||||||
|
struct Package
|
||||||
|
{
|
||||||
|
BAN::Vector<PackageElement> elements;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<Package> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
// DefVarPackage := VarPackageOp PkgLength VarNumElements PackageElementList
|
||||||
|
struct VarPackage
|
||||||
|
{
|
||||||
|
BAN::Vector<PackageElement> elements;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<VarPackage> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
// DataObject := ComputationalData | DefPackage | DefVarPackage
|
||||||
|
struct DataObject
|
||||||
|
{
|
||||||
|
BAN::Variant<ComputationalData, Package, VarPackage> data;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<DataObject> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
// DataRefObject := DataObject | ObjectReference
|
||||||
|
struct DataRefObject
|
||||||
|
{
|
||||||
|
BAN::Variant<DataObject, Integer> object;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<DataRefObject> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <BAN/ByteSpan.h>
|
||||||
|
#include <BAN/Optional.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML
|
||||||
|
{
|
||||||
|
// ACPI Spec 6.4, Section 20.2.6
|
||||||
|
|
||||||
|
// ArgObj := Arg0Op | Arg1Op | Arg2Op | Arg3Op | Arg4Op | Arg5Op | Arg6Op
|
||||||
|
struct ArgObj
|
||||||
|
{
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
Arg0,
|
||||||
|
Arg1,
|
||||||
|
Arg2,
|
||||||
|
Arg3,
|
||||||
|
Arg4,
|
||||||
|
Arg5,
|
||||||
|
Arg6,
|
||||||
|
};
|
||||||
|
Type type;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<ArgObj> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
// LocalObj := Local0Op | Local1Op | Local2Op | Local3Op | Local4Op | Local5Op | Local6Op | Local7Op
|
||||||
|
struct LocalObj
|
||||||
|
{
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
Local0,
|
||||||
|
Local1,
|
||||||
|
Local2,
|
||||||
|
Local3,
|
||||||
|
Local4,
|
||||||
|
Local5,
|
||||||
|
Local6,
|
||||||
|
Local7,
|
||||||
|
};
|
||||||
|
Type type;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<LocalObj> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
// DebugObj := DebugOp
|
||||||
|
struct DebugObj
|
||||||
|
{
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<DebugObj> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <BAN/ByteSpan.h>
|
||||||
|
#include <BAN/Optional.h>
|
||||||
|
#include <BAN/String.h>
|
||||||
|
#include <BAN/UniqPtr.h>
|
||||||
|
#include <BAN/Variant.h>
|
||||||
|
#include <BAN/Vector.h>
|
||||||
|
#include <kernel/ACPI/AML/MiscObject.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML
|
||||||
|
{
|
||||||
|
// ACPI Spec 6.4, Section 20.2.2
|
||||||
|
|
||||||
|
// NameSeg := LeadNameChar NameChar NameChar NameChar
|
||||||
|
// NameString := ('\' | {'^'}) (NameSeg | (DualNamePrefix NameSeg NameSeg) | (MultiNamePrefix SegCount NameSeg(SegCount)) | 0x00)
|
||||||
|
struct NameString
|
||||||
|
{
|
||||||
|
BAN::String prefix;
|
||||||
|
BAN::Vector<BAN::String> path;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<NameString> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
// SimpleName := NameString | ArgObj | LocalObj
|
||||||
|
struct SimpleName
|
||||||
|
{
|
||||||
|
BAN::Variant<NameString, ArgObj, LocalObj> name;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<SimpleName> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ReferenceTypeOpcode;
|
||||||
|
|
||||||
|
// SuperName := SimpleName | DebugObj | ReferenceTypeOpcode
|
||||||
|
struct SuperName
|
||||||
|
{
|
||||||
|
BAN::Variant<SimpleName, DebugObj, BAN::UniqPtr<ReferenceTypeOpcode>> name;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan span);
|
||||||
|
static BAN::Optional<SuperName> parse(BAN::ConstByteSpan& span);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <BAN/ByteSpan.h>
|
||||||
|
#include <BAN/Optional.h>
|
||||||
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML
|
||||||
|
{
|
||||||
|
|
||||||
|
struct PkgLength
|
||||||
|
{
|
||||||
|
static BAN::Optional<BAN::ConstByteSpan> parse_package(BAN::ConstByteSpan& span)
|
||||||
|
{
|
||||||
|
if (span.size() < 1)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
uint8_t count = (span[0] >> 6) + 1;
|
||||||
|
if (span.size() < count)
|
||||||
|
return {};
|
||||||
|
if (count > 1 && (span[0] & 0x30))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
uint32_t length = span[0] & 0x3F;
|
||||||
|
for (uint8_t i = 1; i < count; i++)
|
||||||
|
length |= static_cast<uint32_t>(span[i]) << (i * 8 - 4);
|
||||||
|
|
||||||
|
if (span.size() < length)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto result = span.slice(count, length - count);
|
||||||
|
span = span.slice(length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,328 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <BAN/ByteSpan.h>
|
||||||
|
#include <BAN/Optional.h>
|
||||||
|
#include <BAN/UniqPtr.h>
|
||||||
|
#include <BAN/Variant.h>
|
||||||
|
#include <BAN/Vector.h>
|
||||||
|
#include <kernel/ACPI/AML/DataObject.h>
|
||||||
|
#include <kernel/ACPI/AML/MiscObject.h>
|
||||||
|
#include <kernel/ACPI/AML/NameObject.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML
|
||||||
|
{
|
||||||
|
// ACPI Spec 6.4, Section 20.2.5
|
||||||
|
|
||||||
|
struct TermObj;
|
||||||
|
struct TermArg;
|
||||||
|
|
||||||
|
// TermList := Nothing | TermObj TermList
|
||||||
|
struct TermList
|
||||||
|
{
|
||||||
|
BAN::Vector<TermObj> terms;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan);
|
||||||
|
static BAN::Optional<TermList> parse(BAN::ConstByteSpan&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// MethodInvocation := NameString TermArgList
|
||||||
|
struct MethodInvocation
|
||||||
|
{
|
||||||
|
NameString name;
|
||||||
|
BAN::Vector<TermArg> term_args;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan);
|
||||||
|
static BAN::Optional<MethodInvocation> parse(BAN::ConstByteSpan&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ExpressionOpcode := DefAcquire | DefAdd | DefAnd | DefBuffer | DefConcat | DefConcatRes | DefCondRefOf
|
||||||
|
// | DefCopyObject | DefDecrement | DefDerefOf | DefDivide | DefFindSetLeftBit
|
||||||
|
// | DefFindSetRightBit | DefFromBCD | DefIncrement | DefIndex | DefLAnd | DefLEqual
|
||||||
|
// | DefLGreater | DefLGreaterEqual | DefLLess | DefLLessEqual | DefMid | DefLNot
|
||||||
|
// | DefLNotEqual | DefLoadTable | DefLOr | DefMatch | DefMod | DefMultiply | DefNAnd
|
||||||
|
// | DefNOr | DefNot | DefObjectType | DefOr | DefPackage | DefVarPackage | DefRefOf
|
||||||
|
// | DefShiftLeft | DefShiftRight | DefSizeOf | DefStore | DefSubtract | DefTimer
|
||||||
|
// | DefToBCD | DefToBuffer | DefToDecimalString | DefToHexString | DefToInteger
|
||||||
|
// | DefToString | DefWait | DefXOr | MethodInvocation
|
||||||
|
struct ExpressionOpcode
|
||||||
|
{
|
||||||
|
struct UnaryOp
|
||||||
|
{
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
Decrement,
|
||||||
|
Increment,
|
||||||
|
RefOf,
|
||||||
|
SizeOf,
|
||||||
|
};
|
||||||
|
Type type;
|
||||||
|
SuperName object;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BinaryOp
|
||||||
|
{
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
Add,
|
||||||
|
And,
|
||||||
|
Multiply,
|
||||||
|
NAnd,
|
||||||
|
NOr,
|
||||||
|
Or,
|
||||||
|
Subtract,
|
||||||
|
XOr,
|
||||||
|
ShiftLeft,
|
||||||
|
ShiftRight,
|
||||||
|
};
|
||||||
|
Type type;
|
||||||
|
BAN::UniqPtr<TermArg> source1;
|
||||||
|
BAN::UniqPtr<TermArg> source2;
|
||||||
|
SuperName target;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LogicalBinaryOp
|
||||||
|
{
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
And,
|
||||||
|
Equal,
|
||||||
|
Greater,
|
||||||
|
Less,
|
||||||
|
Or,
|
||||||
|
// GreaterEqual, LessEqual, NotEqual handled by Not + LogicalBinaryOp
|
||||||
|
};
|
||||||
|
Type type;
|
||||||
|
BAN::UniqPtr<TermArg> operand1;
|
||||||
|
BAN::UniqPtr<TermArg> operand2;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GEN_OPCODE_STRUCT_OPERAND_TARGET(NAME) struct NAME { BAN::UniqPtr<TermArg> operand; SuperName target; }
|
||||||
|
GEN_OPCODE_STRUCT_OPERAND_TARGET(ToBuffer);
|
||||||
|
GEN_OPCODE_STRUCT_OPERAND_TARGET(ToDecimalString);
|
||||||
|
GEN_OPCODE_STRUCT_OPERAND_TARGET(ToHexString);
|
||||||
|
GEN_OPCODE_STRUCT_OPERAND_TARGET(ToInteger);
|
||||||
|
#undef GEN_OPCODE_STRUCT_OPERAND_TARGET
|
||||||
|
|
||||||
|
struct Acquire
|
||||||
|
{
|
||||||
|
SuperName mutex;
|
||||||
|
uint16_t timeout;
|
||||||
|
};
|
||||||
|
struct Store
|
||||||
|
{
|
||||||
|
BAN::UniqPtr<TermArg> source;
|
||||||
|
SuperName target;
|
||||||
|
};
|
||||||
|
|
||||||
|
BAN::Variant<
|
||||||
|
UnaryOp, BinaryOp, LogicalBinaryOp,
|
||||||
|
ToBuffer, ToDecimalString, ToHexString, ToInteger,
|
||||||
|
Acquire, Buffer, Package, VarPackage, Store, MethodInvocation
|
||||||
|
> opcode;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan);
|
||||||
|
static BAN::Optional<ExpressionOpcode> parse(BAN::ConstByteSpan&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// TermArg := ExpressionOpcode | DataObject | ArgObj | LocalObj
|
||||||
|
struct TermArg
|
||||||
|
{
|
||||||
|
BAN::Variant<ExpressionOpcode, DataObject, ArgObj, LocalObj> arg;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan);
|
||||||
|
static BAN::Optional<TermArg> parse(BAN::ConstByteSpan&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// NameSpaceModifierObj := DefAlias | DefName | DefScope
|
||||||
|
struct NameSpaceModifierObj
|
||||||
|
{
|
||||||
|
struct Alias {};
|
||||||
|
struct Name
|
||||||
|
{
|
||||||
|
NameString name;
|
||||||
|
DataRefObject object;
|
||||||
|
};
|
||||||
|
struct Scope
|
||||||
|
{
|
||||||
|
NameString name;
|
||||||
|
TermList term_list;
|
||||||
|
};
|
||||||
|
BAN::Variant<Alias, Name, Scope> modifier;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan);
|
||||||
|
static BAN::Optional<NameSpaceModifierObj> parse(BAN::ConstByteSpan&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// NamedObj := DefBankField | DefCreateBitField | DefCreateByteField | DefCreateDWordField | DefCreateField
|
||||||
|
// | DefCreateQWordField | DefCreateWordField | DefDataRegion | DefExternal | DefOpRegion
|
||||||
|
// | DefProcessor(deprecated) | DefPowerRes | DefThermalZone
|
||||||
|
// Spec does not specify any of DefDevice, DefEvent, DefField, DefIndexField, DefMethod, DefMutex as options
|
||||||
|
struct NamedObj
|
||||||
|
{
|
||||||
|
struct CreateSizedField
|
||||||
|
{
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
Bit,
|
||||||
|
Byte,
|
||||||
|
Word,
|
||||||
|
DWord,
|
||||||
|
QWord,
|
||||||
|
};
|
||||||
|
Type type;
|
||||||
|
TermArg buffer;
|
||||||
|
TermArg index;
|
||||||
|
NameString name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BankField {};
|
||||||
|
struct CreateField {};
|
||||||
|
struct DataRegion {};
|
||||||
|
struct External {};
|
||||||
|
struct OpRegion
|
||||||
|
{
|
||||||
|
enum class RegionSpace : uint8_t
|
||||||
|
{
|
||||||
|
SystemMemory = 0x00,
|
||||||
|
SystemIO = 0x01,
|
||||||
|
PCIConfigSpace = 0x02,
|
||||||
|
EmbeddedController = 0x03,
|
||||||
|
SMBus = 0x04,
|
||||||
|
SystemCMOS = 0x05,
|
||||||
|
PCIBarTarget = 0x06,
|
||||||
|
IPMI = 0x07,
|
||||||
|
GeneralPurposeIO = 0x08,
|
||||||
|
ResourceDescriptor = 0x09,
|
||||||
|
PCC = 0x0A,
|
||||||
|
};
|
||||||
|
|
||||||
|
NameString name;
|
||||||
|
RegionSpace region_space;
|
||||||
|
TermArg region_offset;
|
||||||
|
TermArg region_length;
|
||||||
|
};
|
||||||
|
struct Processor
|
||||||
|
{
|
||||||
|
NameString name;
|
||||||
|
uint8_t processor_id;
|
||||||
|
uint32_t p_blk_address;
|
||||||
|
uint8_t p_blk_length;
|
||||||
|
TermList term_list;
|
||||||
|
};
|
||||||
|
struct PowerRes {};
|
||||||
|
struct ThermalZone {};
|
||||||
|
struct Device
|
||||||
|
{
|
||||||
|
NameString name;
|
||||||
|
TermList term_list;
|
||||||
|
};
|
||||||
|
struct Event {};
|
||||||
|
struct Field
|
||||||
|
{
|
||||||
|
NameString name;
|
||||||
|
// field flags
|
||||||
|
// field list
|
||||||
|
};
|
||||||
|
struct IndexField {};
|
||||||
|
struct Method
|
||||||
|
{
|
||||||
|
NameString name;
|
||||||
|
uint8_t argument_count;
|
||||||
|
bool serialized;
|
||||||
|
uint8_t sync_level;
|
||||||
|
TermList term_list;
|
||||||
|
};
|
||||||
|
struct Mutex
|
||||||
|
{
|
||||||
|
NameString name;
|
||||||
|
uint8_t sync_level;
|
||||||
|
};
|
||||||
|
|
||||||
|
BAN::Variant<BankField, CreateSizedField, CreateField, DataRegion,
|
||||||
|
External, OpRegion, PowerRes, Processor, ThermalZone, Device,
|
||||||
|
Event, Field, IndexField, Method, Mutex
|
||||||
|
> object;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan);
|
||||||
|
static BAN::Optional<NamedObj> parse(BAN::ConstByteSpan&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Object := NameSpaceModifierObj | NamedObj
|
||||||
|
struct Object
|
||||||
|
{
|
||||||
|
BAN::Variant<NameSpaceModifierObj, NamedObj> object;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan);
|
||||||
|
static BAN::Optional<Object> parse(BAN::ConstByteSpan&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// StatementOpcode := DefBreak | DefBreakPoint | DefContinue | DefFatal | DefIfElse | DefNoop | DefNotify
|
||||||
|
// | DefRelease | DefReset | DefReturn | DefSignal | DefSleep | DefStall | DefWhile
|
||||||
|
struct StatementOpcode
|
||||||
|
{
|
||||||
|
struct IfElse
|
||||||
|
{
|
||||||
|
TermArg predicate;
|
||||||
|
TermList true_list;
|
||||||
|
TermList false_list;
|
||||||
|
};
|
||||||
|
struct Notify
|
||||||
|
{
|
||||||
|
SuperName object;
|
||||||
|
TermArg value;
|
||||||
|
};
|
||||||
|
struct Release
|
||||||
|
{
|
||||||
|
SuperName mutex;
|
||||||
|
};
|
||||||
|
struct Return
|
||||||
|
{
|
||||||
|
// TODO: Is argument actually optional?
|
||||||
|
// This is not specified in the spec but it seems like it should be
|
||||||
|
BAN::Optional<DataRefObject> arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
BAN::Variant<IfElse, Notify, Release, Return> opcode;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan);
|
||||||
|
static BAN::Optional<StatementOpcode> parse(BAN::ConstByteSpan&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// TermObj := Object | StatementOpcode | ExpressionOpcode
|
||||||
|
struct TermObj
|
||||||
|
{
|
||||||
|
BAN::Variant<Object, StatementOpcode, ExpressionOpcode> term;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan);
|
||||||
|
static BAN::Optional<TermObj> parse(BAN::ConstByteSpan&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ReferenceTypeOpcode := DefRefOf | DefDerefOf | DefIndex | UserTermObj
|
||||||
|
struct ReferenceTypeOpcode
|
||||||
|
{
|
||||||
|
struct RefOf
|
||||||
|
{
|
||||||
|
SuperName target;
|
||||||
|
};
|
||||||
|
struct DerefOf
|
||||||
|
{
|
||||||
|
TermArg source;
|
||||||
|
};
|
||||||
|
struct Index
|
||||||
|
{
|
||||||
|
TermArg source;
|
||||||
|
TermArg index;
|
||||||
|
SuperName destination;
|
||||||
|
};
|
||||||
|
struct UserTermObj
|
||||||
|
{
|
||||||
|
MethodInvocation method;
|
||||||
|
};
|
||||||
|
|
||||||
|
BAN::Variant<RefOf, DerefOf, Index, UserTermObj> opcode;
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan);
|
||||||
|
static BAN::Optional<ReferenceTypeOpcode> parse(BAN::ConstByteSpan&);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI
|
||||||
|
{
|
||||||
|
|
||||||
|
struct GAS
|
||||||
|
{
|
||||||
|
uint8_t address_space_id;
|
||||||
|
uint8_t register_bit_width;
|
||||||
|
uint8_t register_bit_offset;
|
||||||
|
uint8_t access_size;
|
||||||
|
uint64_t address;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct SDTHeader
|
||||||
|
{
|
||||||
|
uint8_t signature[4];
|
||||||
|
uint32_t length;
|
||||||
|
uint8_t revision;
|
||||||
|
uint8_t checksum;
|
||||||
|
uint8_t oemid[6];
|
||||||
|
uint64_t oem_table_id;
|
||||||
|
uint32_t oem_revision;
|
||||||
|
uint32_t creator_id;
|
||||||
|
uint32_t creator_revision;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct FADT : public SDTHeader
|
||||||
|
{
|
||||||
|
uint32_t firmware_ctrl;
|
||||||
|
uint32_t dsdt;
|
||||||
|
uint8_t __reserved;
|
||||||
|
uint8_t preferred_pm_profile;
|
||||||
|
uint16_t sci_int;
|
||||||
|
uint32_t smi_cmd;
|
||||||
|
uint8_t acpi_enable;
|
||||||
|
uint8_t acpi_disable;
|
||||||
|
uint8_t s4bios_req;
|
||||||
|
uint8_t pstate_cnt;
|
||||||
|
uint32_t pm1a_evt_blk;
|
||||||
|
uint32_t pm1b_evt_blk;
|
||||||
|
uint32_t pm1a_cnt_blk;
|
||||||
|
uint32_t pm1b_cnt_blk;
|
||||||
|
uint32_t pm2_cnt_blk;
|
||||||
|
uint32_t pm_tmr_blk;
|
||||||
|
uint32_t gpe0_blk;
|
||||||
|
uint32_t gpe1_blk;
|
||||||
|
uint8_t pm1_evt_len;
|
||||||
|
uint8_t pm1_cnt_len;
|
||||||
|
uint8_t pm2_cnt_len;
|
||||||
|
uint8_t pm_tmr_len;
|
||||||
|
uint8_t gpe0_blk_len;
|
||||||
|
uint8_t gpe1_blk_len;
|
||||||
|
uint8_t gpe1_base;
|
||||||
|
uint8_t cst_cnt;
|
||||||
|
uint16_t p_lvl2_lat;
|
||||||
|
uint16_t p_lvl3_lat;
|
||||||
|
uint16_t flush_size;
|
||||||
|
uint16_t flush_stride;
|
||||||
|
uint8_t duty_offset;
|
||||||
|
uint8_t duty_width;
|
||||||
|
uint8_t day_alrm;
|
||||||
|
uint8_t mon_alrm;
|
||||||
|
uint8_t century;
|
||||||
|
uint16_t iapc_boot_arch;
|
||||||
|
uint8_t __reserved2;
|
||||||
|
uint32_t flags;
|
||||||
|
uint8_t reset_reg[12];
|
||||||
|
uint8_t reset_value;
|
||||||
|
uint16_t arm_boot_arch;
|
||||||
|
uint8_t fadt_minor_version;
|
||||||
|
uint64_t x_firmware_version;
|
||||||
|
uint64_t x_dsdt;
|
||||||
|
uint8_t x_pm1a_evt_blk[12];
|
||||||
|
uint8_t x_pm1b_evt_blk[12];
|
||||||
|
uint8_t x_pm1a_cnt_blk[12];
|
||||||
|
uint8_t x_pm1b_cnt_blk[12];
|
||||||
|
uint8_t x_pm2_cnt_blk[12];
|
||||||
|
uint8_t x_pm_tmr_blk[12];
|
||||||
|
uint8_t x_gpe0_blk[12];
|
||||||
|
uint8_t x_gpe1_blk[12];
|
||||||
|
uint8_t sleep_control_reg[12];
|
||||||
|
uint8_t sleep_status_reg[12];
|
||||||
|
uint64_t hypervison_vendor_identity;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct HPET : public SDTHeader
|
||||||
|
{
|
||||||
|
uint8_t hardware_rev_id;
|
||||||
|
uint8_t comparator_count : 5;
|
||||||
|
uint8_t count_size_cap : 1;
|
||||||
|
uint8_t reserved : 1;
|
||||||
|
uint8_t legacy_replacement_irq_routing_cable : 1;
|
||||||
|
uint16_t pci_vendor_id;
|
||||||
|
GAS base_address;
|
||||||
|
uint8_t hpet_number;
|
||||||
|
uint16_t main_counter_minimum_clock_tick;
|
||||||
|
uint8_t page_protection_and_oem_attribute;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace BAN::Formatter
|
||||||
|
{
|
||||||
|
template<typename F>
|
||||||
|
void print_argument(F putc, const Kernel::ACPI::SDTHeader& header, const struct ValueFormat&)
|
||||||
|
{
|
||||||
|
putc(header.signature[0]);
|
||||||
|
putc(header.signature[1]);
|
||||||
|
putc(header.signature[2]);
|
||||||
|
putc(header.signature[3]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -93,7 +93,7 @@ namespace Kernel
|
||||||
void on_exit();
|
void on_exit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t m_kernel_stack_size = PAGE_SIZE * 4;
|
static constexpr size_t m_kernel_stack_size = PAGE_SIZE * 64;
|
||||||
static constexpr size_t m_userspace_stack_size = PAGE_SIZE * 4;
|
static constexpr size_t m_userspace_stack_size = PAGE_SIZE * 4;
|
||||||
BAN::UniqPtr<VirtualRange> m_kernel_stack;
|
BAN::UniqPtr<VirtualRange> m_kernel_stack;
|
||||||
BAN::UniqPtr<VirtualRange> m_userspace_stack;
|
BAN::UniqPtr<VirtualRange> m_userspace_stack;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <BAN/ScopeGuard.h>
|
#include <BAN/ScopeGuard.h>
|
||||||
#include <BAN/StringView.h>
|
#include <BAN/StringView.h>
|
||||||
#include <kernel/ACPI.h>
|
#include <kernel/ACPI/ACPI.h>
|
||||||
|
#include <kernel/ACPI/AML.h>
|
||||||
#include <kernel/BootInfo.h>
|
#include <kernel/BootInfo.h>
|
||||||
#include <kernel/Memory/PageTable.h>
|
#include <kernel/Memory/PageTable.h>
|
||||||
|
|
||||||
|
@ -9,15 +10,15 @@
|
||||||
#define RSPD_SIZE 20
|
#define RSPD_SIZE 20
|
||||||
#define RSPDv2_SIZE 36
|
#define RSPDv2_SIZE 36
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel::ACPI
|
||||||
{
|
{
|
||||||
|
|
||||||
struct RSDT : public ACPI::SDTHeader
|
struct RSDT : public SDTHeader
|
||||||
{
|
{
|
||||||
uint32_t entries[];
|
uint32_t entries[];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct XSDT : public ACPI::SDTHeader
|
struct XSDT : public SDTHeader
|
||||||
{
|
{
|
||||||
uint64_t entries[];
|
uint64_t entries[];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
@ -31,6 +32,11 @@ namespace Kernel
|
||||||
if (s_instance == nullptr)
|
if (s_instance == nullptr)
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
TRY(s_instance->initialize_impl());
|
TRY(s_instance->initialize_impl());
|
||||||
|
|
||||||
|
auto dsdt = s_instance->get_header("DSDT", 0);
|
||||||
|
ASSERT(dsdt);
|
||||||
|
AMLParser::parse_table(*dsdt);
|
||||||
|
|
||||||
#if ARCH(x86_64)
|
#if ARCH(x86_64)
|
||||||
lai_create_namespace();
|
lai_create_namespace();
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,7 +88,7 @@ namespace Kernel
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_valid_std_header(const ACPI::SDTHeader* header)
|
static bool is_valid_std_header(const SDTHeader* header)
|
||||||
{
|
{
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
for (uint32_t i = 0; i < header->length; i++)
|
for (uint32_t i = 0; i < header->length; i++)
|
||||||
|
@ -225,7 +231,7 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const ACPI::SDTHeader* ACPI::get_header(BAN::StringView signature, uint32_t index)
|
const SDTHeader* ACPI::get_header(BAN::StringView signature, uint32_t index)
|
||||||
{
|
{
|
||||||
if (signature.size() != 4)
|
if (signature.size() != 4)
|
||||||
{
|
{
|
|
@ -0,0 +1,281 @@
|
||||||
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
|
#include <kernel/ACPI/AML/DataObject.h>
|
||||||
|
#include <kernel/ACPI/AML/PackageLength.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI
|
||||||
|
{
|
||||||
|
|
||||||
|
// Integer
|
||||||
|
|
||||||
|
bool AML::Integer::can_parse(BAN::ConstByteSpan span)
|
||||||
|
{
|
||||||
|
if (span.size() < 1)
|
||||||
|
return false;
|
||||||
|
switch (static_cast<AML::Byte>(span[0]))
|
||||||
|
{
|
||||||
|
case AML::Byte::BytePrefix:
|
||||||
|
case AML::Byte::WordPrefix:
|
||||||
|
case AML::Byte::DWordPrefix:
|
||||||
|
case AML::Byte::QWordPrefix:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Optional<AML::Integer> AML::Integer::parse(BAN::ConstByteSpan& span)
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_FN();
|
||||||
|
ASSERT(can_parse(span));
|
||||||
|
|
||||||
|
switch (static_cast<AML::Byte>(span[0]))
|
||||||
|
{
|
||||||
|
#define AML_PARSE_INTEGER_CASE(TYPE, BYTES) \
|
||||||
|
case AML::Byte::TYPE##Prefix: \
|
||||||
|
{ \
|
||||||
|
span = span.slice(1); \
|
||||||
|
if (span.size() < BYTES) \
|
||||||
|
{ \
|
||||||
|
AML_DEBUG_CANNOT_PARSE(#TYPE, span); \
|
||||||
|
return {}; \
|
||||||
|
} \
|
||||||
|
uint64_t value = 0; \
|
||||||
|
for (size_t i = 0; i < BYTES; i++) \
|
||||||
|
value |= static_cast<uint64_t>(span[i]) << (i * 8); \
|
||||||
|
AML_DEBUG_PRINT("0x{H}", value); \
|
||||||
|
span = span.slice(BYTES); \
|
||||||
|
return Integer { .value = value }; \
|
||||||
|
}
|
||||||
|
AML_PARSE_INTEGER_CASE(Byte, 1)
|
||||||
|
AML_PARSE_INTEGER_CASE(Word, 2)
|
||||||
|
AML_PARSE_INTEGER_CASE(DWord, 4)
|
||||||
|
AML_PARSE_INTEGER_CASE(QWord, 8)
|
||||||
|
#undef AML_PARSE_INTEGER_CASE
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Buffer
|
||||||
|
|
||||||
|
bool AML::Buffer::can_parse(BAN::ConstByteSpan span)
|
||||||
|
{
|
||||||
|
if (span.size() < 1)
|
||||||
|
return false;
|
||||||
|
if (static_cast<AML::Byte>(span[0]) == AML::Byte::BufferOp)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Optional<AML::Buffer> AML::Buffer::parse(BAN::ConstByteSpan& span)
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_FN();
|
||||||
|
ASSERT(can_parse(span));
|
||||||
|
|
||||||
|
span = span.slice(1);
|
||||||
|
|
||||||
|
AML_TRY_PARSE_PACKAGE(buffer_span);
|
||||||
|
|
||||||
|
AML_TRY_PARSE(buffer_size, AML::Integer, buffer_span);
|
||||||
|
|
||||||
|
if (buffer_span.size() < buffer_size->value)
|
||||||
|
{
|
||||||
|
AML_DEBUG_ERROR("Buffer size {} bytes and span only {} bytes", buffer_size->value, buffer_span.size());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Vector<uint8_t> data;
|
||||||
|
MUST(data.resize(buffer_size->value));
|
||||||
|
for (size_t i = 0; i < buffer_size->value; i++)
|
||||||
|
data[i] = buffer_span[i];
|
||||||
|
|
||||||
|
return Buffer { .buffer_size = buffer_size.release_value(), .data = BAN::move(data) };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ComputationalData
|
||||||
|
|
||||||
|
bool AML::ComputationalData::can_parse(BAN::ConstByteSpan span)
|
||||||
|
{
|
||||||
|
if (span.size() < 1)
|
||||||
|
return false;
|
||||||
|
if (static_cast<AML::Byte>(span[0]) == AML::Byte::ExtOpPrefix)
|
||||||
|
{
|
||||||
|
if (span.size() < 2)
|
||||||
|
return false;
|
||||||
|
switch (static_cast<AML::Byte>(span[1]))
|
||||||
|
{
|
||||||
|
case AML::Byte::ExtRevisionOp:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (static_cast<AML::Byte>(span[0]))
|
||||||
|
{
|
||||||
|
case AML::Byte::ZeroOp:
|
||||||
|
case AML::Byte::OneOp:
|
||||||
|
case AML::Byte::OnesOp:
|
||||||
|
case AML::Byte::BytePrefix:
|
||||||
|
case AML::Byte::WordPrefix:
|
||||||
|
case AML::Byte::DWordPrefix:
|
||||||
|
case AML::Byte::StringPrefix:
|
||||||
|
case AML::Byte::QWordPrefix:
|
||||||
|
case AML::Byte::BufferOp:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Optional<AML::ComputationalData> AML::ComputationalData::parse(BAN::ConstByteSpan& span)
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_FN();
|
||||||
|
ASSERT(can_parse(span));
|
||||||
|
|
||||||
|
AML_TRY_PARSE_IF_CAN(AML::Buffer);
|
||||||
|
AML_TRY_PARSE_IF_CAN(AML::Integer);
|
||||||
|
|
||||||
|
switch (static_cast<AML::Byte>(span[0]))
|
||||||
|
{
|
||||||
|
#define AML_PARSE_CONST(TYPE) \
|
||||||
|
case AML::Byte::TYPE##Op: \
|
||||||
|
{ \
|
||||||
|
span = span.slice(1); \
|
||||||
|
AML_DEBUG_PRINT("{}", #TYPE); \
|
||||||
|
return ConstObj { .type = ConstObj::Type::TYPE }; \
|
||||||
|
}
|
||||||
|
AML_PARSE_CONST(Zero);
|
||||||
|
AML_PARSE_CONST(One);
|
||||||
|
AML_PARSE_CONST(Ones);
|
||||||
|
#undef AML_PARSE_CONST
|
||||||
|
case AML::Byte::StringPrefix:
|
||||||
|
{
|
||||||
|
span = span.slice(1);
|
||||||
|
|
||||||
|
BAN::String value;
|
||||||
|
while (span.size() > 0)
|
||||||
|
{
|
||||||
|
if (span[0] == 0x00 || span[0] > 0x7F)
|
||||||
|
break;
|
||||||
|
MUST(value.push_back(span[0]));
|
||||||
|
span = span.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (span.size() == 0 || span[0] != 0x00)
|
||||||
|
return {};
|
||||||
|
span = span.slice(1);
|
||||||
|
|
||||||
|
AML_DEBUG_PRINT("\"{}\"", value);
|
||||||
|
return String { .value = BAN::move(value) };
|
||||||
|
}
|
||||||
|
GEN_PARSE_CASE_TODO(BufferOp)
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define AML_GEN_PACKAGE(NAME) \
|
||||||
|
bool AML::NAME::can_parse(BAN::ConstByteSpan span) \
|
||||||
|
{ \
|
||||||
|
if (span.size() < 1) \
|
||||||
|
return false; \
|
||||||
|
if (static_cast<AML::Byte>(span[0]) == AML::Byte::NAME##Op) \
|
||||||
|
return true; \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
BAN::Optional<AML::NAME> AML::NAME::parse(BAN::ConstByteSpan& span) \
|
||||||
|
{ \
|
||||||
|
AML_DEBUG_PRINT_FN(); \
|
||||||
|
ASSERT(can_parse(span)); \
|
||||||
|
\
|
||||||
|
span = span.slice(1); \
|
||||||
|
\
|
||||||
|
AML_TRY_PARSE_PACKAGE(package_span); \
|
||||||
|
\
|
||||||
|
uint8_t count = package_span[0]; \
|
||||||
|
package_span = package_span.slice(1); \
|
||||||
|
\
|
||||||
|
AML_DEBUG_PRINT("Count: {}", count); \
|
||||||
|
\
|
||||||
|
BAN::Vector<PackageElement> elements; \
|
||||||
|
for (uint8_t i = 0; i < count; i++) \
|
||||||
|
{ \
|
||||||
|
if (DataRefObject::can_parse(package_span)) \
|
||||||
|
{ \
|
||||||
|
AML_TRY_PARSE(element, DataRefObject, package_span); \
|
||||||
|
MUST(elements.push_back(PackageElement { \
|
||||||
|
MUST(BAN::UniqPtr<DataRefObject>::create(element.release_value())) \
|
||||||
|
})); \
|
||||||
|
} \
|
||||||
|
else if (NameString::can_parse(package_span)) \
|
||||||
|
{ \
|
||||||
|
AML_TRY_PARSE(element, NameString, package_span); \
|
||||||
|
MUST(elements.push_back(PackageElement { \
|
||||||
|
element.release_value() \
|
||||||
|
})); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
AML_DEBUG_CANNOT_PARSE("PackageElement", package_span); \
|
||||||
|
return {}; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
return NAME { .elements = BAN::move(elements) }; \
|
||||||
|
}
|
||||||
|
|
||||||
|
AML_GEN_PACKAGE(Package)
|
||||||
|
AML_GEN_PACKAGE(VarPackage)
|
||||||
|
#undef AML_GEN_PACKAGE
|
||||||
|
|
||||||
|
// DataObject
|
||||||
|
|
||||||
|
bool AML::DataObject::can_parse(BAN::ConstByteSpan span)
|
||||||
|
{
|
||||||
|
if (ComputationalData::can_parse(span))
|
||||||
|
return true;
|
||||||
|
if (Package::can_parse(span))
|
||||||
|
return true;
|
||||||
|
if (VarPackage::can_parse(span))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Optional<AML::DataObject> AML::DataObject::parse(BAN::ConstByteSpan& span)
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_FN();
|
||||||
|
ASSERT(can_parse(span));
|
||||||
|
AML_TRY_PARSE_IF_CAN(ComputationalData);
|
||||||
|
AML_TRY_PARSE_IF_CAN(Package);
|
||||||
|
AML_TRY_PARSE_IF_CAN(VarPackage);
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// DataRefObject
|
||||||
|
|
||||||
|
bool AML::DataRefObject::can_parse(BAN::ConstByteSpan span)
|
||||||
|
{
|
||||||
|
if (DataObject::can_parse(span))
|
||||||
|
return true;
|
||||||
|
if (Integer::can_parse(span))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Optional<AML::DataRefObject> AML::DataRefObject::parse(BAN::ConstByteSpan& span)
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_FN();
|
||||||
|
ASSERT(can_parse(span));
|
||||||
|
AML_TRY_PARSE_IF_CAN(DataObject);
|
||||||
|
AML_TRY_PARSE_IF_CAN(Integer);
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
|
#include <kernel/ACPI/AML/MiscObject.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI
|
||||||
|
{
|
||||||
|
|
||||||
|
// ArgObj
|
||||||
|
|
||||||
|
bool AML::ArgObj::can_parse(BAN::ConstByteSpan span)
|
||||||
|
{
|
||||||
|
if (span.size() < 1)
|
||||||
|
return false;
|
||||||
|
switch (static_cast<AML::Byte>(span[0]))
|
||||||
|
{
|
||||||
|
case AML::Byte::Arg0Op:
|
||||||
|
case AML::Byte::Arg1Op:
|
||||||
|
case AML::Byte::Arg2Op:
|
||||||
|
case AML::Byte::Arg3Op:
|
||||||
|
case AML::Byte::Arg4Op:
|
||||||
|
case AML::Byte::Arg5Op:
|
||||||
|
case AML::Byte::Arg6Op:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Optional<AML::ArgObj> AML::ArgObj::parse(BAN::ConstByteSpan& span)
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_FN();
|
||||||
|
ASSERT(can_parse(span));
|
||||||
|
|
||||||
|
uint8_t type = static_cast<uint8_t>(span[0]) - static_cast<uint8_t>(AML::Byte::Arg0Op);
|
||||||
|
span = span.slice(1);
|
||||||
|
|
||||||
|
AML_DEBUG_PRINT("Arg{}", type);
|
||||||
|
|
||||||
|
return ArgObj { .type = static_cast<Type>(type) };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// LocalObj
|
||||||
|
|
||||||
|
bool AML::LocalObj::can_parse(BAN::ConstByteSpan span)
|
||||||
|
{
|
||||||
|
if (span.size() < 1)
|
||||||
|
return false;
|
||||||
|
switch (static_cast<AML::Byte>(span[0]))
|
||||||
|
{
|
||||||
|
case AML::Byte::Local0Op:
|
||||||
|
case AML::Byte::Local1Op:
|
||||||
|
case AML::Byte::Local2Op:
|
||||||
|
case AML::Byte::Local3Op:
|
||||||
|
case AML::Byte::Local4Op:
|
||||||
|
case AML::Byte::Local5Op:
|
||||||
|
case AML::Byte::Local6Op:
|
||||||
|
case AML::Byte::Local7Op:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Optional<AML::LocalObj> AML::LocalObj::parse(BAN::ConstByteSpan& span)
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_FN();
|
||||||
|
ASSERT(can_parse(span));
|
||||||
|
|
||||||
|
uint8_t type = static_cast<uint8_t>(span[0]) - static_cast<uint8_t>(AML::Byte::Local0Op);
|
||||||
|
span = span.slice(1);
|
||||||
|
|
||||||
|
AML_DEBUG_PRINT("Local{}", type);
|
||||||
|
|
||||||
|
return LocalObj { .type = static_cast<Type>(type) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// DebugObj
|
||||||
|
|
||||||
|
bool AML::DebugObj::can_parse(BAN::ConstByteSpan span)
|
||||||
|
{
|
||||||
|
if (span.size() < 2)
|
||||||
|
return false;
|
||||||
|
if (static_cast<AML::Byte>(span[0]) != AML::Byte::ExtOpPrefix)
|
||||||
|
return false;
|
||||||
|
if (static_cast<AML::Byte>(span[1]) != AML::Byte::ExtDebugOp)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Optional<AML::DebugObj> AML::DebugObj::parse(BAN::ConstByteSpan& span)
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_FN();
|
||||||
|
ASSERT(can_parse(span));
|
||||||
|
|
||||||
|
span = span.slice(2);
|
||||||
|
return DebugObj {};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,162 @@
|
||||||
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
|
#include <kernel/ACPI/AML/NameObject.h>
|
||||||
|
#include <kernel/ACPI/AML/TermObject.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI
|
||||||
|
{
|
||||||
|
|
||||||
|
static constexpr bool is_lead_name_char(uint8_t ch)
|
||||||
|
{
|
||||||
|
return ('A' <= ch && ch <= 'Z') || ch == '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr bool is_name_char(uint8_t ch)
|
||||||
|
{
|
||||||
|
return is_lead_name_char(ch) || ('0' <= ch && ch <= '9');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// NameString
|
||||||
|
|
||||||
|
bool AML::NameString::can_parse(BAN::ConstByteSpan span)
|
||||||
|
{
|
||||||
|
if (span.size() < 1)
|
||||||
|
return false;
|
||||||
|
if (span[0] == '\\' || span[0] == '^' || span[0] == 0x00)
|
||||||
|
return true;
|
||||||
|
if (static_cast<AML::Byte>(span[0]) == AML::Byte::DualNamePrefix)
|
||||||
|
return true;
|
||||||
|
if (static_cast<AML::Byte>(span[0]) == AML::Byte::MultiNamePrefix)
|
||||||
|
return true;
|
||||||
|
if (is_lead_name_char(span[0]))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Optional<AML::NameString> AML::NameString::parse(BAN::ConstByteSpan& span)
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_FN();
|
||||||
|
ASSERT(can_parse(span));
|
||||||
|
|
||||||
|
NameString name_string;
|
||||||
|
|
||||||
|
if (span[0] == '\\')
|
||||||
|
{
|
||||||
|
MUST(name_string.prefix.push_back('\\'));
|
||||||
|
span = span.slice(1);
|
||||||
|
}
|
||||||
|
else if (span[0] == '^')
|
||||||
|
{
|
||||||
|
while (span[0] == '^')
|
||||||
|
{
|
||||||
|
MUST(name_string.prefix.push_back('^'));
|
||||||
|
span = span.slice(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t name_count = 1;
|
||||||
|
switch (span[0])
|
||||||
|
{
|
||||||
|
case 0x00:
|
||||||
|
name_count = 0;
|
||||||
|
span = span.slice(1);
|
||||||
|
break;
|
||||||
|
case static_cast<uint8_t>(AML::Byte::DualNamePrefix):
|
||||||
|
name_count = 2;
|
||||||
|
span = span.slice(1);
|
||||||
|
break;
|
||||||
|
case static_cast<uint8_t>(AML::Byte::MultiNamePrefix):
|
||||||
|
name_count = span[1];
|
||||||
|
span = span.slice(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (span.size() < name_count * 4)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
MUST(name_string.path.resize(name_count));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < name_count; i++)
|
||||||
|
{
|
||||||
|
if (!is_lead_name_char(span[0]) || !is_name_char(span[1]) || !is_name_char(span[2]) || !is_name_char(span[3]))
|
||||||
|
{
|
||||||
|
AML_DEBUG_ERROR("Invalid NameSeg {2H} {2H} {2H} {2H}", span[0], span[1], span[2], span[3]);
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
MUST(name_string.path[i].append(BAN::StringView(reinterpret_cast<const char*>(span.data()), 4)));
|
||||||
|
while (name_string.path[i].back() == '_')
|
||||||
|
name_string.path[i].pop_back();
|
||||||
|
span = span.slice(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr(DUMP_AML)
|
||||||
|
{
|
||||||
|
BAN::String full_string;
|
||||||
|
MUST(full_string.append(name_string.prefix));
|
||||||
|
for (size_t i = 0; i < name_string.path.size(); i++)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
MUST(full_string.push_back('.'));
|
||||||
|
MUST(full_string.append(name_string.path[i]));
|
||||||
|
}
|
||||||
|
AML_DEBUG_PRINT("'{}'", full_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SimpleName
|
||||||
|
|
||||||
|
bool AML::SimpleName::can_parse(BAN::ConstByteSpan span)
|
||||||
|
{
|
||||||
|
if (NameString::can_parse(span))
|
||||||
|
return true;
|
||||||
|
if (ArgObj::can_parse(span))
|
||||||
|
return true;
|
||||||
|
if (LocalObj::can_parse(span))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Optional<AML::SimpleName> AML::SimpleName::parse(BAN::ConstByteSpan& span)
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_FN();
|
||||||
|
ASSERT(can_parse(span));
|
||||||
|
AML_TRY_PARSE_IF_CAN(NameString);
|
||||||
|
AML_TRY_PARSE_IF_CAN(ArgObj);
|
||||||
|
AML_TRY_PARSE_IF_CAN(LocalObj);
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SuperName
|
||||||
|
|
||||||
|
bool AML::SuperName::can_parse(BAN::ConstByteSpan span)
|
||||||
|
{
|
||||||
|
if (SimpleName::can_parse(span))
|
||||||
|
return true;
|
||||||
|
if (DebugObj::can_parse(span))
|
||||||
|
return true;
|
||||||
|
if (ReferenceTypeOpcode::can_parse(span))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::Optional<AML::SuperName> AML::SuperName::parse(BAN::ConstByteSpan& span)
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_FN();
|
||||||
|
ASSERT(can_parse(span));
|
||||||
|
|
||||||
|
AML_TRY_PARSE_IF_CAN(SimpleName);
|
||||||
|
AML_TRY_PARSE_IF_CAN(DebugObj);
|
||||||
|
|
||||||
|
ASSERT(ReferenceTypeOpcode::can_parse(span));
|
||||||
|
auto opcode = ReferenceTypeOpcode::parse(span);
|
||||||
|
if (!opcode.has_value())
|
||||||
|
return {};
|
||||||
|
return SuperName { .name = MUST(BAN::UniqPtr<ReferenceTypeOpcode>::create(opcode.release_value())) };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
||||||
#include <BAN/ScopeGuard.h>
|
#include <BAN/ScopeGuard.h>
|
||||||
#include <kernel/ACPI.h>
|
#include <kernel/ACPI/ACPI.h>
|
||||||
#include <kernel/APIC.h>
|
#include <kernel/APIC.h>
|
||||||
#include <kernel/CPUID.h>
|
#include <kernel/CPUID.h>
|
||||||
#include <kernel/Debug.h>
|
#include <kernel/Debug.h>
|
||||||
|
@ -132,7 +132,7 @@ namespace Kernel
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MADT* madt = (const MADT*)Kernel::ACPI::get().get_header("APIC"sv, 0);
|
const MADT* madt = (const MADT*)ACPI::ACPI::get().get_header("APIC"sv, 0);
|
||||||
if (madt == nullptr)
|
if (madt == nullptr)
|
||||||
{
|
{
|
||||||
dprintln("Could not find MADT header");
|
dprintln("Could not find MADT header");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <BAN/ScopeGuard.h>
|
#include <BAN/ScopeGuard.h>
|
||||||
#include <kernel/ACPI.h>
|
#include <kernel/ACPI/ACPI.h>
|
||||||
#include <kernel/FS/DevFS/FileSystem.h>
|
#include <kernel/FS/DevFS/FileSystem.h>
|
||||||
#include <kernel/IDT.h>
|
#include <kernel/IDT.h>
|
||||||
#include <kernel/Input/PS2/Config.h>
|
#include <kernel/Input/PS2/Config.h>
|
||||||
|
@ -244,7 +244,7 @@ namespace Kernel::Input
|
||||||
// FIXME: Initialise USB Controllers
|
// FIXME: Initialise USB Controllers
|
||||||
|
|
||||||
// Determine if the PS/2 Controller Exists
|
// Determine if the PS/2 Controller Exists
|
||||||
auto* fadt = static_cast<const ACPI::FADT*>(ACPI::get().get_header("FACP"sv, 0));
|
auto* fadt = static_cast<const ACPI::FADT*>(ACPI::ACPI::get().get_header("FACP"sv, 0));
|
||||||
if (fadt && fadt->revision > 1 && !(fadt->iapc_boot_arch & (1 << 1)))
|
if (fadt && fadt->revision > 1 && !(fadt->iapc_boot_arch & (1 << 1)))
|
||||||
{
|
{
|
||||||
dwarnln_if(DEBUG_PS2, "No PS/2 available");
|
dwarnln_if(DEBUG_PS2, "No PS/2 available");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <BAN/ScopeGuard.h>
|
#include <BAN/ScopeGuard.h>
|
||||||
#include <kernel/ACPI.h>
|
#include <kernel/ACPI/ACPI.h>
|
||||||
#include <kernel/IDT.h>
|
#include <kernel/IDT.h>
|
||||||
#include <kernel/InterruptController.h>
|
#include <kernel/InterruptController.h>
|
||||||
#include <kernel/Memory/PageTable.h>
|
#include <kernel/Memory/PageTable.h>
|
||||||
|
@ -131,7 +131,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> HPET::initialize(bool force_pic)
|
BAN::ErrorOr<void> HPET::initialize(bool force_pic)
|
||||||
{
|
{
|
||||||
auto* header = static_cast<const ACPI::HPET*>(ACPI::get().get_header("HPET"sv, 0));
|
auto* header = static_cast<const ACPI::HPET*>(ACPI::ACPI::get().get_header("HPET"sv, 0));
|
||||||
if (header == nullptr)
|
if (header == nullptr)
|
||||||
return BAN::Error::from_errno(ENODEV);
|
return BAN::Error::from_errno(ENODEV);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include <kernel/ACPI.h>
|
#include <kernel/ACPI/ACPI.h>
|
||||||
#include <kernel/Arch.h>
|
#include <kernel/Arch.h>
|
||||||
#include <kernel/BootInfo.h>
|
#include <kernel/BootInfo.h>
|
||||||
#include <kernel/Debug.h>
|
#include <kernel/Debug.h>
|
||||||
|
@ -116,7 +116,7 @@ extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info)
|
||||||
parse_command_line();
|
parse_command_line();
|
||||||
dprintln("command line parsed, root='{}', console='{}'", cmdline.root, cmdline.console);
|
dprintln("command line parsed, root='{}', console='{}'", cmdline.root, cmdline.console);
|
||||||
|
|
||||||
MUST(ACPI::initialize());
|
MUST(ACPI::ACPI::initialize());
|
||||||
dprintln("ACPI initialized");
|
dprintln("ACPI initialized");
|
||||||
|
|
||||||
InterruptController::initialize(cmdline.force_pic);
|
InterruptController::initialize(cmdline.force_pic);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include <kernel/ACPI.h>
|
#include <kernel/ACPI/ACPI.h>
|
||||||
#include <kernel/IO.h>
|
#include <kernel/IO.h>
|
||||||
#include <kernel/Memory/kmalloc.h>
|
#include <kernel/Memory/kmalloc.h>
|
||||||
#include <kernel/Memory/PageTable.h>
|
#include <kernel/Memory/PageTable.h>
|
||||||
|
@ -51,7 +51,7 @@ void laihost_panic(const char* msg)
|
||||||
|
|
||||||
void* laihost_scan(const char* sig, size_t index)
|
void* laihost_scan(const char* sig, size_t index)
|
||||||
{
|
{
|
||||||
return (void*)ACPI::get().get_header(sig, index);
|
return (void*)ACPI::ACPI::get().get_header(sig, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* laihost_map(size_t address, size_t count)
|
void* laihost_map(size_t address, size_t count)
|
||||||
|
|
Loading…
Reference in New Issue