mirror of https://github.com/xemu-project/xemu.git
xbox: Add ACPI GPE0 block and support EXTSMI#
This commit is contained in:
parent
95a3ced4c3
commit
ab5add9a2f
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ typedef struct XBOX_PMRegs {
|
|||
ACPIREGS acpi_regs;
|
||||
|
||||
MemoryRegion io;
|
||||
MemoryRegion io_gpe;
|
||||
MemoryRegion io_gpio;
|
||||
|
||||
qemu_irq irq;
|
||||
|
|
|
@ -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 },
|
||||
{ },
|
||||
},
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue