xbox: Add ACPI GPE0 block and support EXTSMI#

This commit is contained in:
Matt Borgerson 2020-06-02 20:59:11 -07:00
parent 95a3ced4c3
commit ab5add9a2f
4 changed files with 69 additions and 9 deletions

View File

@ -2,6 +2,7 @@
* Xbox ACPI implementation
*
* Copyright (c) 2012 espes
* Copyright (c) 2020 Matt Borgerson
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -24,6 +25,7 @@
#include "hw/pci/pci.h"
#include "qemu/timer.h"
#include "sysemu/sysemu.h"
#include "sysemu/reset.h"
#include "hw/acpi/acpi.h"
#include "hw/xbox/xbox_pci.h"
#include "hw/xbox/acpi_xbox.h"
@ -36,6 +38,8 @@
#endif
#define XBOX_PM_BASE_BAR 0
#define XBOX_PM_GPE_BASE 0x20
#define XBOX_PM_GPE_LEN 4
#define XBOX_PM_GPIO_BASE 0xC0
#define XBOX_PM_GPIO_LEN 26
@ -93,6 +97,42 @@ static void xbox_pm_update_sci_fn(ACPIREGS *regs)
pm_update_sci(pm);
}
static uint64_t xbox_pm_gpe_readb(void *opaque, hwaddr addr, unsigned width)
{
XBOX_PMRegs *pm = opaque;
return acpi_gpe_ioport_readb(&pm->acpi_regs, addr);
}
static void xbox_pm_gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
unsigned width)
{
XBOX_PMRegs *pm = opaque;
acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val);
acpi_update_sci(&pm->acpi_regs, pm->irq);
}
static const MemoryRegionOps xbox_pm_gpe_ops = {
.read = xbox_pm_gpe_readb,
.write = xbox_pm_gpe_writeb,
.valid.min_access_size = 1,
.valid.max_access_size = 4,
.impl.min_access_size = 1,
.impl.max_access_size = 1,
.endianness = DEVICE_LITTLE_ENDIAN,
};
static void pm_reset(void *opaque)
{
XBOX_PMRegs *pm = opaque;
acpi_pm1_evt_reset(&pm->acpi_regs);
acpi_pm1_cnt_reset(&pm->acpi_regs);
acpi_pm_tmr_reset(&pm->acpi_regs);
acpi_gpe_reset(&pm->acpi_regs);
acpi_update_sci(&pm->acpi_regs, pm->irq);
}
void xbox_pm_init(PCIDevice *dev, XBOX_PMRegs *pm, qemu_irq sci_irq)
{
memory_region_init(&pm->io, OBJECT(dev), "xbox-pm", 256);
@ -102,10 +142,16 @@ void xbox_pm_init(PCIDevice *dev, XBOX_PMRegs *pm, qemu_irq sci_irq)
acpi_pm_tmr_init(&pm->acpi_regs, xbox_pm_update_sci_fn, &pm->io);
acpi_pm1_evt_init(&pm->acpi_regs, xbox_pm_update_sci_fn, &pm->io);
acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io, true, true, 2);
acpi_gpe_init(&pm->acpi_regs, XBOX_PM_GPE_LEN);
memory_region_init_io(&pm->io_gpe, OBJECT(dev), &xbox_pm_gpe_ops, pm,
"xbox-pm-gpe0", XBOX_PM_GPE_LEN);
memory_region_add_subregion(&pm->io, XBOX_PM_GPE_BASE, &pm->io_gpe);
memory_region_init_io(&pm->io_gpio, OBJECT(dev), &xbox_pm_gpio_ops, pm,
"xbox-pm-gpio", XBOX_PM_GPIO_LEN);
memory_region_add_subregion(&pm->io, XBOX_PM_GPIO_BASE, &pm->io_gpio);
pm->irq = sci_irq;
qemu_register_reset(pm_reset, pm);
}

View File

@ -26,6 +26,7 @@ typedef struct XBOX_PMRegs {
ACPIREGS acpi_regs;
MemoryRegion io;
MemoryRegion io_gpe;
MemoryRegion io_gpio;
qemu_irq irq;

View File

@ -2,7 +2,7 @@
* QEMU Xbox PCI buses implementation
*
* Copyright (c) 2012 espes
* Copyright (c) 2018 Matt Borgerson
* Copyright (c) 2018-2020 Matt Borgerson
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -351,23 +351,32 @@ static const VMStateDescription vmstate_xbox_lpc = {
};
#endif
static void xbox_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
{
XBOX_LPCState *s = XBOX_LPC_DEVICE(adev);
acpi_send_gpe_event(&s->pm.acpi_regs, s->pm.irq, ev);
}
static void xbox_lpc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(klass);
dc->hotpluggable = false;
k->realize = xbox_lpc_realize;
k->realize = xbox_lpc_realize;
//k->config_write = xbox_lpc_config_write;
k->vendor_id = PCI_VENDOR_ID_NVIDIA;
k->device_id = PCI_DEVICE_ID_NVIDIA_NFORCE_LPC;
k->revision = 212;
k->class_id = PCI_CLASS_BRIDGE_ISA;
k->vendor_id = PCI_VENDOR_ID_NVIDIA;
k->device_id = PCI_DEVICE_ID_NVIDIA_NFORCE_LPC;
k->revision = 212;
k->class_id = PCI_CLASS_BRIDGE_ISA;
dc->desc = "nForce LPC Bridge";
dc->desc = "nForce LPC Bridge";
dc->user_creatable = false;
dc->reset = xbox_lpc_reset;
//dc->vmsd = &vmstate_xbox_lpc;
dc->reset = xbox_lpc_reset;
//dc->vmsd = &vmstate_xbox_lpc;
adevc->send_event = xbox_send_gpe;
}
static const TypeInfo xbox_lpc_info = {
@ -376,6 +385,7 @@ static const TypeInfo xbox_lpc_info = {
.instance_size = sizeof(XBOX_LPCState),
.class_init = xbox_lpc_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_ACPI_DEVICE_IF },
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
},

View File

@ -8,6 +8,9 @@
/* These values are part of guest ABI, and can not be changed */
typedef enum {
#ifdef XBOX
ACPI_EXTSMI_STATUS = 2,
#endif
ACPI_PCI_HOTPLUG_STATUS = 2,
ACPI_CPU_HOTPLUG_STATUS = 4,
ACPI_MEMORY_HOTPLUG_STATUS = 8,