diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-03-16 11:05:03 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-03-16 11:05:03 +0000 |
commit | 3788c7b6e56fa34ee2a73e41706eb2a2447ba75a (patch) | |
tree | 8f016e7c9175686b4d7c2d1847c8cc877102dc6b /hw/isa/pc87312.c | |
parent | a57946ff2acb9c0d95c9f127914540586b0b8c21 (diff) | |
parent | 0790f86861079b1932679d0f011e431aaf4ee9e2 (diff) |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* Record-replay lockstep execution, log dumper and fixes (Alex, Pavel)
* SCSI fix to pass maximum transfer size (Daniel Barboza)
* chardev fixes and improved iothread support (Daniel Berrangé, Peter)
* checkpatch tweak (Eric)
* make help tweak (Marc-André)
* make more PCI NICs available with -net or -nic (myself)
* change default q35 NIC to e1000e (myself)
* SCSI support for NDOB bit (myself)
* membarrier system call support (myself)
* SuperIO refactoring (Philippe)
* miscellaneous cleanups and fixes (Thomas)
# gpg: Signature made Mon 12 Mar 2018 16:10:52 GMT
# gpg: using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* remotes/bonzini/tags/for-upstream: (69 commits)
tcg: fix cpu_io_recompile
replay: update documentation
replay: save vmstate of the asynchronous events
replay: don't process async events when warping the clock
scripts/replay-dump.py: replay log dumper
replay: avoid recursive call of checkpoints
replay: check return values of fwrite
replay: push replay_mutex_lock up the call tree
replay: don't destroy mutex at exit
replay: make locking visible outside replay code
replay/replay-internal.c: track holding of replay_lock
replay/replay.c: bump REPLAY_VERSION again
replay: save prior value of the host clock
replay: added replay log format description
replay: fix save/load vm for non-empty queue
replay: fixed replay_enable_events
replay: fix processing async events
cpu-exec: fix exception_index handling
hw/i386/pc: Factor out the superio code
hw/alpha/dp264: Use the TYPE_SMC37C669_SUPERIO
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
# Conflicts:
# default-configs/i386-softmmu.mak
# default-configs/x86_64-softmmu.mak
Diffstat (limited to 'hw/isa/pc87312.c')
-rw-r--r-- | hw/isa/pc87312.c | 178 |
1 files changed, 78 insertions, 100 deletions
diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c index 48b29e3c3c..5cf64505fe 100644 --- a/hw/isa/pc87312.c +++ b/hw/isa/pc87312.c @@ -27,10 +27,6 @@ #include "hw/isa/pc87312.h" #include "qapi/error.h" #include "qemu/error-report.h" -#include "sysemu/block-backend.h" -#include "sysemu/blockdev.h" -#include "sysemu/sysemu.h" -#include "chardev/char.h" #include "trace.h" @@ -64,22 +60,25 @@ /* Parallel port */ -static inline bool is_parallel_enabled(PC87312State *s) +static bool is_parallel_enabled(ISASuperIODevice *sio, uint8_t index) { - return s->regs[REG_FER] & FER_PARALLEL_EN; + PC87312State *s = PC87312(sio); + return index ? false : s->regs[REG_FER] & FER_PARALLEL_EN; } -static const uint32_t parallel_base[] = { 0x378, 0x3bc, 0x278, 0x00 }; +static const uint16_t parallel_base[] = { 0x378, 0x3bc, 0x278, 0x00 }; -static inline uint32_t get_parallel_iobase(PC87312State *s) +static uint16_t get_parallel_iobase(ISASuperIODevice *sio, uint8_t index) { + PC87312State *s = PC87312(sio); return parallel_base[s->regs[REG_FAR] & FAR_PARALLEL_ADDR]; } -static const uint32_t parallel_irq[] = { 5, 7, 5, 0 }; +static const unsigned int parallel_irq[] = { 5, 7, 5, 0 }; -static inline uint32_t get_parallel_irq(PC87312State *s) +static unsigned int get_parallel_irq(ISASuperIODevice *sio, uint8_t index) { + PC87312State *s = PC87312(sio); int idx; idx = (s->regs[REG_FAR] & FAR_PARALLEL_ADDR); if (idx == 0) { @@ -92,13 +91,14 @@ static inline uint32_t get_parallel_irq(PC87312State *s) /* UARTs */ -static const uint32_t uart_base[2][4] = { +static const uint16_t uart_base[2][4] = { { 0x3e8, 0x338, 0x2e8, 0x220 }, { 0x2e8, 0x238, 0x2e0, 0x228 } }; -static inline uint32_t get_uart_iobase(PC87312State *s, int i) +static uint16_t get_uart_iobase(ISASuperIODevice *sio, uint8_t i) { + PC87312State *s = PC87312(sio); int idx; idx = (s->regs[REG_FAR] >> (2 * i + 2)) & 0x3; if (idx == 0) { @@ -110,44 +110,68 @@ static inline uint32_t get_uart_iobase(PC87312State *s, int i) } } -static inline uint32_t get_uart_irq(PC87312State *s, int i) +static unsigned int get_uart_irq(ISASuperIODevice *sio, uint8_t i) { + PC87312State *s = PC87312(sio); int idx; idx = (s->regs[REG_FAR] >> (2 * i + 2)) & 0x3; return (idx & 1) ? 3 : 4; } -static inline bool is_uart_enabled(PC87312State *s, int i) +static bool is_uart_enabled(ISASuperIODevice *sio, uint8_t i) { + PC87312State *s = PC87312(sio); return s->regs[REG_FER] & (FER_UART1_EN << i); } /* Floppy controller */ -static inline bool is_fdc_enabled(PC87312State *s) +static bool is_fdc_enabled(ISASuperIODevice *sio, uint8_t index) { + PC87312State *s = PC87312(sio); + assert(!index); return s->regs[REG_FER] & FER_FDC_EN; } -static inline uint32_t get_fdc_iobase(PC87312State *s) +static uint16_t get_fdc_iobase(ISASuperIODevice *sio, uint8_t index) { + PC87312State *s = PC87312(sio); + assert(!index); return (s->regs[REG_FER] & FER_FDC_ADDR) ? 0x370 : 0x3f0; } +static unsigned int get_fdc_irq(ISASuperIODevice *sio, uint8_t index) +{ + assert(!index); + return 6; +} + /* IDE controller */ -static inline bool is_ide_enabled(PC87312State *s) +static bool is_ide_enabled(ISASuperIODevice *sio, uint8_t index) { + PC87312State *s = PC87312(sio); + return s->regs[REG_FER] & FER_IDE_EN; } -static inline uint32_t get_ide_iobase(PC87312State *s) +static uint16_t get_ide_iobase(ISASuperIODevice *sio, uint8_t index) { + PC87312State *s = PC87312(sio); + + if (index == 1) { + return get_ide_iobase(sio, 0) + 0x206; + } return (s->regs[REG_FER] & FER_IDE_ADDR) ? 0x170 : 0x1f0; } +static unsigned int get_ide_irq(ISASuperIODevice *sio, uint8_t index) +{ + assert(index == 0); + return 14; +} static void reconfigure_devices(PC87312State *s) { @@ -265,90 +289,18 @@ static void pc87312_reset(DeviceState *d) static void pc87312_realize(DeviceState *dev, Error **errp) { PC87312State *s; - DeviceState *d; ISADevice *isa; - ISABus *bus; - Chardev *chr; - DriveInfo *drive; - char name[5]; - int i; + Error *local_err = NULL; s = PC87312(dev); isa = ISA_DEVICE(dev); - bus = isa_bus_from_device(isa); isa_register_ioport(isa, &s->io, s->iobase); pc87312_hard_reset(s); - if (is_parallel_enabled(s)) { - /* FIXME use a qdev chardev prop instead of parallel_hds[] */ - chr = parallel_hds[0]; - if (chr == NULL) { - chr = qemu_chr_new("par0", "null"); - } - isa = isa_create(bus, "isa-parallel"); - d = DEVICE(isa); - qdev_prop_set_uint32(d, "index", 0); - qdev_prop_set_uint32(d, "iobase", get_parallel_iobase(s)); - qdev_prop_set_uint32(d, "irq", get_parallel_irq(s)); - qdev_prop_set_chr(d, "chardev", chr); - qdev_init_nofail(d); - s->parallel.dev = isa; - trace_pc87312_info_parallel(get_parallel_iobase(s), - get_parallel_irq(s)); - } - - for (i = 0; i < 2; i++) { - if (is_uart_enabled(s, i)) { - /* FIXME use a qdev chardev prop instead of serial_hds[] */ - chr = serial_hds[i]; - if (chr == NULL) { - snprintf(name, sizeof(name), "ser%d", i); - chr = qemu_chr_new(name, "null"); - } - isa = isa_create(bus, "isa-serial"); - d = DEVICE(isa); - qdev_prop_set_uint32(d, "index", i); - qdev_prop_set_uint32(d, "iobase", get_uart_iobase(s, i)); - qdev_prop_set_uint32(d, "irq", get_uart_irq(s, i)); - qdev_prop_set_chr(d, "chardev", chr); - qdev_init_nofail(d); - s->uart[i].dev = isa; - trace_pc87312_info_serial(i, get_uart_iobase(s, i), - get_uart_irq(s, i)); - } - } - - if (is_fdc_enabled(s)) { - isa = isa_create(bus, "isa-fdc"); - d = DEVICE(isa); - qdev_prop_set_uint32(d, "iobase", get_fdc_iobase(s)); - qdev_prop_set_uint32(d, "irq", 6); - /* FIXME use a qdev drive property instead of drive_get() */ - drive = drive_get(IF_FLOPPY, 0, 0); - if (drive != NULL) { - qdev_prop_set_drive(d, "driveA", blk_by_legacy_dinfo(drive), - &error_fatal); - } - /* FIXME use a qdev drive property instead of drive_get() */ - drive = drive_get(IF_FLOPPY, 0, 1); - if (drive != NULL) { - qdev_prop_set_drive(d, "driveB", blk_by_legacy_dinfo(drive), - &error_fatal); - } - qdev_init_nofail(d); - s->fdc.dev = isa; - trace_pc87312_info_floppy(get_fdc_iobase(s)); - } - - if (is_ide_enabled(s)) { - isa = isa_create(bus, "isa-ide"); - d = DEVICE(isa); - qdev_prop_set_uint32(d, "iobase", get_ide_iobase(s)); - qdev_prop_set_uint32(d, "iobase2", get_ide_iobase(s) + 0x206); - qdev_prop_set_uint32(d, "irq", 14); - qdev_init_nofail(d); - s->ide.dev = isa; - trace_pc87312_info_ide(get_ide_iobase(s)); + ISA_SUPERIO_GET_CLASS(dev)->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; } } @@ -373,7 +325,7 @@ static const VMStateDescription vmstate_pc87312 = { }; static Property pc87312_properties[] = { - DEFINE_PROP_UINT32("iobase", PC87312State, iobase, 0x398), + DEFINE_PROP_UINT16("iobase", PC87312State, iobase, 0x398), DEFINE_PROP_UINT8("config", PC87312State, config, 1), DEFINE_PROP_END_OF_LIST() }; @@ -381,21 +333,47 @@ static Property pc87312_properties[] = { static void pc87312_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); + sc->parent_realize = dc->realize; dc->realize = pc87312_realize; dc->reset = pc87312_reset; dc->vmsd = &vmstate_pc87312; dc->props = pc87312_properties; - /* Reason: Uses parallel_hds[0] in realize(), so it can't be used twice */ - dc->user_creatable = false; + + sc->parallel = (ISASuperIOFuncs){ + .count = 1, + .is_enabled = is_parallel_enabled, + .get_iobase = get_parallel_iobase, + .get_irq = get_parallel_irq, + }; + sc->serial = (ISASuperIOFuncs){ + .count = 2, + .is_enabled = is_uart_enabled, + .get_iobase = get_uart_iobase, + .get_irq = get_uart_irq, + }; + sc->floppy = (ISASuperIOFuncs){ + .count = 1, + .is_enabled = is_fdc_enabled, + .get_iobase = get_fdc_iobase, + .get_irq = get_fdc_irq, + }; + sc->ide = (ISASuperIOFuncs){ + .count = 1, + .is_enabled = is_ide_enabled, + .get_iobase = get_ide_iobase, + .get_irq = get_ide_irq, + }; } static const TypeInfo pc87312_type_info = { - .name = TYPE_PC87312, - .parent = TYPE_ISA_DEVICE, + .name = TYPE_PC87312_SUPERIO, + .parent = TYPE_ISA_SUPERIO, .instance_size = sizeof(PC87312State), .instance_init = pc87312_initfn, .class_init = pc87312_class_init, + /* FIXME use a qdev drive property instead of drive_get() */ }; static void pc87312_register_types(void) |