feat: ACPI parsing improvements, username in process struct + syscalls

This commit is contained in:
2026-03-24 17:17:47 +01:00
parent f902ab48a1
commit 1542e80a3f
14 changed files with 176 additions and 43 deletions
+1 -2
View File
@@ -1652,8 +1652,7 @@ namespace Hal {
}
if (space == RegionSpace::PciConfig) {
// PCI config space access — address encodes bus/dev/func/offset
// Not implemented yet; would need PCI config read support
// PCI config space access -- not yet implemented
return false;
}
+68 -27
View File
@@ -6,29 +6,74 @@
#include "AmlNamespace.hpp"
#include <Libraries/Memory.hpp>
#include <Memory/Heap.hpp>
namespace Hal {
namespace AML {
Namespace::Namespace() : m_nodeCount(0) {
for (int i = 0; i < MaxNamespaceNodes; i++)
m_nodes[i].Clear();
Namespace::Namespace() : m_chunkCount(0), m_nodeCount(0) {
for (int i = 0; i < MaxChunks; i++)
m_chunks[i] = nullptr;
// Root node is created lazily by the first CreateNode/AllocNode call,
// which happens during LoadTable -- after the kernel heap is ready.
}
// Create root node "\"
void Namespace::EnsureRoot() {
if (m_nodeCount > 0) return;
int32_t root = AllocNode();
m_nodes[root].Name[0] = '\\';
m_nodes[root].Name[1] = '\0';
m_nodes[root].ParentIndex = -1;
auto* rootNode = GetNode(root);
if (rootNode) {
rootNode->Name[0] = '\\';
rootNode->Name[1] = '\0';
rootNode->ParentIndex = -1;
}
}
bool Namespace::AllocChunk() {
if (m_chunkCount >= MaxChunks) return false;
auto* chunk = (NamespaceNode*)Memory::g_heap->Request(
sizeof(NamespaceNode) * NodesPerChunk);
if (!chunk) return false;
// Zero-initialize the chunk
memset(chunk, 0, sizeof(NamespaceNode) * NodesPerChunk);
for (int i = 0; i < NodesPerChunk; i++)
chunk[i].Clear();
m_chunks[m_chunkCount++] = chunk;
return true;
}
int32_t Namespace::AllocNode() {
if (m_nodeCount >= MaxNamespaceNodes)
return -1;
// Check if we need a new chunk
int32_t capacity = m_chunkCount * NodesPerChunk;
if (m_nodeCount >= capacity) {
if (!AllocChunk()) return -1;
}
int32_t idx = m_nodeCount++;
m_nodes[idx].Clear();
auto* node = GetNode(idx);
if (node) node->Clear();
return idx;
}
NamespaceNode* Namespace::GetNode(int32_t index) {
if (index < 0 || index >= m_nodeCount) return nullptr;
int chunk = index / NodesPerChunk;
int offset = index % NodesPerChunk;
if (chunk >= m_chunkCount || !m_chunks[chunk]) return nullptr;
return &m_chunks[chunk][offset];
}
const NamespaceNode* Namespace::GetNode(int32_t index) const {
if (index < 0 || index >= m_nodeCount) return nullptr;
int chunk = index / NodesPerChunk;
int offset = index % NodesPerChunk;
if (chunk >= m_chunkCount || !m_chunks[chunk]) return nullptr;
return &m_chunks[chunk][offset];
}
bool Namespace::SegmentEqual(const char* a, const char* b) {
for (int i = 0; i < MaxNameSegLen; i++) {
char ca = a[i] ? a[i] : '_';
@@ -63,7 +108,7 @@ namespace Hal {
while (*p && count < maxSegments) {
// Skip dots (parent prefix / dual/multi name prefix separator)
if (*p == '.') { p++; continue; }
// Skip caret (parent prefix) we don't handle relative paths here
// Skip caret (parent prefix) -- we don't handle relative paths here
if (*p == '^') { p++; continue; }
// Read up to 4 characters for a name segment
@@ -91,14 +136,16 @@ namespace Hal {
for (int32_t i = 0; i < parent->ChildCount; i++) {
int32_t ci = parent->ChildIndices[i];
if (ci < 0 || ci >= m_nodeCount) continue;
if (SegmentEqual(m_nodes[ci].Name, seg))
auto* child = GetNode(ci);
if (!child) continue;
if (SegmentEqual(child->Name, seg))
return ci;
}
return -1;
}
int32_t Namespace::CreateNode(const char* absolutePath) {
EnsureRoot();
char segments[MaxPathDepth][MaxNameSegLen + 1];
int segCount = ParsePath(absolutePath, segments, MaxPathDepth);
@@ -110,11 +157,14 @@ namespace Hal {
child = AllocNode();
if (child < 0) return -1;
memcpy(m_nodes[child].Name, segments[i], MaxNameSegLen + 1);
m_nodes[child].ParentIndex = current;
auto* childNode = GetNode(child);
if (!childNode) return -1;
memcpy(childNode->Name, segments[i], MaxNameSegLen + 1);
childNode->ParentIndex = current;
// Add to parent's children
auto* parent = &m_nodes[current];
auto* parent = GetNode(current);
if (!parent) return -1;
if (parent->ChildCount < MaxChildren) {
parent->ChildIndices[parent->ChildCount++] = child;
} else {
@@ -151,22 +201,13 @@ namespace Hal {
while (scope >= 0) {
int32_t found = FindChildByName(scope, padded);
if (found >= 0) return found;
scope = m_nodes[scope].ParentIndex;
auto* node = GetNode(scope);
scope = node ? node->ParentIndex : -1;
}
return -1;
}
NamespaceNode* Namespace::GetNode(int32_t index) {
if (index < 0 || index >= m_nodeCount) return nullptr;
return &m_nodes[index];
}
const NamespaceNode* Namespace::GetNode(int32_t index) const {
if (index < 0 || index >= m_nodeCount) return nullptr;
return &m_nodes[index];
}
char* Namespace::GetNodePath(int32_t index, char* outBuf, int maxLen) const {
if (!outBuf || maxLen < 2) return outBuf;
+16 -5
View File
@@ -55,13 +55,17 @@ namespace Hal {
// ============================================================================
static constexpr int MaxNameSegLen = 4;
static constexpr int MaxPathDepth = 16;
static constexpr int MaxChildren = 32;
static constexpr int MaxChildren = 64;
static constexpr int MaxStringLen = 64;
static constexpr int MaxBufferLen = 256;
static constexpr int MaxPackageElements = 16;
static constexpr int MaxMethodArgs = 7;
static constexpr int MaxMethodLocals = 8;
static constexpr int MaxNamespaceNodes = 256;
// Nodes are allocated dynamically in chunks from the kernel heap.
// Each chunk holds this many nodes; new chunks are allocated on demand.
static constexpr int NodesPerChunk = 256;
static constexpr int MaxChunks = 128; // up to 32768 nodes
// ============================================================================
@@ -143,7 +147,8 @@ namespace Hal {
// Namespace
// ============================================================================
// Flat array of nodes forming a tree via parent/child indices.
// Dynamically-allocated node pool forming a tree via parent/child indices.
// Nodes are allocated in chunks from the kernel heap on demand.
class Namespace {
public:
Namespace();
@@ -174,6 +179,9 @@ namespace Hal {
// Get the number of nodes in the namespace.
int32_t NodeCount() const { return m_nodeCount; }
// Maximum capacity with current chunk limit.
int32_t MaxCapacity() const { return MaxChunks * NodesPerChunk; }
// Iterate children of a node matching a given object type.
// callback returns true to continue, false to stop.
// Returns the index of the node that stopped iteration, or -1.
@@ -208,6 +216,8 @@ namespace Hal {
private:
int32_t AllocNode();
bool AllocChunk();
void EnsureRoot();
int32_t FindChildByName(int32_t parentIndex, const char* seg) const;
// Parse an absolute path into segments. Returns number of segments.
@@ -215,8 +225,9 @@ namespace Hal {
static bool SegmentEqual(const char* a, const char* b);
static void PadSegment(const char* src, char* dst); // pad to 4 chars with '_'
NamespaceNode m_nodes[MaxNamespaceNodes];
int32_t m_nodeCount;
NamespaceNode* m_chunks[MaxChunks]; // array of pointers to heap-allocated chunks
int32_t m_chunkCount;
int32_t m_nodeCount;
};
};
+3
View File
@@ -244,6 +244,9 @@ namespace Hal {
if (!interp.LoadTable(dsdtData)) {
KernelLogStream(ERROR, "AML") << "Failed to load DSDT into AML interpreter";
}
auto& ns = interp.GetNamespace();
KernelLogStream(OK, "AML") << "Namespace: " << base::dec
<< (uint64_t)ns.NodeCount() << " / " << (uint64_t)ns.MaxCapacity() << " nodes (dynamic)";
}
};
+21
View File
@@ -99,4 +99,25 @@ namespace Montauk {
static int Sys_Kill(int pid) {
return Sched::KillProcess(pid);
}
static int Sys_SetUser(int pid, const char* name) {
if (name == nullptr) return -1;
auto* target = Sched::GetProcessByPid(pid);
if (target == nullptr) return -1;
int i = 0;
for (; i < 31 && name[i]; i++)
target->user[i] = name[i];
target->user[i] = '\0';
return 0;
}
static int Sys_GetUser(char* buf, uint64_t maxLen) {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr || buf == nullptr || maxLen == 0) return -1;
int i = 0;
for (; i < (int)maxLen - 1 && proc->user[i]; i++)
buf[i] = proc->user[i];
buf[i] = '\0';
return i;
}
};
+10
View File
@@ -178,6 +178,10 @@ namespace Montauk {
static constexpr uint64_t SYS_SETTZ = 90;
static constexpr uint64_t SYS_GETTZ = 91;
/* Process.hpp */
static constexpr uint64_t SYS_SETUSER = 92;
static constexpr uint64_t SYS_GETUSER = 93;
static constexpr int SOCK_TCP = 1;
static constexpr int SOCK_UDP = 2;
@@ -371,6 +375,12 @@ namespace Montauk {
char name[64];
};
struct ThermalInfo {
char name[32]; // short zone name (e.g. "THRM", "TZ00")
int32_t temperature; // tenths of degrees Celsius, or -1 if unavailable
uint32_t _pad;
};
// Stack frame pushed by SyscallEntry.asm
struct SyscallFrame {
uint64_t r15, r14, r13, r12, rbp, rbx; // callee-saved
+18
View File
@@ -90,6 +90,7 @@ namespace Sched {
processTable[i].userStackTop = 0;
processTable[i].heapNext = 0;
processTable[i].args[0] = '\0';
processTable[i].user[0] = '\0';
processTable[i].runningOnCpu = -1;
processTable[i].killPending = false;
processTable[i].waitingForPid = -1;
@@ -283,6 +284,23 @@ namespace Sched {
proc.args[i] = '\0';
}
// Inherit user string from parent, or default to "system" if no parent
{
auto* cpu = Smp::GetCurrentCpuData();
int parentSlot = cpu->currentSlot;
if (parentSlot >= 0) {
int i = 0;
for (; i < 31 && processTable[parentSlot].user[i]; i++)
proc.user[i] = processTable[parentSlot].user[i];
proc.user[i] = '\0';
} else {
// Spawned from kernel (no parent process) - set to "system"
proc.user[0] = 's'; proc.user[1] = 'y'; proc.user[2] = 's';
proc.user[3] = 't'; proc.user[4] = 'e'; proc.user[5] = 'm';
proc.user[6] = '\0';
}
}
proc.redirected = false;
proc.parentPid = -1;
proc.outBuf = nullptr;
+1
View File
@@ -43,6 +43,7 @@ namespace Sched {
uint64_t userStackTop; // User-space stack top
uint64_t heapNext; // Simple bump allocator for user heap
char args[256]; // Command-line arguments (set by parent via Spawn)
char user[32]; // Owner user name (inherited from parent on spawn)
int runningOnCpu; // CPU index running this process (-1 if not running)
bool killPending = false; // Set by Sys_Kill when target is running on another CPU