[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v9 08/24] hw/arm/virt-acpi-build: Generate FADT
From: |
Shannon Zhao |
Subject: |
Re: [Qemu-devel] [PATCH v9 08/24] hw/arm/virt-acpi-build: Generate FADT table and update ACPI headers |
Date: |
Wed, 27 May 2015 16:36:37 +0800 |
User-agent: |
Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Thunderbird/24.4.0 |
On 2015/5/27 16:25, Alex Bennée wrote:
>
> Shannon Zhao <address@hidden> writes:
>
>> 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 | 135
>> ++++++++++++++++++++++++++++++++------------
>> 2 files changed, 129 insertions(+), 37 deletions(-)
>>
>> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
>> index 2cf2cc5..0791501 100644
>> --- a/hw/arm/virt-acpi-build.c
>> +++ b/hw/arm/virt-acpi-build.c
>> @@ -137,6 +137,31 @@ static void acpi_dsdt_add_virtio(Aml *scope,
>> }
>> }
>>
>> +/* 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));
>
> So the ACPI_FADT_* symbols are actually bit positions. Perhaps naming
> them *_SHIFT will make that clearer else where.
>
>> +
>> + /* 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)
>> @@ -183,6 +208,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 */,
>> @@ -202,8 +228,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..fadcf84 100644
>> --- a/include/hw/acpi/acpi-defs.h
>> +++ b/include/hw/acpi/acpi-defs.h
>> @@ -88,46 +88,54 @@ 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 */ \
>> + /* Value to write to SMI CMD to enter S4BIOS state */ \
>> + uint8_t S4bios_req; \
>> + uint8_t reserved2; /* Reserved - must be zero */ \
>> + /* Port address of Power Mgt 1a acpi_event Reg Blk */ \
>> + uint32_t pm1a_evt_blk; \
>> + /* Port address of Power Mgt 1b acpi_event Reg Blk */ \
>> + uint32_t pm1b_evt_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
>> */ \
>> + /* Port addr of General Purpose acpi_event 0 Reg Blk */ \
>> + uint32_t gpe0_blk; \
>> + /* Port addr of General Purpose acpi_event 1 Reg Blk */ \
>> + uint32_t gpe1_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 +143,59 @@ struct AcpiFadtDescriptorRev1
>> } QEMU_PACKED;
>> typedef struct AcpiFadtDescriptorRev1 AcpiFadtDescriptorRev1;
>>
>> +struct AcpiGenericAddress {
>> + 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
>> + /* IA-PC Boot Architecture Flags (see below for individual flags) */
>> + uint16_t boot_flags;
>> + uint8_t reserved; /* Reserved, must be zero */
>> + /* Miscellaneous flag bits (see below for individual flags) */
>> + uint32_t flags;
>> + /* 64-bit address of the Reset register */
>> + struct AcpiGenericAddress reset_register;
>> + /* Value to write to the reset_register port to reset the system */
>> + uint8_t reset_value;
>> + /* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1)
>> */
>> + uint16_t arm_boot_flags;
>> + 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 */
>> + /* 64-bit Extended Power Mgt 1a Event Reg Blk address */
>> + struct AcpiGenericAddress xpm1a_event_block;
>> + /* 64-bit Extended Power Mgt 1b Event Reg Blk address */
>> + struct AcpiGenericAddress xpm1b_event_block;
>> + /* 64-bit Extended Power Mgt 1a Control Reg Blk address */
>> + struct AcpiGenericAddress xpm1a_control_block;
>> + /* 64-bit Extended Power Mgt 1b Control Reg Blk address */
>> + struct AcpiGenericAddress xpm1b_control_block;
>> + /* 64-bit Extended Power Mgt 2 Control Reg Blk address */
>> + struct AcpiGenericAddress xpm2_control_block;
>> + /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
>> + struct AcpiGenericAddress xpm_timer_block;
>> + /* 64-bit Extended General Purpose Event 0 Reg Blk address */
>> + struct AcpiGenericAddress xgpe0_block;
>> + /* 64-bit Extended General Purpose Event 1 Reg Blk address */
>> + struct AcpiGenericAddress xgpe1_block;
>> + /* 64-bit Sleep Control register (ACPI 5.0) */
>> + struct AcpiGenericAddress sleep_control;
>> + /* 64-bit Sleep Status register (ACPI 5.0) */
>> + struct AcpiGenericAddress sleep_status;
>> +} QEMU_PACKED;
>> +
>> +typedef struct AcpiFadtDescriptorRev5_1 AcpiFadtDescriptorRev5_1;
>> +
>> +enum {
>> + ACPI_FADT_ARM_USE_PSCI_G_0_2 = 0,
>> + ACPI_FADT_ARM_PSCI_USE_HVC = 1,
>> +};
>
> Where do these names come from? Are they really ARM specific?
>
>From ACPI 5.1 spec:
Table 5-37 Fixed ACPI Description Table ARM Boot Architecture Flags
> I'm not sure what the benefit of the enum is here over a #define,
> especially if the values mean something to the outside world. If it was
> being passed around and we were doing type checking it would make more
> sense.
>
>> +
>> /*
>> * ACPI 1.0 Root System Description Table (RSDT)
>> */
>
--
Shannon
- [Qemu-devel] [PATCH v9 03/24] hw/arm/virt: Record PCIe ranges in MemMapEntry array, (continued)
- [Qemu-devel] [PATCH v9 03/24] hw/arm/virt: Record PCIe ranges in MemMapEntry array, Shannon Zhao, 2015/05/24
- [Qemu-devel] [PATCH v9 06/24] hw/acpi/aml-build: Add aml_interrupt() term, Shannon Zhao, 2015/05/24
- [Qemu-devel] [PATCH v9 01/24] hw/acpi/aml-build: Make enum values to be upper case to match coding style, Shannon Zhao, 2015/05/24
- [Qemu-devel] [PATCH v9 04/24] hw/arm/virt-acpi-build: Basic framework for building ACPI tables on ARM, Shannon Zhao, 2015/05/24
- [Qemu-devel] [PATCH v9 05/24] hw/acpi/aml-build: Add aml_memory32_fixed() term, Shannon Zhao, 2015/05/24
- [Qemu-devel] [PATCH v9 07/24] hw/arm/virt-acpi-build: Generation of DSDT table for virt devices, Shannon Zhao, 2015/05/24
- [Qemu-devel] [PATCH v9 08/24] hw/arm/virt-acpi-build: Generate FADT table and update ACPI headers, Shannon Zhao, 2015/05/24
- [Qemu-devel] [PATCH v9 09/24] hw/arm/virt-acpi-build: Generate MADT table, Shannon Zhao, 2015/05/24
[Qemu-devel] [PATCH v9 13/24] hw/arm/virt-acpi-build: Generate MCFG table, Shannon Zhao, 2015/05/24
[Qemu-devel] [PATCH v9 17/24] hw/acpi/aml-build: Add aml_lnot() term, Shannon Zhao, 2015/05/24
[Qemu-devel] [PATCH v9 18/24] hw/acpi/aml-build: Add aml_else() term, Shannon Zhao, 2015/05/24