@@ -133,14 +133,47 @@ static void acpi_create_gtdt(const struct acpi_gtdt_info *irqs)
static void acpi_create_fadt(void)
{
- acpi_table[FADT] = NULL;
- acpi_size[FADT] = 0;
+ AcpiFacpDescriptorRev5_1 *fadt;
+ hwaddr facs_offset;
+ int i;
+
+ fadt = g_malloc0(sizeof(*fadt));
+ acpi_fill_common_header_data(fadt, "FACP", 5, sizeof(*fadt));
+
+ /* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */
+ fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI);
+ fadt->arm_boot_flags = cpu_to_le16((1 << ACPI_FADT_ARM_USE_PSCI_G_0_2) |
+ (1 << ACPI_FADT_ARM_PSCI_USE_HVC));
+
+ /* ACPI v5.1 (fadt->revision.fadt->minor_revision) */
+ fadt->minor_revision = 0x1;
+
+ acpi_size[FADT] = fadt->length;
+
+ /* Calculate FACS and DSDT table offsets */
+ for (i = RSDP, facs_offset = 0; i < FACS; ++i) {
+ facs_offset += acpi_size[i];
+ }
+ fadt->Xfacs = cpu_to_le64(ACPI_BASE_ADDRESS + facs_offset);
+ fadt->Xdsdt = cpu_to_le64(fadt->Xfacs + acpi_size[FACS]);
+
+ acpi_do_checksum(fadt, fadt->length, &fadt->checksum);
+
+ acpi_table[FADT] = (void *)fadt;
}
static void acpi_create_facs(void)
{
- acpi_table[FACS] = NULL;
- acpi_size[FACS] = 0;
+ AcpiFacsDescriptorRev5_1 *facs;
+
+ facs = g_malloc0(sizeof(*facs));
+
+ memcpy(&facs->signature, "FACS", sizeof(facs->signature));
+ facs->length = cpu_to_le32(sizeof(*facs));
+ facs->version = 0x02;
+
+ acpi_table[FACS] = (void *)facs;
+ acpi_size[FACS] = facs->length;
}
static void acpi_create_dsdt(int smp_cpus, const struct acpi_dsdt_info *info)
@@ -97,46 +97,49 @@ struct AcpiXsdtDescriptor {
typedef struct AcpiXsdtDescriptor AcpiXsdtDescriptor;
/*
- * ACPI 1.0 Fixed ACPI Description Table (FADT)
+ * ACPI Fixed ACPI Description Table (FADT)
*/
+#define ACPI_FADT_COMMON_DEF /* FADT common definition */ \
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \
+ uint32_t firmware_ctrl; /* Physical address of FACS */ \
+ uint32_t dsdt; /* Physical address of DSDT */ \
+ uint8_t model; /* System Interrupt Model */ \
+ uint8_t reserved1; /* Reserved */ \
+ uint16_t sci_int; /* System vector of SCI interrupt */ \
+ uint32_t smi_cmd; /* Port address of SMI command port */ \
+ uint8_t acpi_enable; /* Value to write to smi_cmd to enable ACPI */ \
+ uint8_t acpi_disable; /* Value to write to smi_cmd to disable ACPI */ \
+ uint8_t S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ \
+ uint8_t reserved2; /* Reserved - must be zero */ \
+ uint32_t pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ \
+ uint32_t pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ \
+ uint32_t pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ \
+ uint32_t pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ \
+ uint32_t pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ \
+ uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ \
+ uint32_t gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ \
+ uint32_t gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ \
+ uint8_t pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ \
+ uint8_t pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ \
+ uint8_t pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ \
+ uint8_t pm_tmr_len; /* Byte Length of ports at pm_tm_blk */ \
+ uint8_t gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ \
+ uint8_t gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ \
+ uint8_t gpe1_base; /* Offset in gpe model where gpe1 events start */ \
+ uint8_t reserved3; /* Reserved */ \
+ uint16_t plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ \
+ uint16_t plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ \
+ uint16_t flush_size; /* Size of area read to flush caches */ \
+ uint16_t flush_stride; /* Stride used in flushing caches */ \
+ uint8_t duty_offset; /* Bit location of duty cycle field in p_cnt reg */ \
+ uint8_t duty_width; /* Bit width of duty cycle field in p_cnt reg */ \
+ uint8_t day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ \
+ uint8_t mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ \
+ uint8_t century; /* Index to century in RTC CMOS RAM */
+
struct AcpiFadtDescriptorRev1
{
- ACPI_TABLE_HEADER_DEF /* ACPI common table header */
- uint32_t firmware_ctrl; /* Physical address of FACS */
- uint32_t dsdt; /* Physical address of DSDT */
- uint8_t model; /* System Interrupt Model */
- uint8_t reserved1; /* Reserved */
- uint16_t sci_int; /* System vector of SCI interrupt */
- uint32_t smi_cmd; /* Port address of SMI command port */
- uint8_t acpi_enable; /* Value to write to smi_cmd to enable ACPI */
- uint8_t acpi_disable; /* Value to write to smi_cmd to disable ACPI */
- uint8_t S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
- uint8_t reserved2; /* Reserved - must be zero */
- uint32_t pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
- uint32_t pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
- uint32_t pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
- uint32_t pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
- uint32_t pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
- uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
- uint32_t gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
- uint32_t gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
- uint8_t pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
- uint8_t pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
- uint8_t pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
- uint8_t pm_tmr_len; /* Byte Length of ports at pm_tm_blk */
- uint8_t gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
- uint8_t gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
- uint8_t gpe1_base; /* Offset in gpe model where gpe1 events start */
- uint8_t reserved3; /* Reserved */
- uint16_t plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
- uint16_t plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
- uint16_t flush_size; /* Size of area read to flush caches */
- uint16_t flush_stride; /* Stride used in flushing caches */
- uint8_t duty_offset; /* Bit location of duty cycle field in p_cnt reg */
- uint8_t duty_width; /* Bit width of duty cycle field in p_cnt reg */
- uint8_t day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
- uint8_t mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
- uint8_t century; /* Index to century in RTC CMOS RAM */
+ ACPI_FADT_COMMON_DEF
uint8_t reserved4; /* Reserved */
uint8_t reserved4a; /* Reserved */
uint8_t reserved4b; /* Reserved */
@@ -144,6 +147,43 @@ struct AcpiFadtDescriptorRev1
} QEMU_PACKED;
typedef struct AcpiFadtDescriptorRev1 AcpiFadtDescriptorRev1;
+struct acpi_generic_address {
+ uint8_t space_id; /* Address space where struct or register exists */
+ uint8_t bit_width; /* Size in bits of given register */
+ uint8_t bit_offset; /* Bit offset within the register */
+ uint8_t access_width; /* Minimum Access size (ACPI 3.0) */
+ uint64_t address; /* 64-bit address of struct or register */
+} QEMU_PACKED;
+
+struct AcpiFacpDescriptorRev5_1 {
+ ACPI_FADT_COMMON_DEF
+ uint16_t boot_flags; /* IA-PC Boot Architecture Flags (see below for individual flags) */
+ uint8_t reserved; /* Reserved, must be zero */
+ uint32_t flags; /* Miscellaneous flag bits (see below for individual flags) */
+ struct acpi_generic_address reset_register; /* 64-bit address of the Reset register */
+ uint8_t reset_value; /* Value to write to the reset_register port to reset the system */
+ uint16_t arm_boot_flags; /* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */
+ uint8_t minor_revision; /* FADT Minor Revision (ACPI 5.1) */
+ uint64_t Xfacs; /* 64-bit physical address of FACS */
+ uint64_t Xdsdt; /* 64-bit physical address of DSDT */
+ struct acpi_generic_address xpm1a_event_block; /* 64-bit Extended Power Mgt 1a Event Reg Blk address */
+ struct acpi_generic_address xpm1b_event_block; /* 64-bit Extended Power Mgt 1b Event Reg Blk address */
+ struct acpi_generic_address xpm1a_control_block; /* 64-bit Extended Power Mgt 1a Control Reg Blk address */
+ struct acpi_generic_address xpm1b_control_block; /* 64-bit Extended Power Mgt 1b Control Reg Blk address */
+ struct acpi_generic_address xpm2_control_block; /* 64-bit Extended Power Mgt 2 Control Reg Blk address */
+ struct acpi_generic_address xpm_timer_block; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
+ struct acpi_generic_address xgpe0_block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */
+ struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */
+ struct acpi_generic_address sleep_control; /* 64-bit Sleep Control register (ACPI 5.0) */
+ struct acpi_generic_address sleep_status; /* 64-bit Sleep Status register (ACPI 5.0) */
+} QEMU_PACKED;
+typedef struct AcpiFacpDescriptorRev5_1 AcpiFacpDescriptorRev5_1;
+
+enum {
+ ACPI_FADT_ARM_USE_PSCI_G_0_2,
+ ACPI_FADT_ARM_PSCI_USE_HVC,
+};
+
/*
* ACPI 1.0 Root System Description Table (RSDT)
*/
@@ -156,20 +196,33 @@ struct AcpiRsdtDescriptorRev1
typedef struct AcpiRsdtDescriptorRev1 AcpiRsdtDescriptorRev1;
/*
- * ACPI 1.0 Firmware ACPI Control Structure (FACS)
+ * ACPI Firmware ACPI Control Structure (FACS)
*/
+#define ACPI_FACS_COMMON_DEF /* FACS common definition */ \
+ uint32_t signature; /* ACPI Signature */ \
+ uint32_t length; /* Length of structure, in bytes */ \
+ uint32_t hardware_signature; /* Hardware configuration signature */ \
+ uint32_t firmware_waking_vector; /* ACPI OS waking vector */ \
+ uint32_t global_lock; /* Global Lock */ \
+ uint32_t flags;
+
struct AcpiFacsDescriptorRev1
{
- uint32_t signature; /* ACPI Signature */
- uint32_t length; /* Length of structure, in bytes */
- uint32_t hardware_signature; /* Hardware configuration signature */
- uint32_t firmware_waking_vector; /* ACPI OS waking vector */
- uint32_t global_lock; /* Global Lock */
- uint32_t flags;
+ ACPI_FACS_COMMON_DEF
uint8_t resverved3 [40]; /* Reserved - must be zero */
} QEMU_PACKED;
typedef struct AcpiFacsDescriptorRev1 AcpiFacsDescriptorRev1;
+struct AcpiFacsDescriptorRev5_1 {
+ ACPI_FACS_COMMON_DEF
+ uint64_t xfirmware_waking_vector; /* 64-bit version of the Firmware Waking Vector (ACPI 2.0+) */
+ uint8_t version; /* Version of this table (ACPI 2.0+) */
+ uint8_t reserved [3]; /* Reserved, must be zero */
+ uint32_t ospm_flags; /* Flags to be set by OSPM (ACPI 4.0) */
+ uint8_t reserved1 [24]; /* Reserved, must be zero */
+} QEMU_PACKED;
+typedef struct AcpiFacsDescriptorRev5_1 AcpiFacsDescriptorRev5_1;
+
/*
* Differentiated System Description Table (DSDT)
*/