qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v4 07/20] hw/arm/virt-acpi-build: Generate FADT tabl


From: Shannon Zhao
Subject: [Qemu-devel] [PATCH v4 07/20] hw/arm/virt-acpi-build: Generate FADT table and update ACPI headers
Date: Fri, 3 Apr 2015 18:03:39 +0800

From: Shannon Zhao <address@hidden>

In the case of mach virt, it is used to set the Hardware Reduced bit
and enable PSCI SMP booting through HVC. So ignore FACS and FADT
points to DSDT.

Update the header definitions for FADT taking into account the new
additions of ACPI v5.1 in `include/hw/acpi/acpi-defs.h`

Signed-off-by: Shannon Zhao <address@hidden>
Signed-off-by: Shannon Zhao <address@hidden>
---
 hw/arm/virt-acpi-build.c    |  31 ++++++++++++
 include/hw/acpi/acpi-defs.h | 114 ++++++++++++++++++++++++++++++--------------
 2 files changed, 108 insertions(+), 37 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 516c1d0..cb8b030 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -162,6 +162,31 @@ static void acpi_dsdt_add_virtio(Aml *scope, const hwaddr 
*mmio_addrs,
     }
 }
 
+/* FADT */
+static void
+build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
+{
+    AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, 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;
+
+    fadt->dsdt = cpu_to_le32(dsdt);
+    /* DSDT address to be filled by Guest linker */
+    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+                                   ACPI_BUILD_TABLE_FILE,
+                                   table_data, &fadt->dsdt,
+                                   sizeof fadt->dsdt);
+
+    build_header(linker, table_data,
+                 (void *)fadt, "FACP", sizeof(*fadt), 5);
+}
+
 /* DSDT */
 static void
 build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
@@ -205,6 +230,7 @@ static
 void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
 {
     GArray *table_offsets;
+    unsigned dsdt;
     GArray *tables_blob = tables->table_data;
 
     table_offsets = g_array_new(false, true /* clear */,
@@ -224,8 +250,13 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
      */
 
     /* DSDT is pointed to by FADT */
+    dsdt = tables_blob->len;
     build_dsdt(tables_blob, tables->linker, guest_info);
 
+    /* FADT MADT GTDT pointed to by RSDT */
+    acpi_add_table(table_offsets, tables_blob);
+    build_fadt(tables_blob, tables->linker, dsdt);
+
     /* Cleanup memory that's no longer used. */
     g_array_free(table_offsets, true);
 }
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index c4468f8..e588df5 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -88,46 +88,49 @@ struct AcpiTableHeader         /* ACPI common table header 
*/
 typedef struct AcpiTableHeader AcpiTableHeader;
 
 /*
- * 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 */
@@ -135,6 +138,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 AcpiFadtDescriptorRev5_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 AcpiFadtDescriptorRev5_1 AcpiFadtDescriptorRev5_1;
+
+enum {
+    ACPI_FADT_ARM_USE_PSCI_G_0_2,
+    ACPI_FADT_ARM_PSCI_USE_HVC,
+};
+
 /*
  * ACPI 1.0 Root System Description Table (RSDT)
  */
-- 
2.0.4





reply via email to

[Prev in Thread] Current Thread [Next in Thread]