#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 "qemu/module.h"
#include "trace.h"
{ 0x2e8, 0x238, 0x2e0, 0x228 }
};
-static inline uint16_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) {
}
}
-static inline unsigned int 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 uint16_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 uint16_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)
{
static void pc87312_realize(DeviceState *dev, Error **errp)
{
PC87312State *s;
- DeviceState *d;
ISADevice *isa;
- ISABus *bus;
- Chardev *chr;
- DriveInfo *drive;
Error *local_err = NULL;
- char name[5];
- int i;
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);
error_propagate(errp, local_err);
return;
}
-
- 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));
- }
}
static void pc87312_initfn(Object *obj)
dc->reset = pc87312_reset;
dc->vmsd = &vmstate_pc87312;
dc->props = pc87312_properties;
- /* Reason: Uses serial_hds[0] in realize(), so it can't be used twice */
- dc->user_creatable = false;
sc->parallel = (ISASuperIOFuncs){
.count = 1,
.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 = {
.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)