Page 1 of 1

Size of ACPI descriptor tables

Posted: Wed Oct 08, 2014 3:12 am
by max
Hey guys :)

I'm currently writing logic to read the ACPI tables to find out info about things like the APIC.

My memory model requires me to map the physical ranges to my higher-half area (where the kernel resides), but the RSPD doesn't specify the size of the RSDT. Only the RSDP for ACPI 2.0 or higher contains the "length" field that contains the length of the root table in bytes.

Thus I can't determine how many pages I need to map to make sure that the entire root table is accessible.. the same is for all the other tables that are referenced by the root table.

So my question is, how can I get
a) the length of the root table when using ACPI 1.0
b) the length of each table referenced by the root table

Is there a specification about the maximum table length / Can I get the table length somehow / Do I have to make assumptions ?

Thank you! :)

Greets, Max

Re: Size of ACPI descriptor tables

Posted: Wed Oct 08, 2014 3:36 am
by iocoder
Hi,
According to the RSDT article on the wiki, and section 5.2.2 of the specs (v1.0) You can find the length of any SDT using the "Length" member of the header of the table.

EDIT: You may temporarily map the first page of the table, get the length, and then map the whole table as you want.

Re: Size of ACPI descriptor tables

Posted: Wed Oct 08, 2014 5:10 am
by max
iocoder wrote:Hi,
According to the RSDT article on the wiki, and section 5.2.2 of the specs (v1.0) You can find the length of any SDT using the "Length" member of the header of the table.

EDIT: You may temporarily map the first page of the table, get the length, and then map the whole table as you want.
Okay well, I've seen that there is a length field, but yes as you say I must map the table to get its length.

I decided to temporarily map the table, get its length, unmap it again, and then map the space that is actually required (from PAGE_ALIGN_DOWN(tableLoc) to PAGE_ALIGN_UP(tableLoc + length)). ;)

Thanks for the help :)

Re: Size of ACPI descriptor tables

Posted: Wed Oct 08, 2014 10:19 am
by Brendan
Hi,
max wrote:I decided to temporarily map the table, get its length, unmap it again, and then map the space that is actually required (from PAGE_ALIGN_DOWN(tableLoc) to PAGE_ALIGN_UP(tableLoc + length)). ;)
It'd probably be more efficient to map the first page/s, get the length, then map the remainder (if necessary) without unmapping then remapping the first page/s. Note: it is possible for the table to start at an annoying physical address (e.g. 0x12345FFC) where you have to map 2 pages just to get the length.

Don't forget that the RSDT (and/or the XSDT) is mostly just a list of pointers; and that you'll need to do the same for every table that an entry in the RSDT/XSDT points to. For this reason it's likely that you'll want some sort of "map_ACPI_table(uint64_t physicalAddress, ...)" function; which maps the first page or the first 2 pages, then gets the length, maps the remainder and checks the checksum; and returns any error it detects (e.g. "Not enough space", "failed to allocate RAM for page table", "Bad checksum", etc).


Cheers,

Brendan

Re: Size of ACPI descriptor tables

Posted: Wed Oct 08, 2014 11:08 am
by max
Hey Brendan,

Hehe :)
Brendan wrote:Note: it is possible for the table to start at an annoying physical address (e.g. 0x12345FFC) where you have to map 2 pages just to get the length.
Just what I thought about - thats why I simply always map two pages starting at PAGE_ALIGN_DOWN(location). Okay, it would be slightly faster to not unmap them, but I don't think it matters; like this I wrote a "getSDTlength" function which is then used by my "mapSDT".
Brendan wrote:Don't forget that the RSDT (and/or the XSDT) is mostly just a list of pointers; and that you'll need to do the same for every table that an entry in the RSDT/XSDT points to. For this reason it's likely that you'll want some sort of "map_ACPI_table(uint64_t physicalAddress, ...)" function; which maps the first page or the first 2 pages, then gets the length, maps the remainder and checks the checksum; and returns any error it detects (e.g. "Not enough space", "failed to allocate RAM for page table", "Bad checksum", etc).
Thats exactly what I did. Great minds think alike :mrgreen: