diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-09-10 11:09:30 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-09-10 11:09:30 +0100 |
commit | 6d1272d3ef81aa33e97ca5c69707cbcad953cbdb (patch) | |
tree | 827eab7033f23a01834c521897f84b93d9848f86 /hw | |
parent | 500f1f3e81ad112e28b7c979136847e32dad83b6 (diff) | |
parent | dde602ae539910c3579952834b713e2f360ec34a (diff) | |
download | qemu-6d1272d3ef81aa33e97ca5c69707cbcad953cbdb.zip qemu-6d1272d3ef81aa33e97ca5c69707cbcad953cbdb.tar.gz qemu-6d1272d3ef81aa33e97ca5c69707cbcad953cbdb.tar.bz2 |
Merge remote-tracking branch 'remotes/vivier/tags/q800-pull-request' into staging
q800 pull request 20210908
mac_via: remove MAC_VIA device and prepare for Nubus IRQs
# gpg: Signature made Wed 08 Sep 2021 16:35:03 BST
# gpg: using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C
# gpg: issuer "laurent@vivier.eu"
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg: aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C
* remotes/vivier/tags/q800-pull-request:
mac_via: add qdev gpios for nubus slot interrupts to VIA2
mac_via: rename VIA2_IRQ_SLOT_BIT to VIA2_IRQ_NUBUS_BIT
mac_via: remove explicit viaN prefix from VIA IRQ gpios
mac_via: remove mac_via device
mac_via: move VIA1 realize logic from mac_via_realize() to mos6522_q800_via1_realize()
mac_via: move VIA1 reset logic from mac_via_reset() to mos6522_q800_via1_reset()
mac_via: move q800 VIA1 timer variables to q800 VIA1 VMStateDescription
mac_via: move ADB variables to MOS6522Q800VIA1State
mac_via: move PRAM/RTC variables to MOS6522Q800VIA1State
mac_via: move PRAM contents and block backend to MOS6522Q800VIA1State
mac_via: move last_b variable into q800 VIA1 VMStateDescription
mac_via: introduce new VMStateDescription for q800 VIA1 and VIA2
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/m68k/q800.c | 38 | ||||
-rw-r--r-- | hw/misc/mac_via.c | 547 |
2 files changed, 278 insertions, 307 deletions
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index ac0a130..5ba87f7 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -225,7 +225,7 @@ static void q800_init(MachineState *machine) hwaddr parameters_base; CPUState *cs; DeviceState *dev; - DeviceState *via_dev; + DeviceState *via1_dev, *via2_dev; DeviceState *escc_orgate; SysBusESPState *sysbus_esp; ESPState *esp; @@ -270,28 +270,30 @@ static void q800_init(MachineState *machine) object_property_set_link(OBJECT(glue), "cpu", OBJECT(cpu), &error_abort); sysbus_realize_and_unref(SYS_BUS_DEVICE(glue), &error_fatal); - /* VIA */ - - via_dev = qdev_new(TYPE_MAC_VIA); + /* VIA 1 */ + via1_dev = qdev_new(TYPE_MOS6522_Q800_VIA1); dinfo = drive_get(IF_MTD, 0, 0); if (dinfo) { - qdev_prop_set_drive(via_dev, "drive", blk_by_legacy_dinfo(dinfo)); + qdev_prop_set_drive(via1_dev, "drive", blk_by_legacy_dinfo(dinfo)); } - sysbus = SYS_BUS_DEVICE(via_dev); + sysbus = SYS_BUS_DEVICE(via1_dev); sysbus_realize_and_unref(sysbus, &error_fatal); - sysbus_mmio_map(sysbus, 0, VIA_BASE); - qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 0, - qdev_get_gpio_in(glue, 0)); - qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 1, - qdev_get_gpio_in(glue, 1)); - + sysbus_mmio_map(sysbus, 1, VIA_BASE); + sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(glue, 0)); - adb_bus = qdev_get_child_bus(via_dev, "adb.0"); + adb_bus = qdev_get_child_bus(via1_dev, "adb.0"); dev = qdev_new(TYPE_ADB_KEYBOARD); qdev_realize_and_unref(dev, adb_bus, &error_fatal); dev = qdev_new(TYPE_ADB_MOUSE); qdev_realize_and_unref(dev, adb_bus, &error_fatal); + /* VIA 2 */ + via2_dev = qdev_new(TYPE_MOS6522_Q800_VIA2); + sysbus = SYS_BUS_DEVICE(via2_dev); + sysbus_realize_and_unref(sysbus, &error_fatal); + sysbus_mmio_map(sysbus, 1, VIA_BASE + VIA_SIZE); + sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(glue, 1)); + /* MACSONIC */ if (nb_nics > 1) { @@ -375,12 +377,10 @@ static void q800_init(MachineState *machine) sysbus = SYS_BUS_DEVICE(dev); sysbus_realize_and_unref(sysbus, &error_fatal); - sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in_named(via_dev, - "via2-irq", - VIA2_IRQ_SCSI_BIT)); - sysbus_connect_irq(sysbus, 1, - qdev_get_gpio_in_named(via_dev, "via2-irq", - VIA2_IRQ_SCSI_DATA_BIT)); + sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(via2_dev, + VIA2_IRQ_SCSI_BIT)); + sysbus_connect_irq(sysbus, 1, qdev_get_gpio_in(via2_dev, + VIA2_IRQ_SCSI_DATA_BIT)); sysbus_mmio_map(sysbus, 0, ESP_BASE); sysbus_mmio_map(sysbus, 1, ESP_PDMA); diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c index ff0156d..d1abcd9 100644 --- a/hw/misc/mac_via.c +++ b/hw/misc/mac_via.c @@ -34,11 +34,9 @@ #include "qemu/log.h" /* - * VIAs: There are two in every machine, + * VIAs: There are two in every machine */ -#define VIA_SIZE (0x2000) - /* * Not all of these are true post MacII I think. * CSA: probably the ones CHRP marks as 'unused' change purposes @@ -374,11 +372,10 @@ static void via2_irq_request(void *opaque, int irq, int level) } -static void pram_update(MacVIAState *m) +static void pram_update(MOS6522Q800VIA1State *v1s) { - if (m->blk) { - if (blk_pwrite(m->blk, 0, m->mos6522_via1.PRAM, - sizeof(m->mos6522_via1.PRAM), 0) < 0) { + if (v1s->blk) { + if (blk_pwrite(v1s->blk, 0, v1s->PRAM, sizeof(v1s->PRAM), 0) < 0) { qemu_log("pram_update: cannot write to file\n"); } } @@ -434,9 +431,8 @@ static int via1_rtc_compact_cmd(uint8_t value) return REG_INVALID; } -static void via1_rtc_update(MacVIAState *m) +static void via1_rtc_update(MOS6522Q800VIA1State *v1s) { - MOS6522Q800VIA1State *v1s = &m->mos6522_via1; MOS6522State *s = MOS6522(v1s); int cmd, sector, addr; uint32_t time; @@ -448,40 +444,40 @@ static void via1_rtc_update(MacVIAState *m) if (s->dirb & VIA1B_vRTCData) { /* send bits to the RTC */ if (!(v1s->last_b & VIA1B_vRTCClk) && (s->b & VIA1B_vRTCClk)) { - m->data_out <<= 1; - m->data_out |= s->b & VIA1B_vRTCData; - m->data_out_cnt++; + v1s->data_out <<= 1; + v1s->data_out |= s->b & VIA1B_vRTCData; + v1s->data_out_cnt++; } - trace_via1_rtc_update_data_out(m->data_out_cnt, m->data_out); + trace_via1_rtc_update_data_out(v1s->data_out_cnt, v1s->data_out); } else { - trace_via1_rtc_update_data_in(m->data_in_cnt, m->data_in); + trace_via1_rtc_update_data_in(v1s->data_in_cnt, v1s->data_in); /* receive bits from the RTC */ if ((v1s->last_b & VIA1B_vRTCClk) && !(s->b & VIA1B_vRTCClk) && - m->data_in_cnt) { + v1s->data_in_cnt) { s->b = (s->b & ~VIA1B_vRTCData) | - ((m->data_in >> 7) & VIA1B_vRTCData); - m->data_in <<= 1; - m->data_in_cnt--; + ((v1s->data_in >> 7) & VIA1B_vRTCData); + v1s->data_in <<= 1; + v1s->data_in_cnt--; } return; } - if (m->data_out_cnt != 8) { + if (v1s->data_out_cnt != 8) { return; } - m->data_out_cnt = 0; + v1s->data_out_cnt = 0; - trace_via1_rtc_internal_status(m->cmd, m->alt, m->data_out); + trace_via1_rtc_internal_status(v1s->cmd, v1s->alt, v1s->data_out); /* first byte: it's a command */ - if (m->cmd == REG_EMPTY) { + if (v1s->cmd == REG_EMPTY) { - cmd = via1_rtc_compact_cmd(m->data_out); + cmd = via1_rtc_compact_cmd(v1s->data_out); trace_via1_rtc_internal_cmd(cmd); if (cmd == REG_INVALID) { - trace_via1_rtc_cmd_invalid(m->data_out); + trace_via1_rtc_cmd_invalid(v1s->data_out); return; } @@ -493,20 +489,20 @@ static void via1_rtc_update(MacVIAState *m) * register 3 is highest-order byte */ - time = m->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + time = v1s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / NANOSECONDS_PER_SECOND); trace_via1_rtc_internal_time(time); - m->data_in = (time >> ((cmd & 0x03) << 3)) & 0xff; - m->data_in_cnt = 8; + v1s->data_in = (time >> ((cmd & 0x03) << 3)) & 0xff; + v1s->data_in_cnt = 8; trace_via1_rtc_cmd_seconds_read((cmd & 0x7f) - REG_0, - m->data_in); + v1s->data_in); break; case REG_PRAM_ADDR...REG_PRAM_ADDR_LAST: /* PRAM address 0x00 -> 0x13 */ - m->data_in = v1s->PRAM[(cmd & 0x7f) - REG_PRAM_ADDR]; - m->data_in_cnt = 8; + v1s->data_in = v1s->PRAM[(cmd & 0x7f) - REG_PRAM_ADDR]; + v1s->data_in_cnt = 8; trace_via1_rtc_cmd_pram_read((cmd & 0x7f) - REG_PRAM_ADDR, - m->data_in); + v1s->data_in); break; case REG_PRAM_SECT...REG_PRAM_SECT_LAST: /* @@ -514,7 +510,7 @@ static void via1_rtc_update(MacVIAState *m) * the only two-byte read command */ trace_via1_rtc_internal_set_cmd(cmd); - m->cmd = cmd; + v1s->cmd = cmd; break; default: g_assert_not_reached(); @@ -524,9 +520,9 @@ static void via1_rtc_update(MacVIAState *m) } /* this is a write command, needs a parameter */ - if (cmd == REG_WPROTECT || !m->wprotect) { + if (cmd == REG_WPROTECT || !v1s->wprotect) { trace_via1_rtc_internal_set_cmd(cmd); - m->cmd = cmd; + v1s->cmd = cmd; } else { trace_via1_rtc_internal_ignore_cmd(cmd); } @@ -534,46 +530,47 @@ static void via1_rtc_update(MacVIAState *m) } /* second byte: it's a parameter */ - if (m->alt == REG_EMPTY) { - switch (m->cmd & 0x7f) { + if (v1s->alt == REG_EMPTY) { + switch (v1s->cmd & 0x7f) { case REG_0...REG_3: /* seconds register */ /* FIXME */ - trace_via1_rtc_cmd_seconds_write(m->cmd - REG_0, m->data_out); - m->cmd = REG_EMPTY; + trace_via1_rtc_cmd_seconds_write(v1s->cmd - REG_0, v1s->data_out); + v1s->cmd = REG_EMPTY; break; case REG_TEST: /* device control: nothing to do */ - trace_via1_rtc_cmd_test_write(m->data_out); - m->cmd = REG_EMPTY; + trace_via1_rtc_cmd_test_write(v1s->data_out); + v1s->cmd = REG_EMPTY; break; case REG_WPROTECT: /* Write Protect register */ - trace_via1_rtc_cmd_wprotect_write(m->data_out); - m->wprotect = !!(m->data_out & 0x80); - m->cmd = REG_EMPTY; + trace_via1_rtc_cmd_wprotect_write(v1s->data_out); + v1s->wprotect = !!(v1s->data_out & 0x80); + v1s->cmd = REG_EMPTY; break; case REG_PRAM_ADDR...REG_PRAM_ADDR_LAST: /* PRAM address 0x00 -> 0x13 */ - trace_via1_rtc_cmd_pram_write(m->cmd - REG_PRAM_ADDR, m->data_out); - v1s->PRAM[m->cmd - REG_PRAM_ADDR] = m->data_out; - pram_update(m); - m->cmd = REG_EMPTY; + trace_via1_rtc_cmd_pram_write(v1s->cmd - REG_PRAM_ADDR, + v1s->data_out); + v1s->PRAM[v1s->cmd - REG_PRAM_ADDR] = v1s->data_out; + pram_update(v1s); + v1s->cmd = REG_EMPTY; break; case REG_PRAM_SECT...REG_PRAM_SECT_LAST: - addr = (m->data_out >> 2) & 0x1f; - sector = (m->cmd & 0x7f) - REG_PRAM_SECT; - if (m->cmd & 0x80) { + addr = (v1s->data_out >> 2) & 0x1f; + sector = (v1s->cmd & 0x7f) - REG_PRAM_SECT; + if (v1s->cmd & 0x80) { /* it's a read */ - m->data_in = v1s->PRAM[sector * 32 + addr]; - m->data_in_cnt = 8; + v1s->data_in = v1s->PRAM[sector * 32 + addr]; + v1s->data_in_cnt = 8; trace_via1_rtc_cmd_pram_sect_read(sector, addr, sector * 32 + addr, - m->data_in); - m->cmd = REG_EMPTY; + v1s->data_in); + v1s->cmd = REG_EMPTY; } else { /* it's a write, we need one more parameter */ trace_via1_rtc_internal_set_alt(addr, sector, addr); - m->alt = addr; + v1s->alt = addr; } break; default: @@ -584,22 +581,21 @@ static void via1_rtc_update(MacVIAState *m) } /* third byte: it's the data of a REG_PRAM_SECT write */ - g_assert(REG_PRAM_SECT <= m->cmd && m->cmd <= REG_PRAM_SECT_LAST); - sector = m->cmd - REG_PRAM_SECT; - v1s->PRAM[sector * 32 + m->alt] = m->data_out; - pram_update(m); - trace_via1_rtc_cmd_pram_sect_write(sector, m->alt, sector * 32 + m->alt, - m->data_out); - m->alt = REG_EMPTY; - m->cmd = REG_EMPTY; + g_assert(REG_PRAM_SECT <= v1s->cmd && v1s->cmd <= REG_PRAM_SECT_LAST); + sector = v1s->cmd - REG_PRAM_SECT; + v1s->PRAM[sector * 32 + v1s->alt] = v1s->data_out; + pram_update(v1s); + trace_via1_rtc_cmd_pram_sect_write(sector, v1s->alt, sector * 32 + v1s->alt, + v1s->data_out); + v1s->alt = REG_EMPTY; + v1s->cmd = REG_EMPTY; } static void adb_via_poll(void *opaque) { - MacVIAState *m = opaque; - MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1); + MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque); MOS6522State *s = MOS6522(v1s); - ADBBusState *adb_bus = &m->adb_bus; + ADBBusState *adb_bus = &v1s->adb_bus; uint8_t obuf[9]; uint8_t *data = &s->sr; int olen; @@ -611,50 +607,50 @@ static void adb_via_poll(void *opaque) */ adb_autopoll_block(adb_bus); - if (m->adb_data_in_size > 0 && m->adb_data_in_index == 0) { + if (v1s->adb_data_in_size > 0 && v1s->adb_data_in_index == 0) { /* * For older Linux kernels that switch to IDLE mode after sending the * ADB command, detect if there is an existing response and return that * as a a "fake" autopoll reply or bus timeout accordingly */ - *data = m->adb_data_out[0]; - olen = m->adb_data_in_size; + *data = v1s->adb_data_out[0]; + olen = v1s->adb_data_in_size; s->b &= ~VIA1B_vADBInt; - qemu_irq_raise(m->adb_data_ready); + qemu_irq_raise(v1s->adb_data_ready); } else { /* * Otherwise poll as normal */ - m->adb_data_in_index = 0; - m->adb_data_out_index = 0; + v1s->adb_data_in_index = 0; + v1s->adb_data_out_index = 0; olen = adb_poll(adb_bus, obuf, adb_bus->autopoll_mask); if (olen > 0) { /* Autopoll response */ *data = obuf[0]; olen--; - memcpy(m->adb_data_in, &obuf[1], olen); - m->adb_data_in_size = olen; + memcpy(v1s->adb_data_in, &obuf[1], olen); + v1s->adb_data_in_size = olen; s->b &= ~VIA1B_vADBInt; - qemu_irq_raise(m->adb_data_ready); + qemu_irq_raise(v1s->adb_data_ready); } else { - *data = m->adb_autopoll_cmd; + *data = v1s->adb_autopoll_cmd; obuf[0] = 0xff; obuf[1] = 0xff; olen = 2; - memcpy(m->adb_data_in, obuf, olen); - m->adb_data_in_size = olen; + memcpy(v1s->adb_data_in, obuf, olen); + v1s->adb_data_in_size = olen; s->b &= ~VIA1B_vADBInt; - qemu_irq_raise(m->adb_data_ready); + qemu_irq_raise(v1s->adb_data_ready); } } trace_via1_adb_poll(*data, (s->b & VIA1B_vADBInt) ? "+" : "-", - adb_bus->status, m->adb_data_in_index, olen); + adb_bus->status, v1s->adb_data_in_index, olen); } static int adb_via_send_len(uint8_t data) @@ -687,11 +683,10 @@ static int adb_via_send_len(uint8_t data) } } -static void adb_via_send(MacVIAState *s, int state, uint8_t data) +static void adb_via_send(MOS6522Q800VIA1State *v1s, int state, uint8_t data) { - MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&s->mos6522_via1); MOS6522State *ms = MOS6522(v1s); - ADBBusState *adb_bus = &s->adb_bus; + ADBBusState *adb_bus = &v1s->adb_bus; uint16_t autopoll_mask; switch (state) { @@ -707,22 +702,22 @@ static void adb_via_send(MacVIAState *s, int state, uint8_t data) ms->b &= ~VIA1B_vADBInt; } else { ms->b |= VIA1B_vADBInt; - s->adb_data_out_index = 0; - s->adb_data_out[s->adb_data_out_index++] = data; + v1s->adb_data_out_index = 0; + v1s->adb_data_out[v1s->adb_data_out_index++] = data; } trace_via1_adb_send(" NEW", data, (ms->b & VIA1B_vADBInt) ? "+" : "-"); - qemu_irq_raise(s->adb_data_ready); + qemu_irq_raise(v1s->adb_data_ready); break; case ADB_STATE_EVEN: case ADB_STATE_ODD: ms->b |= VIA1B_vADBInt; - s->adb_data_out[s->adb_data_out_index++] = data; + v1s->adb_data_out[v1s->adb_data_out_index++] = data; trace_via1_adb_send(state == ADB_STATE_EVEN ? "EVEN" : " ODD", data, (ms->b & VIA1B_vADBInt) ? "+" : "-"); - qemu_irq_raise(s->adb_data_ready); + qemu_irq_raise(v1s->adb_data_ready); break; case ADB_STATE_IDLE: @@ -730,40 +725,39 @@ static void adb_via_send(MacVIAState *s, int state, uint8_t data) } /* If the command is complete, execute it */ - if (s->adb_data_out_index == adb_via_send_len(s->adb_data_out[0])) { - s->adb_data_in_size = adb_request(adb_bus, s->adb_data_in, - s->adb_data_out, - s->adb_data_out_index); - s->adb_data_in_index = 0; + if (v1s->adb_data_out_index == adb_via_send_len(v1s->adb_data_out[0])) { + v1s->adb_data_in_size = adb_request(adb_bus, v1s->adb_data_in, + v1s->adb_data_out, + v1s->adb_data_out_index); + v1s->adb_data_in_index = 0; if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) { /* * Bus timeout (but allow first EVEN and ODD byte to indicate * timeout via vADBInt and SRQ status) */ - s->adb_data_in[0] = 0xff; - s->adb_data_in[1] = 0xff; - s->adb_data_in_size = 2; + v1s->adb_data_in[0] = 0xff; + v1s->adb_data_in[1] = 0xff; + v1s->adb_data_in_size = 2; } /* * If last command is TALK, store it for use by autopoll and adjust * the autopoll mask accordingly */ - if ((s->adb_data_out[0] & 0xc) == 0xc) { - s->adb_autopoll_cmd = s->adb_data_out[0]; + if ((v1s->adb_data_out[0] & 0xc) == 0xc) { + v1s->adb_autopoll_cmd = v1s->adb_data_out[0]; - autopoll_mask = 1 << (s->adb_autopoll_cmd >> 4); + autopoll_mask = 1 << (v1s->adb_autopoll_cmd >> 4); adb_set_autopoll_mask(adb_bus, autopoll_mask); } } } -static void adb_via_receive(MacVIAState *s, int state, uint8_t *data) +static void adb_via_receive(MOS6522Q800VIA1State *v1s, int state, uint8_t *data) { - MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&s->mos6522_via1); MOS6522State *ms = MOS6522(v1s); - ADBBusState *adb_bus = &s->adb_bus; + ADBBusState *adb_bus = &v1s->adb_bus; uint16_t pending; switch (state) { @@ -777,16 +771,16 @@ static void adb_via_receive(MacVIAState *s, int state, uint8_t *data) trace_via1_adb_receive("IDLE", *data, (ms->b & VIA1B_vADBInt) ? "+" : "-", adb_bus->status, - s->adb_data_in_index, s->adb_data_in_size); + v1s->adb_data_in_index, v1s->adb_data_in_size); break; case ADB_STATE_EVEN: case ADB_STATE_ODD: - switch (s->adb_data_in_index) { + switch (v1s->adb_data_in_index) { case 0: /* First EVEN byte: vADBInt indicates bus timeout */ - *data = s->adb_data_in[s->adb_data_in_index]; + *data = v1s->adb_data_in[v1s->adb_data_in_index]; if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) { ms->b &= ~VIA1B_vADBInt; } else { @@ -795,16 +789,16 @@ static void adb_via_receive(MacVIAState *s, int state, uint8_t *data) trace_via1_adb_receive(state == ADB_STATE_EVEN ? "EVEN" : " ODD", *data, (ms->b & VIA1B_vADBInt) ? "+" : "-", - adb_bus->status, s->adb_data_in_index, - s->adb_data_in_size); + adb_bus->status, v1s->adb_data_in_index, + v1s->adb_data_in_size); - s->adb_data_in_index++; + v1s->adb_data_in_index++; break; case 1: /* First ODD byte: vADBInt indicates SRQ */ - *data = s->adb_data_in[s->adb_data_in_index]; - pending = adb_bus->pending & ~(1 << (s->adb_autopoll_cmd >> 4)); + *data = v1s->adb_data_in[v1s->adb_data_in_index]; + pending = adb_bus->pending & ~(1 << (v1s->adb_autopoll_cmd >> 4)); if (pending) { ms->b &= ~VIA1B_vADBInt; } else { @@ -813,10 +807,10 @@ static void adb_via_receive(MacVIAState *s, int state, uint8_t *data) trace_via1_adb_receive(state == ADB_STATE_EVEN ? "EVEN" : " ODD", *data, (ms->b & VIA1B_vADBInt) ? "+" : "-", - adb_bus->status, s->adb_data_in_index, - s->adb_data_in_size); + adb_bus->status, v1s->adb_data_in_index, + v1s->adb_data_in_size); - s->adb_data_in_index++; + v1s->adb_data_in_index++; break; default: @@ -826,11 +820,11 @@ static void adb_via_receive(MacVIAState *s, int state, uint8_t *data) * end of the poll reply, so provide these extra bytes below to * keep it happy */ - if (s->adb_data_in_index < s->adb_data_in_size) { + if (v1s->adb_data_in_index < v1s->adb_data_in_size) { /* Next data byte */ - *data = s->adb_data_in[s->adb_data_in_index]; + *data = v1s->adb_data_in[v1s->adb_data_in_index]; ms->b |= VIA1B_vADBInt; - } else if (s->adb_data_in_index == s->adb_data_in_size) { + } else if (v1s->adb_data_in_index == v1s->adb_data_in_size) { if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) { /* Bus timeout (no more data) */ *data = 0xff; @@ -849,23 +843,22 @@ static void adb_via_receive(MacVIAState *s, int state, uint8_t *data) trace_via1_adb_receive(state == ADB_STATE_EVEN ? "EVEN" : " ODD", *data, (ms->b & VIA1B_vADBInt) ? "+" : "-", - adb_bus->status, s->adb_data_in_index, - s->adb_data_in_size); + adb_bus->status, v1s->adb_data_in_index, + v1s->adb_data_in_size); - if (s->adb_data_in_index <= s->adb_data_in_size) { - s->adb_data_in_index++; + if (v1s->adb_data_in_index <= v1s->adb_data_in_size) { + v1s->adb_data_in_index++; } break; } - qemu_irq_raise(s->adb_data_ready); + qemu_irq_raise(v1s->adb_data_ready); break; } } -static void via1_adb_update(MacVIAState *m) +static void via1_adb_update(MOS6522Q800VIA1State *v1s) { - MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1); MOS6522State *s = MOS6522(v1s); int oldstate, state; @@ -875,10 +868,10 @@ static void via1_adb_update(MacVIAState *m) if (state != oldstate) { if (s->acr & VIA1ACR_vShiftOut) { /* output mode */ - adb_via_send(m, state, s->sr); + adb_via_send(v1s, state, s->sr); } else { /* input mode */ - adb_via_receive(m, state, &s->sr); + adb_via_receive(v1s, state, &s->sr); } } } @@ -896,7 +889,6 @@ static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque); - MacVIAState *m = container_of(v1s, MacVIAState, mos6522_via1); MOS6522State *ms = MOS6522(v1s); addr = (addr >> 9) & 0xf; @@ -904,8 +896,8 @@ static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val, switch (addr) { case VIA_REG_B: - via1_rtc_update(m); - via1_adb_update(m); + via1_rtc_update(v1s); + via1_adb_update(v1s); v1s->last_b = ms->b; break; @@ -951,216 +943,155 @@ static const MemoryRegionOps mos6522_q800_via2_ops = { }, }; -static void mac_via_reset(DeviceState *dev) +static void via1_postload_update_cb(void *opaque, bool running, RunState state) { - MacVIAState *m = MAC_VIA(dev); - ADBBusState *adb_bus = &m->adb_bus; + MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque); - adb_set_autopoll_enabled(adb_bus, true); + qemu_del_vm_change_state_handler(v1s->vmstate); + v1s->vmstate = NULL; + + pram_update(v1s); +} + +static int via1_post_load(void *opaque, int version_id) +{ + MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque); + + if (v1s->blk) { + v1s->vmstate = qemu_add_vm_change_state_handler( + via1_postload_update_cb, v1s); + } + + return 0; +} + +/* VIA 1 */ +static void mos6522_q800_via1_reset(DeviceState *dev) +{ + MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(dev); + MOS6522State *ms = MOS6522(v1s); + MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(ms); + ADBBusState *adb_bus = &v1s->adb_bus; + + mdc->parent_reset(dev); + + ms->timers[0].frequency = VIA_TIMER_FREQ; + ms->timers[1].frequency = VIA_TIMER_FREQ; + + ms->b = VIA1B_vADB_StateMask | VIA1B_vADBInt | VIA1B_vRTCEnb; - m->cmd = REG_EMPTY; - m->alt = REG_EMPTY; + /* ADB/RTC */ + adb_set_autopoll_enabled(adb_bus, true); + v1s->cmd = REG_EMPTY; + v1s->alt = REG_EMPTY; } -static void mac_via_realize(DeviceState *dev, Error **errp) +static void mos6522_q800_via1_realize(DeviceState *dev, Error **errp) { - MacVIAState *m = MAC_VIA(dev); - MOS6522State *ms; - ADBBusState *adb_bus = &m->adb_bus; + MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(dev); + ADBBusState *adb_bus = &v1s->adb_bus; struct tm tm; int ret; - /* Init VIAs 1 and 2 */ - object_initialize_child(OBJECT(dev), "via1", &m->mos6522_via1, - TYPE_MOS6522_Q800_VIA1); - - object_initialize_child(OBJECT(dev), "via2", &m->mos6522_via2, - TYPE_MOS6522_Q800_VIA2); - - /* Pass through mos6522 output IRQs */ - ms = MOS6522(&m->mos6522_via1); - object_property_add_alias(OBJECT(dev), "irq[0]", OBJECT(ms), - SYSBUS_DEVICE_GPIO_IRQ "[0]"); - ms = MOS6522(&m->mos6522_via2); - object_property_add_alias(OBJECT(dev), "irq[1]", OBJECT(ms), - SYSBUS_DEVICE_GPIO_IRQ "[0]"); - - sysbus_realize(SYS_BUS_DEVICE(&m->mos6522_via1), &error_abort); - sysbus_realize(SYS_BUS_DEVICE(&m->mos6522_via2), &error_abort); - - /* Pass through mos6522 input IRQs */ - qdev_pass_gpios(DEVICE(&m->mos6522_via1), dev, "via1-irq"); - qdev_pass_gpios(DEVICE(&m->mos6522_via2), dev, "via2-irq"); - - /* VIA 1 */ - m->mos6522_via1.one_second_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, - via1_one_second, - &m->mos6522_via1); - via1_one_second_update(&m->mos6522_via1); - m->mos6522_via1.sixty_hz_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, - via1_sixty_hz, - &m->mos6522_via1); - via1_sixty_hz_update(&m->mos6522_via1); + v1s->one_second_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, via1_one_second, + v1s); + via1_one_second_update(v1s); + v1s->sixty_hz_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, via1_sixty_hz, + v1s); + via1_sixty_hz_update(v1s); qemu_get_timedate(&tm, 0); - m->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET; + v1s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET; - adb_register_autopoll_callback(adb_bus, adb_via_poll, m); - m->adb_data_ready = qdev_get_gpio_in_named(dev, "via1-irq", - VIA1_IRQ_ADB_READY_BIT); + adb_register_autopoll_callback(adb_bus, adb_via_poll, v1s); + v1s->adb_data_ready = qdev_get_gpio_in(dev, VIA1_IRQ_ADB_READY_BIT); - if (m->blk) { - int64_t len = blk_getlength(m->blk); + if (v1s->blk) { + int64_t len = blk_getlength(v1s->blk); if (len < 0) { error_setg_errno(errp, -len, "could not get length of backing image"); return; } - ret = blk_set_perm(m->blk, + ret = blk_set_perm(v1s->blk, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE, BLK_PERM_ALL, errp); if (ret < 0) { return; } - len = blk_pread(m->blk, 0, m->mos6522_via1.PRAM, - sizeof(m->mos6522_via1.PRAM)); - if (len != sizeof(m->mos6522_via1.PRAM)) { + len = blk_pread(v1s->blk, 0, v1s->PRAM, sizeof(v1s->PRAM)); + if (len != sizeof(v1s->PRAM)) { error_setg(errp, "can't read PRAM contents"); return; } } } -static void mac_via_init(Object *obj) +static void mos6522_q800_via1_init(Object *obj) { - SysBusDevice *sbd = SYS_BUS_DEVICE(obj); - MacVIAState *m = MAC_VIA(obj); - - /* MMIO */ - memory_region_init(&m->mmio, obj, "mac-via", 2 * VIA_SIZE); - sysbus_init_mmio(sbd, &m->mmio); + MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(v1s); - memory_region_init_io(&m->via1mem, obj, &mos6522_q800_via1_ops, - &m->mos6522_via1, "via1", VIA_SIZE); - memory_region_add_subregion(&m->mmio, 0x0, &m->via1mem); - - memory_region_init_io(&m->via2mem, obj, &mos6522_q800_via2_ops, - &m->mos6522_via2, "via2", VIA_SIZE); - memory_region_add_subregion(&m->mmio, VIA_SIZE, &m->via2mem); + memory_region_init_io(&v1s->via_mem, obj, &mos6522_q800_via1_ops, v1s, + "via1", VIA_SIZE); + sysbus_init_mmio(sbd, &v1s->via_mem); /* ADB */ - qbus_create_inplace((BusState *)&m->adb_bus, sizeof(m->adb_bus), - TYPE_ADB_BUS, DEVICE(obj), "adb.0"); -} + qbus_create_inplace((BusState *)&v1s->adb_bus, sizeof(v1s->adb_bus), + TYPE_ADB_BUS, DEVICE(v1s), "adb.0"); -static void postload_update_cb(void *opaque, bool running, RunState state) -{ - MacVIAState *m = MAC_VIA(opaque); - - qemu_del_vm_change_state_handler(m->vmstate); - m->vmstate = NULL; - - pram_update(m); + qdev_init_gpio_in(DEVICE(obj), via1_irq_request, VIA1_IRQ_NB); } -static int mac_via_post_load(void *opaque, int version_id) -{ - MacVIAState *m = MAC_VIA(opaque); - - if (m->blk) { - m->vmstate = qemu_add_vm_change_state_handler(postload_update_cb, - m); - } - - return 0; -} - -static const VMStateDescription vmstate_mac_via = { - .name = "mac-via", - .version_id = 2, - .minimum_version_id = 2, - .post_load = mac_via_post_load, +static const VMStateDescription vmstate_q800_via1 = { + .name = "q800-via1", + .version_id = 0, + .minimum_version_id = 0, + .post_load = via1_post_load, .fields = (VMStateField[]) { - /* VIAs */ - VMSTATE_STRUCT(mos6522_via1.parent_obj, MacVIAState, 0, vmstate_mos6522, - MOS6522State), - VMSTATE_UINT8(mos6522_via1.last_b, MacVIAState), - VMSTATE_BUFFER(mos6522_via1.PRAM, MacVIAState), - VMSTATE_TIMER_PTR(mos6522_via1.one_second_timer, MacVIAState), - VMSTATE_INT64(mos6522_via1.next_second, MacVIAState), - VMSTATE_TIMER_PTR(mos6522_via1.sixty_hz_timer, MacVIAState), - VMSTATE_INT64(mos6522_via1.next_sixty_hz, MacVIAState), - VMSTATE_STRUCT(mos6522_via2.parent_obj, MacVIAState, 0, vmstate_mos6522, + VMSTATE_STRUCT(parent_obj, MOS6522Q800VIA1State, 0, vmstate_mos6522, MOS6522State), + VMSTATE_UINT8(last_b, MOS6522Q800VIA1State), /* RTC */ - VMSTATE_UINT32(tick_offset, MacVIAState), - VMSTATE_UINT8(data_out, MacVIAState), - VMSTATE_INT32(data_out_cnt, MacVIAState), - VMSTATE_UINT8(data_in, MacVIAState), - VMSTATE_UINT8(data_in_cnt, MacVIAState), - VMSTATE_UINT8(cmd, MacVIAState), - VMSTATE_INT32(wprotect, MacVIAState), - VMSTATE_INT32(alt, MacVIAState), + VMSTATE_BUFFER(PRAM, MOS6522Q800VIA1State), + VMSTATE_UINT32(tick_offset, MOS6522Q800VIA1State), + VMSTATE_UINT8(data_out, MOS6522Q800VIA1State), + VMSTATE_INT32(data_out_cnt, MOS6522Q800VIA1State), + VMSTATE_UINT8(data_in, MOS6522Q800VIA1State), + VMSTATE_UINT8(data_in_cnt, MOS6522Q800VIA1State), + VMSTATE_UINT8(cmd, MOS6522Q800VIA1State), + VMSTATE_INT32(wprotect, MOS6522Q800VIA1State), + VMSTATE_INT32(alt, MOS6522Q800VIA1State), /* ADB */ - VMSTATE_INT32(adb_data_in_size, MacVIAState), - VMSTATE_INT32(adb_data_in_index, MacVIAState), - VMSTATE_INT32(adb_data_out_index, MacVIAState), - VMSTATE_BUFFER(adb_data_in, MacVIAState), - VMSTATE_BUFFER(adb_data_out, MacVIAState), - VMSTATE_UINT8(adb_autopoll_cmd, MacVIAState), + VMSTATE_INT32(adb_data_in_size, MOS6522Q800VIA1State), + VMSTATE_INT32(adb_data_in_index, MOS6522Q800VIA1State), + VMSTATE_INT32(adb_data_out_index, MOS6522Q800VIA1State), + VMSTATE_BUFFER(adb_data_in, MOS6522Q800VIA1State), + VMSTATE_BUFFER(adb_data_out, MOS6522Q800VIA1State), + VMSTATE_UINT8(adb_autopoll_cmd, MOS6522Q800VIA1State), + /* Timers */ + VMSTATE_TIMER_PTR(one_second_timer, MOS6522Q800VIA1State), + VMSTATE_INT64(next_second, MOS6522Q800VIA1State), + VMSTATE_TIMER_PTR(sixty_hz_timer, MOS6522Q800VIA1State), + VMSTATE_INT64(next_sixty_hz, MOS6522Q800VIA1State), VMSTATE_END_OF_LIST() } }; -static Property mac_via_properties[] = { - DEFINE_PROP_DRIVE("drive", MacVIAState, blk), +static Property mos6522_q800_via1_properties[] = { + DEFINE_PROP_DRIVE("drive", MOS6522Q800VIA1State, blk), DEFINE_PROP_END_OF_LIST(), }; -static void mac_via_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = mac_via_realize; - dc->reset = mac_via_reset; - dc->vmsd = &vmstate_mac_via; - device_class_set_props(dc, mac_via_properties); -} - -static TypeInfo mac_via_info = { - .name = TYPE_MAC_VIA, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(MacVIAState), - .instance_init = mac_via_init, - .class_init = mac_via_class_init, -}; - -/* VIA 1 */ -static void mos6522_q800_via1_reset(DeviceState *dev) -{ - MOS6522State *ms = MOS6522(dev); - MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(ms); - - mdc->parent_reset(dev); - - ms->timers[0].frequency = VIA_TIMER_FREQ; - ms->timers[1].frequency = VIA_TIMER_FREQ; - - ms->b = VIA1B_vADB_StateMask | VIA1B_vADBInt | VIA1B_vRTCEnb; -} - -static void mos6522_q800_via1_init(Object *obj) -{ - qdev_init_gpio_in_named(DEVICE(obj), via1_irq_request, "via1-irq", - VIA1_IRQ_NB); -} - static void mos6522_q800_via1_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); + dc->realize = mos6522_q800_via1_realize; dc->reset = mos6522_q800_via1_reset; + dc->vmsd = &vmstate_q800_via1; + device_class_set_props(dc, mos6522_q800_via1_properties); } static const TypeInfo mos6522_q800_via1_type_info = { @@ -1192,20 +1123,61 @@ static void mos6522_q800_via2_reset(DeviceState *dev) ms->dirb = 0; ms->b = 0; + ms->dira = 0; + ms->a = 0x7f; +} + +static void via2_nubus_irq_request(void *opaque, int irq, int level) +{ + MOS6522Q800VIA2State *v2s = opaque; + MOS6522State *s = MOS6522(v2s); + MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s); + + if (level) { + /* Port A nubus IRQ inputs are active LOW */ + s->a &= ~(1 << irq); + s->ifr |= 1 << VIA2_IRQ_NUBUS_BIT; + } else { + s->a |= (1 << irq); + s->ifr &= ~(1 << VIA2_IRQ_NUBUS_BIT); + } + + mdc->update_irq(s); } static void mos6522_q800_via2_init(Object *obj) { - qdev_init_gpio_in_named(DEVICE(obj), via2_irq_request, "via2-irq", - VIA2_IRQ_NB); + MOS6522Q800VIA2State *v2s = MOS6522_Q800_VIA2(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(v2s); + + memory_region_init_io(&v2s->via_mem, obj, &mos6522_q800_via2_ops, v2s, + "via2", VIA_SIZE); + sysbus_init_mmio(sbd, &v2s->via_mem); + + qdev_init_gpio_in(DEVICE(obj), via2_irq_request, VIA2_IRQ_NB); + + qdev_init_gpio_in_named(DEVICE(obj), via2_nubus_irq_request, "nubus-irq", + VIA2_NUBUS_IRQ_NB); } +static const VMStateDescription vmstate_q800_via2 = { + .name = "q800-via2", + .version_id = 0, + .minimum_version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(parent_obj, MOS6522Q800VIA2State, 0, vmstate_mos6522, + MOS6522State), + VMSTATE_END_OF_LIST() + } +}; + static void mos6522_q800_via2_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); MOS6522DeviceClass *mdc = MOS6522_CLASS(oc); dc->reset = mos6522_q800_via2_reset; + dc->vmsd = &vmstate_q800_via2; mdc->portB_write = mos6522_q800_via2_portB_write; } @@ -1221,7 +1193,6 @@ static void mac_via_register_types(void) { type_register_static(&mos6522_q800_via1_type_info); type_register_static(&mos6522_q800_via2_type_info); - type_register_static(&mac_via_info); } type_init(mac_via_register_types); |