Issues with loading ACPI tables with LAI
Posted: Thu May 05, 2022 3:41 pm
I have integrated the LAI core AML interpreter (https://github.com/managarm/lai) into my OS but I am having a few problems.
I have tried to create a namespace with:
These are the logs that have occurred when trying to create a namespace:
But the fact the "total bytes for the DSDT table" is about 1.6GB points to a serious problem.
Details:
qemu i386 emulator
32-bit kernel booted with GRUB
Using cross-compiler with libgcc
C++ kernel with C compiled with i686 gcc and C++ compiled with i686 g++
No paging enabled or handled
laihost_scan implementation (all structs such as RSDT are from the forum page):
I should also mention the code which finds the tables works fine as I have tried running them on their own and they locate the relevant tables without a problem.
Thanks!
I have tried to create a namespace with:
Code: Select all
lai_set_acpi_revision(rsdp->Revision);
lai_create_namespace();
I don't know too much about LAI so I don't know how to interpret them, hoping someone with more experience can help here.[ACPI] Discovered table with signature FACP
[ACPI] Discovered table with signature APIC
[ACPI] Discovered table with signature HPET
[ACPI LAI] loaded AML table 'DSDT', total 1634628864 bytes of AML code.
[ACPI LAI WARN] undefined reference PSDT in object mode, aborting
[ACPI LAI WARN] lai_exec_run() failed in lai_populate()
[ACPI LAI] loaded AML table 'SSDT', total 1146310656 bytes of AML code.
[ACPI LAI PANIC] assertion failed: parse_mode == LAI_OBJECT_MODE at src/c/lai/exec.c:3083
But the fact the "total bytes for the DSDT table" is about 1.6GB points to a serious problem.
Details:
qemu i386 emulator
32-bit kernel booted with GRUB
Using cross-compiler with libgcc
C++ kernel with C compiled with i686 gcc and C++ compiled with i686 g++
No paging enabled or handled
laihost_scan implementation (all structs such as RSDT are from the forum page):
Code: Select all
void* locate_rsdp() {
// Start address of EBDA.
uint8_t* ebda = (uint8_t*)0x9FC00;
// Look for RSDP in the bios extended area.
for (uint32_t i = 0; i < 64; i++) {
uint8_t* segment = (ebda + (i * 16));
// Verify signature.
if (verify_signature(segment, 8, "RSD PTR ") == true) {
// RSDP found, return address.
return segment;
}
}
// Address of possible RSDP area.
uint8_t* mba = (uint8_t*)0x000E0000;
for (uint32_t i = 0; i < 8192; i++) {
uint8_t* segment = mba + (i * 16);
// Verify signature.
if (verify_signature(segment, 8, "RSD PTR ") == true) {
// RSDP found, return address.
return segment;
}
}
return NULL;
}
void* laihost_scan(const char* signature, size_t index) {
struct RSDT* rsdp = locate_rsdp();
uint32_t entries = (rsdp->h.Length - sizeof(rsdp->h)) / 4;
uint32_t current_index = 0;
for (uint32_t i = 0; i < entries; i++) {
// Get table of header.
struct SDTHeader* header = rsdp->table_pointers[i];
// Check if signature matches requested table.
if (verify_signature(header, 4, (char*)signature) == true) {
if (index == current_index) return header;
else current_index++;
}
}
return NULL;
}
Thanks!