aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-09-10 11:09:30 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-09-10 11:09:30 +0100
commit6d1272d3ef81aa33e97ca5c69707cbcad953cbdb (patch)
tree827eab7033f23a01834c521897f84b93d9848f86 /hw
parent500f1f3e81ad112e28b7c979136847e32dad83b6 (diff)
parentdde602ae539910c3579952834b713e2f360ec34a (diff)
downloadqemu-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.c38
-rw-r--r--hw/misc/mac_via.c547
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);