mirror of https://github.com/xemu-project/xemu.git
xbox: smbus irq, and make pmbase a pci bar, since that's what the available bios uses
This commit is contained in:
parent
75d73527ea
commit
71c5309318
|
@ -30,7 +30,7 @@
|
|||
#include "qemu-timer.h"
|
||||
#include "sysemu.h"
|
||||
#include "acpi.h"
|
||||
|
||||
#include "xbox_pci.h"
|
||||
#include "acpi_mcpx.h"
|
||||
|
||||
//#define DEBUG
|
||||
|
@ -55,10 +55,11 @@ static void mcpx_pm_update_sci_gn(ACPIREGS *regs)
|
|||
#define MCPX_PMIO_PM1_CNT 0x4
|
||||
#define MCPX_PMIO_PM_TMR 0x8
|
||||
|
||||
static void mcpx_pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
|
||||
uint64_t val)
|
||||
static void mcpx_pm_ioport_write(void *opaque,
|
||||
target_phys_addr_t addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
MCPX_PMRegs *pm = container_of(ioport, MCPX_PMRegs, ioport);
|
||||
MCPX_PMRegs *pm = opaque;
|
||||
|
||||
switch (addr) {
|
||||
case MCPX_PMIO_PM1_STS:
|
||||
|
@ -79,11 +80,12 @@ static void mcpx_pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
|
|||
(unsigned int)addr, (unsigned int)val);
|
||||
}
|
||||
|
||||
static void mcpx_pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
|
||||
uint64_t *data)
|
||||
static uint64_t mcpx_pm_ioport_read(void *opaque,
|
||||
target_phys_addr_t addr,
|
||||
unsigned size)
|
||||
{
|
||||
MCPX_PMRegs *pm = container_of(ioport, MCPX_PMRegs, ioport);
|
||||
uint32_t val;
|
||||
MCPX_PMRegs *pm = opaque;
|
||||
uint64_t val;
|
||||
|
||||
switch (addr) {
|
||||
case MCPX_PMIO_PM1_STS:
|
||||
|
@ -104,15 +106,19 @@ static void mcpx_pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
|
|||
}
|
||||
MCPX_DPRINTF("PM: read port=0x%04x val=0x%04x\n",
|
||||
(unsigned int)addr, (unsigned int)val);
|
||||
*data = val;
|
||||
return val;
|
||||
}
|
||||
|
||||
static const IORangeOps mcpx_iorange_ops = {
|
||||
static const MemoryRegionOps mcpx_pm_ops = {
|
||||
.read = mcpx_pm_ioport_read,
|
||||
.write = mcpx_pm_ioport_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
void mcpx_pm_iospace_update(MCPX_PMRegs *pm, uint32_t pm_io_base) {
|
||||
MCPX_DPRINTF("PM: iospace update to 0x%x\n", pm_io_base);
|
||||
|
||||
|
@ -122,8 +128,18 @@ void mcpx_pm_iospace_update(MCPX_PMRegs *pm, uint32_t pm_io_base) {
|
|||
ioport_register(&pm->ioport);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define MCPX_PM_BASE_BAR 0
|
||||
|
||||
void mcpx_pm_init(PCIDevice *dev, MCPX_PMRegs *pm/*, qemu_irq sci_irq*/) {
|
||||
|
||||
memory_region_init_io(&pm->bar, &mcpx_pm_ops,
|
||||
pm, "mcpx-pm-bar", 256);
|
||||
pci_register_bar(dev, MCPX_PM_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO,
|
||||
&pm->bar);
|
||||
|
||||
void mcpx_pm_init(MCPX_PMRegs *pm/*, qemu_irq sci_irq*/) {
|
||||
acpi_pm_tmr_init(&pm->acpi_regs, mcpx_pm_update_sci_gn);
|
||||
acpi_pm1_cnt_init(&pm->acpi_regs);
|
||||
//acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
#include "acpi.h"
|
||||
|
||||
typedef struct MCPX_PMRegs {
|
||||
IORange ioport;
|
||||
MemoryRegion bar;
|
||||
ACPIREGS acpi_regs;
|
||||
|
||||
qemu_irq irq;
|
||||
} MCPX_PMRegs;
|
||||
|
||||
void mcpx_pm_init(MCPX_PMRegs *pm /*, qemu_irq sci_irq*/);
|
||||
void mcpx_pm_iospace_update(MCPX_PMRegs *pm, uint32_t pm_io_base);
|
||||
void mcpx_pm_init(PCIDevice *dev, MCPX_PMRegs *pm/*, qemu_irq sci_irq*/);
|
||||
//void mcpx_pm_iospace_update(MCPX_PMRegs *pm, uint32_t pm_io_base);
|
||||
|
||||
|
||||
#endif
|
|
@ -4,45 +4,48 @@
|
|||
#include "smbus.h"
|
||||
|
||||
/* AMD756 SMBus address offsets */
|
||||
#define SMB_ADDR_OFFSET 0xE0
|
||||
#define SMB_IOSIZE 16
|
||||
#define SMB_GLOBAL_STATUS 0x0
|
||||
#define SMB_GLOBAL_ENABLE 0x2
|
||||
#define SMB_HOST_ADDRESS 0x4
|
||||
#define SMB_HOST_DATA 0x6
|
||||
#define SMB_HOST_COMMAND 0x8
|
||||
#define SMB_HOST_BLOCK_DATA 0x9
|
||||
#define SMB_HAS_DATA 0xA
|
||||
#define SMB_HAS_DEVICE_ADDRESS 0xC
|
||||
#define SMB_HAS_HOST_ADDRESS 0xE
|
||||
#define SMB_SNOOP_ADDRESS 0xF
|
||||
#define SMB_ADDR_OFFSET 0xE0
|
||||
#define SMB_IOSIZE 16
|
||||
|
||||
#define SMB_GLOBAL_STATUS 0x0
|
||||
#define SMB_GLOBAL_ENABLE 0x2
|
||||
#define SMB_HOST_ADDRESS 0x4
|
||||
#define SMB_HOST_DATA 0x6
|
||||
#define SMB_HOST_COMMAND 0x8
|
||||
#define SMB_HOST_BLOCK_DATA 0x9
|
||||
#define SMB_HAS_DATA 0xA
|
||||
#define SMB_HAS_DEVICE_ADDRESS 0xC
|
||||
#define SMB_HAS_HOST_ADDRESS 0xE
|
||||
#define SMB_SNOOP_ADDRESS 0xF
|
||||
|
||||
/* AMD756 constants */
|
||||
#define AMD756_QUICK 0x00
|
||||
#define AMD756_BYTE 0x01
|
||||
#define AMD756_BYTE_DATA 0x02
|
||||
#define AMD756_WORD_DATA 0x03
|
||||
#define AMD756_PROCESS_CALL 0x04
|
||||
#define AMD756_BLOCK_DATA 0x05
|
||||
#define AMD756_QUICK 0x00
|
||||
#define AMD756_BYTE 0x01
|
||||
#define AMD756_BYTE_DATA 0x02
|
||||
#define AMD756_WORD_DATA 0x03
|
||||
#define AMD756_PROCESS_CALL 0x04
|
||||
#define AMD756_BLOCK_DATA 0x05
|
||||
|
||||
/*
|
||||
SMBUS event = I/O 28-29 bit 11
|
||||
see E0 for the status bits and enabled in E2
|
||||
*/
|
||||
#define GS_ABRT_STS (1 << 0)
|
||||
#define GS_COL_STS (1 << 1)
|
||||
#define GS_PRERR_STS (1 << 2)
|
||||
#define GS_HST_STS (1 << 3)
|
||||
#define GS_HCYC_STS (1 << 4)
|
||||
#define GS_TO_STS (1 << 5)
|
||||
#define GS_SMB_STS (1 << 11)
|
||||
#define GS_ABRT_STS (1 << 0)
|
||||
#define GS_COL_STS (1 << 1)
|
||||
#define GS_PRERR_STS (1 << 2)
|
||||
#define GS_HST_STS (1 << 3)
|
||||
#define GS_HCYC_STS (1 << 4)
|
||||
#define GS_TO_STS (1 << 5)
|
||||
#define GS_SMB_STS (1 << 11)
|
||||
|
||||
#define GS_CLEAR_STS (GS_ABRT_STS | GS_COL_STS | GS_PRERR_STS | \
|
||||
GS_HCYC_STS | GS_TO_STS )
|
||||
#define GS_CLEAR_STS (GS_ABRT_STS | GS_COL_STS | GS_PRERR_STS | \
|
||||
GS_HCYC_STS | GS_TO_STS )
|
||||
|
||||
#define GE_CYC_TYPE_MASK (7)
|
||||
#define GE_HOST_STC (1 << 3)
|
||||
#define GE_ABORT (1 << 5)
|
||||
#define GE_CYC_TYPE_MASK (7)
|
||||
#define GE_HOST_STC (1 << 3)
|
||||
|
||||
#define GE_HCYC_EN (1 << 4)
|
||||
#define GE_ABORT (1 << 5)
|
||||
|
||||
|
||||
|
||||
|
@ -118,7 +121,20 @@ void amd756_smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
|
|||
SMBUS_DPRINTF("SMB writeb port=0x%04x val=0x%02x\n", addr, val);
|
||||
switch(addr) {
|
||||
case SMB_GLOBAL_STATUS:
|
||||
//s->smb_stat = 0;
|
||||
|
||||
if (s->irq) {
|
||||
/* Raise an irq if interrupts are enabled and a new
|
||||
* status is being set */
|
||||
if ((s->smb_ctl & GE_HCYC_EN)
|
||||
&& ((val & GS_CLEAR_STS)
|
||||
& (~(s->smb_stat & GS_CLEAR_STS)))) {
|
||||
|
||||
qemu_irq_raise(s->irq);
|
||||
} else {
|
||||
qemu_irq_lower(s->irq);
|
||||
}
|
||||
}
|
||||
|
||||
if (val & GS_CLEAR_STS) {
|
||||
s->smb_stat = 0;
|
||||
s->smb_index = 0;
|
||||
|
@ -135,8 +151,16 @@ void amd756_smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
|
|||
s->smb_ctl = val;
|
||||
if (val & GE_ABORT)
|
||||
s->smb_stat |= GS_ABRT_STS;
|
||||
if (val & GE_HOST_STC)
|
||||
if (val & GE_HOST_STC) {
|
||||
amd756_smb_transaction(s);
|
||||
|
||||
if (s->irq
|
||||
&& (val & GE_HCYC_EN)
|
||||
&& (s->smb_stat & GS_CLEAR_STS)) {
|
||||
qemu_irq_raise(s->irq);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case SMB_HOST_COMMAND:
|
||||
s->smb_cmd = val;
|
||||
|
@ -199,8 +223,10 @@ uint32_t amd756_smb_ioport_readb(void *opaque, uint32_t addr)
|
|||
return val;
|
||||
}
|
||||
|
||||
void amd756_smbus_init(DeviceState *parent, AMD756SMBus *smb)
|
||||
void amd756_smbus_init(DeviceState *parent, AMD756SMBus *smb, qemu_irq irq)
|
||||
{
|
||||
smb->smbus = i2c_init_bus(parent, "i2c");
|
||||
smb->smb_stat = 0;
|
||||
|
||||
smb->irq = irq;
|
||||
}
|
|
@ -12,9 +12,11 @@ typedef struct AMD756SMBus {
|
|||
//uint8_t smb_data1;
|
||||
uint8_t smb_data[32];
|
||||
uint8_t smb_index;
|
||||
|
||||
qemu_irq irq;
|
||||
} AMD756SMBus;
|
||||
|
||||
void amd756_smbus_init(DeviceState *parent, AMD756SMBus *smb);
|
||||
void amd756_smbus_init(DeviceState *parent, AMD756SMBus *smb, qemu_irq irq);
|
||||
void amd756_smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val);
|
||||
uint32_t amd756_smb_ioport_readb(void *opaque, uint32_t addr);
|
||||
|
||||
|
|
|
@ -183,7 +183,6 @@ static void xbox_init(QEMUMachineInitArgs *args)
|
|||
|
||||
ISADevice *rtc_state;
|
||||
ISADevice *pit;
|
||||
DeviceState *xboxpci_host;
|
||||
i2c_bus *smbus;
|
||||
PCIBus *agp_bus;
|
||||
|
||||
|
@ -210,15 +209,15 @@ static void xbox_init(QEMUMachineInitArgs *args)
|
|||
|
||||
|
||||
/* init buses */
|
||||
host_bus = xbox_pci_init(&xboxpci_host, gsi,
|
||||
host_bus = xbox_pci_init(gsi,
|
||||
system_memory, system_io,
|
||||
pci_memory, ram_memory);
|
||||
|
||||
|
||||
/* bridges */
|
||||
agp_bus = xbox_agp_init(xboxpci_host, host_bus);
|
||||
isa_bus = mcpx_lpc_init(xboxpci_host, host_bus);
|
||||
smbus = mcpx_smbus_init(xboxpci_host, host_bus);
|
||||
agp_bus = xbox_agp_init(host_bus);
|
||||
isa_bus = mcpx_lpc_init(host_bus, gsi);
|
||||
smbus = mcpx_smbus_init(host_bus, gsi);
|
||||
|
||||
|
||||
/* irq shit */
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
*/
|
||||
|
||||
|
||||
//#define DEBUG
|
||||
#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
# define XBOXPCI_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
|
||||
|
@ -60,8 +60,7 @@
|
|||
|
||||
|
||||
|
||||
PCIBus *xbox_pci_init(DeviceState **xbox_pci_hostp,
|
||||
qemu_irq *pic,
|
||||
PCIBus *xbox_pci_init(qemu_irq *pic,
|
||||
MemoryRegion *address_space_mem,
|
||||
MemoryRegion *address_space_io,
|
||||
MemoryRegion *pci_memory,
|
||||
|
@ -105,12 +104,11 @@ PCIBus *xbox_pci_init(DeviceState **xbox_pci_hostp,
|
|||
&bridge->pci_hole);
|
||||
|
||||
|
||||
*xbox_pci_hostp = dev;
|
||||
return hostBus;
|
||||
}
|
||||
|
||||
|
||||
PCIBus *xbox_agp_init(DeviceState *host, PCIBus *bus)
|
||||
PCIBus *xbox_agp_init(PCIBus *bus)
|
||||
{
|
||||
PCIDevice *d;
|
||||
PCIBridge *br;
|
||||
|
@ -130,7 +128,7 @@ PCIBus *xbox_agp_init(DeviceState *host, PCIBus *bus)
|
|||
}
|
||||
|
||||
|
||||
ISABus *mcpx_lpc_init(DeviceState *host, PCIBus *bus)
|
||||
ISABus *mcpx_lpc_init(PCIBus *bus, qemu_irq *gsi)
|
||||
{
|
||||
PCIDevice *d;
|
||||
MCPX_LPCState *s;
|
||||
|
@ -142,14 +140,14 @@ ISABus *mcpx_lpc_init(DeviceState *host, PCIBus *bus)
|
|||
s = MCPX_LPC_DEVICE(d);
|
||||
|
||||
//sci_irq = qemu_allocate_irqs(mcpx_set_sci, &s->irq_state, 1);
|
||||
mcpx_pm_init(&s->pm /*, sci_irq[0]*/);
|
||||
mcpx_pm_init(d, &s->pm /*, sci_irq[0]*/);
|
||||
//mcpx_lpc_reset(&s->dev.qdev);
|
||||
|
||||
return s->isa_bus;
|
||||
}
|
||||
|
||||
|
||||
i2c_bus *mcpx_smbus_init(DeviceState *host, PCIBus *bus)
|
||||
i2c_bus *mcpx_smbus_init(PCIBus *bus, qemu_irq *gsi)
|
||||
{
|
||||
PCIDevice *d;
|
||||
MCPX_SMBState *s;
|
||||
|
@ -158,6 +156,7 @@ i2c_bus *mcpx_smbus_init(DeviceState *host, PCIBus *bus)
|
|||
true, "mcpx-smbus");
|
||||
|
||||
s = MCPX_SMBUS_DEVICE(d);
|
||||
amd756_smbus_init(&d->qdev, &s->smb, gsi[11]);
|
||||
|
||||
return s->smb.smbus;
|
||||
}
|
||||
|
@ -203,7 +202,6 @@ static int mcpx_smbus_initfn(PCIDevice *dev)
|
|||
s, "mcpx-smbus-bar", 32);
|
||||
pci_register_bar(dev, MCPX_SMBUS_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO,
|
||||
&s->smb_bar);
|
||||
amd756_smbus_init(&dev->qdev, &s->smb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -235,9 +233,6 @@ static const TypeInfo mcpx_smbus_info = {
|
|||
|
||||
|
||||
|
||||
#define MCPX_LPC_PMBASE 0x84
|
||||
#define MCPX_LPC_PMBASE_ADDRESS_MASK 0xff00
|
||||
#define MCPX_LPC_PMBASE_DEFAULT 0x1
|
||||
|
||||
static int mcpx_lpc_initfn(PCIDevice *d)
|
||||
{
|
||||
|
@ -250,6 +245,12 @@ static int mcpx_lpc_initfn(PCIDevice *d)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Xbox 1.1 uses a config register instead of a bar to set the pm base address */
|
||||
#define MCPX_LPC_PMBASE 0x84
|
||||
#define MCPX_LPC_PMBASE_ADDRESS_MASK 0xff00
|
||||
#define MCPX_LPC_PMBASE_DEFAULT 0x1
|
||||
|
||||
static void mcpx_lpc_pmbase_update(MCPX_LPCState *s)
|
||||
{
|
||||
uint32_t pm_io_base = pci_get_long(s->dev.config + MCPX_LPC_PMBASE);
|
||||
|
@ -290,6 +291,7 @@ static const VMStateDescription vmstate_mcpx_lpc = {
|
|||
.version_id = 1,
|
||||
.post_load = mcpx_lpc_post_load,
|
||||
};
|
||||
#endif
|
||||
|
||||
static void mcpx_lpc_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
|
@ -298,7 +300,7 @@ static void mcpx_lpc_class_init(ObjectClass *klass, void *data)
|
|||
|
||||
k->no_hotplug = 1;
|
||||
k->init = mcpx_lpc_initfn;
|
||||
k->config_write = mcpx_lpc_config_write;
|
||||
//k->config_write = mcpx_lpc_config_write;
|
||||
k->vendor_id = PCI_VENDOR_ID_NVIDIA;
|
||||
k->device_id = PCI_DEVICE_ID_NVIDIA_NFORCE_LPC;
|
||||
k->revision = 212;
|
||||
|
@ -306,8 +308,8 @@ static void mcpx_lpc_class_init(ObjectClass *klass, void *data)
|
|||
|
||||
dc->desc = "nForce LPC Bridge";
|
||||
dc->no_user = 1;
|
||||
dc->reset = mcpx_lpc_reset;
|
||||
dc->vmsd = &vmstate_mcpx_lpc;
|
||||
//dc->reset = mcpx_lpc_reset;
|
||||
//dc->vmsd = &vmstate_mcpx_lpc;
|
||||
}
|
||||
|
||||
static const TypeInfo mcpx_lpc_info = {
|
||||
|
|
|
@ -65,18 +65,17 @@ typedef struct MCPX_LPCState {
|
|||
|
||||
|
||||
|
||||
PCIBus *xbox_pci_init(DeviceState **xbox_pci_hostp,
|
||||
qemu_irq *pic,
|
||||
PCIBus *xbox_pci_init(qemu_irq *pic,
|
||||
MemoryRegion *address_space_mem,
|
||||
MemoryRegion *address_space_io,
|
||||
MemoryRegion *pci_memory,
|
||||
MemoryRegion *ram_memory);
|
||||
|
||||
PCIBus *xbox_agp_init(DeviceState *host, PCIBus *bus);
|
||||
PCIBus *xbox_agp_init(PCIBus *bus);
|
||||
|
||||
ISABus *mcpx_lpc_init(DeviceState *host, PCIBus *bus);
|
||||
ISABus *mcpx_lpc_init(PCIBus *bus, qemu_irq *gsi);
|
||||
|
||||
i2c_bus *mcpx_smbus_init(DeviceState *host, PCIBus *bus);
|
||||
i2c_bus *mcpx_smbus_init(PCIBus *bus, qemu_irq *gsi);
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue