diff --git a/hw/xbox/chihiro.c b/hw/xbox/chihiro.c index 9bae859945..8abc9bdb47 100644 --- a/hw/xbox/chihiro.c +++ b/hw/xbox/chihiro.c @@ -83,97 +83,6 @@ typedef struct ChihiroMachineClass { /*< public >*/ } ChihiroMachineClass; - - -#define SEGA_CHIP_REVISION 0xF0 -# define SEGA_CHIP_REVISION_CHIP_ID 0xFF00 -# define SEGA_CHIP_REVISION_FPGA_CHIP_ID 0x0000 -# define SEGA_CHIP_REVISION_ASIC_CHIP_ID 0x0100 -# define SEGA_CHIP_REVISION_REVISION_ID_MASK 0x00FF -#define SEGA_DIMM_SIZE 0xF4 -# define SEGA_DIMM_SIZE_128M 0 -# define SEGA_DIMM_SIZE_256M 1 -# define SEGA_DIMM_SIZE_512M 2 -# define SEGA_DIMM_SIZE_1024M 3 - -//#define DEBUG_CHIHIRO - -typedef struct ChihiroLPCState { - ISADevice dev; - MemoryRegion ioport; -} ChihiroLPCState; - -#define CHIHIRO_LPC_DEVICE(obj) \ - OBJECT_CHECK(ChihiroLPCState, (obj), "chihiro-lpc") - - -static uint64_t chhiro_lpc_io_read(void *opaque, hwaddr addr, - unsigned size) -{ - uint64_t r = 0; - switch (addr) { - case SEGA_CHIP_REVISION: - r = SEGA_CHIP_REVISION_ASIC_CHIP_ID; - break; - case SEGA_DIMM_SIZE: - r = SEGA_DIMM_SIZE_128M; - break; - } -#ifdef DEBUG_CHIHIRO - printf("chihiro lpc read [0x%llx] -> 0x%llx\n", addr, r); -#endif - return r; -} - -static void chhiro_lpc_io_write(void *opaque, hwaddr addr, uint64_t val, - unsigned size) -{ -#ifdef DEBUG_CHIHIRO - printf("chihiro lpc write [0x%llx] = 0x%llx\n", addr, val); -#endif -} - -static const MemoryRegionOps chihiro_lpc_io_ops = { - .read = chhiro_lpc_io_read, - .write = chhiro_lpc_io_write, - .impl = { - .min_access_size = 2, - .max_access_size = 2, - }, -}; - -static void chihiro_lpc_realize(DeviceState *dev, Error **errp) -{ - ChihiroLPCState *s = CHIHIRO_LPC_DEVICE(dev); - ISADevice *isa = ISA_DEVICE(dev); - - memory_region_init_io(&s->ioport, OBJECT(dev), &chihiro_lpc_io_ops, s, - "chihiro-lpc-io", 0x100); - isa_register_ioport(isa, &s->ioport, 0x4000); -} - -static void chihiro_lpc_class_initfn(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - dc->realize = chihiro_lpc_realize; - dc->desc = "Chihiro LPC"; -} - -static const TypeInfo chihiro_lpc_info = { - .name = "chihiro-lpc", - .parent = TYPE_ISA_DEVICE, - .instance_size = sizeof(ChihiroLPCState), - .class_init = chihiro_lpc_class_initfn, -}; - -static void chihiro_register_types(void) -{ - type_register_static(&chihiro_lpc_info); -} - -type_init(chihiro_register_types) - - /* The chihiro baseboard communicates with the xbox by acting as an IDE * device. The device maps the boot rom from the mediaboard, a communication * area for interfacing with the network board, and the ram on the baseboard. @@ -285,7 +194,7 @@ static void chihiro_init(MachineState *machine) ISABus *isa_bus; xbox_init_common(machine, NULL, &isa_bus); - isa_create_simple(isa_bus, "chihiro-lpc"); + isa_create_simple(isa_bus, "lpcsega"); } static void chihiro_machine_options(MachineClass *m) diff --git a/hw/xbox/lpcsega.c b/hw/xbox/lpcsega.c new file mode 100644 index 0000000000..1d1af892cb --- /dev/null +++ b/hw/xbox/lpcsega.c @@ -0,0 +1,138 @@ +/* + * QEMU Chihiro emulation + * + * Copyright (c) 2013 espes + * Copyright (c) 2018-2021 Matt Borgerson + * + * 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 . + */ + +#include "qemu/osdep.h" +#include "hw/qdev-properties.h" +#include "hw/qdev-properties-system.h" +#include "migration/vmstate.h" +#include "sysemu/sysemu.h" +#include "hw/char/serial.h" +#include "hw/isa/isa.h" +#include "qapi/error.h" + +#define SEGA_CHIP_REVISION 0xF0 +# define SEGA_CHIP_REVISION_CHIP_ID 0xFF00 +# define SEGA_CHIP_REVISION_FPGA_CHIP_ID 0x0000 +# define SEGA_CHIP_REVISION_ASIC_CHIP_ID 0x0100 +# define SEGA_CHIP_REVISION_REVISION_ID_MASK 0x00FF +#define SEGA_DIMM_SIZE 0xF4 +# define SEGA_DIMM_SIZE_128M 0 +# define SEGA_DIMM_SIZE_256M 1 +# define SEGA_DIMM_SIZE_512M 2 +# define SEGA_DIMM_SIZE_1024M 3 + +#define TYPE_ISA_LPCSEGA_DEVICE "lpcsega" +#define ISA_LPCSEGA_DEVICE(obj) \ + OBJECT_CHECK(ISALPCSEGAState, (obj), TYPE_ISA_LPCSEGA_DEVICE) + +// #define DEBUG +#ifdef DEBUG +# define DPRINTF(format, ...) printf(format, ## __VA_ARGS__) +#else +# define DPRINTF(format, ...) do { } while (0) +#endif + +typedef struct LPCSEGAState { + MemoryRegion io; +} LPCSEGAState; + +typedef struct ISALPCSEGAState { + ISADevice parent_obj; + + bool sysopt; + uint16_t iobase; + LPCSEGAState state; +} ISALPCSEGAState; + +static void lpcsega_io_write(void *opaque, hwaddr addr, uint64_t val, + unsigned int size) +{ + DPRINTF("lpcsega io write 0x%02" HWADDR_PRIx " = 0x%02" PRIx64 "\n", addr, val); +} + +static uint64_t lpcsega_io_read(void *opaque, hwaddr addr, unsigned int size) +{ + uint32_t val = 0; + + switch (addr) { + case SEGA_CHIP_REVISION: + val = SEGA_CHIP_REVISION_ASIC_CHIP_ID; + break; + case SEGA_DIMM_SIZE: + val = SEGA_DIMM_SIZE_128M; + break; + } + + DPRINTF("lpcsega io read 0x%02" HWADDR_PRIx " -> 0x%02x\n", addr, val); + + return val; +} + +static const MemoryRegionOps lpcsega_io_ops = { + .read = lpcsega_io_read, + .write = lpcsega_io_write, + .valid = { + .min_access_size = 2, + .max_access_size = 2, + }, +}; + +static void lpcsega_realize(DeviceState *dev, Error **errp) +{ + ISADevice *isadev = ISA_DEVICE(dev); + ISALPCSEGAState *isa = ISA_LPCSEGA_DEVICE(isadev); + LPCSEGAState *s = &isa->state; + + memory_region_init_io(&s->io, OBJECT(dev), &lpcsega_io_ops, s, + "lpcsega-io", 0x100); + isa_register_ioport(isadev, &s->io, 0x4000); +} + +static Property lpcsega_properties[] = { + DEFINE_PROP_BOOL("sysopt", ISALPCSEGAState, sysopt, false), + DEFINE_PROP_END_OF_LIST(), +}; + +static void lpcsega_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = lpcsega_realize; + device_class_set_props(dc, lpcsega_properties); +} + +static void lpcsega_initfn(Object *o) +{ +} + +static const TypeInfo lpcsega_type_info = { + .name = TYPE_ISA_LPCSEGA_DEVICE, + .parent = TYPE_ISA_DEVICE, + .instance_init = lpcsega_initfn, + .instance_size = sizeof(ISALPCSEGAState), + .class_init = lpcsega_class_init, +}; + +static void lpcsega_register_types(void) +{ + type_register_static(&lpcsega_type_info); +} + +type_init(lpcsega_register_types) diff --git a/hw/xbox/meson.build b/hw/xbox/meson.build index dce2d3729e..f07706cb1b 100644 --- a/hw/xbox/meson.build +++ b/hw/xbox/meson.build @@ -5,6 +5,7 @@ specific_ss.add(files( # 'chihiro.c', 'eeprom_generation.c', 'lpc47m157.c', + 'lpcsega.c', 'nvnet.c', 'smbus_adm1032.c', 'smbus_cx25871.c',