SRAT

From OSDev Wiki
Jump to navigation Jump to search
ACPI
Fixed Tables
Differentiated Tables
Tools/Libs

This page is about the ACPI SRAT (System/Static Resource Affinity Table) It describes how the APIC works.

Introduction

The SRAT table is described by the ACPI Specification 5.0a [1] in section 5.2.16 as a table providing information that allows an OSPM (Operating System Power Management [System]) "to associate processors and memory ranges, including ranges of memory provided by hot-added memory devices, with system localities proximity domains and clock domains." Basically, the SRAT provides information on relationships of resources in the system - namely the processor(s) and memory. The SRAT table associates each processor and blocks of memory to a plain ol' integer, called proximity domains in ACPI jargon.

Header Structure

The SRAT table follows this structure:

struct SRAT
{
    char signature[4];   // Contains "SRAT"
    uint32_t length;     // Length of entire SRAT including entries
    uint8_t  rev;        // 3
    uint8_t  checksum;   // Entire table must sum to zero
    uint8_t  OEMID[6];   // What do you think it is?
    uint64_t OEMTableID; // For the SRAT it's the manufacturer model ID
    uint32_t OEMRev;     // OEM revision for OEM Table ID
    uint32_t creatorID;  // Vendor ID of the utility used to create the table
    uint32_t creatorRev; // Blah blah
    
    uint8_t reserved[12];
} __attribute__((packed));

This header structure (48 bytes) is then followed by a list of Static Resource Allocation Structures. There are 3 types of SRAS:

Type Name
0x0 Processor Local APIC/SAPIC Affinity Structure
0x1 Memory Affinity Structure
0x2 Processor Local x2APIC Affinity Structure


Processor Local APIC Affinity Structure

This structure (whose name is too long to repeat) gives us the association of a processor's APIC ID (or SAPIC ID/EID) and the proximity domain (in ACPI jargon) in which it belongs to. Here goes nothing:

struct SRAT_proc_lapic_struct
{
    uint8_t type;      // 0x0 for this type of structure
    uint8_t length;    // 16
    uint8_t lo_DM;     // Bits [0:7] of the proximity domain
    uint8_t APIC_ID;   // Processor's APIC ID
    uint32_t flags;    // Haha the most useless thing ever
    uint8_t SAPIC_EID; // The processor's local SAPIC EID. Don't even bother.
    uint8_t hi_DM[3];  // Bits [8:31] of the proximity domain
    uint32_t _CDM;     // The clock domain which the processor belongs to (more jargon)
} __attribute__((packed));

And here's for (drumroll please) the utterly mind-blowing flags:

Field name Field bit width Bit offset Description
Enabled 1 0 If clear, the OS should ignore the contents of the structure. This is to allow system firmware to populate the SRAT with a static number of entries and enable as needed.
Reserved 31 1 Must be zero.

Memory Affinity Structure

The Memory Affinity structure contains:

  • A range of memory and the unexciting integer (proximity domain) to which it belongs
  • Information about whether the range of memory is hot-pluggable
struct SRAT_mem_struct
{
    uint8_t type;         // 0x1 for this type of structure
    uint8_t length;       // 40
    uint32_t domain;      // The domain to which this memory region belongs to
    uint8_t reserved1[2]; // Reserved
    uint32_t lo_base;     // Low 32 bits of the base address of the memory range
    uint32_t hi_base;     // High 32 bits of the base address of the memory range
    uint32_t lo_length;   // Low 32 bits of the length of the range
    uint32_t hi_length;   // High 32 bits of the length
    uint8_t reserved2[4]; // Reserved
    uint32_t flags;       // Flags
    uint8_t reserved3[8]; // Reserved
} __attribute__ ((packed));

Flags:

Field name Field bit width Bit offset Description
Enabled 1 0 If clear, the OS should ignore the contents of the structure. This is to allow system firmware to populate the SRAT with a static number of entries and enable as needed.
Hot-pluggable* 1 1 If both Enabled and Hot-pluggable flags are set, then the system supports hot-adding and hot-removing of this memory region.
Non-Volatile 1 2 If set, this memory region is non-volatile memory
Reserved 29 3 Must be zero.

* The asterisk says nothing

Processor Local x2APIC Affinity Structure

The x2APIC structure is basically the APIC structure but for x2APIC.

struct SRAT_proc_lapic2_struct
{
    uint8_t type;         // 0x2 for this type of structure
    uint8_t length;       // 24
    uint8_t reserved1[2]; // Must be zero
    uint32_t domain;      // The proximity domain which the logical processor belongs to
    uint32_t x2APIC_ID;   // Processor's x2APIC ID
    uint32_t flags;       // Haha the most useless thing ever
    uint32_t _CDM;        // The clock domain which the processor belongs to (more jargon)
    uint8_t reserved2[4]; // Reserved.
} __attribute__((packed));

Clock Domain

Go read the docs (section 6.2.1). The clock domain represents the clock connected to a processor of that domain. When a processor attempts to access a clock source that is not in the same clock domain as itself, inaccuracies may occur when compared to other processors. This is the same concept as a proximity domain, where processors accessing memory or I/O resources outside its domain will need to ask a processor inside the domain to perform the memory or I/O action.