xbox: smbus irq, and make pmbase a pci bar, since that's what the available bios uses

This commit is contained in:
espes 2012-10-25 10:42:05 +11:00
parent 75d73527ea
commit 71c5309318
7 changed files with 118 additions and 74 deletions

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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 */

View File

@ -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 = {

View File

@ -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