FADT: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content deleted Content added
Undo revision 11221 because it used non-C types and serialization was not properly handled (in C, there may be gaps between fields)
Combuster (talk | contribs)
Undo revision 11222 by Love4boobies (Talk) - Destruction of information
Line 2: Line 2:


==Finding the FADT==
==Finding the FADT==
The FADT is pointed to by an entry in the [[RSDT]]. The signature is 'FACP'.
The FADT is pointed to by an entry in the [[RSDT]]. The signature is 'FACP'. Even if the pointer was found in another ACPI valid structure, you should anyway do the checksum to check that the table is valid.


==Structure==
==Structure==
The FADT contains pointers to two additional tables (in addition to a lot of other information):
The FADT is a complex structure and contains a lot of data. Here it is:
<source lang="c">struct FADT {
* The FACS (Firmware ACPI Control Structure) at offset 36 (4 byte physical address)
struct ACPISDTHeader h;
* The DSDT (Differentiated System Description Table) at offset 40 (4 byte physical address)
uint32_t FirmwareCtrl;
uint32_t Dsdt;
uint8_t Reserved; // Was used in ACPI 1.0. Today is not used anymore. Some bioses still use it for compatibility with old os. for more info see the ACPI specification 1.0
uint8_t PreferredPowerManagementProfile;
uint16_t SCI_Interrupt;
uint32_t SMI_CommandPort;
uint8_t AcpiEnable;
uint8_t AcpiDisable;
uint8_t S4BIOS_REQ;
uint8_t PSTATE_Control;
uint32_t PM1aEventBlock;
uint32_t PM1bEventBlock;
uint32_t PM1aControlBlock;
uint32_t PM1bControlBlock;
uint32_t PM2ControlBlock;
uint32_t PMTimerBlock;
uint32_t GPE0Block;
uint32_t GPE1Block;
uint8_t PM1EventLength;
uint8_t PM1ControlLength;
uint8_t PM2ControlLength;
uint8_t PMTimerLength;
uint8_t GPE0Length;
uint8_t GPE1Length;
uint8_t GPE1Base;
uint8_t CStateControl;
uint16_t WorstC2Latency;
uint16_t WorstC3Latency;
uint16_t FlushSize;
uint16_t FlushStride;
uint8_t DutyOffset;
uint8_t DutyWidth;
uint8_t DayAlarm;
uint8_t MonthAlarm;
uint8_t Century;
uint16_t BootArchitectureFlags;
uint8_t Reserved2;
uint32_t Flags;
GenericAddressStructure ResetRet; // For details see below. Just know that GenericAddressStructure is made of 12 bytes
uint8_t ResetValue;
uint8_t Reserved3[3];
// 64bit pointers
uint64_t X_FirmwareControl;
uint64_t X_Dsdt;
GenericAddressStructure X_PM1aEventBlock;
GenericAddressStructure X_PM1bEventBlock;
GenericAddressStructure X_PM1aControlBlock;
GenericAddressStructure X_PM1bControlBlock;
GenericAddressStructure X_PM2ControlBlock;
GenericAddressStructure X_PMTimerBlock;
GenericAddressStructure X_GPE0Block;
GenericAddressStructure X_GPE1Block;
};</source>

== GenericAddressStructure ==
Before going to far, keep in mind that the GAS is a structure used by ACPI to describe the position of registers. Its structure is:
<source lang="c">struct GenericAddressStructure
{
uint8_t AddressSpace;
uint8_t BitWidth;
uint8_t BitOffset;
uint8_t AccessSize;
uint64_t Address;
};</source>
'''AddressSpace''' can be one of the following:
* 0 System Memory
* 1 System I/O
* 2 PCI Configuration Space
* 3 Embedded Controller
* 4 SMBus
* 5 to 0x7E Reserved
* 0x7F Functional Fixed Hardware
* 0x80 to 0xBF Reserved
* 0xC0 to 0xFF OEM Defined

'''BitWidth''' and '''BitOffset''' are required only when accessing a bit field.

'''AccessSize''' defines how many bytes at once you can read/write and it must be one of the following:
* 0 Undefined (legacy reasons)
* 1 Byte access
* 2 16-bit Word access
* 3 32-bit Doubleword access
* 4 64-bit Quadword access

Address is a 64bit pointer in the defined address space to the data structure.

== Fields ==
'''TODO'''

== What's next? ==
You should preserve the pointer to the Facs (in FirmwareControl (if < 4gb) or in X_FirmwareControl (if >= 4gb)). Then you should parse the [[DSDT]].

Revision as of 15:58, 10 March 2011

FADT (Fixed ACPI Description Table) is a data structure used in the ACPI programming interface. This table contains information about fixed register blocks pertaining to power management.

Finding the FADT

The FADT is pointed to by an entry in the RSDT. The signature is 'FACP'. Even if the pointer was found in another ACPI valid structure, you should anyway do the checksum to check that the table is valid.

Structure

The FADT is a complex structure and contains a lot of data. Here it is:

struct FADT {
  struct ACPISDTHeader h;
  uint32_t FirmwareCtrl;
  uint32_t Dsdt;
  uint8_t Reserved;  // Was used in ACPI 1.0. Today is not used anymore. Some bioses still use it for compatibility with old os. for more info see the ACPI specification 1.0
  uint8_t PreferredPowerManagementProfile;
  uint16_t SCI_Interrupt;
  uint32_t SMI_CommandPort;
  uint8_t AcpiEnable;
  uint8_t AcpiDisable;
  uint8_t S4BIOS_REQ;
  uint8_t PSTATE_Control;
  uint32_t PM1aEventBlock;
  uint32_t PM1bEventBlock;
  uint32_t PM1aControlBlock;
  uint32_t PM1bControlBlock;
  uint32_t PM2ControlBlock;
  uint32_t PMTimerBlock;
  uint32_t GPE0Block;
  uint32_t GPE1Block;
  uint8_t PM1EventLength;
  uint8_t PM1ControlLength;
  uint8_t PM2ControlLength;
  uint8_t PMTimerLength;
  uint8_t GPE0Length;
  uint8_t GPE1Length;
  uint8_t GPE1Base;
  uint8_t CStateControl;
  uint16_t WorstC2Latency;
  uint16_t WorstC3Latency;
  uint16_t FlushSize;
  uint16_t FlushStride;
  uint8_t DutyOffset;
  uint8_t DutyWidth;
  uint8_t DayAlarm;
  uint8_t MonthAlarm;
  uint8_t Century;
  uint16_t BootArchitectureFlags;
  uint8_t Reserved2;
  uint32_t Flags;
  GenericAddressStructure ResetRet;  // For details see below. Just know that GenericAddressStructure is made of 12 bytes
  uint8_t ResetValue;
  uint8_t Reserved3[3];
  
  // 64bit pointers
  uint64_t X_FirmwareControl;
  uint64_t X_Dsdt;
  GenericAddressStructure X_PM1aEventBlock;
  GenericAddressStructure X_PM1bEventBlock;
  GenericAddressStructure X_PM1aControlBlock;
  GenericAddressStructure X_PM1bControlBlock;
  GenericAddressStructure X_PM2ControlBlock;
  GenericAddressStructure X_PMTimerBlock;
  GenericAddressStructure X_GPE0Block;
  GenericAddressStructure X_GPE1Block;
};

GenericAddressStructure

Before going to far, keep in mind that the GAS is a structure used by ACPI to describe the position of registers. Its structure is:

struct GenericAddressStructure
{
  uint8_t AddressSpace;
  uint8_t BitWidth;
  uint8_t BitOffset;
  uint8_t AccessSize;
  uint64_t Address;
};

AddressSpace can be one of the following:

  • 0 System Memory
  • 1 System I/O
  • 2 PCI Configuration Space
  • 3 Embedded Controller
  • 4 SMBus
  • 5 to 0x7E Reserved
  • 0x7F Functional Fixed Hardware
  • 0x80 to 0xBF Reserved
  • 0xC0 to 0xFF OEM Defined

BitWidth and BitOffset are required only when accessing a bit field.

AccessSize defines how many bytes at once you can read/write and it must be one of the following:

  • 0 Undefined (legacy reasons)
  • 1 Byte access
  • 2 16-bit Word access
  • 3 32-bit Doubleword access
  • 4 64-bit Quadword access

Address is a 64bit pointer in the defined address space to the data structure.

Fields

TODO

What's next?

You should preserve the pointer to the Facs (in FirmwareControl (if < 4gb) or in X_FirmwareControl (if >= 4gb)). Then you should parse the DSDT.