RSDT: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content deleted Content added
No edit summary
m Bot: Replace deprecated source tag with syntaxhighlight
 
(20 intermediate revisions by 13 users not shown)
Line 1: Line 1:
{{ACPI}}

'''RSDT''' (Root System Description Table) is a data structure used in the [[ACPI]] programming interface. This table contains pointers to all the other System Description Tables.
'''RSDT''' (Root System Description Table) is a data structure used in the [[ACPI]] programming interface. This table contains pointers to all the other System Description Tables.


Line 4: Line 6:
To find the RSDT you need first to locate and check the [[RSDP]], then use the RsdtPointer for ACPI Version < 2.0 an XsdtPointer for any other case.
To find the RSDT you need first to locate and check the [[RSDP]], then use the RsdtPointer for ACPI Version < 2.0 an XsdtPointer for any other case.


The ACPI standards state that an OS that complies with ACPI version 2.0 or later should use the XSDT instead of the RSDT, however I personally doubt that there is a difference on 80x86 computers. AFAIK the XSDT itself was introduced for Itanium's (IA64) and other 64 bit computers where it's likely that the BIOS (and ACPI tables) are above 4 GB. On 80x86 it's likely that the RSDT and the XSDT both point to the same tables below 4 GB for compatibility reasons (it doesn't make sense to have 2 versions of the same tables) -- Brendan.
The ACPI standards state that an OS that complies with ACPI version 2.0 or later should use the [[XSDT]] instead of the RSDT, however I personally doubt that there is a difference on 80x86 computers. AFAIK the XSDT itself was introduced for Itanium's (IA-64) and other 64 bit computers where it's likely that the BIOS (and ACPI tables) are above 4 GB. On 80x86 it's likely that the RSDT and the XSDT both point to the same tables below 4 GB for compatibility reasons (it doesn't make sense to have 2 versions of the same tables) -- Brendan.


==Validating the RSDT==
==Validating the RSDT==
You only need to sum all the bytes in the table and compare the result to 0.
You only need to sum all the bytes in the table and compare the result to 0 (mod 0x100).


==Structure==
==Structure==
The RSDT is the main System Description Table. However there are many kinds of SDT. All the SDT may be split into two parts. One (the header) which is common to all the SDT an another (data) which is different for each table.
The RSDT is the main System Description Table. However there are many kinds of SDT. All the SDT may be split into two parts. One (the header) which is common to all the SDT and another (data) which is different for each table.
The structure of the header is:
The structure of the header is:
<source lang="c">
<syntaxhighlight lang="c">
struct ACPISDTHeader {
struct ACPISDTHeader {
char Signature[4];
char Signature[4];
DWORD Length;
uint32_t Length;
BYTE Revision;
uint8_t Revision;
BYTE Checksum;
uint8_t Checksum;
char OEMID[6];
char OEMID[6];
char OEMTableID[8];
char OEMTableID[8];
DWORD OEMRevision;
uint32_t OEMRevision;
DWORD CreatorID;
uint32_t CreatorID;
DWORD CreatorRevision;
uint32_t CreatorRevision;
};
</syntaxhighlight>
=== Header fields ===
==== Signature ====
All the ACPI tables have a 4 byte Signature field (except the RSDP which has an 8 byte one). Using the signature, you can determine what table are you working with.

==== Length ====
Total size of the table, inclusive of the header.
==== Checksum ====
A 8-bit checksum field of the whole table, inclusive of the header. All bytes of the table summed must be equal to 0 (mod 0x100). You should always do a checksum of the table before using it, even if you found the table linked by other tables.
<syntaxhighlight lang="c">
bool doChecksum(ACPISDTHeader *tableHeader)
{
unsigned char sum = 0;

for (int i = 0; i < tableHeader->Length; i++)
{
sum += ((char *) tableHeader)[i];
}

return sum == 0;
}
}
</syntaxhighlight>
</source>


=== Other fields ===
In case you used RsdtPointer, the complete table structure is:
In case you used RsdtPointer, the complete table structure is:
<source lang="c">
<syntaxhighlight lang="c">
struct RSDT {
struct RSDT {
struct ACPISDTHeader h;
struct ACPISDTHeader h;
DWORD PointerToOtherSDT[(h.Length - sizeof(h)) / 4];
uint32_t PointerToOtherSDT[(h.Length - sizeof(h)) / 4];
}
};
</syntaxhighlight>
</source>
If you instead used the XsdtPointer, then the table is:
If you instead used the XsdtPointer, then the table is:
<source lang="c">
<syntaxhighlight lang="c">
struct XSDT {
struct XSDT {
struct ACPISDTHeader h;
struct ACPISDTHeader h;
QWORD PointerToOtherSDT[(h.Length - sizeof(h)) / 8];
uint64_t PointerToOtherSDT[(h.Length - sizeof(h)) / 8];
}
};
</syntaxhighlight>
</source>


== How to use ==
== How to use ==
Well, suppose you want to find the [[FADT]]. The FADT, being a SDT has a ACPISDTHeader. It's signature is "FACP".
Well, suppose you want to find the [[FADT]]. The FADT, being a SDT has a ACPISDTHeader. It's signature is "FACP".
You may use this code:
You may use this code:
<source lang="c">
<syntaxhighlight lang="c">
void *findFACP(void *RootSDT) {
void *findFACP(void *RootSDT)
{
RSDT *rsdt = (RSDT *) RootSDT;
int n = (rsdt->h.Length - sizeof(rsdt->h)) / 4;
RSDT *rsdt = (RSDT *) RootSDT;
for (int i = 0; i < n; i++) {
int entries = (rsdt->h.Length - sizeof(rsdt->h)) / 4;

ACPISDTHeader *h = (ACPISDTHeader *) rsdt->PointerToOtherSDT[i];
for (int i = 0; i < entries; i++)
if (!strncmp(h->Signature, "FACP"))
{
return (void *) h;
ACPISDTHeader *h = (ACPISDTHeader *) rsdt->PointerToOtherSDT[i];
}
if (!strncmp(h->Signature, "FACP", 4))
return NULL;
return (void *) h;
}

// No FACP found
return NULL;
}
}
</syntaxhighlight>
</source>

== What can you find? ==

=== Defined by ACPI ===

The ACPI Specification 5.0 has direct definitions for the following System Descriptor tables, identified by their signatures:

* "APIC": Multiple APIC Description Table ([[MADT]])
* "BERT": Boot Error Record Table ([[BERT]])
* "CPEP": Corrected Platform Error Polling Table ([[CPEP]])
* "DSDT": Differentiated System Description Table ([[DSDT]])
* "ECDT": Embedded Controller Boot Resources Table ([[ECDT]])
* "EINJ": Error Injection Table ([[EINJ]])
* "ERST": Error Record Serialization Table ([[ERST]])
* "FACP": Fixed ACPI Description Table ([[FADT]])
* "FACS": Firmware ACPI Control Structure ([[FACS]])
* "HEST": Hardware Error Source Table ([[HEST]])
* "MSCT": Maximum System Characteristics Table ([[MSCT]])
* "MPST": Memory Power State Table ([[MPST]])
* "OEMx": OEM Specific Information Tables (Any table with a signature beginning with "OEM" falls into this definition)
* "PMTT" Platform Memory Topology Table ([[PMTT]])
* "PSDT": Persistent System Description Table ([[PSDT]])
* "RASF": ACPI RAS Feature Table ([[RASF]])
* "RSDT": Root System Description Table (This wiki page; included for completeness)
* "SBST": Smart Battery Specification Table ([[SBST]])
* "SLIT": System Locality System Information Table ([[SLIT]])
* "SRAT": System Resource Affinity Table ([[SRAT]])
* "SSDT": Secondary System Description Table ([[SSDT]])
* "XSDT": Extended System Description Table ([[XSDT]]; 64-bit version of the RSDT)

=== Reserved by ACPI ===

The ACPI specification maintains reservations for additional third party defined description tables. Each third party submitting a request for a reservation also maintains a specification for these tables, located on individual sites. See the ACPI spec ([http://www.acpi.info/spec50.htm]) for more information.


== What's next? ==
== What's next? ==
You should now parse each table pointed by the RSDP. (Probably you will need only the [[FADT]], the [[SSDT]] and the [[MADT]]
You should now parse each table pointed by the RSDT (Probably you will need only the [[FADT]], the [[SSDT]] and the [[MADT]]). On multiprocessor systems, you should refer to the [[SRAT]] and the [[SLIT]] tables to obtain the NUMA (proximity domain in ACPI jargon) of each processor.


[[Category:Power management]]
[[Category:ACPI]]

Latest revision as of 05:39, 9 June 2024

ACPI
Fixed Tables
Differentiated Tables
Tools/Libs

RSDT (Root System Description Table) is a data structure used in the ACPI programming interface. This table contains pointers to all the other System Description Tables.

Detecting the RSDT

To find the RSDT you need first to locate and check the RSDP, then use the RsdtPointer for ACPI Version < 2.0 an XsdtPointer for any other case.

The ACPI standards state that an OS that complies with ACPI version 2.0 or later should use the XSDT instead of the RSDT, however I personally doubt that there is a difference on 80x86 computers. AFAIK the XSDT itself was introduced for Itanium's (IA-64) and other 64 bit computers where it's likely that the BIOS (and ACPI tables) are above 4 GB. On 80x86 it's likely that the RSDT and the XSDT both point to the same tables below 4 GB for compatibility reasons (it doesn't make sense to have 2 versions of the same tables) -- Brendan.

Validating the RSDT

You only need to sum all the bytes in the table and compare the result to 0 (mod 0x100).

Structure

The RSDT is the main System Description Table. However there are many kinds of SDT. All the SDT may be split into two parts. One (the header) which is common to all the SDT and another (data) which is different for each table. The structure of the header is:

struct ACPISDTHeader {
  char Signature[4];
  uint32_t Length;
  uint8_t Revision;
  uint8_t Checksum;
  char OEMID[6];
  char OEMTableID[8];
  uint32_t OEMRevision;
  uint32_t CreatorID;
  uint32_t CreatorRevision;
};

Header fields

Signature

All the ACPI tables have a 4 byte Signature field (except the RSDP which has an 8 byte one). Using the signature, you can determine what table are you working with.

Length

Total size of the table, inclusive of the header.

Checksum

A 8-bit checksum field of the whole table, inclusive of the header. All bytes of the table summed must be equal to 0 (mod 0x100). You should always do a checksum of the table before using it, even if you found the table linked by other tables.

bool doChecksum(ACPISDTHeader *tableHeader)
{
    unsigned char sum = 0;

    for (int i = 0; i < tableHeader->Length; i++)
    {
        sum += ((char *) tableHeader)[i];
    }

    return sum == 0;
}

Other fields

In case you used RsdtPointer, the complete table structure is:

struct RSDT {
  struct ACPISDTHeader h;
  uint32_t PointerToOtherSDT[(h.Length - sizeof(h)) / 4];
};

If you instead used the XsdtPointer, then the table is:

struct XSDT {
  struct ACPISDTHeader h;
  uint64_t PointerToOtherSDT[(h.Length - sizeof(h)) / 8];
};

How to use

Well, suppose you want to find the FADT. The FADT, being a SDT has a ACPISDTHeader. It's signature is "FACP". You may use this code:

void *findFACP(void *RootSDT)
{
    RSDT *rsdt = (RSDT *) RootSDT;
    int entries = (rsdt->h.Length - sizeof(rsdt->h)) / 4;

    for (int i = 0; i < entries; i++)
    {
        ACPISDTHeader *h = (ACPISDTHeader *) rsdt->PointerToOtherSDT[i];
        if (!strncmp(h->Signature, "FACP", 4))
            return (void *) h;
    }

    // No FACP found
    return NULL;
}

What can you find?

Defined by ACPI

The ACPI Specification 5.0 has direct definitions for the following System Descriptor tables, identified by their signatures:

  • "APIC": Multiple APIC Description Table (MADT)
  • "BERT": Boot Error Record Table (BERT)
  • "CPEP": Corrected Platform Error Polling Table (CPEP)
  • "DSDT": Differentiated System Description Table (DSDT)
  • "ECDT": Embedded Controller Boot Resources Table (ECDT)
  • "EINJ": Error Injection Table (EINJ)
  • "ERST": Error Record Serialization Table (ERST)
  • "FACP": Fixed ACPI Description Table (FADT)
  • "FACS": Firmware ACPI Control Structure (FACS)
  • "HEST": Hardware Error Source Table (HEST)
  • "MSCT": Maximum System Characteristics Table (MSCT)
  • "MPST": Memory Power State Table (MPST)
  • "OEMx": OEM Specific Information Tables (Any table with a signature beginning with "OEM" falls into this definition)
  • "PMTT" Platform Memory Topology Table (PMTT)
  • "PSDT": Persistent System Description Table (PSDT)
  • "RASF": ACPI RAS Feature Table (RASF)
  • "RSDT": Root System Description Table (This wiki page; included for completeness)
  • "SBST": Smart Battery Specification Table (SBST)
  • "SLIT": System Locality System Information Table (SLIT)
  • "SRAT": System Resource Affinity Table (SRAT)
  • "SSDT": Secondary System Description Table (SSDT)
  • "XSDT": Extended System Description Table (XSDT; 64-bit version of the RSDT)

Reserved by ACPI

The ACPI specification maintains reservations for additional third party defined description tables. Each third party submitting a request for a reservation also maintains a specification for these tables, located on individual sites. See the ACPI spec ([1]) for more information.

What's next?

You should now parse each table pointed by the RSDT (Probably you will need only the FADT, the SSDT and the MADT). On multiprocessor systems, you should refer to the SRAT and the SLIT tables to obtain the NUMA (proximity domain in ACPI jargon) of each processor.