Signed-off-by: Mauro Carvalho Chehab <mchehab+hua...@kernel.org> --- hw/i386/acpi-build.c | 42 ++++++++++++++++++++++++++++++++++++++++++ hw/i386/pc.c | 7 +++---- include/hw/i386/x86.h | 2 ++ 3 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index cf11231b5fe6..ad829e2c75c8 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1352,6 +1352,28 @@ static void build_acpi0017(Aml *table) aml_append(table, scope); } +#define GED_COMMON_MMIO_BASE 0xfee00000 +#define GED_COMMON_MMIO_BASE_REGS (GED_COMMON_MMIO_BASE + 0x100) +#define GED_MMIO_IRQ 9 + +static DeviceState *create_acpi_ged(X86MachineState *x86ms) +{ + DeviceState *dev = qdev_new(TYPE_ACPI_GED); + + fprintf(stderr, "creating GED\n"); + + assert(x86ms->gsi); + + qdev_prop_set_uint32(dev, "ged-event", ACPI_GED_ERROR_EVT); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, GED_COMMON_MMIO_BASE); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, GED_COMMON_MMIO_BASE_REGS); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, x86ms->gsi[GED_MMIO_IRQ]); + + return dev; +} + static void build_dsdt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm, AcpiMiscInfo *misc, @@ -1794,6 +1816,26 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, aml_append(dsdt, scope); } + /* Notification type SCI requires GED */ + if (pcms->ras) { + if (!x86ms->ged_dev) { + x86ms->ged_dev = create_acpi_ged(x86ms); + } + + sb_scope = aml_scope("_SB"); + build_ged_aml(sb_scope, GED_DEVICE, HOTPLUG_HANDLER(x86ms->ged_dev), + GED_MMIO_IRQ, AML_SYSTEM_MEMORY, GED_COMMON_MMIO_BASE); + aml_append(sb_scope, aml_error_device()); + aml_append(dsdt, sb_scope); + + scope = aml_scope("_GPE"); + method = aml_method("L08", 0, AML_NOTSERIALIZED); + aml_append(method, aml_notify(aml_name("\\_SB.GEDD"), + aml_int(0x80))); + aml_append(scope, method); + aml_append(dsdt, scope); + } + /* copy AML table into ACPI tables blob and patch header there */ g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len); acpi_table_end(linker, &table); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index b9c32dbdbcd8..b4a2fe61da49 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1700,6 +1700,8 @@ static void virt_set_ras(Object *obj, bool value, Error **errp) static void pc_sci_error(Notifier *n, void *opaque) { + PCMachineState *pcms = container_of(n, PCMachineState, ghes_sci_notifier); + X86MachineState *x86ms = X86_MACHINE(pcms); uint16_t *source_id = opaque; fprintf(stderr, "GHES error for source ID: %d\n", *source_id); @@ -1710,10 +1712,7 @@ static void pc_sci_error(Notifier *n, void *opaque) fprintf(stderr, "GHES error notified for QMP\n"); - // TODO: add something equivalent to: - // PCMachineState *s = container_of(n, PCMachineState, ghes_sci_notifier); - // acpi_send_event(s->acpi_dev, ACPI_GENERIC_ERROR); - // by calling acpi_update_sci(); + acpi_send_event(x86ms->ged_dev, ACPI_GENERIC_ERROR); } static void pc_machine_initfn(Object *obj) diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h index d43cb3908e65..06d62a944835 100644 --- a/include/hw/i386/x86.h +++ b/include/hw/i386/x86.h @@ -54,6 +54,8 @@ struct X86MachineState { GMappedFile *initrd_mapped_file; HotplugHandler *acpi_dev; + DeviceState *ged_dev; + /* * Map the whole BIOS just underneath the 4 GiB address boundary. Only used * in the ROM (-bios) case. -- 2.48.1