version 1.1.1.2, 2018/04/24 17:24:23
|
version 1.1.1.3, 2018/04/24 17:38:45
|
Line 38
|
Line 38
|
//#define DEBUG_MOUSE |
//#define DEBUG_MOUSE |
|
|
/* |
/* |
|
* Chipset docs: |
|
* "Z80C30/Z85C30/Z80230/Z85230/Z85233 SCC/ESCC User Manual", |
|
* http://www.zilog.com/docs/serial/scc_escc_um.pdf |
|
* |
* On Sparc32 this is the serial port, mouse and keyboard part of chip STP2001 |
* On Sparc32 this is the serial port, mouse and keyboard part of chip STP2001 |
* (Slave I/O), also produced as NCR89C105. See |
* (Slave I/O), also produced as NCR89C105. See |
* http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt |
* http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt |
Line 113 typedef struct ChannelState {
|
Line 117 typedef struct ChannelState {
|
int e0_mode, led_mode, caps_lock_mode, num_lock_mode; |
int e0_mode, led_mode, caps_lock_mode, num_lock_mode; |
int disabled; |
int disabled; |
int clock; |
int clock; |
|
uint32_t vmstate_dummy; |
} ChannelState; |
} ChannelState; |
|
|
struct SerialState { |
struct SerialState { |
SysBusDevice busdev; |
SysBusDevice busdev; |
struct ChannelState chn[2]; |
struct ChannelState chn[2]; |
int it_shift; |
uint32_t it_shift; |
int mmio_index; |
int mmio_index; |
uint32_t disabled; |
uint32_t disabled; |
uint32_t frequency; |
uint32_t frequency; |
Line 326 static void escc_reset_chn(ChannelState
|
Line 331 static void escc_reset_chn(ChannelState
|
clear_queue(s); |
clear_queue(s); |
} |
} |
|
|
static void escc_reset(void *opaque) |
static void escc_reset(DeviceState *d) |
{ |
{ |
SerialState *s = opaque; |
SerialState *s = container_of(d, SerialState, busdev.qdev); |
|
|
escc_reset_chn(&s->chn[0]); |
escc_reset_chn(&s->chn[0]); |
escc_reset_chn(&s->chn[1]); |
escc_reset_chn(&s->chn[1]); |
} |
} |
Line 547 static void escc_mem_writeb(void *opaque
|
Line 553 static void escc_mem_writeb(void *opaque
|
escc_reset_chn(&serial->chn[1]); |
escc_reset_chn(&serial->chn[1]); |
return; |
return; |
case MINTR_RST_ALL: |
case MINTR_RST_ALL: |
escc_reset(serial); |
escc_reset(&serial->busdev.qdev); |
return; |
return; |
} |
} |
break; |
break; |
Line 654 static void serial_event(void *opaque, i
|
Line 660 static void serial_event(void *opaque, i
|
serial_receive_break(s); |
serial_receive_break(s); |
} |
} |
|
|
static CPUReadMemoryFunc *escc_mem_read[3] = { |
static CPUReadMemoryFunc * const escc_mem_read[3] = { |
escc_mem_readb, |
escc_mem_readb, |
NULL, |
NULL, |
NULL, |
NULL, |
}; |
}; |
|
|
static CPUWriteMemoryFunc *escc_mem_write[3] = { |
static CPUWriteMemoryFunc * const escc_mem_write[3] = { |
escc_mem_writeb, |
escc_mem_writeb, |
NULL, |
NULL, |
NULL, |
NULL, |
}; |
}; |
|
|
static void escc_save_chn(QEMUFile *f, ChannelState *s) |
static const VMStateDescription vmstate_escc_chn = { |
{ |
.name ="escc_chn", |
uint32_t tmp = 0; |
.version_id = 2, |
|
.minimum_version_id = 1, |
qemu_put_be32s(f, &tmp); /* unused, was IRQ. */ |
.minimum_version_id_old = 1, |
qemu_put_be32s(f, &s->reg); |
.fields = (VMStateField []) { |
qemu_put_be32s(f, &s->rxint); |
VMSTATE_UINT32(vmstate_dummy, ChannelState), |
qemu_put_be32s(f, &s->txint); |
VMSTATE_UINT32(reg, ChannelState), |
qemu_put_be32s(f, &s->rxint_under_svc); |
VMSTATE_UINT32(rxint, ChannelState), |
qemu_put_be32s(f, &s->txint_under_svc); |
VMSTATE_UINT32(txint, ChannelState), |
qemu_put_8s(f, &s->rx); |
VMSTATE_UINT32(rxint_under_svc, ChannelState), |
qemu_put_8s(f, &s->tx); |
VMSTATE_UINT32(txint_under_svc, ChannelState), |
qemu_put_buffer(f, s->wregs, SERIAL_REGS); |
VMSTATE_UINT8(rx, ChannelState), |
qemu_put_buffer(f, s->rregs, SERIAL_REGS); |
VMSTATE_UINT8(tx, ChannelState), |
} |
VMSTATE_BUFFER(wregs, ChannelState), |
|
VMSTATE_BUFFER(rregs, ChannelState), |
static void escc_save(QEMUFile *f, void *opaque) |
VMSTATE_END_OF_LIST() |
{ |
|
SerialState *s = opaque; |
|
|
|
escc_save_chn(f, &s->chn[0]); |
|
escc_save_chn(f, &s->chn[1]); |
|
} |
|
|
|
static int escc_load_chn(QEMUFile *f, ChannelState *s, int version_id) |
|
{ |
|
uint32_t tmp; |
|
|
|
if (version_id > 2) |
|
return -EINVAL; |
|
|
|
qemu_get_be32s(f, &tmp); /* unused */ |
|
qemu_get_be32s(f, &s->reg); |
|
qemu_get_be32s(f, &s->rxint); |
|
qemu_get_be32s(f, &s->txint); |
|
if (version_id >= 2) { |
|
qemu_get_be32s(f, &s->rxint_under_svc); |
|
qemu_get_be32s(f, &s->txint_under_svc); |
|
} |
} |
qemu_get_8s(f, &s->rx); |
}; |
qemu_get_8s(f, &s->tx); |
|
qemu_get_buffer(f, s->wregs, SERIAL_REGS); |
|
qemu_get_buffer(f, s->rregs, SERIAL_REGS); |
|
return 0; |
|
} |
|
|
|
static int escc_load(QEMUFile *f, void *opaque, int version_id) |
|
{ |
|
SerialState *s = opaque; |
|
int ret; |
|
|
|
ret = escc_load_chn(f, &s->chn[0], version_id); |
|
if (ret != 0) |
|
return ret; |
|
ret = escc_load_chn(f, &s->chn[1], version_id); |
|
return ret; |
|
|
|
} |
static const VMStateDescription vmstate_escc = { |
|
.name ="escc", |
|
.version_id = 2, |
|
.minimum_version_id = 1, |
|
.minimum_version_id_old = 1, |
|
.fields = (VMStateField []) { |
|
VMSTATE_STRUCT_ARRAY(chn, SerialState, 2, 2, vmstate_escc_chn, |
|
ChannelState), |
|
VMSTATE_END_OF_LIST() |
|
} |
|
}; |
|
|
int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, |
int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, |
CharDriverState *chrA, CharDriverState *chrB, |
CharDriverState *chrA, CharDriverState *chrB, |
Line 737 int escc_init(target_phys_addr_t base, q
|
Line 716 int escc_init(target_phys_addr_t base, q
|
qdev_prop_set_uint32(dev, "disabled", 0); |
qdev_prop_set_uint32(dev, "disabled", 0); |
qdev_prop_set_uint32(dev, "frequency", clock); |
qdev_prop_set_uint32(dev, "frequency", clock); |
qdev_prop_set_uint32(dev, "it_shift", it_shift); |
qdev_prop_set_uint32(dev, "it_shift", it_shift); |
qdev_prop_set_ptr(dev, "chrB", chrB); |
qdev_prop_set_chr(dev, "chrB", chrB); |
qdev_prop_set_ptr(dev, "chrA", chrA); |
qdev_prop_set_chr(dev, "chrA", chrA); |
qdev_prop_set_uint32(dev, "chnBtype", ser); |
qdev_prop_set_uint32(dev, "chnBtype", ser); |
qdev_prop_set_uint32(dev, "chnAtype", ser); |
qdev_prop_set_uint32(dev, "chnAtype", ser); |
qdev_init(dev); |
qdev_init_nofail(dev); |
s = sysbus_from_qdev(dev); |
s = sysbus_from_qdev(dev); |
sysbus_connect_irq(s, 0, irqB); |
sysbus_connect_irq(s, 0, irqB); |
sysbus_connect_irq(s, 1, irqA); |
sysbus_connect_irq(s, 1, irqA); |
Line 869 static void sunmouse_event(void *opaque,
|
Line 848 static void sunmouse_event(void *opaque,
|
ch = dx; |
ch = dx; |
|
|
if (ch > 127) |
if (ch > 127) |
ch=127; |
ch = 127; |
else if (ch < -127) |
else if (ch < -127) |
ch=-127; |
ch = -127; |
|
|
put_queue(s, ch & 0xff); |
put_queue(s, ch & 0xff); |
|
|
ch = -dy; |
ch = -dy; |
|
|
if (ch > 127) |
if (ch > 127) |
ch=127; |
ch = 127; |
else if (ch < -127) |
else if (ch < -127) |
ch=-127; |
ch = -127; |
|
|
put_queue(s, ch & 0xff); |
put_queue(s, ch & 0xff); |
|
|
Line 900 void slavio_serial_ms_kbd_init(target_ph
|
Line 879 void slavio_serial_ms_kbd_init(target_ph
|
qdev_prop_set_uint32(dev, "disabled", disabled); |
qdev_prop_set_uint32(dev, "disabled", disabled); |
qdev_prop_set_uint32(dev, "frequency", clock); |
qdev_prop_set_uint32(dev, "frequency", clock); |
qdev_prop_set_uint32(dev, "it_shift", it_shift); |
qdev_prop_set_uint32(dev, "it_shift", it_shift); |
qdev_prop_set_ptr(dev, "chrB", NULL); |
qdev_prop_set_chr(dev, "chrB", NULL); |
qdev_prop_set_ptr(dev, "chrA", NULL); |
qdev_prop_set_chr(dev, "chrA", NULL); |
qdev_prop_set_uint32(dev, "chnBtype", mouse); |
qdev_prop_set_uint32(dev, "chnBtype", mouse); |
qdev_prop_set_uint32(dev, "chnAtype", kbd); |
qdev_prop_set_uint32(dev, "chnAtype", kbd); |
qdev_init(dev); |
qdev_init_nofail(dev); |
s = sysbus_from_qdev(dev); |
s = sysbus_from_qdev(dev); |
sysbus_connect_irq(s, 0, irq); |
sysbus_connect_irq(s, 0, irq); |
sysbus_connect_irq(s, 1, irq); |
sysbus_connect_irq(s, 1, irq); |
sysbus_mmio_map(s, 0, base); |
sysbus_mmio_map(s, 0, base); |
} |
} |
|
|
static void escc_init1(SysBusDevice *dev) |
static int escc_init1(SysBusDevice *dev) |
{ |
{ |
SerialState *s = FROM_SYSBUS(SerialState, dev); |
SerialState *s = FROM_SYSBUS(SerialState, dev); |
int io; |
int io; |
Line 942 static void escc_init1(SysBusDevice *dev
|
Line 921 static void escc_init1(SysBusDevice *dev
|
if (s->chn[1].type == kbd) { |
if (s->chn[1].type == kbd) { |
qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]); |
qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]); |
} |
} |
register_savevm("escc", -1, 2, escc_save, escc_load, s); |
|
qemu_register_reset(escc_reset, s); |
return 0; |
escc_reset(s); |
|
} |
} |
|
|
static SysBusDeviceInfo escc_info = { |
static SysBusDeviceInfo escc_info = { |
.init = escc_init1, |
.init = escc_init1, |
.qdev.name = "escc", |
.qdev.name = "escc", |
.qdev.size = sizeof(SerialState), |
.qdev.size = sizeof(SerialState), |
|
.qdev.vmsd = &vmstate_escc, |
|
.qdev.reset = escc_reset, |
.qdev.props = (Property[]) { |
.qdev.props = (Property[]) { |
{ |
DEFINE_PROP_UINT32("frequency", SerialState, frequency, 0), |
.name = "frequency", |
DEFINE_PROP_UINT32("it_shift", SerialState, it_shift, 0), |
.info = &qdev_prop_uint32, |
DEFINE_PROP_UINT32("disabled", SerialState, disabled, 0), |
.offset = offsetof(SerialState, frequency), |
DEFINE_PROP_UINT32("disabled", SerialState, disabled, 0), |
}, |
DEFINE_PROP_UINT32("chnBtype", SerialState, chn[0].type, 0), |
{ |
DEFINE_PROP_UINT32("chnAtype", SerialState, chn[1].type, 0), |
.name = "it_shift", |
DEFINE_PROP_CHR("chrB", SerialState, chn[0].chr), |
.info = &qdev_prop_uint32, |
DEFINE_PROP_CHR("chrA", SerialState, chn[1].chr), |
.offset = offsetof(SerialState, it_shift), |
DEFINE_PROP_END_OF_LIST(), |
}, |
|
{ |
|
.name = "disabled", |
|
.info = &qdev_prop_uint32, |
|
.offset = offsetof(SerialState, disabled), |
|
}, |
|
{ |
|
.name = "chrB", |
|
.info = &qdev_prop_ptr, |
|
.offset = offsetof(SerialState, chn[0].chr), |
|
}, |
|
{ |
|
.name = "chrA", |
|
.info = &qdev_prop_ptr, |
|
.offset = offsetof(SerialState, chn[1].chr), |
|
}, |
|
{ |
|
.name = "chnBtype", |
|
.info = &qdev_prop_uint32, |
|
.offset = offsetof(SerialState, chn[0].type), |
|
}, |
|
{ |
|
.name = "chnAtype", |
|
.info = &qdev_prop_uint32, |
|
.offset = offsetof(SerialState, chn[1].type), |
|
}, |
|
{/* end of list */} |
|
} |
} |
}; |
}; |
|
|