OSDev.org
https://forum.osdev.org/

[Solved] LAI / QEMU / OVMF - No DSDT table
https://forum.osdev.org/viewtopic.php?f=1&t=56509
Page 1 of 1

Author:  kzinti [ Fri Sep 30, 2022 4:26 pm ]
Post subject:  [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

Author:  devc1 [ Fri Sep 30, 2022 4:38 pm ]
Post subject:  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.

Author:  devc1 [ Fri Sep 30, 2022 4:41 pm ]
Post subject:  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.

Author:  kzinti [ Fri Sep 30, 2022 4:45 pm ]
Post subject:  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:
Code:
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!

Author:  devc1 [ Fri Sep 30, 2022 4:47 pm ]
Post subject:  Re: LAI / QEMU / OVMF - No DSDT table

You're welcome !

Author:  kzinti [ Fri Sep 30, 2022 4:56 pm ]
Post subject:  Re: LAI / QEMU / OVMF - No DSDT table

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.

Author:  devc1 [ Fri Sep 30, 2022 6:39 pm ]
Post subject:  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.
Code:
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;

Author:  kzinti [ Fri Sep 30, 2022 11:18 pm ]
Post subject:  Re: [Solved] LAI / QEMU / OVMF - No DSDT table

Sure. This seems unrelated to my issue and this thread.

Author:  devc1 [ Sat Oct 01, 2022 1:26 pm ]
Post subject:  Re: LAI / QEMU / OVMF - No DSDT table

Quote:
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+.

Author:  nexos [ Sat Oct 01, 2022 2:30 pm ]
Post subject:  Re: [Solved] LAI / QEMU / OVMF - No DSDT table

I agree with kzinti. Don't trust what firmware hands you.

Author:  kzinti [ Sat Oct 01, 2022 7:46 pm ]
Post subject:  Re: [Solved] LAI / QEMU / OVMF - No DSDT table

nexos wrote:
I agree with kzinti. Don't trust what firmware hands you.

Indeed, never trust the firmware.

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/