[Solved] LAI / QEMU / OVMF - No DSDT table
[Solved] LAI / QEMU / OVMF - No DSDT table
I am in the process of integrating LAI (https://github.com/managarm/lai) into my OS and have run into an issue. It appears there is no DSDT table in my firmware and LAI needs it.
This is under QEMU. Firmware is OVMF. I have enumerated all tables from the RSDT and from the XSDT. In both cases I do not find any DSDT table.
LAI complains with "unable to find ACPI DSDT." in lai_create_namespace().
Is there a trick / workaround to this?
Image of log here: https://ibb.co/dp5fTt5
This is under QEMU. Firmware is OVMF. I have enumerated all tables from the RSDT and from the XSDT. In both cases I do not find any DSDT table.
LAI complains with "unable to find ACPI DSDT." in lai_create_namespace().
Is there a trick / workaround to this?
Image of log here: https://ibb.co/dp5fTt5
Last edited by kzinti on Fri Sep 30, 2022 5:29 pm, edited 3 times in total.
Re: LAI / QEMU / OVMF - No DSDT table
I can confirm to you that there is a dsdt in OVMF.
The DSDT pointer is located in the FADT Table (Signature 'FACP') Not with the SDT Array.
When you find the FADT, Check if the ACPI revision is 2 (in the R/XSDT) if yes (This is the case with OVMF) then you can use the 64 Bit X_Dsdt Pointer in the FADT, if the revision is 1 then use the 32 Bit Dsdt pointer.
The DSDT pointer is located in the FADT Table (Signature 'FACP') Not with the SDT Array.
When you find the FADT, Check if the ACPI revision is 2 (in the R/XSDT) if yes (This is the case with OVMF) then you can use the 64 Bit X_Dsdt Pointer in the FADT, if the revision is 1 then use the 32 Bit Dsdt pointer.
Re: LAI / QEMU / OVMF - No DSDT table
Check if you have the latest versions of OVMF, otherwise there is a problem with your usage of the LAI library.
Personnaly, I prefered to create my own ACPI driver, but this takes alot of time,.
Every ACPI compatible firmware has a DSDT.
Personnaly, I prefered to create my own ACPI driver, but this takes alot of time,.
Every ACPI compatible firmware has a DSDT.
Re: LAI / QEMU / OVMF - No DSDT table
It appears that the DSDT is indeed in the FADT. This means that my "obvious/trivial" implementation for laihost_scan() doesn't work. My implementation needs to know to look for the DSDT behind the FADT. Interesting.
Here is what I have:
I need to update this code to check for 'DSDT' and look inside the FADT instead of naively looping the XSDT.
I'll give this a try, thanks!
Here is what I have:
Code: Select all
template <typename T>
static void* laihost_scan(const T& rootTable, std::string_view signature, int index)
{
int count = 0;
for (auto address : rootTable)
{
const auto table = (acpi::Table*)(laihost_map(address, sizeof(acpi::Table)));
MTL_LOG(Debug) << "ACPI Table: " << table->GetSignature();
if (table->GetSignature() == signature)
{
if (index == count)
{
laihost_map(address, table->length); // TODO: is this required? can we do better?
return table;
}
++count;
}
}
return nullptr;
}
void* laihost_scan(const char* signature, size_t index)
{
if (g_xsdt)
return laihost_scan(*g_xsdt, signature, index);
else
return laihost_scan(*g_rsdt, signature, index);
}
I'll give this a try, thanks!
Re: LAI / QEMU / OVMF - No DSDT table
You're welcome !
Re: LAI / QEMU / OVMF - No DSDT table
Shouldn't we be checking the revision number in the FADT table (as opposed to the R/XSDT)?devc1 wrote:When you find the FADT, Check if the ACPI revision is 2 (in the R/XSDT) if yes (This is the case with OVMF) then you can use the 64 Bit X_Dsdt Pointer in the FADT, if the revision is 1 then use the 32 Bit Dsdt pointer.
It seems safest to check the size of the FADT table before accessing X_DSDT.
Re: [Solved] LAI / QEMU / OVMF - No DSDT table
You should check the value in the RSDP (I said RSDT by error) to determine if you have an XSDT or a legacy RSDT, to enumerate SDTs you should know the size of the pointers, 32 bits for RSDT and 64 bits for XSDT.
If the revision field is set to 2 then use the XSDT and 64 bit pointers.
You can test the compatibility of your OS with these 2 revisions by running on OVMF and SeaBIOS (Normal QEMU w Legacy ACPI).
These are my structures:
The XRSDP struct is apended with the RSDP.
If the revision field is set to 2 then use the XSDT and 64 bit pointers.
You can test the compatibility of your OS with these 2 revisions by running on OVMF and SeaBIOS (Normal QEMU w Legacy ACPI).
These are my structures:
The XRSDP struct is apended with the RSDP.
Code: Select all
typedef struct _ACPI_RSDP_DESCRIPTOR{
char Signature[8];
char Checksum;
char OEMId[6];
char Revision;
UINT32 RsdtAddress;
} ACPI_RSDP_DESCRIPTOR;
typedef struct _ACPI_EXTENDED_RSDP_DESCRIPTOR {
ACPI_RSDP_DESCRIPTOR RsdpDescriptor;
UINT32 Length;
UINT64 XsdtAddress;
char ExtendedChecksum;
char Reserved[3];
} ACPI_EXTENDED_RSDP_DESCRIPTOR;
typedef struct _ACPI_RSDT{
ACPI_SDT Sdt;
UINT32 SdtPtr[];//[(hdr.length - sizeof(hdr)) / 4];
} ACPI_RSDT;
typedef struct _ACPI_XSDT{
ACPI_SDT Sdt;
UINT64 SdtPtr[]; //[(hdr.length - sizeof(hdr)) / 8];
} ACPI_XSDT;
Re: [Solved] LAI / QEMU / OVMF - No DSDT table
Sure. This seems unrelated to my issue and this thread.
Re: LAI / QEMU / OVMF - No DSDT table
this is not needed, just check if you have an XSDT if yes then you can use the X_Dsdt field along with other fields from ACPI 2.0+.It seems safest to check the size of the FADT table before accessing X_DSDT.
Re: [Solved] LAI / QEMU / OVMF - No DSDT table
I agree with kzinti. Don't trust what firmware hands you.
Re: [Solved] LAI / QEMU / OVMF - No DSDT table
Indeed, never trust the firmware.nexos wrote:I agree with kzinti. Don't trust what firmware hands you.