All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Shannon Zhao <zhaoshenglong@huawei.com>
Cc: peter.maydell@linaro.org, hangaohuai@huawei.com,
	a.spyridakis@virtualopensystems.com, claudio.fontana@huawei.com,
	qemu-devel@nongnu.org, wanghaibin.wang@huawei.com,
	peter.huangpeng@huawei.com, hanjun.guo@linaro.org,
	imammedo@redhat.com, pbonzini@redhat.com, lersek@redhat.com,
	christoffer.dall@linaro.org
Subject: Re: [Qemu-devel] [RFC PATCH 02/11] hw/arm/virt-acpi-build: Basic framework for building ACPI tables
Date: Sat, 24 Jan 2015 18:22:31 +0200	[thread overview]
Message-ID: <20150124162231.GB6293@redhat.com> (raw)
In-Reply-To: <1422091280-14532-3-git-send-email-zhaoshenglong@huawei.com>

On Sat, Jan 24, 2015 at 05:21:11PM +0800, Shannon Zhao wrote:
> Introduce a preliminary framework in virt-acpi-build.c with the main
> ACPI build functions. It exposes the generated ACPI contents to
> guest over fw_cfg. Some codes borrowed from hw/i386/acpi-build.c.
> 
> The minimum required ACPI v5.1 tables for ARM are:
> - RSDP: Initial table that points to XSDT
> - XSDT: Points to all other tables (except FACS & DSDT)
> - FADT: Generic information about the machine
> - DSDT: Holds all information about system devices/peripherals
> - FACS: Needs to be pointed from FADT
> 
> Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
> ---
>  hw/arm/Makefile.objs             |    1 +
>  hw/arm/virt-acpi-build.c         |  263 ++++++++++++++++++++++++++++++++++++++
>  include/hw/arm/virt-acpi-build.h |   71 ++++++++++
>  3 files changed, 335 insertions(+), 0 deletions(-)
>  create mode 100644 hw/arm/virt-acpi-build.c
>  create mode 100644 include/hw/arm/virt-acpi-build.h
> 
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index 6088e53..8daf825 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -3,6 +3,7 @@ obj-$(CONFIG_DIGIC) += digic_boards.o
>  obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
>  obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
>  obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
> +obj-$(CONFIG_ACPI) += virt-acpi-build.o
>  
>  obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
>  obj-$(CONFIG_DIGIC) += digic.o
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> new file mode 100644
> index 0000000..4eed0a3
> --- /dev/null
> +++ b/hw/arm/virt-acpi-build.c
> @@ -0,0 +1,263 @@
> +/* Support for generating ACPI tables and passing them to Guests
> + *
> + * ARM virt ACPI generation
> + *
> + * Copyright (c) 2014 HUAWEI TECHNOLOGIES CO.,LTD.
> + *
> + * Author: Shannon Zhao <zhaoshenglong@huawei.com>

Since you copied code over, you should append copyright and author
information from the original file to the new one.

> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "hw/arm/virt-acpi-build.h"
> +#include <stddef.h>
> +#include <glib.h>
> +#include "qemu-common.h"
> +#include "qemu/bitmap.h"
> +#include "qemu/osdep.h"
> +#include "qemu/range.h"
> +#include "qemu/error-report.h"
> +#include "qom/cpu.h"
> +#include "target-arm/cpu.h"
> +#include "hw/acpi/acpi-defs.h"
> +#include "hw/acpi/acpi.h"
> +#include "hw/nvram/fw_cfg.h"
> +#include "hw/acpi/bios-linker-loader.h"
> +#include "hw/loader.h"
> +
> +#include "hw/acpi/acpi-build-utils.h"
> +
> +#include "qapi/qmp/qint.h"
> +#include "qom/qom-qobject.h"
> +#include "exec/ram_addr.h"
> +
> +
> +#define ACPI_BUILD_TABLE_SIZE             0x20000
> +
> +/* Reserve RAM space for tables: add another order of magnitude. */
> +#define ACPI_BUILD_TABLE_MAX_SIZE         0x200000
> +
> +/* #define DEBUG_ACPI_BUILD */
> +#ifdef DEBUG_ACPI_BUILD
> +#define ACPI_BUILD_DPRINTF(fmt, ...)        \
> +    do {printf("ACPI_BUILD: " fmt, ## __VA_ARGS__); } while (0)
> +#else
> +#define ACPI_BUILD_DPRINTF(fmt, ...)
> +#endif
> +
> +#define ACPI_BUILD_APPNAME  "Bochs"
> +#define ACPI_BUILD_APPNAME6 "BOCHS "
> +
> +#define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
> +#define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
> +
> +static inline void *acpi_data_push(GArray *table_data, uint64_t size)
> +{
> +    unsigned off = table_data->len;
> +    g_array_set_size(table_data, off + size);
> +    return table_data->data + off;
> +}
> +
> +static unsigned acpi_data_len(GArray *table)
> +{
> +#if GLIB_CHECK_VERSION(2, 22, 0)
> +    assert(g_array_get_element_size(table) == 1);
> +#endif
> +    return table->len;
> +}
> +
> +static inline void acpi_add_table(GArray *table_offsets, GArray *table_data)
> +{
> +    uint32_t offset = cpu_to_le32(table_data->len);
> +    g_array_append_val(table_offsets, offset);
> +}
> +
> +/* RSDP */
> +static GArray *
> +build_rsdp(GArray *rsdp_table, GArray *linker, uint64_t xsdt)
> +{
> +    return rsdp_table;
> +}
> +
> +/* XSDT */
> +static void
> +build_xsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
> +{
> +}
> +
> +/* MADT */
> +static void
> +build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
> +{
> +}
> +
> +/* GTDT */
> +static void
> +build_gtdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
> +{
> +}
> +
> +/* FADT */
> +static void
> +build_fadt(GArray *table_data, GArray *linker, uint64_t facs, uint64_t dsdt)
> +{
> +}
> +
> +/* FACS */
> +static void
> +build_facs(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
> +{
> +}
> +
> +/* DSDT */
> +static void
> +build_dsdt(AcpiAml *table_aml, GArray *linker, VirtGuestInfo *guest_info)
> +{
> +}
> +
> +typedef
> +struct AcpiBuildTables {
> +    AcpiAml table_data;
> +    GArray *rsdp;
> +    GArray *tcpalog;
> +    GArray *linker;
> +} AcpiBuildTables;
> +
> +static inline void acpi_build_tables_init(AcpiBuildTables *tables)
> +{
> +    tables->rsdp = g_array_new(false, true /* clear */, 1);
> +    tables->table_data.buf = g_array_new(false, true /* clear */, 1);
> +    tables->tcpalog = g_array_new(false, true /* clear */, 1);
> +    tables->linker = bios_linker_loader_init();
> +    tables->table_data.linker = tables->linker;
> +}
> +
> +static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
> +{
> +    void *linker_data = bios_linker_loader_cleanup(tables->linker);
> +    g_free(linker_data);
> +    g_array_free(tables->rsdp, mfre);
> +    g_array_free(tables->table_data.buf, true);
> +    g_array_free(tables->tcpalog, mfre);
> +}
> +
> +typedef
> +struct AcpiBuildState {
> +    /* Copy of table in RAM (for patching). */
> +    ram_addr_t table_ram;
> +    uint32_t table_size;
> +    /* Is table patched? */
> +    uint8_t patched;
> +    VirtGuestInfo *guest_info;
> +} AcpiBuildState;
> +
> +static
> +void acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
> +{
> +    GArray *table_offsets;
> +    unsigned facs, dsdt, xsdt;
> +
> +    table_offsets = g_array_new(false, true /* clear */,
> +                                        sizeof(uint32_t));
> +    ACPI_BUILD_DPRINTF("init ACPI tables\n");
> +
> +    bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
> +                             64 /* Ensure FACS is aligned */,
> +                             false /* high memory */);
> +
> +    /*
> +     * FACS is pointed to by FADT.
> +     * We place it first since it's the only table that has alignment
> +     * requirements.
> +     */
> +    facs = tables->table_data.buf->len;
> +    build_facs(tables->table_data.buf, tables->linker, guest_info);
> +
> +    /* DSDT is pointed to by FADT */
> +    dsdt = tables->table_data.buf->len;
> +    build_dsdt(&tables->table_data, tables->linker, guest_info);
> +
> +    /* ACPI tables pointed to by XSDT */
> +    acpi_add_table(table_offsets, tables->table_data.buf);
> +    build_fadt(tables->table_data.buf, tables->linker, facs, dsdt);
> +
> +    acpi_add_table(table_offsets, tables->table_data.buf);
> +    build_madt(tables->table_data.buf, tables->linker, guest_info);
> +
> +    acpi_add_table(table_offsets, tables->table_data.buf);
> +    build_gtdt(tables->table_data.buf, tables->linker, guest_info);
> +
> +    /* XSDT is pointed to by RSDP */
> +    xsdt = tables->table_data.buf->len;
> +    build_xsdt(tables->table_data.buf, tables->linker, table_offsets);
> +
> +    /* RSDP is in FSEG memory, so allocate it separately */
> +    build_rsdp(tables->rsdp, tables->linker, xsdt);
> +
> +    /* Cleanup memory that's no longer used. */
> +    g_array_free(table_offsets, true);
> +}
> +
> +static ram_addr_t acpi_add_rom_blob(AcpiBuildState *build_state, GArray *blob,
> +                               const char *name, uint64_t max_size)
> +{
> +    return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1,
> +                        name, NULL, build_state);
> +}
> +
> +void virt_acpi_setup(VirtGuestInfo *guest_info)
> +{
> +    AcpiBuildTables tables;
> +    AcpiBuildState *build_state;
> +
> +    if (!guest_info->fw_cfg) {
> +        ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n");
> +        return;
> +    }
> +
> +    if (!acpi_enabled) {
> +        ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n");
> +        return;
> +    }
> +
> +    build_state = g_malloc0(sizeof *build_state);
> +    build_state->guest_info = guest_info;
> +
> +    acpi_build_tables_init(&tables);
> +    acpi_build(build_state->guest_info, &tables);
> +
> +    /* Now expose it all to Guest */
> +    build_state->table_ram = acpi_add_rom_blob(build_state,
> +                                               tables.table_data.buf,
> +                                               ACPI_BUILD_TABLE_FILE,
> +                                               ACPI_BUILD_TABLE_MAX_SIZE);
> +    assert(build_state->table_ram != RAM_ADDR_MAX);
> +    build_state->table_size = acpi_data_len(tables.table_data.buf);
> +
> +    acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader", 0);
> +
> +    fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
> +                    tables.tcpalog->data, acpi_data_len(tables.tcpalog));
> +
> +    /*
> +     * RSDP is small so it's easy to keep it immutable, no need to
> +     * bother with ROM blobs.
> +     */
> +    fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE,
> +                    tables.rsdp->data, acpi_data_len(tables.rsdp));
> +
> +    /* Cleanup tables but don't free the memory: we track it
> +     * in build_state.
> +     */
> +    acpi_build_tables_cleanup(&tables, false);
> +}
> diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
> new file mode 100644
> index 0000000..7a09c34
> --- /dev/null
> +++ b/include/hw/arm/virt-acpi-build.h
> @@ -0,0 +1,71 @@
> +/*
> + *
> + * Copyright (c) 2014 HUAWEI TECHNOLOGIES CO.,LTD.
> + *
> + * Author: Shannon Zhao <zhaoshenglong@huawei.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef QEMU_VIRT_ACPI_BUILD_H
> +#define QEMU_VIRT_ACPI_BUILD_H
> +
> +#include "qemu-common.h"
> +#include "hw/acpi/acpi-defs.h"
> +
> +
> +#define ACPI_VIRT_QEMU_STR_4 "QEMU"
> +#define ACPI_VIRT_QEMU_STR_6 "QEMU  "
> +#define ACPI_VIRT_MACH_STR_8 "MACHVIRT"
> +
> +struct acpi_gtdt_info {
> +    uint32_t timer_virt;
> +    uint32_t timer_s_el1;
> +    uint32_t timer_ns_el1;
> +    uint32_t timer_ns_el2;
> +};
> +
> +struct acpi_madt_info {
> +    const hwaddr *gic_cpu_base_addr;
> +    const hwaddr *gic_dist_base_addr;
> +};
> +
> +struct acpi_dsdt_info {
> +    const hwaddr *uart_addr;
> +    const int *uart_irq;
> +    const hwaddr *virtio_mmio_addr;
> +    const int *virtio_mmio_irq;
> +    int virtio_mmio_num;
> +    const hwaddr *rtc_addr;
> +    const int *rtc_irq;
> +    const hwaddr *flash_addr;
> +};
> +
> +typedef struct VirtGuestInfo {
> +    int nb_cpus;
> +    int max_cpus;
> +    FWCfgState *fw_cfg;
> +    const struct acpi_madt_info *madt_info;
> +    const struct acpi_dsdt_info *dsdt_info;
> +    const struct acpi_gtdt_info *gtdt_info;
> +} VirtGuestInfo;
> +
> +
> +typedef struct VirtGuestInfoState {
> +    VirtGuestInfo info;
> +    Notifier machine_done;
> +} VirtGuestInfoState;
> +
> +void virt_acpi_setup(VirtGuestInfo *guest_info);
> +
> +#endif
> -- 
> 1.7.1
> 

  reply	other threads:[~2015-01-24 16:23 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-24  9:21 [Qemu-devel] [RFC PATCH 00/11] Generate ACPI v5.1 tables and expose it to guest over fw_cfg on ARM Shannon Zhao
2015-01-24  9:21 ` [Qemu-devel] [RFC PATCH 01/11] hw/i386: Move ACPI header definitions in an arch-independent location Shannon Zhao
2015-01-24  9:21 ` [Qemu-devel] [RFC PATCH 02/11] hw/arm/virt-acpi-build: Basic framework for building ACPI tables Shannon Zhao
2015-01-24 16:22   ` Michael S. Tsirkin [this message]
2015-01-26  2:37     ` Shannon Zhao
2015-01-26 10:19   ` Igor Mammedov
2015-01-27  6:47     ` Shannon Zhao
2015-01-27 10:30       ` Igor Mammedov
2015-01-28  6:28         ` Shannon Zhao
2015-01-27 12:12   ` Hanjun Guo
2015-01-24  9:21 ` [Qemu-devel] [RFC PATCH 03/11] hw/arm/virt-acpi-build: Generate RSDP table Shannon Zhao
2015-01-26 10:22   ` Igor Mammedov
2015-01-27  6:50     ` Shannon Zhao
2015-01-27  9:36     ` Shannon Zhao
2015-01-27  9:42       ` Igor Mammedov
2015-01-24  9:21 ` [Qemu-devel] [RFC PATCH 04/11] hw/arm/virt-acpi-build: Generate XSDT table and add a build_header function Shannon Zhao
2015-01-24 22:04   ` Laszlo Ersek
2015-01-26  1:45     ` Shannon Zhao
2015-01-24  9:21 ` [Qemu-devel] [RFC PATCH 05/11] hw/arm/virt-acpi-build: Generate MADT table Shannon Zhao
2015-01-24  9:21 ` [Qemu-devel] [RFC PATCH 06/11] hw/arm/virt-acpi-build: Generate GTDT table Shannon Zhao
2015-01-24  9:21 ` [Qemu-devel] [RFC PATCH 07/11] hw/arm/virt-acpi-build: Generate FADT table and update ACPI headers Shannon Zhao
2015-01-24 22:05   ` Laszlo Ersek
2015-01-26  1:48     ` Shannon Zhao
2015-01-24  9:21 ` [Qemu-devel] [RFC PATCH 08/11] hw/arm/virt-acpi-build: Generate FACS " Shannon Zhao
2015-01-24  9:21 ` [Qemu-devel] [RFC PATCH 09/11] hw/acpi/acpi-build-utils: Add acpi_fixed_memory32() and acpi_extended_irq() Shannon Zhao
2015-01-25  8:39   ` Michael S. Tsirkin
2015-01-26  1:58     ` Shannon Zhao
2015-01-26 10:46     ` Igor Mammedov
2015-01-24  9:21 ` [Qemu-devel] [RFC PATCH 10/11] hw/arm/virt-acpi-build: Generation of DSDT table for virt devices Shannon Zhao
2015-01-26 10:40   ` Igor Mammedov
2015-01-27  7:19     ` Shannon Zhao
2015-01-24  9:21 ` [Qemu-devel] [RFC PATCH 11/11] hw/arm/virt: Enable dynamic generation of ACPI v5.1 tables Shannon Zhao
2015-01-24 18:56   ` Laszlo Ersek
2015-01-26  1:59     ` Shannon Zhao
2015-01-24 23:31 ` [Qemu-devel] [RFC PATCH 00/11] Generate ACPI v5.1 tables and expose it to guest over fw_cfg on ARM Laszlo Ersek
2015-01-26  2:34   ` Shannon Zhao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150124162231.GB6293@redhat.com \
    --to=mst@redhat.com \
    --cc=a.spyridakis@virtualopensystems.com \
    --cc=christoffer.dall@linaro.org \
    --cc=claudio.fontana@huawei.com \
    --cc=hangaohuai@huawei.com \
    --cc=hanjun.guo@linaro.org \
    --cc=imammedo@redhat.com \
    --cc=lersek@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.huangpeng@huawei.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=wanghaibin.wang@huawei.com \
    --cc=zhaoshenglong@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.