mirror of https://github.com/xemu-project/xemu.git
xbox: initial skeleton!
This commit is contained in:
parent
8b4a3df808
commit
d823f5802e
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* ACPI implementation
|
||||
*
|
||||
* Copyright (c) 2006 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* Contributions after 2012-01-13 are licensed under the terms of the
|
||||
* GNU GPL, version 2 or (at your option) any later version.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2012 espes
|
||||
*
|
||||
* Based on acpi.c, acpi_ich9.c, acpi_piix4.c
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "pc.h"
|
||||
#include "pci.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "sysemu.h"
|
||||
#include "acpi.h"
|
||||
|
||||
#include "acpi_mcpx.h"
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
# define MCPX_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
|
||||
#else
|
||||
# define MCPX_DPRINTF(format, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void mcpx_pm_update_sci_gn(ACPIREGS *regs)
|
||||
{
|
||||
MCPX_PMRegs *pm = container_of(regs, MCPX_PMRegs, acpi_regs);
|
||||
//pm_update_sci(pm);
|
||||
}
|
||||
|
||||
|
||||
#define MCPX_PMIO_PM1_STS 0x0
|
||||
#define MCPX_PMIO_PM1_EN 0x2
|
||||
#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)
|
||||
{
|
||||
MCPX_PMRegs *pm = container_of(ioport, MCPX_PMRegs, ioport);
|
||||
|
||||
switch (addr) {
|
||||
case MCPX_PMIO_PM1_STS:
|
||||
acpi_pm1_evt_write_sts(&pm->acpi_regs, val);
|
||||
//pm_update_sci(pm);
|
||||
break;
|
||||
case MCPX_PMIO_PM1_EN:
|
||||
pm->acpi_regs.pm1.evt.en = val;
|
||||
//pm_update_sci(pm);
|
||||
break;
|
||||
case MCPX_PMIO_PM1_CNT:
|
||||
acpi_pm1_cnt_write(&pm->acpi_regs, val, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
MCPX_DPRINTF("PM: write port=0x%04x val=0x%04x\n",
|
||||
(unsigned int)addr, (unsigned int)val);
|
||||
}
|
||||
|
||||
static void mcpx_pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
|
||||
uint64_t *data)
|
||||
{
|
||||
MCPX_PMRegs *pm = container_of(ioport, MCPX_PMRegs, ioport);
|
||||
uint32_t val;
|
||||
|
||||
switch (addr) {
|
||||
case MCPX_PMIO_PM1_STS:
|
||||
val = acpi_pm1_evt_get_sts(&pm->acpi_regs);
|
||||
break;
|
||||
case MCPX_PMIO_PM1_EN:
|
||||
val = pm->acpi_regs.pm1.evt.en;
|
||||
break;
|
||||
case MCPX_PMIO_PM1_CNT:
|
||||
val = pm->acpi_regs.pm1.cnt.cnt;
|
||||
break;
|
||||
case MCPX_PMIO_PM_TMR:
|
||||
val = acpi_pm_tmr_get(&pm->acpi_regs);
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
MCPX_DPRINTF("PM: read port=0x%04x val=0x%04x\n",
|
||||
(unsigned int)addr, (unsigned int)val);
|
||||
*data = val;
|
||||
}
|
||||
|
||||
static const IORangeOps mcpx_iorange_ops = {
|
||||
.read = mcpx_pm_ioport_read,
|
||||
.write = mcpx_pm_ioport_write,
|
||||
};
|
||||
|
||||
|
||||
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);
|
||||
|
||||
//Disabled when 0
|
||||
if (pm_io_base != 0) {
|
||||
iorange_init(&pm->ioport, &mcpx_iorange_ops, pm_io_base, 256);
|
||||
ioport_register(&pm->ioport);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
//pm->irq = sci_irq;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* QEMU MCPX PM Emulation
|
||||
*
|
||||
* Copyright (c) 2012 espes
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef HW_ACPI_MCPX_H
|
||||
#define HW_ACPI_MCPX_H
|
||||
|
||||
#include "acpi.h"
|
||||
|
||||
typedef struct MCPX_PMRegs {
|
||||
IORange ioport;
|
||||
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);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,206 @@
|
|||
#include "hw.h"
|
||||
#include "pc.h"
|
||||
#include "amd_smbus.h"
|
||||
#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
|
||||
|
||||
/* 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
|
||||
|
||||
/*
|
||||
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_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 DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
# define SMBUS_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
|
||||
#else
|
||||
# define SMBUS_DPRINTF(format, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
static void amd756_smb_transaction(AMD756SMBus *s)
|
||||
{
|
||||
uint8_t prot = s->smb_ctl & GE_CYC_TYPE_MASK;
|
||||
uint8_t read = s->smb_addr & 0x01;
|
||||
uint8_t cmd = s->smb_cmd;
|
||||
uint8_t addr = (s->smb_addr >> 1) & 0x7f;
|
||||
i2c_bus *bus = s->smbus;
|
||||
|
||||
SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
|
||||
switch(prot) {
|
||||
case AMD756_QUICK:
|
||||
smbus_quick_command(bus, addr, read);
|
||||
break;
|
||||
case AMD756_BYTE:
|
||||
if (read) {
|
||||
s->smb_data0 = smbus_receive_byte(bus, addr);
|
||||
} else {
|
||||
smbus_send_byte(bus, addr, cmd);
|
||||
}
|
||||
break;
|
||||
case AMD756_BYTE_DATA:
|
||||
if (read) {
|
||||
s->smb_data0 = smbus_read_byte(bus, addr, cmd);
|
||||
} else {
|
||||
smbus_write_byte(bus, addr, cmd, s->smb_data0);
|
||||
}
|
||||
break;
|
||||
case AMD756_WORD_DATA:
|
||||
if (read) {
|
||||
uint16_t val;
|
||||
val = smbus_read_word(bus, addr, cmd);
|
||||
s->smb_data0 = val;
|
||||
//s->smb_data1 = val >> 8;
|
||||
} else {
|
||||
smbus_write_word(bus, addr, cmd, s->smb_data0);
|
||||
}
|
||||
break;
|
||||
case AMD756_BLOCK_DATA:
|
||||
if (read) {
|
||||
s->smb_data0 = smbus_read_block(bus, addr, cmd, s->smb_data);
|
||||
} else {
|
||||
smbus_write_block(bus, addr, cmd, s->smb_data, s->smb_data0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
s->smb_stat |= GS_HCYC_STS;
|
||||
|
||||
return;
|
||||
|
||||
|
||||
error:
|
||||
s->smb_stat |= GS_PRERR_STS;
|
||||
}
|
||||
|
||||
void amd756_smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
|
||||
{
|
||||
AMD756SMBus *s = opaque;
|
||||
addr &= 0x3f;
|
||||
SMBUS_DPRINTF("SMB writeb port=0x%04x val=0x%02x\n", addr, val);
|
||||
switch(addr) {
|
||||
case SMB_GLOBAL_STATUS:
|
||||
//s->smb_stat = 0;
|
||||
if (val & GS_CLEAR_STS) {
|
||||
s->smb_stat = 0;
|
||||
s->smb_index = 0;
|
||||
} else if (val & GS_HCYC_STS) {
|
||||
s->smb_stat = GS_HCYC_STS;
|
||||
s->smb_index = 0;
|
||||
} else {
|
||||
s->smb_stat = GS_HCYC_STS;
|
||||
s->smb_index = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
case SMB_GLOBAL_ENABLE:
|
||||
s->smb_ctl = val;
|
||||
if (val & GE_ABORT)
|
||||
s->smb_stat |= GS_ABRT_STS;
|
||||
if (val & GE_HOST_STC)
|
||||
amd756_smb_transaction(s);
|
||||
break;
|
||||
case SMB_HOST_COMMAND:
|
||||
s->smb_cmd = val;
|
||||
break;
|
||||
case SMB_HOST_ADDRESS:
|
||||
s->smb_addr = val;
|
||||
break;
|
||||
case SMB_HOST_DATA:
|
||||
s->smb_data0 = val;
|
||||
break;
|
||||
/*case SMBHSTDAT1:
|
||||
s->smb_data1 = val;
|
||||
break;*/
|
||||
case SMB_HOST_BLOCK_DATA:
|
||||
s->smb_data[s->smb_index++] = val;
|
||||
if (s->smb_index > 31)
|
||||
s->smb_index = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t amd756_smb_ioport_readb(void *opaque, uint32_t addr)
|
||||
{
|
||||
AMD756SMBus *s = opaque;
|
||||
uint32_t val;
|
||||
|
||||
addr &= 0x3f;
|
||||
switch(addr) {
|
||||
case SMB_GLOBAL_STATUS:
|
||||
val = s->smb_stat;
|
||||
break;
|
||||
case SMB_GLOBAL_ENABLE:
|
||||
//s->smb_index = 0;
|
||||
val = s->smb_ctl & 0x1f;
|
||||
break;
|
||||
case SMB_HOST_COMMAND:
|
||||
val = s->smb_cmd;
|
||||
break;
|
||||
case SMB_HOST_ADDRESS:
|
||||
val = s->smb_addr;
|
||||
break;
|
||||
case SMB_HOST_DATA:
|
||||
val = s->smb_data0;
|
||||
break;
|
||||
/*case SMBHSTDAT1:
|
||||
val = s->smb_data1;
|
||||
break;*/
|
||||
case SMB_HOST_BLOCK_DATA:
|
||||
val = s->smb_data[s->smb_index++];
|
||||
if (s->smb_index > 31)
|
||||
s->smb_index = 0;
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
SMBUS_DPRINTF("SMB readb port=0x%04x val=0x%02x\n", addr, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
void amd756_smbus_init(DeviceState *parent, AMD756SMBus *smb)
|
||||
{
|
||||
smb->smbus = i2c_init_bus(parent, "i2c");
|
||||
smb->smb_stat = 0;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef AMD_SMBUS_H
|
||||
#define AMD_SMBUS_H
|
||||
|
||||
typedef struct AMD756SMBus {
|
||||
i2c_bus *smbus;
|
||||
|
||||
uint8_t smb_stat;
|
||||
uint8_t smb_ctl;
|
||||
uint8_t smb_cmd;
|
||||
uint8_t smb_addr;
|
||||
uint8_t smb_data0;
|
||||
//uint8_t smb_data1;
|
||||
uint8_t smb_data[32];
|
||||
uint8_t smb_index;
|
||||
} AMD756SMBus;
|
||||
|
||||
void amd756_smbus_init(DeviceState *parent, AMD756SMBus *smb);
|
||||
void amd756_smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val);
|
||||
uint32_t amd756_smb_ioport_readb(void *opaque, uint32_t addr);
|
||||
|
||||
#endif /* !AMD_SMBUS_H */
|
|
@ -12,4 +12,6 @@ obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o
|
|||
obj-y += kvm/
|
||||
obj-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
|
||||
|
||||
obj-$(CONFIG_XBOX) += xbox.o xbox_pci.o acpi_mcpx.o amd_smbus.o nv2a.o smbus_pic16lc.o smbus_cx25871.o smbus_adm1032.o
|
||||
|
||||
obj-y := $(addprefix ../,$(obj-y))
|
||||
|
|
|
@ -0,0 +1,569 @@
|
|||
/*
|
||||
* QEMU Geforce NV2A implementation
|
||||
*
|
||||
* Copyright (c) 2012 espes
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* Contributions after 2012-01-13 are licensed under the terms of the
|
||||
* GNU GPL, version 2 or (at your option) any later version.
|
||||
*/
|
||||
#include "hw.h"
|
||||
#include "pc.h"
|
||||
#include "console.h"
|
||||
#include "pci.h"
|
||||
#include "vga_int.h"
|
||||
|
||||
#include "nv2a.h"
|
||||
|
||||
#define DEBUG_NV2A
|
||||
#ifdef DEBUG_NV2A
|
||||
# define NV2A_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
|
||||
#else
|
||||
# define NV2A_DPRINTF(format, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
#define NV_NUM_BLOCKS 20
|
||||
#define NV_PMC 0 /* card master control */
|
||||
#define NV_PBUS 1 /* bus control */
|
||||
#define NV_PFIFO 2 /* MMIO and DMA FIFO submission to PGRAPH and VPE */
|
||||
#define NV_PFIFO_CACHE 3
|
||||
#define NV_PRMA 4 /* access to BAR0/BAR1 from real mode */
|
||||
#define NV_PVIDEO 5 /* video overlay */
|
||||
#define NV_PTIMER 6 /* time measurement and time-based alarms */
|
||||
#define NV_PCOUNTER 7 /* performance monitoring counters */
|
||||
#define NV_PVPE 8 /* MPEG2 decoding engine */
|
||||
#define NV_PTV 9 /* TV encoder */
|
||||
#define NV_PRMFB 10 /* aliases VGA memory window */
|
||||
#define NV_PRMVIO 11 /* aliases VGA sequencer and graphics controller registers */
|
||||
#define NV_PSTRAPS 12 /* straps readout / override */
|
||||
#define NV_PGRAPH 13 /* accelerated 2d/3d drawing engine */
|
||||
#define NV_PCRTC 14 /* more CRTC controls */
|
||||
#define NV_PRMCIO 15 /* aliases VGA CRTC and attribute controller registers */
|
||||
#define NV_PRAMDAC 16 /* RAMDAC, cursor, and PLL control */
|
||||
#define NV_PRMDIO 17 /* aliases VGA palette registers */
|
||||
#define NV_PRAMIN 18 /* RAMIN access */
|
||||
#define NV_USER 19 /* PFIFO MMIO and DMA submission area */
|
||||
|
||||
|
||||
typedef struct NV2AState {
|
||||
PCIDevice dev;
|
||||
VGACommonState vga;
|
||||
|
||||
MemoryRegion vram;
|
||||
MemoryRegion mmio;
|
||||
|
||||
MemoryRegion block_mmio[NV_NUM_BLOCKS];
|
||||
} NV2AState;
|
||||
|
||||
|
||||
|
||||
|
||||
static uint64_t nv2a_pmc_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PMC: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_pmc_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PMC: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_pbus_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PBUS: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_pbus_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PBUS: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_pfifo_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PFIFO: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_pfifo_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PFIFO: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_prma_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRMA: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_prma_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRMA: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_pvideo_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PVIDEO: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_pvideo_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PVIDEO: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_ptimer_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PTIMER: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_ptimer_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PTIMER: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_pcounter_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PCOUNTER: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_pcounter_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PCOUNTER: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_pvpe_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PVPE: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_pvpe_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PVPE: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_ptv_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PTV: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_ptv_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PTV: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_prmfb_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRMFB: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_prmfb_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRMFB: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_prmvio_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRMVIO: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_prmvio_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRMVIO: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_pstraps_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PSTRAPS: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_pstraps_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PSTRAPS: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_pgraph_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PGRAPH: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_pgraph_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PGRAPH: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_pcrtc_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PCRTC: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_pcrtc_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PCRTC: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_prmcio_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRMCIO: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_prmcio_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRMCIO: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_pramdac_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRAMDAC: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_pramdac_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRAMDAC: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_prmdio_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRMDIO: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_prmdio_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRMDIO: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_pramin_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRAMIN: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_pramin_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a PRAMIN: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t nv2a_user_read(void *opaque,
|
||||
target_phys_addr_t addr, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a USER: read [0x%llx]\n", addr);
|
||||
return 0;
|
||||
}
|
||||
static void nv2a_user_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned int size)
|
||||
{
|
||||
NV2A_DPRINTF("nv2a USER: [0x%llx] = 0x%02llx\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct NV2ABlockInfo {
|
||||
const char* name;
|
||||
target_phys_addr_t offset;
|
||||
uint64_t size;
|
||||
MemoryRegionOps ops;
|
||||
} NV2ABlockInfo;
|
||||
|
||||
static const struct NV2ABlockInfo blocktable[] = {
|
||||
[ NV_PMC ] = {
|
||||
.name = "PMC",
|
||||
.offset = 0x000000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_pmc_read,
|
||||
.write = nv2a_pmc_write,
|
||||
},
|
||||
},
|
||||
[ NV_PBUS ] = {
|
||||
.name = "PBUS",
|
||||
.offset = 0x001000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_pbus_read,
|
||||
.write = nv2a_pbus_write,
|
||||
},
|
||||
},
|
||||
[ NV_PFIFO ] = {
|
||||
.name = "PFIFO",
|
||||
.offset = 0x002000,
|
||||
.size = 0x002000,
|
||||
.ops = {
|
||||
.read = nv2a_pfifo_read,
|
||||
.write = nv2a_pfifo_write,
|
||||
},
|
||||
},
|
||||
[ NV_PRMA ] = {
|
||||
.name = "PRMA",
|
||||
.offset = 0x007000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_prma_read,
|
||||
.write = nv2a_prma_write,
|
||||
},
|
||||
},
|
||||
[ NV_PVIDEO ] = {
|
||||
.name = "PVIDEO",
|
||||
.offset = 0x008000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_pvideo_read,
|
||||
.write = nv2a_pvideo_write,
|
||||
},
|
||||
},
|
||||
[ NV_PTIMER ] = {
|
||||
.name = "PTIMER",
|
||||
.offset = 0x009000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_ptimer_read,
|
||||
.write = nv2a_ptimer_write,
|
||||
},
|
||||
},
|
||||
[ NV_PCOUNTER ] = {
|
||||
.name = "PCOUNTER",
|
||||
.offset = 0x00a000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_pcounter_read,
|
||||
.write = nv2a_pcounter_write,
|
||||
},
|
||||
},
|
||||
[ NV_PVPE ] = {
|
||||
.name = "PVPE",
|
||||
.offset = 0x00b000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_pvpe_read,
|
||||
.write = nv2a_pvpe_write,
|
||||
},
|
||||
},
|
||||
[ NV_PTV ] = {
|
||||
.name = "PTV",
|
||||
.offset = 0x00d000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_ptv_read,
|
||||
.write = nv2a_ptv_write,
|
||||
},
|
||||
},
|
||||
[ NV_PRMFB ] = {
|
||||
.name = "PRMFB",
|
||||
.offset = 0x0a0000,
|
||||
.size = 0x020000,
|
||||
.ops = {
|
||||
.read = nv2a_prmfb_read,
|
||||
.write = nv2a_prmfb_write,
|
||||
},
|
||||
},
|
||||
[ NV_PRMVIO ] = {
|
||||
.name = "PRMVIO",
|
||||
.offset = 0x0c0000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_prmvio_read,
|
||||
.write = nv2a_prmvio_write,
|
||||
},
|
||||
},
|
||||
[ NV_PSTRAPS ] = {
|
||||
.name = "PSTRAPS",
|
||||
.offset = 0x101000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_pstraps_read,
|
||||
.write = nv2a_pstraps_write,
|
||||
},
|
||||
},
|
||||
[ NV_PGRAPH ] = {
|
||||
.name = "PGRAPH",
|
||||
.offset = 0x400000,
|
||||
.size = 0x002000,
|
||||
.ops = {
|
||||
.read = nv2a_pgraph_read,
|
||||
.write = nv2a_pgraph_write,
|
||||
},
|
||||
},
|
||||
[ NV_PCRTC ] = {
|
||||
.name = "PCRTC",
|
||||
.offset = 0x600000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_pcrtc_read,
|
||||
.write = nv2a_pcrtc_write,
|
||||
},
|
||||
},
|
||||
[ NV_PRMCIO ] = {
|
||||
.name = "PRMCIO",
|
||||
.offset = 0x601000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_prmcio_read,
|
||||
.write = nv2a_prmcio_write,
|
||||
},
|
||||
},
|
||||
[ NV_PRAMDAC ] = {
|
||||
.name = "PRAMDAC",
|
||||
.offset = 0x680000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_pramdac_read,
|
||||
.write = nv2a_pramdac_write,
|
||||
},
|
||||
},
|
||||
[ NV_PRMDIO ] = {
|
||||
.name = "PRMDIO",
|
||||
.offset = 0x681000,
|
||||
.size = 0x001000,
|
||||
.ops = {
|
||||
.read = nv2a_prmdio_read,
|
||||
.write = nv2a_prmdio_write,
|
||||
},
|
||||
},
|
||||
[ NV_PRAMIN ] = {
|
||||
.name = "PRAMIN",
|
||||
.offset = 0x700000,
|
||||
.size = 0x100000,
|
||||
.ops = {
|
||||
.read = nv2a_pramin_read,
|
||||
.write = nv2a_pramin_write,
|
||||
},
|
||||
},
|
||||
[ NV_USER ] = {
|
||||
.name = "USER",
|
||||
.offset = 0x800000,
|
||||
.size = 0x800000,
|
||||
.ops = {
|
||||
.read = nv2a_user_read,
|
||||
.write = nv2a_user_write,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static int nv2a_initfn(PCIDevice *dev)
|
||||
{
|
||||
int i;
|
||||
NV2AState *d = DO_UPCAST(NV2AState, dev, dev);
|
||||
//uint8_t *pci_conf = d->dev.config;
|
||||
|
||||
/* setup legacy VGA */
|
||||
//d->vga.vram_size_mb = 16;
|
||||
//vga_common_init(&d->vga);
|
||||
|
||||
memory_region_init(&d->mmio, "nv2a-mmio", 0x1000000);
|
||||
|
||||
pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
|
||||
|
||||
memory_region_init_ram(&d->vram, "nv2a-vram", 128 * 0x100000);
|
||||
pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, &d->vram);
|
||||
|
||||
for (i=0; i<sizeof(blocktable)/sizeof(blocktable[0]); i++) {
|
||||
if (!blocktable[i].name) continue;
|
||||
memory_region_init_io(&d->block_mmio[i], &blocktable[i].ops, d,
|
||||
blocktable[i].name, blocktable[i].size);
|
||||
memory_region_add_subregion(&d->mmio, blocktable[i].offset,
|
||||
&d->block_mmio[i]);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nv2a_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
k->vendor_id = PCI_VENDOR_ID_NVIDIA;
|
||||
k->device_id = PCI_DEVICE_ID_NVIDIA_GEFORCE_NV2A;
|
||||
k->revision = 161;
|
||||
k->class_id = PCI_CLASS_DISPLAY_3D;
|
||||
k->init = nv2a_initfn;
|
||||
|
||||
dc->desc = "GeForce NV2A Integrated Graphics";
|
||||
}
|
||||
|
||||
static const TypeInfo nv2a_info = {
|
||||
.name = "nv2a",
|
||||
.parent = TYPE_PCI_DEVICE,
|
||||
.instance_size = sizeof(NV2AState),
|
||||
.class_init = nv2a_class_init,
|
||||
};
|
||||
|
||||
static void nv2a_register(void)
|
||||
{
|
||||
type_register_static(&nv2a_info);
|
||||
}
|
||||
type_init(nv2a_register);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void nv2a_init(PCIBus *bus, int devfn)
|
||||
{
|
||||
pci_create_simple(bus, devfn, "nv2a");
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* QEMU Geforce NV2A implementation
|
||||
*
|
||||
* Copyright (c) 2012 espes
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* Contributions after 2012-01-13 are licensed under the terms of the
|
||||
* GNU GPL, version 2 or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef HW_NV2A_H
|
||||
#define HW_NV2A_H
|
||||
|
||||
void nv2a_init(PCIBus *bus, int devfn);
|
||||
|
||||
#endif
|
11
hw/pci_ids.h
11
hw/pci_ids.h
|
@ -22,6 +22,7 @@
|
|||
#define PCI_CLASS_NETWORK_ETHERNET 0x0200
|
||||
|
||||
#define PCI_CLASS_DISPLAY_VGA 0x0300
|
||||
#define PCI_CLASS_DISPLAY_3D 0x0302
|
||||
#define PCI_CLASS_DISPLAY_OTHER 0x0380
|
||||
|
||||
#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401
|
||||
|
@ -31,6 +32,7 @@
|
|||
#define PCI_CLASS_SYSTEM_OTHER 0x0880
|
||||
|
||||
#define PCI_CLASS_SERIAL_USB 0x0c03
|
||||
#define PCI_CLASS_SERIAL_SMBUS 0x0c05
|
||||
|
||||
#define PCI_CLASS_BRIDGE_HOST 0x0600
|
||||
#define PCI_CLASS_BRIDGE_ISA 0x0601
|
||||
|
@ -128,3 +130,12 @@
|
|||
|
||||
#define PCI_VENDOR_ID_NEC 0x1033
|
||||
#define PCI_DEVICE_ID_NEC_UPD720200 0x0194
|
||||
|
||||
#define PCI_VENDOR_ID_NVIDIA 0x10de
|
||||
#define PCI_DEVICE_ID_NVIDIA_NFORCE_LPC 0x01b2
|
||||
#define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS 0x01b4
|
||||
#define PCI_DEVICE_ID_NVIDIA_NFORCE_AGP 0x01b7
|
||||
|
||||
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_NV2A 0x02a0
|
||||
#define PCI_DEVICE_ID_NVIDIA_XBOX_PCHB 0x02a5
|
||||
|
||||
|
|
|
@ -77,7 +77,14 @@ int smbus_read_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data)
|
|||
void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data,
|
||||
int len);
|
||||
|
||||
void smbus_eeprom_init_single(i2c_bus *smbus, int address,
|
||||
uint8_t *eeprom_buf);
|
||||
void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
|
||||
const uint8_t *eeprom_spd, int size);
|
||||
|
||||
|
||||
void smbus_pic16lc_init(i2c_bus *smbus, int address);
|
||||
void smbus_cx25871_init(i2c_bus *smbus, int address);
|
||||
void smbus_adm1032_init(i2c_bus *smbus, int address);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* QEMU SMBus ADM1032 Temperature Monitor
|
||||
*
|
||||
* Copyright (c) 2012 espes
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "i2c.h"
|
||||
#include "smbus.h"
|
||||
|
||||
#define DEBUG
|
||||
|
||||
static uint8_t tm_read_data(SMBusDevice *dev, uint8_t cmd, int n)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("tm_read_data: addr=0x%02x cmd=0x%02x n=%d\n",
|
||||
dev->i2c.address, cmd, n);
|
||||
#endif
|
||||
|
||||
switch (cmd) {
|
||||
case 0x0:
|
||||
case 0x1:
|
||||
return 50;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tm_init(SMBusDevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void smbus_adm1032_class_initfn(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass);
|
||||
|
||||
sc->init = tm_init;
|
||||
sc->read_data = tm_read_data;
|
||||
}
|
||||
|
||||
static TypeInfo smbus_adm1032_info = {
|
||||
.name = "smbus-adm1032",
|
||||
.parent = TYPE_SMBUS_DEVICE,
|
||||
.instance_size = sizeof(SMBusDevice),
|
||||
.class_init = smbus_adm1032_class_initfn,
|
||||
};
|
||||
|
||||
|
||||
static void smbus_adm1032_register_devices(void)
|
||||
{
|
||||
type_register_static(&smbus_adm1032_info);
|
||||
}
|
||||
|
||||
type_init(smbus_adm1032_register_devices)
|
||||
|
||||
|
||||
void smbus_adm1032_init(i2c_bus *smbus, int address)
|
||||
{
|
||||
DeviceState *tm;
|
||||
tm = qdev_create((BusState *)smbus, "smbus-adm1032");
|
||||
qdev_prop_set_uint8(tm, "address", address);
|
||||
qdev_init_nofail(tm);
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* QEMU SMBus Conexant CX25871 Video Encoder
|
||||
*
|
||||
* Copyright (c) 2012 espes
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "i2c.h"
|
||||
#include "smbus.h"
|
||||
|
||||
typedef struct SMBusCX25871Device {
|
||||
SMBusDevice smbusdev;
|
||||
|
||||
uint8_t registers[256];
|
||||
} SMBusCX25871Device;
|
||||
|
||||
#define DEBUG
|
||||
|
||||
static void cx_quick_cmd(SMBusDevice *dev, uint8_t read)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("cx_quick_cmd: addr=0x%02x read=%d\n", dev->i2c.address, read);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void cx_send_byte(SMBusDevice *dev, uint8_t val)
|
||||
{
|
||||
SMBusCX25871Device *cx = (SMBusCX25871Device *) dev;
|
||||
#ifdef DEBUG
|
||||
printf("cx_send_byte: addr=0x%02x val=0x%02x\n",
|
||||
dev->i2c.address, val);
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint8_t cx_receive_byte(SMBusDevice *dev)
|
||||
{
|
||||
SMBusCX25871Device *cx = (SMBusCX25871Device *) dev;
|
||||
#ifdef DEBUG
|
||||
printf("cx_receive_byte: addr=0x%02x\n",
|
||||
dev->i2c.address);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cx_write_data(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len)
|
||||
{
|
||||
SMBusCX25871Device *cx = (SMBusCX25871Device *) dev;
|
||||
#ifdef DEBUG
|
||||
printf("cx_write_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n",
|
||||
dev->i2c.address, cmd, buf[0]);
|
||||
#endif
|
||||
|
||||
memcpy(cx->registers+cmd, buf, MIN(len, 256-cmd));
|
||||
}
|
||||
|
||||
static uint8_t cx_read_data(SMBusDevice *dev, uint8_t cmd, int n)
|
||||
{
|
||||
SMBusCX25871Device *cx = (SMBusCX25871Device *) dev;
|
||||
#ifdef DEBUG
|
||||
printf("cx_read_data: addr=0x%02x cmd=0x%02x n=%d\n",
|
||||
dev->i2c.address, cmd, n);
|
||||
#endif
|
||||
|
||||
return cx->registers[cmd];
|
||||
}
|
||||
|
||||
static int smbus_cx_init(SMBusDevice *dev)
|
||||
{
|
||||
SMBusCX25871Device *cx = (SMBusCX25871Device *)dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void smbus_cx25871_class_initfn(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass);
|
||||
|
||||
sc->init = smbus_cx_init;
|
||||
sc->quick_cmd = cx_quick_cmd;
|
||||
sc->send_byte = cx_send_byte;
|
||||
sc->receive_byte = cx_receive_byte;
|
||||
sc->write_data = cx_write_data;
|
||||
sc->read_data = cx_read_data;
|
||||
}
|
||||
|
||||
static TypeInfo smbus_cx25871_info = {
|
||||
.name = "smbus-cx25871",
|
||||
.parent = TYPE_SMBUS_DEVICE,
|
||||
.instance_size = sizeof(SMBusCX25871Device),
|
||||
.class_init = smbus_cx25871_class_initfn,
|
||||
};
|
||||
|
||||
|
||||
static void smbus_cx25871_register_devices(void)
|
||||
{
|
||||
type_register_static(&smbus_cx25871_info);
|
||||
}
|
||||
|
||||
type_init(smbus_cx25871_register_devices)
|
||||
|
||||
|
||||
void smbus_cx25871_init(i2c_bus *smbus, int address)
|
||||
{
|
||||
DeviceState *cx;
|
||||
cx = qdev_create((BusState *)smbus, "smbus-cx25871");
|
||||
qdev_prop_set_uint8(cx, "address", address);
|
||||
qdev_init_nofail(cx);
|
||||
}
|
|
@ -26,7 +26,7 @@
|
|||
#include "i2c.h"
|
||||
#include "smbus.h"
|
||||
|
||||
//#define DEBUG
|
||||
#define DEBUG
|
||||
|
||||
typedef struct SMBusEEPROMDevice {
|
||||
SMBusDevice smbusdev;
|
||||
|
@ -137,6 +137,16 @@ static void smbus_eeprom_register_types(void)
|
|||
|
||||
type_init(smbus_eeprom_register_types)
|
||||
|
||||
void smbus_eeprom_init_single(i2c_bus *smbus, int address,
|
||||
uint8_t *eeprom_buf)
|
||||
{
|
||||
DeviceState *eeprom;
|
||||
eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
|
||||
qdev_prop_set_uint8(eeprom, "address", address);
|
||||
qdev_prop_set_ptr(eeprom, "data", eeprom_buf);
|
||||
qdev_init_nofail(eeprom);
|
||||
}
|
||||
|
||||
void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
|
||||
const uint8_t *eeprom_spd, int eeprom_spd_size)
|
||||
{
|
||||
|
@ -147,10 +157,7 @@ void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
|
|||
}
|
||||
|
||||
for (i = 0; i < nb_eeprom; i++) {
|
||||
DeviceState *eeprom;
|
||||
eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
|
||||
qdev_prop_set_uint8(eeprom, "address", 0x50 + i);
|
||||
qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
|
||||
qdev_init_nofail(eeprom);
|
||||
smbus_eeprom_init_single(smbus,
|
||||
0x50 + i, eeprom_buf + (i * 256));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* QEMU SMBus PIC16LC System Monitor
|
||||
*
|
||||
* Copyright (c) 2011 espes
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "i2c.h"
|
||||
#include "smbus.h"
|
||||
|
||||
|
||||
#define PIC16LC_REG_VER 0x01
|
||||
#define PIC16LC_REG_POWER 0x02
|
||||
#define PIC16LC_REG_POWER_RESET 0x01
|
||||
#define PIC16LC_REG_POWER_CYCLE 0x40
|
||||
#define PIC16LC_REG_POWER_SHUTDOWN 0x80
|
||||
#define PIC16LC_REG_TRAYSTATE 0x03
|
||||
#define PIC16LC_REG_AVPACK 0x04
|
||||
#define PIC16LC_REG_AVPACK_SCART 0x00
|
||||
#define PIC16LC_REG_AVPACK_HDTV 0x01
|
||||
#define PIC16LC_REG_AVPACK_VGA_SOG 0x02
|
||||
#define PIC16LC_REG_AVPACK_SVIDEO 0x04
|
||||
#define PIC16LC_REG_AVPACK_COMPOSITE 0x06
|
||||
#define PIC16LC_REG_AVPACK_VGA 0x07
|
||||
#define PIC16LC_REG_FANMODE 0x05
|
||||
#define PIC16LC_REG_FANSPEED 0x06
|
||||
#define PIC16LC_REG_LEDMODE 0x07
|
||||
#define PIC16LC_REG_LEDSEQ 0x08
|
||||
#define PIC16LC_REG_CPUTEMP 0x09
|
||||
#define PIC16LC_REG_BOARDTEMP 0x0a
|
||||
#define PIC16LC_REG_TRAYEJECT 0x0c
|
||||
#define PIC16LC_REG_INTACK 0x0d
|
||||
#define PIC16LC_REG_INTSTATUS 0x11
|
||||
#define PIC16LC_REG_INTSTATUS_POWER 0x01
|
||||
#define PIC16LC_REG_INTSTATUS_TRAYCLOSED 0x02
|
||||
#define PIC16LC_REG_INTSTATUS_TRAYOPENING 0x04
|
||||
#define PIC16LC_REG_INTSTATUS_AVPACK_PLUG 0x08
|
||||
#define PIC16LC_REG_INTSTATUS_AVPACK_UNPLUG 0x10
|
||||
#define PIC16LC_REG_INTSTATUS_EJECT_BUTTON 0x20
|
||||
#define PIC16LC_REG_INTSTATUS_TRAYCLOSING 0x40
|
||||
#define PIC16LC_REG_RESETONEJECT 0x19
|
||||
#define PIC16LC_REG_INTEN 0x1a
|
||||
|
||||
static const char* pic_version_string = "P01";
|
||||
|
||||
|
||||
#define DEBUG
|
||||
|
||||
typedef struct SMBusPIC16LCDevice {
|
||||
SMBusDevice smbusdev;
|
||||
int versionStringIndex;
|
||||
} SMBusPIC16LCDevice;
|
||||
|
||||
static void pic_quick_cmd(SMBusDevice *dev, uint8_t read)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("pic_quick_cmd: addr=0x%02x read=%d\n", dev->i2c.address, read);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void pic_send_byte(SMBusDevice *dev, uint8_t val)
|
||||
{
|
||||
SMBusPIC16LCDevice *pic = (SMBusPIC16LCDevice *) dev;
|
||||
#ifdef DEBUG
|
||||
printf("pic_send_byte: addr=0x%02x val=0x%02x\n",
|
||||
dev->i2c.address, val);
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint8_t pic_receive_byte(SMBusDevice *dev)
|
||||
{
|
||||
SMBusPIC16LCDevice *pic = (SMBusPIC16LCDevice *) dev;
|
||||
#ifdef DEBUG
|
||||
printf("pic_receive_byte: addr=0x%02x\n",
|
||||
dev->i2c.address);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pic_write_data(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len)
|
||||
{
|
||||
SMBusPIC16LCDevice *pic = (SMBusPIC16LCDevice *) dev;
|
||||
#ifdef DEBUG
|
||||
printf("pic_write_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n",
|
||||
dev->i2c.address, cmd, buf[0]);
|
||||
#endif
|
||||
|
||||
switch(cmd) {
|
||||
case PIC16LC_REG_VER:
|
||||
//pic version string reset
|
||||
pic->versionStringIndex = buf[0];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t pic_read_data(SMBusDevice *dev, uint8_t cmd, int n)
|
||||
{
|
||||
SMBusPIC16LCDevice *pic = (SMBusPIC16LCDevice *) dev;
|
||||
#ifdef DEBUG
|
||||
printf("pic_read_data: addr=0x%02x cmd=0x%02x n=%d\n",
|
||||
dev->i2c.address, cmd, n);
|
||||
#endif
|
||||
|
||||
switch(cmd) {
|
||||
case PIC16LC_REG_VER:
|
||||
return pic_version_string[
|
||||
pic->versionStringIndex++%(sizeof(pic_version_string)-1)];
|
||||
case PIC16LC_REG_AVPACK:
|
||||
//pretend to ave a composite av pack plugged in
|
||||
return PIC16LC_REG_AVPACK_COMPOSITE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smbus_pic_init(SMBusDevice *dev)
|
||||
{
|
||||
SMBusPIC16LCDevice *pic = (SMBusPIC16LCDevice *)dev;
|
||||
|
||||
pic->versionStringIndex = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void smbus_pic_class_initfn(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass);
|
||||
|
||||
sc->init = smbus_pic_init;
|
||||
sc->quick_cmd = pic_quick_cmd;
|
||||
sc->send_byte = pic_send_byte;
|
||||
sc->receive_byte = pic_receive_byte;
|
||||
sc->write_data = pic_write_data;
|
||||
sc->read_data = pic_read_data;
|
||||
}
|
||||
|
||||
static TypeInfo smbus_pic_info = {
|
||||
.name = "smbus-pic16lc",
|
||||
.parent = TYPE_SMBUS_DEVICE,
|
||||
.instance_size = sizeof(SMBusPIC16LCDevice),
|
||||
.class_init = smbus_pic_class_initfn,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void smbus_pic_register_devices(void)
|
||||
{
|
||||
type_register_static(&smbus_pic_info);
|
||||
}
|
||||
|
||||
type_init(smbus_pic_register_devices)
|
||||
|
||||
|
||||
void smbus_pic16lc_init(i2c_bus *smbus, int address)
|
||||
{
|
||||
DeviceState *pic;
|
||||
pic = qdev_create((BusState *)smbus, "smbus-pic16lc");
|
||||
qdev_prop_set_uint8(pic, "address", address);
|
||||
qdev_init_nofail(pic);
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* QEMU Xbox System Emulator
|
||||
*
|
||||
* Copyright (c) 2012 espes
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "arch_init.h"
|
||||
#include "pc.h"
|
||||
#include "pci.h"
|
||||
#include "net.h"
|
||||
#include "boards.h"
|
||||
#include "ide.h"
|
||||
#include "mc146818rtc.h"
|
||||
#include "i8254.h"
|
||||
#include "pcspk.h"
|
||||
#include "kvm.h"
|
||||
#include "sysemu.h"
|
||||
#include "sysbus.h"
|
||||
#include "smbus.h"
|
||||
#include "blockdev.h"
|
||||
#include "loader.h"
|
||||
#include "exec-memory.h"
|
||||
|
||||
#include "xbox_pci.h"
|
||||
#include "nv2a.h"
|
||||
|
||||
|
||||
/* mostly from pc_memory_init */
|
||||
static void xbox_memory_init(MemoryRegion *system_memory,
|
||||
ram_addr_t mem_size,
|
||||
MemoryRegion *rom_memory,
|
||||
MemoryRegion **ram_memory)
|
||||
{
|
||||
MemoryRegion *ram;
|
||||
MemoryRegion *ram_below_4g;
|
||||
|
||||
int ret;
|
||||
char *filename;
|
||||
int bios_size, isa_bios_size;
|
||||
MemoryRegion *bios, *isa_bios;
|
||||
|
||||
MemoryRegion *map_bios;
|
||||
uint32_t map_loc;
|
||||
|
||||
/* Allocate RAM. We allocate it as a single memory region and use
|
||||
* aliases to address portions of it, mostly for backwards compatibility
|
||||
* with older qemus that used qemu_ram_alloc().
|
||||
*/
|
||||
ram = g_malloc(sizeof(*ram));
|
||||
memory_region_init_ram(ram, "pc.ram", mem_size);
|
||||
vmstate_register_ram_global(ram);
|
||||
*ram_memory = ram;
|
||||
ram_below_4g = g_malloc(sizeof(*ram_below_4g));
|
||||
memory_region_init_alias(ram_below_4g, "ram-below-4g", ram,
|
||||
0, mem_size);
|
||||
memory_region_add_subregion(system_memory, 0, ram_below_4g);
|
||||
|
||||
|
||||
/* Load the bios. (mostly from pc_sysfw)
|
||||
* Can't use it verbatim, since we need the bios repeated\
|
||||
* over top 1MB of memory.
|
||||
*/
|
||||
if (bios_name == NULL) {
|
||||
bios_name = "bios.bin";
|
||||
}
|
||||
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
|
||||
if (filename) {
|
||||
bios_size = get_image_size(filename);
|
||||
} else {
|
||||
bios_size = -1;
|
||||
}
|
||||
bios = g_malloc(sizeof(*bios));
|
||||
memory_region_init_ram(bios, "pc.bios", bios_size);
|
||||
vmstate_register_ram_global(bios);
|
||||
memory_region_set_readonly(bios, true);
|
||||
ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
|
||||
exit(1);
|
||||
}
|
||||
if (filename) {
|
||||
g_free(filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* map the last 128KB of the BIOS in ISA space */
|
||||
isa_bios_size = bios_size;
|
||||
if (isa_bios_size > (128 * 1024)) {
|
||||
isa_bios_size = 128 * 1024;
|
||||
}
|
||||
isa_bios = g_malloc(sizeof(*isa_bios));
|
||||
memory_region_init_alias(isa_bios, "isa-bios", bios,
|
||||
bios_size - isa_bios_size, isa_bios_size);
|
||||
memory_region_add_subregion_overlap(rom_memory,
|
||||
0x100000 - isa_bios_size,
|
||||
isa_bios,
|
||||
1);
|
||||
memory_region_set_readonly(isa_bios, true);
|
||||
|
||||
|
||||
/* map the bios repeated at the top of memory */
|
||||
for (map_loc=(uint32_t)(-bios_size); map_loc >= 0xff000000; map_loc-=bios_size) {
|
||||
map_bios = g_malloc(sizeof(*map_bios));
|
||||
memory_region_init_alias(map_bios, NULL, bios, 0, bios_size);
|
||||
|
||||
memory_region_add_subregion(rom_memory, map_loc, map_bios);
|
||||
memory_region_set_readonly(map_bios, true);
|
||||
}
|
||||
|
||||
/*memory_region_add_subregion(rom_memory,
|
||||
(uint32_t)(-bios_size),
|
||||
bios);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void ioapic_init(GSIState *gsi_state)
|
||||
{
|
||||
DeviceState *dev;
|
||||
SysBusDevice *d;
|
||||
unsigned int i;
|
||||
|
||||
dev = qdev_create(NULL, "ioapic");
|
||||
|
||||
qdev_init_nofail(dev);
|
||||
d = sysbus_from_qdev(dev);
|
||||
sysbus_mmio_map(d, 0, 0xfec00000);
|
||||
|
||||
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
|
||||
gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define MAX_IDE_BUS 2
|
||||
|
||||
/* mostly from pc_init1 */
|
||||
static void xbox_init(ram_addr_t ram_size,
|
||||
const char *boot_device,
|
||||
const char *kernel_filename,
|
||||
const char *kernel_cmdline,
|
||||
const char *initrd_filename,
|
||||
const char *cpu_model)
|
||||
{
|
||||
int i;
|
||||
PCIBus *host_bus;
|
||||
ISABus *isa_bus;
|
||||
qemu_irq *cpu_irq;
|
||||
qemu_irq *gsi;
|
||||
qemu_irq *i8259;
|
||||
GSIState *gsi_state;
|
||||
PCIDevice *ide_dev;
|
||||
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
|
||||
BusState *idebus[MAX_IDE_BUS];
|
||||
ISADevice *rtc_state;
|
||||
ISADevice *pit;
|
||||
MemoryRegion *ram_memory;
|
||||
MemoryRegion *pci_memory;
|
||||
|
||||
DeviceState *xboxpci_host;
|
||||
i2c_bus *smbus;
|
||||
PCIBus *agp_bus;
|
||||
|
||||
|
||||
pc_cpus_init(cpu_model);
|
||||
|
||||
pci_memory = g_new(MemoryRegion, 1);
|
||||
memory_region_init(pci_memory, "pci", INT64_MAX);
|
||||
|
||||
/* allocate ram and load rom/bios */
|
||||
xbox_memory_init(get_system_memory(), ram_size,
|
||||
pci_memory, &ram_memory);
|
||||
|
||||
|
||||
gsi_state = g_malloc0(sizeof(*gsi_state));
|
||||
gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);
|
||||
|
||||
|
||||
/* init buses */
|
||||
host_bus = xbox_pci_init(&xboxpci_host, gsi,
|
||||
get_system_memory(), get_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);
|
||||
|
||||
|
||||
/* irq shit */
|
||||
isa_bus_irqs(isa_bus, gsi);
|
||||
cpu_irq = pc_allocate_cpu_irq();
|
||||
i8259 = i8259_init(isa_bus, cpu_irq[0]);
|
||||
|
||||
for (i = 0; i < ISA_NUM_IRQS; i++) {
|
||||
gsi_state->i8259_irq[i] = i8259[i];
|
||||
}
|
||||
ioapic_init(gsi_state);
|
||||
|
||||
|
||||
/* basic device init */
|
||||
rtc_state = rtc_init(isa_bus, 2000, NULL);
|
||||
pit = pit_init(isa_bus, 0x40, 0, NULL);
|
||||
|
||||
/* does apparently have a pc speaker, though not used? */
|
||||
pcspk_init(isa_bus, pit);
|
||||
|
||||
|
||||
/* TODO: ethernet */
|
||||
|
||||
/* TODO: USB */
|
||||
|
||||
/* hdd shit
|
||||
* piix3's ide be right for now, maybe
|
||||
*/
|
||||
|
||||
|
||||
ide_drive_get(hd, MAX_IDE_BUS);
|
||||
ide_dev = pci_piix4_ide_init(host_bus, hd, PCI_DEVFN(9, 0));
|
||||
|
||||
idebus[0] = qdev_get_child_bus(&ide_dev->qdev, "ide.0");
|
||||
idebus[1] = qdev_get_child_bus(&ide_dev->qdev, "ide.1");
|
||||
|
||||
|
||||
pc_cmos_init(ram_size, 0, boot_device,
|
||||
NULL, idebus[0], idebus[1], rtc_state);
|
||||
|
||||
|
||||
/* TODO: Populate SPD eeprom data. */
|
||||
uint8_t *eeprom_buf = g_malloc0(256);
|
||||
smbus_eeprom_init_single(smbus, 0x54, eeprom_buf);
|
||||
|
||||
smbus_pic16lc_init(smbus, 0x10);
|
||||
smbus_cx25871_init(smbus, 0x45);
|
||||
smbus_adm1032_init(smbus, 0x4c);
|
||||
|
||||
|
||||
|
||||
/* GPU! */
|
||||
nv2a_init(agp_bus, PCI_DEVFN(0, 0));
|
||||
}
|
||||
|
||||
static QEMUMachine xbox_machine = {
|
||||
.name = "xbox",
|
||||
.desc = "Microsoft Xbox",
|
||||
.init = xbox_init,
|
||||
};
|
||||
|
||||
static void xbox_machine_init(void) {
|
||||
qemu_register_machine(&xbox_machine);
|
||||
}
|
||||
|
||||
machine_init(xbox_machine_init);
|
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
* QEMU Xbox PCI buses implementation
|
||||
*
|
||||
* Copyright (c) 2012 espes
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* Contributions after 2012-01-13 are licensed under the terms of the
|
||||
* GNU GPL, version 2 or (at your option) any later version.
|
||||
*/
|
||||
#include "hw.h"
|
||||
#include "range.h"
|
||||
#include "isa.h"
|
||||
#include "sysbus.h"
|
||||
#include "pc.h"
|
||||
#include "pci.h"
|
||||
#include "pci_bridge.h"
|
||||
#include "pci_internals.h"
|
||||
#include "exec-memory.h"
|
||||
#include "acpi_mcpx.h"
|
||||
#include "amd_smbus.h"
|
||||
#include "qemu-common.h"
|
||||
|
||||
#include "xbox_pci.h"
|
||||
|
||||
|
||||
/*
|
||||
* xbox chipset based on nForce 420, which was based on AMD-760
|
||||
*
|
||||
* http://support.amd.com/us/ChipsetMotherboard_TechDocs/24494.pdf
|
||||
* http://support.amd.com/us/ChipsetMotherboard_TechDocs/24416.pdf
|
||||
* http://support.amd.com/us/ChipsetMotherboard_TechDocs/24467.pdf
|
||||
*
|
||||
* http://support.amd.com/us/ChipsetMotherboard_TechDocs/24462.pdf
|
||||
*
|
||||
* - 'NV2A' combination northbridge/gpu
|
||||
* - 'MCPX' combination southbridge/apu
|
||||
*/
|
||||
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
# define XBOXPCI_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
|
||||
#else
|
||||
# define XBOXPCI_DPRINTF(format, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PCIBus *xbox_pci_init(DeviceState **xbox_pci_hostp,
|
||||
qemu_irq *pic,
|
||||
MemoryRegion *address_space_mem,
|
||||
MemoryRegion *address_space_io,
|
||||
MemoryRegion *pci_memory,
|
||||
MemoryRegion *ram_memory)
|
||||
|
||||
{
|
||||
DeviceState *dev;
|
||||
PCIHostState *hostState;
|
||||
PCIBus *hostBus;
|
||||
PCIDevice *bridgeDev;
|
||||
XBOX_PCIState *bridge;
|
||||
|
||||
/* pci host bus */
|
||||
dev = qdev_create(NULL, "xbox-pcihost");
|
||||
hostState = PCI_HOST_BRIDGE(dev);
|
||||
hostState->address_space = address_space_mem;
|
||||
|
||||
|
||||
hostBus = pci_bus_new(dev, NULL, pci_memory,
|
||||
address_space_io, 0);
|
||||
hostState->bus = hostBus;
|
||||
|
||||
//pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
|
||||
// PIIX_NUM_PIRQS);
|
||||
|
||||
qdev_init_nofail(dev);
|
||||
|
||||
bridgeDev = pci_create_simple_multifunction(hostBus, PCI_DEVFN(0, 0),
|
||||
true, "xbox-pci");
|
||||
bridge = XBOX_PCI_DEVICE(bridgeDev);
|
||||
bridge->ram_memory = ram_memory;
|
||||
bridge->pci_address_space = pci_memory;
|
||||
bridge->system_memory = address_space_mem;
|
||||
|
||||
/* PCI hole */
|
||||
memory_region_init_alias(&bridge->pci_hole, "pci-hole",
|
||||
bridge->pci_address_space,
|
||||
ram_size,
|
||||
0x100000000ULL - ram_size);
|
||||
memory_region_add_subregion(bridge->system_memory, ram_size,
|
||||
&bridge->pci_hole);
|
||||
|
||||
|
||||
*xbox_pci_hostp = dev;
|
||||
return hostBus;
|
||||
}
|
||||
|
||||
|
||||
PCIBus *xbox_agp_init(DeviceState *host, PCIBus *bus)
|
||||
{
|
||||
PCIDevice *d;
|
||||
PCIBridge *br;
|
||||
//DeviceState *qdev;
|
||||
|
||||
/* AGP bus */
|
||||
d = pci_create_simple(bus, PCI_DEVFN(30, 0), "xbox-agp");
|
||||
if (!d) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
br = DO_UPCAST(PCIBridge, dev, d);
|
||||
//qdev = &br->dev.qdev;
|
||||
//qdev_init_nofail(qdev);
|
||||
|
||||
return pci_bridge_get_sec_bus(br);
|
||||
}
|
||||
|
||||
|
||||
ISABus *mcpx_lpc_init(DeviceState *host, PCIBus *bus)
|
||||
{
|
||||
PCIDevice *d;
|
||||
MCPX_LPCState *s;
|
||||
//qemu_irq *sci_irq;
|
||||
|
||||
d = pci_create_simple_multifunction(bus, PCI_DEVFN(1, 0),
|
||||
true, "mcpx-lpc");
|
||||
|
||||
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_lpc_reset(&s->dev.qdev);
|
||||
|
||||
return s->isa_bus;
|
||||
}
|
||||
|
||||
|
||||
i2c_bus *mcpx_smbus_init(DeviceState *host, PCIBus *bus)
|
||||
{
|
||||
PCIDevice *d;
|
||||
MCPX_SMBState *s;
|
||||
|
||||
d = pci_create_simple_multifunction(bus, PCI_DEVFN(1, 1),
|
||||
true, "mcpx-smbus");
|
||||
|
||||
s = MCPX_SMBUS_DEVICE(d);
|
||||
|
||||
return s->smb.smbus;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int mcpx_smbus_initfn(PCIDevice *dev)
|
||||
{
|
||||
MCPX_SMBState *s = MCPX_SMBUS_DEVICE(dev);
|
||||
|
||||
//presumably configurable, but can't find docs...
|
||||
const uint32_t smb_io_base = 0xc000;
|
||||
register_ioport_write(smb_io_base, 64, 1, amd756_smb_ioport_writeb, &s->smb);
|
||||
register_ioport_read(smb_io_base, 64, 1, amd756_smb_ioport_readb, &s->smb);
|
||||
|
||||
amd756_smbus_init(&dev->qdev, &s->smb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void mcpx_smbus_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = mcpx_smbus_initfn;
|
||||
k->vendor_id = PCI_VENDOR_ID_NVIDIA;
|
||||
k->device_id = PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS;
|
||||
k->revision = 161;
|
||||
k->class_id = PCI_CLASS_SERIAL_SMBUS;
|
||||
|
||||
dc->desc = "nForce PCI System Management";
|
||||
dc->no_user = 1;
|
||||
}
|
||||
|
||||
static const TypeInfo mcpx_smbus_info = {
|
||||
.name = "mcpx-smbus",
|
||||
.parent = TYPE_PCI_DEVICE,
|
||||
.instance_size = sizeof(PCIDevice),
|
||||
.class_init = mcpx_smbus_class_init,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#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)
|
||||
{
|
||||
MCPX_LPCState *lpc = MCPX_LPC_DEVICE(d);
|
||||
ISABus *isa_bus;
|
||||
|
||||
isa_bus = isa_bus_new(&d->qdev, get_system_io());
|
||||
lpc->isa_bus = isa_bus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mcpx_lpc_pmbase_update(MCPX_LPCState *s)
|
||||
{
|
||||
uint32_t pm_io_base = pci_get_long(s->dev.config + MCPX_LPC_PMBASE);
|
||||
pm_io_base &= MCPX_LPC_PMBASE_ADDRESS_MASK;
|
||||
|
||||
mcpx_pm_iospace_update(&s->pm, pm_io_base);
|
||||
}
|
||||
|
||||
static void mcpx_lpc_reset(DeviceState *dev)
|
||||
{
|
||||
PCIDevice *d = PCI_DEVICE(dev);
|
||||
MCPX_LPCState *s = MCPX_LPC_DEVICE(d);
|
||||
|
||||
pci_set_long(s->dev.config + MCPX_LPC_PMBASE, MCPX_LPC_PMBASE_DEFAULT);
|
||||
mcpx_lpc_pmbase_update(s);
|
||||
}
|
||||
|
||||
static void mcpx_lpc_config_write(PCIDevice *dev,
|
||||
uint32_t addr, uint32_t val, int len)
|
||||
{
|
||||
MCPX_LPCState *s = MCPX_LPC_DEVICE(dev);
|
||||
|
||||
pci_default_write_config(dev, addr, val, len);
|
||||
if (ranges_overlap(addr, len, MCPX_LPC_PMBASE, 2)) {
|
||||
mcpx_lpc_pmbase_update(s);
|
||||
}
|
||||
}
|
||||
|
||||
static int mcpx_lpc_post_load(void *opaque, int version_id)
|
||||
{
|
||||
MCPX_LPCState *s = opaque;
|
||||
mcpx_lpc_pmbase_update(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_mcpx_lpc = {
|
||||
.name = "MCPX LPC",
|
||||
.version_id = 1,
|
||||
.post_load = mcpx_lpc_post_load,
|
||||
};
|
||||
|
||||
static void mcpx_lpc_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
k->no_hotplug = 1;
|
||||
k->init = mcpx_lpc_initfn;
|
||||
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;
|
||||
k->class_id = PCI_CLASS_BRIDGE_ISA;
|
||||
|
||||
dc->desc = "nForce LPC Bridge";
|
||||
dc->no_user = 1;
|
||||
dc->reset = mcpx_lpc_reset;
|
||||
dc->vmsd = &vmstate_mcpx_lpc;
|
||||
}
|
||||
|
||||
static const TypeInfo mcpx_lpc_info = {
|
||||
.name = "mcpx-lpc",
|
||||
.parent = TYPE_PCI_DEVICE,
|
||||
.instance_size = sizeof(PCIDevice),
|
||||
.class_init = mcpx_lpc_class_init,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static void xbox_agp_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = pci_bridge_initfn;
|
||||
k->exit = pci_bridge_exitfn;
|
||||
k->config_write = pci_bridge_write_config;
|
||||
k->is_bridge = 1;
|
||||
k->vendor_id = PCI_VENDOR_ID_NVIDIA;
|
||||
k->device_id = PCI_DEVICE_ID_NVIDIA_NFORCE_AGP;
|
||||
k->revision = 161;
|
||||
|
||||
dc->desc = "nForce AGP to PCI Bridge";
|
||||
dc->reset = pci_bridge_reset;
|
||||
}
|
||||
|
||||
static const TypeInfo xbox_agp_info = {
|
||||
.name = "xbox-agp",
|
||||
.parent = TYPE_PCI_DEVICE,
|
||||
.instance_size = sizeof(PCIBridge),
|
||||
.class_init = xbox_agp_class_init,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int xbox_pci_initfn(PCIDevice *d)
|
||||
{
|
||||
//XBOX_PCIState *s = DO_UPCAST(XBOX_PCIState, dev, dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xbox_pci_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
k->no_hotplug = 1;
|
||||
k->init = xbox_pci_initfn;
|
||||
//k->config_write = xbox_pci_write_config;
|
||||
k->vendor_id = PCI_VENDOR_ID_NVIDIA;
|
||||
k->device_id = PCI_DEVICE_ID_NVIDIA_XBOX_PCHB;
|
||||
k->revision = 161;
|
||||
k->class_id = PCI_CLASS_BRIDGE_HOST;
|
||||
|
||||
dc->desc = "Xbox PCI Host";
|
||||
dc->no_user = 1;
|
||||
}
|
||||
|
||||
static const TypeInfo xbox_pci_info = {
|
||||
.name = "xbox-pci",
|
||||
.parent = TYPE_PCI_DEVICE,
|
||||
.instance_size = sizeof(XBOX_PCIState),
|
||||
.class_init = xbox_pci_class_init,
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define CONFIG_ADDR 0xcf8
|
||||
#define CONFIG_DATA 0xcfc
|
||||
|
||||
static int xbox_pcihost_initfn(SysBusDevice *dev)
|
||||
{
|
||||
PCIHostState *s = PCI_HOST_BRIDGE(dev);
|
||||
|
||||
memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s,
|
||||
"pci-conf-idx", 4);
|
||||
sysbus_add_io(dev, CONFIG_ADDR, &s->conf_mem);
|
||||
sysbus_init_ioports(&s->busdev, CONFIG_ADDR, 4);
|
||||
|
||||
memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s,
|
||||
"pci-conf-data", 4);
|
||||
sysbus_add_io(dev, CONFIG_DATA, &s->data_mem);
|
||||
sysbus_init_ioports(&s->busdev, CONFIG_DATA, 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void xbox_pcihost_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = xbox_pcihost_initfn;
|
||||
dc->no_user = 1;
|
||||
}
|
||||
|
||||
static const TypeInfo xbox_pcihost_info = {
|
||||
.name = "xbox-pcihost",
|
||||
.parent = TYPE_PCI_HOST_BRIDGE,
|
||||
.instance_size = sizeof(PCIHostState),
|
||||
.class_init = xbox_pcihost_class_init,
|
||||
};
|
||||
|
||||
|
||||
static void xboxpci_register_types(void)
|
||||
{
|
||||
type_register(&xbox_pcihost_info);
|
||||
type_register(&xbox_pci_info);
|
||||
type_register(&xbox_agp_info);
|
||||
|
||||
type_register(&mcpx_lpc_info);
|
||||
type_register(&mcpx_smbus_info);
|
||||
}
|
||||
|
||||
type_init(xboxpci_register_types)
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* QEMU Xbox PCI buses implementation
|
||||
*
|
||||
* Copyright (c) 2012 espes
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* Contributions after 2012-01-13 are licensed under the terms of the
|
||||
* GNU GPL, version 2 or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef HW_XBOX_PCI_H
|
||||
#define HW_XBOX_PCI_H
|
||||
|
||||
#include "hw.h"
|
||||
#include "isa.h"
|
||||
#include "pci.h"
|
||||
#include "pci_host.h"
|
||||
#include "amd_smbus.h"
|
||||
#include "acpi.h"
|
||||
#include "acpi_mcpx.h"
|
||||
|
||||
|
||||
typedef struct XBOX_PCIState {
|
||||
PCIDevice dev;
|
||||
|
||||
MemoryRegion *ram_memory;
|
||||
MemoryRegion *pci_address_space;
|
||||
MemoryRegion *system_memory;
|
||||
MemoryRegion pci_hole;
|
||||
} XBOX_PCIState;
|
||||
|
||||
typedef struct MCPX_SMBState {
|
||||
PCIDevice dev;
|
||||
|
||||
AMD756SMBus smb;
|
||||
} MCPX_SMBState;
|
||||
|
||||
typedef struct MCPX_LPCState {
|
||||
PCIDevice dev;
|
||||
|
||||
ISABus *isa_bus;
|
||||
MCPX_PMRegs pm;
|
||||
} MCPX_LPCState;
|
||||
|
||||
#define XBOX_PCI_DEVICE(obj) \
|
||||
OBJECT_CHECK(XBOX_PCIState, (obj), "xbox-pci")
|
||||
|
||||
#define MCPX_SMBUS_DEVICE(obj) \
|
||||
OBJECT_CHECK(MCPX_SMBState, (obj), "mcpx-smbus")
|
||||
|
||||
#define MCPX_LPC_DEVICE(obj) \
|
||||
OBJECT_CHECK(MCPX_LPCState, (obj), "mcpx-lpc")
|
||||
|
||||
|
||||
|
||||
PCIBus *xbox_pci_init(DeviceState **xbox_pci_hostp,
|
||||
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);
|
||||
|
||||
ISABus *mcpx_lpc_init(DeviceState *host, PCIBus *bus);
|
||||
|
||||
i2c_bus *mcpx_smbus_init(DeviceState *host, PCIBus *bus);
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue