Page 1 of 1
[Solved] LAI / QEMU / OVMF - No DSDT table
Posted: Fri Sep 30, 2022 4:26 pm
by kzinti
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
Re: LAI / QEMU / OVMF - No DSDT table
Posted: Fri Sep 30, 2022 4:38 pm
by devc1
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.
Re: LAI / QEMU / OVMF - No DSDT table
Posted: Fri Sep 30, 2022 4:41 pm
by devc1
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.
Re: LAI / QEMU / OVMF - No DSDT table
Posted: Fri Sep 30, 2022 4:45 pm
by kzinti
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:
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 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!
Re: LAI / QEMU / OVMF - No DSDT table
Posted: Fri Sep 30, 2022 4:47 pm
by devc1
You're welcome !
Re: LAI / QEMU / OVMF - No DSDT table
Posted: Fri Sep 30, 2022 4:56 pm
by kzinti
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.
Shouldn't we be checking the revision number in the FADT table (as opposed to the R/XSDT)?
It seems safest to check the size of the FADT table before accessing X_DSDT.
Re: [Solved] LAI / QEMU / OVMF - No DSDT table
Posted: Fri Sep 30, 2022 6:39 pm
by devc1
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.
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
Posted: Fri Sep 30, 2022 11:18 pm
by kzinti
Sure. This seems unrelated to my issue and this thread.
Re: LAI / QEMU / OVMF - No DSDT table
Posted: Sat Oct 01, 2022 1:26 pm
by devc1
It seems safest to check the size of the FADT table before accessing X_DSDT.
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+.
Re: [Solved] LAI / QEMU / OVMF - No DSDT table
Posted: Sat Oct 01, 2022 2:30 pm
by nexos
I agree with kzinti. Don't trust what firmware hands you.
Re: [Solved] LAI / QEMU / OVMF - No DSDT table
Posted: Sat Oct 01, 2022 7:46 pm
by kzinti
nexos wrote:I agree with kzinti. Don't trust what firmware hands you.
Indeed, never trust the firmware.