Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
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 ?
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.
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)).
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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
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).