diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index 0a34a48278..d7a7e43c29 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -12,6 +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-$(CONFIG_XBOX) += xbox.o xbox_pci.o acpi_mcpx.o amd_smbus.o nv2a.o smbus_xbox_smc.o smbus_cx25871.o smbus_adm1032.o obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/smbus.h b/hw/smbus.h index 9dafd32d9a..91fdfd0f24 100644 --- a/hw/smbus.h +++ b/hw/smbus.h @@ -83,7 +83,7 @@ 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_xbox_smc_init(i2c_bus *smbus, int address); void smbus_cx25871_init(i2c_bus *smbus, int address); void smbus_adm1032_init(i2c_bus *smbus, int address); diff --git a/hw/smbus_pic16lc.c b/hw/smbus_pic16lc.c deleted file mode 100644 index 80db68b118..0000000000 --- a/hw/smbus_pic16lc.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * 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; - - //challenge response - // (http://www.xbox-linux.org/wiki/PIC_Challenge_Handshake_Sequence) - case 0x20: - break; - case 0x21: - 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; - - //challenge request - case 0x1c: - return 0x52; - case 0x1d: - return 0x72; - case 0x1e: - return 0xea; - case 0x1f: - return 0x46; - - 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); -} diff --git a/hw/smbus_xbox_smc.c b/hw/smbus_xbox_smc.c new file mode 100644 index 0000000000..58c4e17bf8 --- /dev/null +++ b/hw/smbus_xbox_smc.c @@ -0,0 +1,206 @@ +/* + * QEMU SMBus Xbox System Management Controller + * + * 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" + +/* + * Hardware is a PIC16LC + * http://www.xbox-linux.org/wiki/PIC + */ + +#define SMC_REG_VER 0x01 +#define SMC_REG_POWER 0x02 +#define SMC_REG_POWER_RESET 0x01 +#define SMC_REG_POWER_CYCLE 0x40 +#define SMC_REG_POWER_SHUTDOWN 0x80 +#define SMC_REG_TRAYSTATE 0x03 +#define SMC_REG_AVPACK 0x04 +#define SMC_REG_AVPACK_SCART 0x00 +#define SMC_REG_AVPACK_HDTV 0x01 +#define SMC_REG_AVPACK_VGA_SOG 0x02 +#define SMC_REG_AVPACK_SVIDEO 0x04 +#define SMC_REG_AVPACK_COMPOSITE 0x06 +#define SMC_REG_AVPACK_VGA 0x07 +#define SMC_REG_FANMODE 0x05 +#define SMC_REG_FANSPEED 0x06 +#define SMC_REG_LEDMODE 0x07 +#define SMC_REG_LEDSEQ 0x08 +#define SMC_REG_CPUTEMP 0x09 +#define SMC_REG_BOARDTEMP 0x0a +#define SMC_REG_TRAYEJECT 0x0c +#define SMC_REG_INTACK 0x0d +#define SMC_REG_INTSTATUS 0x11 +#define SMC_REG_INTSTATUS_POWER 0x01 +#define SMC_REG_INTSTATUS_TRAYCLOSED 0x02 +#define SMC_REG_INTSTATUS_TRAYOPENING 0x04 +#define SMC_REG_INTSTATUS_AVPACK_PLUG 0x08 +#define SMC_REG_INTSTATUS_AVPACK_UNPLUG 0x10 +#define SMC_REG_INTSTATUS_EJECT_BUTTON 0x20 +#define SMC_REG_INTSTATUS_TRAYCLOSING 0x40 +#define SMC_REG_RESETONEJECT 0x19 +#define SMC_REG_INTEN 0x1a + +static const char* smc_version_string = "P01"; + + +//#define DEBUG + +typedef struct SMBusSMCDevice { + SMBusDevice smbusdev; + int versionStringIndex; +} SMBusSMCDevice; + +static void smc_quick_cmd(SMBusDevice *dev, uint8_t read) +{ +#ifdef DEBUG + printf("smc_quick_cmd: addr=0x%02x read=%d\n", dev->i2c.address, read); +#endif +} + +static void smc_send_byte(SMBusDevice *dev, uint8_t val) +{ +#ifdef DEBUG + printf("smc_send_byte: addr=0x%02x val=0x%02x\n", + dev->i2c.address, val); +#endif +} + +static uint8_t smc_receive_byte(SMBusDevice *dev) +{ +#ifdef DEBUG + printf("smc_receive_byte: addr=0x%02x\n", + dev->i2c.address); +#endif + return 0; +} + +static void smc_write_data(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len) +{ + SMBusSMCDevice *smc = (SMBusSMCDevice *) dev; +#ifdef DEBUG + printf("smc_write_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n", + dev->i2c.address, cmd, buf[0]); +#endif + + switch(cmd) { + case SMC_REG_VER: + /* version string reset */ + smc->versionStringIndex = buf[0]; + break; + + /* challenge response + * (http://www.xbox-linux.org/wiki/PIC_Challenge_Handshake_Sequence) */ + case 0x20: + break; + case 0x21: + break; + + + default: + break; + } +} + +static uint8_t smc_read_data(SMBusDevice *dev, uint8_t cmd, int n) +{ + SMBusSMCDevice *smc = (SMBusSMCDevice *) dev; + #ifdef DEBUG + printf("smc_read_data: addr=0x%02x cmd=0x%02x n=%d\n", + dev->i2c.address, cmd, n); + #endif + + switch(cmd) { + case SMC_REG_VER: + return smc_version_string[ + smc->versionStringIndex++%(sizeof(smc_version_string)-1)]; + case SMC_REG_AVPACK: + /* pretend to have a composite av pack plugged in */ + return SMC_REG_AVPACK_COMPOSITE; + + /* challenge request: + * must be non-0 */ + case 0x1c: + return 0x52; + case 0x1d: + return 0x72; + case 0x1e: + return 0xea; + case 0x1f: + return 0x46; + + default: + break; + } + + return 0; +} + +static int smbus_smc_init(SMBusDevice *dev) +{ + SMBusSMCDevice *smc = (SMBusSMCDevice *)dev; + + smc->versionStringIndex = 0; + + return 0; +} + + +static void smbus_smc_class_initfn(ObjectClass *klass, void *data) +{ + SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass); + + sc->init = smbus_smc_init; + sc->quick_cmd = smc_quick_cmd; + sc->send_byte = smc_send_byte; + sc->receive_byte = smc_receive_byte; + sc->write_data = smc_write_data; + sc->read_data = smc_read_data; +} + +static TypeInfo smbus_smc_info = { + .name = "smbus-xbox-smc", + .parent = TYPE_SMBUS_DEVICE, + .instance_size = sizeof(SMBusSMCDevice), + .class_init = smbus_smc_class_initfn, +}; + + + +static void smbus_smc_register_devices(void) +{ + type_register_static(&smbus_smc_info); +} + +type_init(smbus_smc_register_devices) + + +void smbus_xbox_smc_init(i2c_bus *smbus, int address) +{ + DeviceState *smc; + smc = qdev_create((BusState *)smbus, "smbus-xbox-smc"); + qdev_prop_set_uint8(smc, "address", address); + qdev_init_nofail(smc); +} diff --git a/hw/xbox.c b/hw/xbox.c index 2bc185cc99..bb50350bd3 100644 --- a/hw/xbox.c +++ b/hw/xbox.c @@ -304,7 +304,7 @@ static void xbox_init(QEMUMachineInitArgs *args) smbus_eeprom_init_single(smbus, 0x54, eeprom_buf); - smbus_pic16lc_init(smbus, 0x10); + smbus_xbox_smc_init(smbus, 0x10); smbus_cx25871_init(smbus, 0x45); smbus_adm1032_init(smbus, 0x4c);