From: Laurent Vivier <laurent@vivier.eu>
To: qemu-devel@nongnu.org
Cc: "Fam Zheng" <fam@euphon.net>, "Kevin Wolf" <kwolf@redhat.com>,
qemu-block@nongnu.org, "Thomas Huth" <huth@tuxfamily.org>,
"Jason Wang" <jasowang@redhat.com>,
"Mark Cave-Ayland" <mark.cave-ayland@ilande.co.uk>,
"Laurent Vivier" <laurent@vivier.eu>,
"Max Reitz" <mreitz@redhat.com>,
"Hervé Poussineau" <hpoussin@reactos.org>,
"Paolo Bonzini" <pbonzini@redhat.com>
Subject: [PULL 06/11] hw/m68k: implement ADB bus support for via
Date: Mon, 28 Oct 2019 19:16:38 +0100 [thread overview]
Message-ID: <20191028181643.5143-7-laurent@vivier.eu> (raw)
In-Reply-To: <20191028181643.5143-1-laurent@vivier.eu>
VIA needs to be able to poll the ADB interface and to read/write data
from/to the bus.
This patch adds functions allowing that.
Co-developed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Hervé Poussineau <hpoussin@reactos.org>
Reviewed-by: Thomas Huth <huth@tuxfamily.org>
Message-Id: <20191026164546.30020-7-laurent@vivier.eu>
---
include/hw/misc/mac_via.h | 7 ++
hw/misc/mac_via.c | 197 ++++++++++++++++++++++++++++++++++++++
hw/misc/Kconfig | 1 +
3 files changed, 205 insertions(+)
diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h
index efc8ef3ce3..3f86fcb7e1 100644
--- a/include/hw/misc/mac_via.h
+++ b/include/hw/misc/mac_via.h
@@ -103,6 +103,13 @@ typedef struct MacVIAState {
/* ADB */
ADBBusState adb_bus;
+ QEMUTimer *adb_poll_timer;
+ qemu_irq adb_data_ready;
+ int adb_data_in_size;
+ int adb_data_in_index;
+ int adb_data_out_index;
+ uint8_t adb_data_in[128];
+ uint8_t adb_data_out[16];
} MacVIAState;
#endif
diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index d2da8b8e60..f3f130ad96 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -264,10 +264,16 @@
* Table 19-10 ADB transaction states
*/
+#define ADB_STATE_NEW 0
+#define ADB_STATE_EVEN 1
+#define ADB_STATE_ODD 2
+#define ADB_STATE_IDLE 3
+
#define VIA1B_vADB_StateMask (VIA1B_vADBS1 | VIA1B_vADBS2)
#define VIA1B_vADB_StateShift 4
#define VIA_TIMER_FREQ (783360)
+#define VIA_ADB_POLL_FREQ 50 /* XXX: not real */
/* VIA returns time offset from Jan 1, 1904, not 1970 */
#define RTC_OFFSET 2082844800
@@ -472,6 +478,181 @@ static void via1_rtc_update(MacVIAState *m)
}
}
+static int adb_via_poll(MacVIAState *s, int state, uint8_t *data)
+{
+ if (state != ADB_STATE_IDLE) {
+ return 0;
+ }
+
+ if (s->adb_data_in_size < s->adb_data_in_index) {
+ return 0;
+ }
+
+ if (s->adb_data_out_index != 0) {
+ return 0;
+ }
+
+ s->adb_data_in_index = 0;
+ s->adb_data_out_index = 0;
+ s->adb_data_in_size = adb_poll(&s->adb_bus, s->adb_data_in, 0xffff);
+
+ if (s->adb_data_in_size) {
+ *data = s->adb_data_in[s->adb_data_in_index++];
+ qemu_irq_raise(s->adb_data_ready);
+ }
+
+ return s->adb_data_in_size;
+}
+
+static int adb_via_send(MacVIAState *s, int state, uint8_t data)
+{
+ switch (state) {
+ case ADB_STATE_NEW:
+ s->adb_data_out_index = 0;
+ break;
+ case ADB_STATE_EVEN:
+ if ((s->adb_data_out_index & 1) == 0) {
+ return 0;
+ }
+ break;
+ case ADB_STATE_ODD:
+ if (s->adb_data_out_index & 1) {
+ return 0;
+ }
+ break;
+ case ADB_STATE_IDLE:
+ return 0;
+ }
+
+ assert(s->adb_data_out_index < sizeof(s->adb_data_out) - 1);
+
+ s->adb_data_out[s->adb_data_out_index++] = data;
+ qemu_irq_raise(s->adb_data_ready);
+ return 1;
+}
+
+static int adb_via_receive(MacVIAState *s, int state, uint8_t *data)
+{
+ switch (state) {
+ case ADB_STATE_NEW:
+ return 0;
+
+ case ADB_STATE_EVEN:
+ if (s->adb_data_in_size <= 0) {
+ qemu_irq_raise(s->adb_data_ready);
+ return 0;
+ }
+
+ if (s->adb_data_in_index >= s->adb_data_in_size) {
+ *data = 0;
+ qemu_irq_raise(s->adb_data_ready);
+ return 1;
+ }
+
+ if ((s->adb_data_in_index & 1) == 0) {
+ return 0;
+ }
+
+ break;
+
+ case ADB_STATE_ODD:
+ if (s->adb_data_in_size <= 0) {
+ qemu_irq_raise(s->adb_data_ready);
+ return 0;
+ }
+
+ if (s->adb_data_in_index >= s->adb_data_in_size) {
+ *data = 0;
+ qemu_irq_raise(s->adb_data_ready);
+ return 1;
+ }
+
+ if (s->adb_data_in_index & 1) {
+ return 0;
+ }
+
+ break;
+
+ case ADB_STATE_IDLE:
+ if (s->adb_data_out_index == 0) {
+ return 0;
+ }
+
+ s->adb_data_in_size = adb_request(&s->adb_bus, s->adb_data_in,
+ s->adb_data_out,
+ s->adb_data_out_index);
+ s->adb_data_out_index = 0;
+ s->adb_data_in_index = 0;
+ if (s->adb_data_in_size < 0) {
+ *data = 0xff;
+ qemu_irq_raise(s->adb_data_ready);
+ return -1;
+ }
+
+ if (s->adb_data_in_size == 0) {
+ return 0;
+ }
+
+ break;
+ }
+
+ assert(s->adb_data_in_index < sizeof(s->adb_data_in) - 1);
+
+ *data = s->adb_data_in[s->adb_data_in_index++];
+ qemu_irq_raise(s->adb_data_ready);
+ if (*data == 0xff || *data == 0) {
+ return 0;
+ }
+ return 1;
+}
+
+static void via1_adb_update(MacVIAState *m)
+{
+ MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
+ MOS6522State *s = MOS6522(v1s);
+ int state;
+ int ret;
+
+ state = (s->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;
+
+ if (s->acr & VIA1ACR_vShiftOut) {
+ /* output mode */
+ ret = adb_via_send(m, state, s->sr);
+ if (ret > 0) {
+ s->b &= ~VIA1B_vADBInt;
+ } else {
+ s->b |= VIA1B_vADBInt;
+ }
+ } else {
+ /* input mode */
+ ret = adb_via_receive(m, state, &s->sr);
+ if (ret > 0 && s->sr != 0xff) {
+ s->b &= ~VIA1B_vADBInt;
+ } else {
+ s->b |= VIA1B_vADBInt;
+ }
+ }
+}
+
+static void via_adb_poll(void *opaque)
+{
+ MacVIAState *m = opaque;
+ MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
+ MOS6522State *s = MOS6522(v1s);
+ int state;
+
+ if (s->b & VIA1B_vADBInt) {
+ state = (s->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;
+ if (adb_via_poll(m, state, &s->sr)) {
+ s->b &= ~VIA1B_vADBInt;
+ }
+ }
+
+ timer_mod(m->adb_poll_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+ (NANOSECONDS_PER_SECOND / VIA_ADB_POLL_FREQ));
+}
+
static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned size)
{
MOS6522Q800VIA1State *s = MOS6522_Q800_VIA1(opaque);
@@ -553,6 +734,10 @@ static void mac_via_reset(DeviceState *dev)
MacVIAState *m = MAC_VIA(dev);
MOS6522Q800VIA1State *v1s = &m->mos6522_via1;
+ timer_mod(m->adb_poll_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+ (NANOSECONDS_PER_SECOND / VIA_ADB_POLL_FREQ));
+
timer_del(v1s->VBL_timer);
v1s->next_VBL = 0;
timer_del(v1s->one_second_timer);
@@ -593,6 +778,10 @@ static void mac_via_realize(DeviceState *dev, Error **errp)
qemu_get_timedate(&tm, 0);
m->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
+
+ m->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, via_adb_poll, m);
+ m->adb_data_ready = qdev_get_gpio_in_named(dev, "via1-irq",
+ VIA1_IRQ_ADB_READY_BIT);
}
static void mac_via_init(Object *obj)
@@ -642,6 +831,13 @@ static const VMStateDescription vmstate_mac_via = {
VMSTATE_UINT8(cmd, MacVIAState),
VMSTATE_INT32(wprotect, MacVIAState),
VMSTATE_INT32(alt, MacVIAState),
+ /* ADB */
+ VMSTATE_TIMER_PTR(adb_poll_timer, MacVIAState),
+ 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_END_OF_LIST()
}
};
@@ -671,6 +867,7 @@ static void mos6522_q800_via1_portB_write(MOS6522State *s)
MacVIAState *m = container_of(v1s, MacVIAState, mos6522_via1);
via1_rtc_update(m);
+ via1_adb_update(m);
v1s->last_b = s->b;
}
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 18a5dc9c09..2164646553 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -123,5 +123,6 @@ config UNIMP
config MAC_VIA
bool
select MOS6522
+ select ADB
source macio/Kconfig
--
2.21.0
next prev parent reply other threads:[~2019-10-28 18:51 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-28 18:16 [PULL 00/11] Q800 branch patches Laurent Vivier
2019-10-28 18:16 ` [PULL 01/11] esp: move handle_ti_cmd() cleanup code to esp_do_dma() Laurent Vivier
2019-10-28 18:16 ` [PULL 02/11] esp: move get_cmd() post-DMA code to get_cmd_cb() Laurent Vivier
2019-10-28 18:16 ` [PULL 03/11] esp: add pseudo-DMA as used by Macintosh Laurent Vivier
2019-10-28 18:16 ` [PULL 04/11] dp8393x: manage big endian bus Laurent Vivier
2019-10-28 18:16 ` [PULL 05/11] hw/m68k: add VIA support Laurent Vivier
2019-10-28 18:16 ` Laurent Vivier [this message]
2019-10-28 18:16 ` [PULL 07/11] hw/m68k: add Nubus support Laurent Vivier
2019-10-28 18:16 ` [PULL 08/11] hw/m68k: add Nubus macfb video card Laurent Vivier
2019-10-28 18:16 ` [PULL 09/11] hw/m68k: add a dummy SWIM floppy controller Laurent Vivier
2019-10-28 18:16 ` [PULL 10/11] hw/m68k: define Macintosh Quadra 800 Laurent Vivier
2019-10-28 18:16 ` [PULL 11/11] BootLinuxConsoleTest: Test the " Laurent Vivier
2019-10-29 23:23 ` [PATCH 0/2] Acceptance test: update kernel used on m68k/q800 test Cleber Rosa
2019-10-29 23:23 ` [PATCH 1/2] Acceptance test: cancel test if m68k kernel packages goes missing Cleber Rosa
2019-10-31 8:06 ` Alex Bennée
2019-10-29 23:23 ` [PATCH 2/2] Acceptance test: update kernel for m68k/q800 test Cleber Rosa
2019-10-31 6:08 ` Alex Bennée
2019-11-07 15:08 ` Wainer dos Santos Moschetta
2019-10-31 8:06 ` Alex Bennée
2019-10-31 9:57 ` [PATCH 0/2] Acceptance test: update kernel used on " Alex Bennée
2019-11-07 15:43 ` Eric Blake
2019-11-07 16:38 ` Cleber Rosa
2019-11-07 17:18 ` Laurent Vivier
2019-11-07 18:00 ` Philippe Mathieu-Daudé
2019-11-07 18:25 ` Laurent Vivier
2019-10-28 23:55 ` [PULL 00/11] Q800 branch patches no-reply
2019-10-29 18:06 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191028181643.5143-7-laurent@vivier.eu \
--to=laurent@vivier.eu \
--cc=fam@euphon.net \
--cc=hpoussin@reactos.org \
--cc=huth@tuxfamily.org \
--cc=jasowang@redhat.com \
--cc=kwolf@redhat.com \
--cc=mark.cave-ayland@ilande.co.uk \
--cc=mreitz@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).