Add basic IO controllers and devices like PCI, VirtIO and UART in the
ACPI namespace.
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/riscv/Kconfig | 1 +
hw/riscv/virt-acpi-build.c | 79 ++++++++++++++++++++++++++++++++++++--
2 files changed, 76 insertions(+), 4 deletions(-)
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index b6a5eb4452..a50717be87 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -45,6 +45,7 @@ config RISCV_VIRT
select FW_CFG_DMA
select PLATFORM_BUS
select ACPI
+ select ACPI_PCI
config SHAKTI_C
bool
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 86c38f7c2b..4d03a27efd 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -27,15 +27,18 @@
#include "hw/acpi/acpi-defs.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/aml-build.h"
+#include "hw/acpi/pci.h"
#include "hw/acpi/utils.h"
+#include "hw/intc/riscv_aclint.h"
#include "hw/nvram/fw_cfg_acpi.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/riscv/virt.h"
+#include "hw/riscv/numa.h"
+#include "hw/virtio/virtio-acpi.h"
+#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "sysemu/reset.h"
-#include "migration/vmstate.h"
-#include "hw/riscv/virt.h"
-#include "hw/riscv/numa.h"
-#include "hw/intc/riscv_aclint.h"
#define ACPI_BUILD_TABLE_SIZE 0x20000
#define ACPI_BUILD_INTC_ID(socket, index) ((socket << 24) | (index))
@@ -132,6 +135,39 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s)
}
}
+static void
+acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
+ uint32_t uart_irq)
+{
+ Aml *dev = aml_device("COM0");
+ aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501")));
+ aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+
+ Aml *crs = aml_resource_template();
+ aml_append(crs, aml_memory32_fixed(uart_memmap->base,
+ uart_memmap->size, AML_READ_WRITE));
+ aml_append(crs,
+ aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
+ AML_EXCLUSIVE, &uart_irq, 1));
+ aml_append(dev, aml_name_decl("_CRS", crs));
+
+ Aml *pkg = aml_package(2);
+ aml_append(pkg, aml_string("clock-frequency"));
+ aml_append(pkg, aml_int(3686400));
+
+ Aml *UUID = aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301");
+
+ Aml *pkg1 = aml_package(1);
+ aml_append(pkg1, pkg);
+
+ Aml *package = aml_package(2);
+ aml_append(package, UUID);
+ aml_append(package, pkg1);
+
+ aml_append(dev, aml_name_decl("_DSD", package));
+ aml_append(scope, dev);
+}
+
/* RHCT Node[N] starts at offset 56 */
#define RHCT_NODE_ARRAY_OFFSET 56
@@ -310,6 +346,8 @@ static void build_dsdt(GArray *table_data,
RISCVVirtState *s)
{
Aml *scope, *dsdt;
+ MachineState *ms = MACHINE(s);
+ uint8_t socket_count;
const MemMapEntry *memmap = s->memmap;
AcpiTable table = { .sig = "DSDT", .rev = 2, .oem_id = s->oem_id,
.oem_table_id = s->oem_table_id };
@@ -329,6 +367,29 @@ static void build_dsdt(GArray *table_data,
fw_cfg_acpi_dsdt_add(scope, &memmap[VIRT_FW_CFG]);
+ socket_count = riscv_socket_count(ms);
+
+ acpi_dsdt_add_uart(scope, &memmap[VIRT_UART0], UART0_IRQ);
+
+ if (socket_count == 1) {
+ virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
+ memmap[VIRT_VIRTIO].size,
+ VIRTIO_IRQ, 0, VIRTIO_COUNT);
+ acpi_dsdt_add_gpex_host(scope, PCIE_IRQ);
+ } else if (socket_count == 2) {
+ virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
+ memmap[VIRT_VIRTIO].size,
+ VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
+ VIRTIO_COUNT);
+ acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES);
+ } else {
+ virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
+ memmap[VIRT_VIRTIO].size,
+ VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
+ VIRTIO_COUNT);
+ acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES * 2);
+ }
+
aml_append(dsdt, scope);
/* copy AML table into ACPI tables blob and patch header there */
@@ -465,6 +526,16 @@ static void virt_acpi_build(RISCVVirtState *s, AcpiBuildTables *tables)
acpi_add_table(table_offsets, tables_blob);
build_rhct(tables_blob, tables->linker, s);
+ acpi_add_table(table_offsets, tables_blob);
+ {
+ AcpiMcfgInfo mcfg = {
+ .base = s->memmap[VIRT_PCIE_MMIO].base,
+ .size = s->memmap[VIRT_PCIE_MMIO].size,
+ };
+ build_mcfg(tables_blob, tables->linker, &mcfg, s->oem_id,
+ s->oem_table_id);
+ }
+
/* XSDT is pointed to by RSDP */
xsdt = tables_blob->len;
build_xsdt(tables_blob, tables->linker, table_offsets, s->oem_id,
--
2.39.2