feat: S3 sleep, PDF viewer graphics rendering, live user environment

This commit is contained in:
2026-03-15 18:46:54 +01:00
parent 4c7efa3203
commit 94433d679b
26 changed files with 1541 additions and 248 deletions
+110 -22
View File
@@ -17,14 +17,22 @@ using namespace Kt;
namespace Hal {
namespace AML {
// ── Global instance ─────────────────────────────────────────────
// ============================================================================
// Global instance
// ============================================================================
static Interpreter g_interpreter;
Interpreter& GetInterpreter() {
return g_interpreter;
}
// ── Helper: is a byte a lead name character? ────────────────────
// ============================================================================
// Helper: is a byte a lead name character?
// ============================================================================
static bool IsLeadNameChar(uint8_t c) {
return (c >= 'A' && c <= 'Z') || c == '_';
}
@@ -33,11 +41,19 @@ namespace Hal {
return IsLeadNameChar(c) || (c >= '0' && c <= '9');
}
// ── Constructor ─────────────────────────────────────────────────
// ============================================================================
// Constructor
// ============================================================================
Interpreter::Interpreter()
: m_dsdt(nullptr), m_dsdtLength(0), m_initialized(false) {}
// ── PkgLength decoding ──────────────────────────────────────────
// ============================================================================
// PkgLength decoding
// ============================================================================
uint32_t Interpreter::DecodePkgLength(const uint8_t* aml, uint32_t* pos) {
uint8_t lead = aml[*pos];
uint32_t byteCount = (lead >> 6) & 0x03;
@@ -58,7 +74,11 @@ namespace Hal {
return length;
}
// ── Integer decoding (data objects) ─────────────────────────────
// ============================================================================
// Integer decoding (data objects)
// ============================================================================
uint64_t Interpreter::DecodeInteger(const uint8_t* aml, uint32_t* pos) {
uint8_t op = aml[*pos];
@@ -107,7 +127,11 @@ namespace Hal {
}
}
// ── NameSeg reading ─────────────────────────────────────────────
// ============================================================================
// NameSeg reading
// ============================================================================
void Interpreter::ReadNameSeg(const uint8_t* aml, uint32_t* pos, char* outSeg) {
for (int i = 0; i < 4; i++) {
outSeg[i] = (char)aml[*pos + i];
@@ -116,7 +140,11 @@ namespace Hal {
*pos += 4;
}
// ── NameString reading ──────────────────────────────────────────
// ============================================================================
// NameString reading
// ============================================================================
// Reads a NameString (which may include root prefix, parent prefixes,
// dual/multi name prefix) and produces an absolute path.
int Interpreter::ReadNameString(const uint8_t* aml, uint32_t* pos, int32_t scopeNode,
@@ -195,7 +223,11 @@ namespace Hal {
return pathPos;
}
// ── LoadTable ───────────────────────────────────────────────────
// ============================================================================
// LoadTable
// ============================================================================
bool Interpreter::LoadTable(void* tableData) {
auto* header = (ACPI::CommonSDTHeader*)tableData;
@@ -231,7 +263,11 @@ namespace Hal {
return result;
}
// ── ParseBlock ──────────────────────────────────────────────────
// ============================================================================
// ParseBlock
// ============================================================================
// Parse a block of AML opcodes, creating namespace objects.
bool Interpreter::ParseBlock(const uint8_t* aml, uint32_t offset, uint32_t endOffset,
int32_t scopeNode) {
@@ -332,7 +368,11 @@ namespace Hal {
return true;
}
// ── ParseNamedObject ────────────────────────────────────────────
// ============================================================================
// ParseNamedObject
// ============================================================================
bool Interpreter::ParseNamedObject(const uint8_t* aml, uint32_t* pos, uint32_t endOffset,
int32_t scopeNode) {
uint8_t op = aml[*pos];
@@ -484,7 +524,11 @@ namespace Hal {
return true;
}
// ── ParseExtendedOp ─────────────────────────────────────────────
// ============================================================================
// ParseExtendedOp
// ============================================================================
bool Interpreter::ParseExtendedOp(const uint8_t* aml, uint32_t* pos, uint32_t endOffset,
int32_t scopeNode) {
(*pos)++; // skip ExtOpPrefix
@@ -743,7 +787,11 @@ namespace Hal {
}
}
// ── EvaluateObject ──────────────────────────────────────────────
// ============================================================================
// EvaluateObject
// ============================================================================
bool Interpreter::EvaluateObject(const char* path, Object& result) {
int32_t node = m_ns.FindNode(path);
if (node < 0) return false;
@@ -772,7 +820,11 @@ namespace Hal {
return true;
}
// ── EvaluateMethod ──────────────────────────────────────────────
// ============================================================================
// EvaluateMethod
// ============================================================================
bool Interpreter::EvaluateMethod(const char* path, const Object* args, int argCount,
Object& result) {
int32_t node = m_ns.FindNode(path);
@@ -812,7 +864,11 @@ namespace Hal {
return ok;
}
// ── ExecuteBlock ────────────────────────────────────────────────
// ============================================================================
// ExecuteBlock
// ============================================================================
bool Interpreter::ExecuteBlock(ExecContext& ctx, uint32_t offset, uint32_t endOffset) {
uint32_t pos = offset;
@@ -824,7 +880,11 @@ namespace Hal {
return true;
}
// ── ExecuteOpcode ───────────────────────────────────────────────
// ============================================================================
// ExecuteOpcode
// ============================================================================
bool Interpreter::ExecuteOpcode(ExecContext& ctx, uint32_t* pos, uint32_t endOffset) {
if (*pos >= endOffset) return true;
@@ -1015,7 +1075,11 @@ namespace Hal {
return EvalTerm(ctx, pos, endOffset, discard);
}
// ── EvalTerm ────────────────────────────────────────────────────
// ============================================================================
// EvalTerm
// ============================================================================
// Evaluate an AML term that produces a value.
bool Interpreter::EvalTerm(ExecContext& ctx, uint32_t* pos, uint32_t endOffset,
Object& result) {
@@ -1412,7 +1476,11 @@ namespace Hal {
return true;
}
// ── EvalTarget ──────────────────────────────────────────────────
// ============================================================================
// EvalTarget
// ============================================================================
bool Interpreter::EvalTarget(ExecContext& ctx, uint32_t* pos,
int32_t& nodeIndex, bool& isLocal, int& localIdx,
bool& isArg, int& argIdx) {
@@ -1464,7 +1532,11 @@ namespace Hal {
return true;
}
// ── StoreToTarget ───────────────────────────────────────────────
// ============================================================================
// StoreToTarget
// ============================================================================
void Interpreter::StoreToTarget(ExecContext& ctx, const Object& value,
int32_t nodeIndex, bool isLocal, int localIdx,
bool isArg, int argIdx) {
@@ -1484,7 +1556,11 @@ namespace Hal {
}
}
// ── ReadField ───────────────────────────────────────────────────
// ============================================================================
// ReadField
// ============================================================================
bool Interpreter::ReadField(int32_t nodeIndex, uint64_t& value) {
auto* node = m_ns.GetNode(nodeIndex);
if (!node || node->Obj.Type != ObjectType::Field) return false;
@@ -1505,7 +1581,11 @@ namespace Hal {
return ReadRegion(regionNode->Obj.Region.Space, byteAddr, bitLen + bitShift, value);
}
// ── WriteField ──────────────────────────────────────────────────
// ============================================================================
// WriteField
// ============================================================================
bool Interpreter::WriteField(int32_t nodeIndex, uint64_t value) {
auto* node = m_ns.GetNode(nodeIndex);
if (!node || node->Obj.Type != ObjectType::Field) return false;
@@ -1534,7 +1614,11 @@ namespace Hal {
return WriteRegion(regionNode->Obj.Region.Space, byteAddr, bitLen + bitShift, value);
}
// ── ReadRegion ──────────────────────────────────────────────────
// ============================================================================
// ReadRegion
// ============================================================================
bool Interpreter::ReadRegion(RegionSpace space, uint64_t address, uint32_t bitWidth,
uint64_t& value) {
value = 0;
@@ -1576,7 +1660,11 @@ namespace Hal {
return false;
}
// ── WriteRegion ─────────────────────────────────────────────────
// ============================================================================
// WriteRegion
// ============================================================================
bool Interpreter::WriteRegion(RegionSpace space, uint64_t address, uint32_t bitWidth,
uint64_t value) {
uint32_t accessBytes = (bitWidth + 7) / 8;
+48 -10
View File
@@ -12,7 +12,11 @@
namespace Hal {
namespace AML {
// ── Extended AML Opcodes ────────────────────────────────────────
// ============================================================================
// Extended AML Opcodes
// ============================================================================
// Single-byte opcodes
static constexpr uint8_t ZeroOp = 0x00;
static constexpr uint8_t OneOp = 0x01;
@@ -93,11 +97,19 @@ namespace Hal {
static constexpr uint8_t ToHexStringOp = 0x98;
static constexpr uint8_t ToDecimalStringOp = 0x97;
// ── Interpreter Configuration ───────────────────────────────────
// ============================================================================
// Interpreter Configuration
// ============================================================================
static constexpr int MaxCallDepth = 16;
static constexpr int MaxLoopIterations = 1024;
// ── Interpreter ─────────────────────────────────────────────────
// ============================================================================
// Interpreter
// ============================================================================
class Interpreter {
public:
Interpreter();
@@ -127,7 +139,9 @@ namespace Hal {
bool IsInitialized() const { return m_initialized; }
private:
// ── Parsing (table load) ────────────────────────────────────
// ============================================================================
// Parsing (table load)
// ============================================================================
bool ParseBlock(const uint8_t* aml, uint32_t offset, uint32_t endOffset,
int32_t scopeNode);
@@ -137,7 +151,11 @@ namespace Hal {
bool ParseExtendedOp(const uint8_t* aml, uint32_t* pos, uint32_t endOffset,
int32_t scopeNode);
// ── Name resolution ─────────────────────────────────────────
// ============================================================================
// Name resolution
// ============================================================================
// Read a NameString from AML and produce an absolute path.
// Advances *pos past the name.
int ReadNameString(const uint8_t* aml, uint32_t* pos, int32_t scopeNode,
@@ -146,11 +164,19 @@ namespace Hal {
// Read a single 4-char NameSeg from AML. Advances *pos.
void ReadNameSeg(const uint8_t* aml, uint32_t* pos, char* outSeg);
// ── Value decoding ──────────────────────────────────────────
// ============================================================================
// Value decoding
// ============================================================================
uint32_t DecodePkgLength(const uint8_t* aml, uint32_t* pos);
uint64_t DecodeInteger(const uint8_t* aml, uint32_t* pos);
// ── Method execution ────────────────────────────────────────
// ============================================================================
// Method execution
// ============================================================================
struct ExecContext {
const uint8_t* Aml;
uint32_t AmlBase; // start of the block within the table
@@ -182,18 +208,30 @@ namespace Hal {
int32_t nodeIndex, bool isLocal, int localIdx,
bool isArg, int argIdx);
// ── Field I/O ───────────────────────────────────────────────
// ============================================================================
// Field I/O
// ============================================================================
bool ReadRegion(RegionSpace space, uint64_t address, uint32_t bitWidth, uint64_t& value);
bool WriteRegion(RegionSpace space, uint64_t address, uint32_t bitWidth, uint64_t value);
// ── State ───────────────────────────────────────────────────
// ============================================================================
// State
// ============================================================================
Namespace m_ns;
const uint8_t* m_dsdt;
uint32_t m_dsdtLength;
bool m_initialized;
};
// ── Global interpreter instance ─────────────────────────────────
// ============================================================================
// Global interpreter instance
// ============================================================================
Interpreter& GetInterpreter();
};
+30 -6
View File
@@ -11,7 +11,11 @@
namespace Hal {
namespace AML {
// ── AML Object Types ────────────────────────────────────────────
// ============================================================================
// AML Object Types
// ============================================================================
enum class ObjectType : uint8_t {
None = 0,
Integer,
@@ -29,7 +33,11 @@ namespace Hal {
BufferField,
};
// ── Region address spaces (OperationRegion) ─────────────────────
// ============================================================================
// Region address spaces (OperationRegion)
// ============================================================================
enum class RegionSpace : uint8_t {
SystemMemory = 0x00,
SystemIO = 0x01,
@@ -40,7 +48,11 @@ namespace Hal {
PciBarTarget = 0x06,
};
// ── Constants ───────────────────────────────────────────────────
// ============================================================================
// Constants
// ============================================================================
static constexpr int MaxNameSegLen = 4;
static constexpr int MaxPathDepth = 16;
static constexpr int MaxChildren = 32;
@@ -51,7 +63,11 @@ namespace Hal {
static constexpr int MaxMethodLocals = 8;
static constexpr int MaxNamespaceNodes = 256;
// ── AML Object ──────────────────────────────────────────────────
// ============================================================================
// AML Object
// ============================================================================
// Tagged union representing any AML value. Kept small for kernel use.
struct Object {
ObjectType Type = ObjectType::None;
@@ -99,7 +115,11 @@ namespace Hal {
Object() : Type(ObjectType::None), Integer(0) {}
};
// ── Namespace Node ──────────────────────────────────────────────
// ============================================================================
// Namespace Node
// ============================================================================
// Each node has a 4-char name segment and an associated object.
struct NamespaceNode {
char Name[MaxNameSegLen + 1]; // null-terminated 4-char segment
@@ -118,7 +138,11 @@ namespace Hal {
}
};
// ── Namespace ───────────────────────────────────────────────────
// ============================================================================
// Namespace
// ============================================================================
// Flat array of nodes forming a tree via parent/child indices.
class Namespace {
public:
+15 -3
View File
@@ -15,7 +15,11 @@ using namespace Kt;
namespace Hal {
namespace AML {
// ── Legacy S5 extraction (brute-force scan) ─────────────────────
// ============================================================================
// Legacy S5 extraction (brute-force scan)
// ============================================================================
// Kept for fast S5 extraction during early boot before the full
// interpreter is loaded.
@@ -158,7 +162,11 @@ namespace Hal {
return result;
}
// ── Generalized brute-force sleep state scanner ──────────────────
// ============================================================================
// Generalized brute-force sleep state scanner
// ============================================================================
SleepObject FindSleepState(void* dsdtData, int state) {
SleepObject result{};
result.Valid = false;
@@ -226,7 +234,11 @@ namespace Hal {
return result;
}
// ── Full interpreter initialization ─────────────────────────────
// ============================================================================
// Full interpreter initialization
// ============================================================================
void InitializeInterpreter(void* dsdtData) {
auto& interp = GetInterpreter();
if (!interp.LoadTable(dsdtData)) {
+16 -4
View File
@@ -9,14 +9,22 @@
namespace Hal {
namespace AML {
// ── Small Resource Tags (bits 6:3 of the tag byte) ──────────────
// ============================================================================
// Small Resource Tags (bits 6:3 of the tag byte)
// ============================================================================
static constexpr uint8_t SmallIrqTag = 0x04; // IRQ descriptor
static constexpr uint8_t SmallDmaTag = 0x05; // DMA descriptor
static constexpr uint8_t SmallIoPortTag = 0x08; // I/O port descriptor
static constexpr uint8_t SmallFixedIoTag = 0x09; // Fixed I/O port descriptor
static constexpr uint8_t SmallEndTag = 0x0F; // End tag
// ── Large Resource Tags (byte following the large tag prefix) ───
// ============================================================================
// Large Resource Tags (byte following the large tag prefix)
// ============================================================================
static constexpr uint8_t LargeMemory24Tag = 0x01;
static constexpr uint8_t LargeVendorTag = 0x04;
static constexpr uint8_t LargeMemory32Tag = 0x05;
@@ -63,7 +71,9 @@ namespace Hal {
break;
if (tag & 0x80) {
// ── Large resource descriptor ───────────────────────
// ============================================================================
// Large resource descriptor
// ============================================================================
uint8_t largeType = tag & 0x7F;
if (pos + 3 > length) break;
uint16_t resLen = Read16(&data[pos + 1]);
@@ -154,7 +164,9 @@ namespace Hal {
pos = dataEnd;
} else {
// ── Small resource descriptor ───────────────────────
// ============================================================================
// Small resource descriptor
// ============================================================================
uint8_t smallType = (tag >> 3) & 0x0F;
uint8_t resLen = tag & 0x07;
uint32_t dataStart = pos + 1;
+15 -3
View File
@@ -10,7 +10,11 @@
namespace Hal {
namespace AML {
// ── Resource Types ──────────────────────────────────────────────
// ============================================================================
// Resource Types
// ============================================================================
enum class ResourceType : uint8_t {
None = 0,
Irq,
@@ -27,7 +31,11 @@ namespace Hal {
GpioConnection,
};
// ── Single Resource Descriptor ──────────────────────────────────
// ============================================================================
// Single Resource Descriptor
// ============================================================================
struct ResourceDescriptor {
ResourceType Type;
@@ -82,7 +90,11 @@ namespace Hal {
}
};
// ── Parsed Resource List ────────────────────────────────────────
// ============================================================================
// Parsed Resource List
// ============================================================================
static constexpr int MaxResources = 16;
struct ResourceList {