Re: [PATCH 5/6] hw/loongarch: Add acpi ged support

2022-07-28 Thread gaosong



On 2022/7/28 下午10:03, Igor Mammedov wrote:

On Tue, 12 Jul 2022 16:32:05 +0800
Xiaojuan Yang  wrote:


Loongarch virt machine uses general hardware reduces acpi method, rather
than LS7A acpi device. Now only power management function is used in
acpi ged device, memory hotplug will be added later. Also acpi tables
such as RSDP/RSDT/FADT etc.

The acpi table has submited to acpi spec, and will release soon.

Signed-off-by: Xiaojuan Yang 
---
  hw/loongarch/Kconfig|   2 +
  hw/loongarch/acpi-build.c   | 609 
  hw/loongarch/loongson3.c|  78 -
  hw/loongarch/meson.build|   1 +
  include/hw/loongarch/virt.h |  13 +
  include/hw/pci-host/ls7a.h  |   4 +
  6 files changed, 704 insertions(+), 3 deletions(-)
  create mode 100644 hw/loongarch/acpi-build.c

diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index 610552e522..a99aa387c3 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -15,3 +15,5 @@ config LOONGARCH_VIRT
  select LOONGARCH_EXTIOI
  select LS7A_RTC
  select SMBIOS
+select ACPI_PCI
+select ACPI_HW_REDUCED
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
new file mode 100644
index 00..b95b83b079
--- /dev/null
+++ b/hw/loongarch/acpi-build.c

[...]


Most of the following code copied from x86 which is needlessly
complicated for loongarch wich doesn't have all that legacy to care about,
see ARM's variant virt_acpi_setup() for a cleaner example and
drop not needed parts.

Thanks for you review, We will send a patch to clean the code.

Thanks.
Song Gao

+static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
+{
+LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
+GArray *table_offsets;
+AcpiFadtData fadt_data;
+unsigned facs, rsdt, fadt, dsdt;
+uint8_t *u;
+size_t aml_len = 0;
+GArray *tables_blob = tables->table_data;
+
+init_common_fadt_data(&fadt_data);
+
+table_offsets = g_array_new(false, true, sizeof(uint32_t));
+ACPI_BUILD_DPRINTF("init ACPI tables\n");
+
+bios_linker_loader_alloc(tables->linker,
+ ACPI_BUILD_TABLE_FILE, tables_blob,
+ 64, false);
+
+/*
+ * FACS is pointed to by FADT.
+ * We place it first since it's the only table that has alignment
+ * requirements.
+ */
+facs = tables_blob->len;
+build_facs(tables_blob);
+
+/* DSDT is pointed to by FADT */
+dsdt = tables_blob->len;
+build_dsdt(tables_blob, tables->linker, machine);
+
+/*
+ * Count the size of the DSDT, we will need it for
+ * legacy sizing of ACPI tables.
+ */
+aml_len += tables_blob->len - dsdt;
+
+/* ACPI tables pointed to by RSDT */
+fadt = tables_blob->len;
+acpi_add_table(table_offsets, tables_blob);
+fadt_data.facs_tbl_offset = &facs;
+fadt_data.dsdt_tbl_offset = &dsdt;
+fadt_data.xdsdt_tbl_offset = &dsdt;
+build_fadt(tables_blob, tables->linker, &fadt_data,
+   lams->oem_id, lams->oem_table_id);
+aml_len += tables_blob->len - fadt;
+
+acpi_add_table(table_offsets, tables_blob);
+build_madt(tables_blob, tables->linker, lams);
+
+acpi_add_table(table_offsets, tables_blob);
+build_srat(tables_blob, tables->linker, machine);
+
+acpi_add_table(table_offsets, tables_blob);
+{
+AcpiMcfgInfo mcfg = {
+   .base = cpu_to_le64(LS_PCIECFG_BASE),
+   .size = cpu_to_le64(LS_PCIECFG_SIZE),
+};
+build_mcfg(tables_blob, tables->linker, &mcfg, lams->oem_id,
+   lams->oem_table_id);
+}
+
+/* Add tables supplied by user (if any) */
+for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
+unsigned len = acpi_table_len(u);
+
+acpi_add_table(table_offsets, tables_blob);
+g_array_append_vals(tables_blob, u, len);
+}
+
+/* RSDT is pointed to by RSDP */
+rsdt = tables_blob->len;
+build_rsdt(tables_blob, tables->linker, table_offsets,
+   lams->oem_id, lams->oem_table_id);
+
+/* RSDP is in FSEG memory, so allocate it separately */
+{
+AcpiRsdpData rsdp_data = {
+.revision = 0,
+.oem_id = lams->oem_id,
+.xsdt_tbl_offset = NULL,
+.rsdt_tbl_offset = &rsdt,
+};
+build_rsdp(tables->rsdp, tables->linker, &rsdp_data);
+}
+
+/*
+ * The align size is 128, warn if 64k is not enough therefore
+ * the align size could be resized.
+ */
+if (tables_blob->len > ACPI_BUILD_TABLE_SIZE / 2) {
+warn_report("ACPI table size %u exceeds %d bytes,"
+" migration may not work",
+tables_blob->len, ACPI_BUILD_TABLE_SIZE / 2);
+error_printf("Try removing CPUs, NUMA nodes, memory slots"
+ " or PCI bridges.");
+}
+
+acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE);
+
+/* Cleanup memory t

Re: [PATCH 5/6] hw/loongarch: Add acpi ged support

2022-07-28 Thread Igor Mammedov
On Tue, 12 Jul 2022 16:32:05 +0800
Xiaojuan Yang  wrote:

> Loongarch virt machine uses general hardware reduces acpi method, rather
> than LS7A acpi device. Now only power management function is used in
> acpi ged device, memory hotplug will be added later. Also acpi tables
> such as RSDP/RSDT/FADT etc.
> 
> The acpi table has submited to acpi spec, and will release soon.
> 
> Signed-off-by: Xiaojuan Yang 
> ---
>  hw/loongarch/Kconfig|   2 +
>  hw/loongarch/acpi-build.c   | 609 
>  hw/loongarch/loongson3.c|  78 -
>  hw/loongarch/meson.build|   1 +
>  include/hw/loongarch/virt.h |  13 +
>  include/hw/pci-host/ls7a.h  |   4 +
>  6 files changed, 704 insertions(+), 3 deletions(-)
>  create mode 100644 hw/loongarch/acpi-build.c
> 
> diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
> index 610552e522..a99aa387c3 100644
> --- a/hw/loongarch/Kconfig
> +++ b/hw/loongarch/Kconfig
> @@ -15,3 +15,5 @@ config LOONGARCH_VIRT
>  select LOONGARCH_EXTIOI
>  select LS7A_RTC
>  select SMBIOS
> +select ACPI_PCI
> +select ACPI_HW_REDUCED
> diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
> new file mode 100644
> index 00..b95b83b079
> --- /dev/null
> +++ b/hw/loongarch/acpi-build.c
[...]


Most of the following code copied from x86 which is needlessly
complicated for loongarch wich doesn't have all that legacy to care about,
see ARM's variant virt_acpi_setup() for a cleaner example and
drop not needed parts.

> +static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
> +{
> +LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
> +GArray *table_offsets;
> +AcpiFadtData fadt_data;
> +unsigned facs, rsdt, fadt, dsdt;
> +uint8_t *u;
> +size_t aml_len = 0;
> +GArray *tables_blob = tables->table_data;
> +
> +init_common_fadt_data(&fadt_data);
> +
> +table_offsets = g_array_new(false, true, sizeof(uint32_t));
> +ACPI_BUILD_DPRINTF("init ACPI tables\n");
> +
> +bios_linker_loader_alloc(tables->linker,
> + ACPI_BUILD_TABLE_FILE, tables_blob,
> + 64, false);
> +
> +/*
> + * FACS is pointed to by FADT.
> + * We place it first since it's the only table that has alignment
> + * requirements.
> + */
> +facs = tables_blob->len;
> +build_facs(tables_blob);
> +
> +/* DSDT is pointed to by FADT */
> +dsdt = tables_blob->len;
> +build_dsdt(tables_blob, tables->linker, machine);
> +
> +/*
> + * Count the size of the DSDT, we will need it for
> + * legacy sizing of ACPI tables.
> + */
> +aml_len += tables_blob->len - dsdt;
> +
> +/* ACPI tables pointed to by RSDT */
> +fadt = tables_blob->len;
> +acpi_add_table(table_offsets, tables_blob);
> +fadt_data.facs_tbl_offset = &facs;
> +fadt_data.dsdt_tbl_offset = &dsdt;
> +fadt_data.xdsdt_tbl_offset = &dsdt;
> +build_fadt(tables_blob, tables->linker, &fadt_data,
> +   lams->oem_id, lams->oem_table_id);
> +aml_len += tables_blob->len - fadt;
> +
> +acpi_add_table(table_offsets, tables_blob);
> +build_madt(tables_blob, tables->linker, lams);
> +
> +acpi_add_table(table_offsets, tables_blob);
> +build_srat(tables_blob, tables->linker, machine);
> +
> +acpi_add_table(table_offsets, tables_blob);
> +{
> +AcpiMcfgInfo mcfg = {
> +   .base = cpu_to_le64(LS_PCIECFG_BASE),
> +   .size = cpu_to_le64(LS_PCIECFG_SIZE),
> +};
> +build_mcfg(tables_blob, tables->linker, &mcfg, lams->oem_id,
> +   lams->oem_table_id);
> +}
> +
> +/* Add tables supplied by user (if any) */
> +for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
> +unsigned len = acpi_table_len(u);
> +
> +acpi_add_table(table_offsets, tables_blob);
> +g_array_append_vals(tables_blob, u, len);
> +}
> +
> +/* RSDT is pointed to by RSDP */
> +rsdt = tables_blob->len;
> +build_rsdt(tables_blob, tables->linker, table_offsets,
> +   lams->oem_id, lams->oem_table_id);
> +
> +/* RSDP is in FSEG memory, so allocate it separately */
> +{
> +AcpiRsdpData rsdp_data = {
> +.revision = 0,
> +.oem_id = lams->oem_id,
> +.xsdt_tbl_offset = NULL,
> +.rsdt_tbl_offset = &rsdt,
> +};
> +build_rsdp(tables->rsdp, tables->linker, &rsdp_data);
> +}
> +
> +/*
> + * The align size is 128, warn if 64k is not enough therefore
> + * the align size could be resized.
> + */
> +if (tables_blob->len > ACPI_BUILD_TABLE_SIZE / 2) {
> +warn_report("ACPI table size %u exceeds %d bytes,"
> +" migration may not work",
> +tables_blob->len, ACPI_BUILD_TABLE_SIZE / 2);
> +error_printf("Try removing CPUs, NUMA nodes, memory slots"
> + " or PCI 

Re: [PATCH 5/6] hw/loongarch: Add acpi ged support

2022-07-19 Thread Richard Henderson

On 7/12/22 14:02, Xiaojuan Yang wrote:

Loongarch virt machine uses general hardware reduces acpi method, rather
than LS7A acpi device. Now only power management function is used in
acpi ged device, memory hotplug will be added later. Also acpi tables
such as RSDP/RSDT/FADT etc.

The acpi table has submited to acpi spec, and will release soon.

Signed-off-by: Xiaojuan Yang
---
  hw/loongarch/Kconfig|   2 +
  hw/loongarch/acpi-build.c   | 609 
  hw/loongarch/loongson3.c|  78 -
  hw/loongarch/meson.build|   1 +
  include/hw/loongarch/virt.h |  13 +
  include/hw/pci-host/ls7a.h  |   4 +
  6 files changed, 704 insertions(+), 3 deletions(-)
  create mode 100644 hw/loongarch/acpi-build.c


I'm not familiar with this at all, but it looks plausible.

Acked-by: Richard Henderson 


r~



[PATCH 5/6] hw/loongarch: Add acpi ged support

2022-07-12 Thread Xiaojuan Yang
Loongarch virt machine uses general hardware reduces acpi method, rather
than LS7A acpi device. Now only power management function is used in
acpi ged device, memory hotplug will be added later. Also acpi tables
such as RSDP/RSDT/FADT etc.

The acpi table has submited to acpi spec, and will release soon.

Signed-off-by: Xiaojuan Yang 
---
 hw/loongarch/Kconfig|   2 +
 hw/loongarch/acpi-build.c   | 609 
 hw/loongarch/loongson3.c|  78 -
 hw/loongarch/meson.build|   1 +
 include/hw/loongarch/virt.h |  13 +
 include/hw/pci-host/ls7a.h  |   4 +
 6 files changed, 704 insertions(+), 3 deletions(-)
 create mode 100644 hw/loongarch/acpi-build.c

diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index 610552e522..a99aa387c3 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -15,3 +15,5 @@ config LOONGARCH_VIRT
 select LOONGARCH_EXTIOI
 select LS7A_RTC
 select SMBIOS
+select ACPI_PCI
+select ACPI_HW_REDUCED
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
new file mode 100644
index 00..b95b83b079
--- /dev/null
+++ b/hw/loongarch/acpi-build.c
@@ -0,0 +1,609 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Support for generating ACPI tables and passing them to Guests
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/bitmap.h"
+#include "hw/pci/pci.h"
+#include "hw/core/cpu.h"
+#include "target/loongarch/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 "migration/vmstate.h"
+#include "hw/mem/memory-device.h"
+#include "sysemu/reset.h"
+
+/* Supported chipsets: */
+#include "hw/pci-host/ls7a.h"
+#include "hw/loongarch/virt.h"
+#include "hw/acpi/aml-build.h"
+
+#include "hw/acpi/utils.h"
+#include "hw/acpi/pci.h"
+
+#include "qom/qom-qobject.h"
+
+#include "hw/acpi/generic_event_device.h"
+
+#define ACPI_BUILD_ALIGN_SIZE 0x1000
+#define ACPI_BUILD_TABLE_SIZE 0x2
+
+#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
+
+/* build FADT */
+static void init_common_fadt_data(AcpiFadtData *data)
+{
+AcpiFadtData fadt = {
+/* ACPI 5.0: 4.1 Hardware-Reduced ACPI */
+.rev = 5,
+.flags = ((1 << ACPI_FADT_F_HW_REDUCED_ACPI) |
+  (1 << ACPI_FADT_F_RESET_REG_SUP)),
+
+/* ACPI 5.0: 4.8.3.7 Sleep Control and Status Registers */
+.sleep_ctl = {
+.space_id = AML_AS_SYSTEM_MEMORY,
+.bit_width = 8,
+.address = VIRT_GED_REG_ADDR + ACPI_GED_REG_SLEEP_CTL,
+},
+.sleep_sts = {
+.space_id = AML_AS_SYSTEM_MEMORY,
+.bit_width = 8,
+.address = VIRT_GED_REG_ADDR + ACPI_GED_REG_SLEEP_STS,
+},
+
+/* ACPI 5.0: 4.8.3.6 Reset Register */
+.reset_reg = {
+.space_id = AML_AS_SYSTEM_MEMORY,
+.bit_width = 8,
+.address = VIRT_GED_REG_ADDR + ACPI_GED_REG_RESET,
+},
+.reset_val = ACPI_GED_RESET_VALUE,
+};
+*data = fadt;
+}
+
+static void acpi_align_size(GArray *blob, unsigned align)
+{
+/*
+ * Align size to multiple of given size. This reduces the chance
+ * we need to change size in the future (breaking cross version migration).
+ */
+g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align));
+}
+
+/* build FACS */
+static void
+build_facs(GArray *table_data)
+{
+const char *sig = "FACS";
+const uint8_t reserved[40] = {};
+
+g_array_append_vals(table_data, sig, 4); /* Signature */
+build_append_int_noprefix(table_data, 64, 4); /* Length */
+build_append_int_noprefix(table_data, 0, 4); /* Hardware Signature */
+build_append_int_noprefix(table_data, 0, 4); /* Firmware Waking Vector */
+build_append_int_noprefix(table_data, 0, 4); /* Global Lock */
+build_append_int_noprefix(table_data, 0, 4); /* Flags */
+g_array_append_vals(table_data, reserved, 40); /* Reserved */
+}
+
+/* build MADT */
+static void
+build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams)
+{
+MachineState *ms = MACHINE(lams);
+int i;
+AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lams->oem_id,
+.oem_table_id = lams->oem_table_id };
+
+acpi_table_begin(&table, table_data);
+
+/* Local APIC Address */
+build_append_int_noprefix(table_data, 0, 4);
+build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */
+
+for (i = 0; i < ms->smp.cpus; i++) {
+/* Processor Core Interrupt Controller Structure */
+build_append_int_noprefix(table_data, 17, 1);/* Type */
+build_append_int_noprefix(table_data, 15, 1);/