From: Xuemei Liu <liu.xuemei1@zte.com.cn>
This patch adds ACPI Generic Event Device (GED) support to
the RISC-V virt machine.
Co-authored-by: Björn Töpel <bjorn@rivosinc.com>
Signed-off-by: Xuemei Liu <liu.xuemei1@zte.com.cn>
---
hw/riscv/Kconfig | 1 +
hw/riscv/virt-acpi-build.c | 6 ++++++
hw/riscv/virt.c | 23 +++++++++++++++++++++++
include/hw/riscv/virt.h | 3 +++
4 files changed, 33 insertions(+)
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 0222c93f87..3dad43669f 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -68,6 +68,7 @@ config RISCV_VIRT
select PLATFORM_BUS
select ACPI
select ACPI_PCI
+ select ACPI_HW_REDUCED
config SHAKTI_C
bool
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index f1406cb683..1717b1c24f 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -27,6 +27,7 @@
#include "hw/acpi/acpi-defs.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/aml-build.h"
+#include "hw/acpi/generic_event_device.h"
#include "hw/acpi/pci.h"
#include "hw/acpi/utils.h"
#include "hw/intc/riscv_aclint.h"
@@ -498,6 +499,11 @@ static void build_dsdt(GArray *table_data,
acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES * 2);
}
+ build_ged_aml(scope, "\\_SB."GED_DEVICE,
+ HOTPLUG_HANDLER(s->acpi_ged),
+ ACPI_GED_IRQ, AML_SYSTEM_MEMORY,
+ s->memmap[VIRT_ACPI_GED].base);
+
aml_append(dsdt, scope);
/* copy AML table into ACPI tables blob and patch header there */
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index bd8608ea5b..1d7011b952 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -55,6 +55,7 @@
#include "hw/pci-host/gpex.h"
#include "hw/display/ramfb.h"
#include "hw/acpi/aml-build.h"
+#include "hw/acpi/generic_event_device.h"
#include "qapi/qapi-visit-common.h"
#include "hw/virtio/virtio-iommu.h"
#include "hw/uefi/var-service-api.h"
@@ -95,6 +96,7 @@ static const MemMapEntry virt_memmap[] = {
[VIRT_UART0] = { 0x10000000, 0x100 },
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
[VIRT_FW_CFG] = { 0x10100000, 0x18 },
+ [VIRT_ACPI_GED] = { 0x10101000, ACPI_GED_EVT_SEL_LEN },
[VIRT_FLASH] = { 0x20000000, 0x4000000 },
[VIRT_IMSIC_M] = { 0x24000000, VIRT_IMSIC_MAX_SIZE },
[VIRT_IMSIC_S] = { 0x28000000, VIRT_IMSIC_MAX_SIZE },
@@ -1270,6 +1272,22 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
return dev;
}
+static DeviceState *create_acpi_ged(RISCVVirtState *s, DeviceState *irqchip)
+{
+ DeviceState *dev;
+ uint32_t event = ACPI_GED_PWR_DOWN_EVT;
+
+ dev = qdev_new(TYPE_ACPI_GED);
+ qdev_prop_set_uint32(dev, "ged-event", event);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, s->memmap[VIRT_ACPI_GED].base);
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
+ qdev_get_gpio_in(irqchip, ACPI_GED_IRQ));
+
+ return dev;
+}
+
static FWCfgState *create_fw_cfg(const MachineState *ms, hwaddr base)
{
FWCfgState *fw_cfg;
@@ -1702,6 +1720,11 @@ static void virt_machine_init(MachineState *machine)
create_platform_bus(s, mmio_irqchip);
+ /* acpi ged */
+ if (virt_is_acpi_enabled(s)) {
+ s->acpi_ged = create_acpi_ged(s, mmio_irqchip);
+ }
+
serial_mm_init(system_memory, s->memmap[VIRT_UART0].base,
0, qdev_get_gpio_in(mmio_irqchip, UART0_IRQ), 399193,
serial_hd(0), DEVICE_LITTLE_ENDIAN);
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 18a2a323a3..9ea0b3b7b6 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -47,6 +47,7 @@ struct RISCVVirtState {
/*< public >*/
Notifier machine_done;
+ DeviceState *acpi_ged;
DeviceState *platform_bus_dev;
RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
DeviceState *irqchip[VIRT_SOCKETS_MAX];
@@ -88,9 +89,11 @@ enum {
VIRT_PLATFORM_BUS,
VIRT_PCIE_ECAM,
VIRT_IOMMU_SYS,
+ VIRT_ACPI_GED,
};
enum {
+ ACPI_GED_IRQ = 9,
UART0_IRQ = 10,
RTC_IRQ = 11,
VIRTIO_IRQ = 1, /* 1 to 8 */
--
2.27.0