mirror of
https://github.com/qemu/qemu.git
synced 2025-08-08 08:05:17 +00:00
qemu-macppc patches
-----BEGIN PGP SIGNATURE----- iQFSBAABCgA8FiEEzGIauY6CIA2RXMnEW8LFb64PMh8FAl71vLgeHG1hcmsuY2F2 ZS1heWxhbmRAaWxhbmRlLmNvLnVrAAoJEFvCxW+uDzIfRx8H/Ao3EPvVW562Y0tq yZNAJ/wCmhTM7+ekOzeImD/G/Tf8ugHgV0BlPfDlOajD6bxrlS6pnv3ncaKfN7G/ d59ERGWUUqM8MsJ7t/tg/JGvLi0wBAj4ekSCe/MD5xxa2b9GzDGThjZASQvKHhMP q4EXMN5SgrRTRIqZ0w+ItPNoihLULiYq1LsNV6VgzBqhVhk349caOxjQ0PSdO64Q M7ymcVmiPg0KQPEzbcZDmiQEHP8AbnrJ+RImRrHOyL6pq87du7kPrb7ENpqgt4cA XLRzOccPvAp7BshEJIPgjaxNbCN555TMPswHp32lBRvDCF5lZ620TmwtWvb5pKXY kTxPd+4= =VN0J -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mcayland/tags/qemu-macppc-20200626' into staging qemu-macppc patches # gpg: Signature made Fri 26 Jun 2020 10:15:36 BST # gpg: using RSA key CC621AB98E82200D915CC9C45BC2C56FAE0F321F # gpg: issuer "mark.cave-ayland@ilande.co.uk" # gpg: Good signature from "Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>" [full] # Primary key fingerprint: CC62 1AB9 8E82 200D 915C C9C4 5BC2 C56F AE0F 321F * remotes/mcayland/tags/qemu-macppc-20200626: (22 commits) adb: add ADB bus trace events adb: use adb_device prefix for ADB device trace events adb: only call autopoll callbacks when autopoll is not blocked mac_via: rework ADB state machine to be compatible with both MacOS and Linux mac_via: move VIA1 portB write logic into mos6522_q800_via1_write() pmu: add adb_autopoll_block() and adb_autopoll_unblock() functions cuda: add adb_autopoll_block() and adb_autopoll_unblock() functions adb: add autopoll_blocked variable to block autopoll adb: use adb_request() only for explicit requests adb: add status field for holding information about the last ADB request adb: keep track of devices with pending data adb: introduce new ADBDeviceHasData method to ADBDeviceClass mac_via: convert to use ADBBusState internal autopoll variables pmu: convert to use ADBBusState internal autopoll variables cuda: convert to use ADBBusState internal autopoll variables adb: create autopoll variables directly within ADBBusState adb: introduce realize/unrealize and VMStateDescription for ADB bus pmu: honour autopoll_rate_ms when rearming the ADB autopoll timer pmu: fix duplicate autopoll mask variable cuda: convert ADB autopoll timer from ns to ms ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
10f7ffabf9
@ -243,7 +243,7 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
|
|||||||
olen = 0;
|
olen = 0;
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case ADB_WRITEREG:
|
case ADB_WRITEREG:
|
||||||
trace_adb_kbd_writereg(reg, buf[1]);
|
trace_adb_device_kbd_writereg(reg, buf[1]);
|
||||||
switch (reg) {
|
switch (reg) {
|
||||||
case 2:
|
case 2:
|
||||||
/* LED status */
|
/* LED status */
|
||||||
@ -256,13 +256,12 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
|
|||||||
case ADB_CMD_CHANGE_ID_AND_ACT:
|
case ADB_CMD_CHANGE_ID_AND_ACT:
|
||||||
case ADB_CMD_CHANGE_ID_AND_ENABLE:
|
case ADB_CMD_CHANGE_ID_AND_ENABLE:
|
||||||
d->devaddr = buf[1] & 0xf;
|
d->devaddr = buf[1] & 0xf;
|
||||||
trace_adb_kbd_request_change_addr(d->devaddr);
|
trace_adb_device_kbd_request_change_addr(d->devaddr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!d->disable_direct_reg3_writes) {
|
|
||||||
d->devaddr = buf[1] & 0xf;
|
d->devaddr = buf[1] & 0xf;
|
||||||
|
/*
|
||||||
/* we support handlers:
|
* we support handlers:
|
||||||
* 1: Apple Standard Keyboard
|
* 1: Apple Standard Keyboard
|
||||||
* 2: Apple Extended Keyboard (LShift = RShift)
|
* 2: Apple Extended Keyboard (LShift = RShift)
|
||||||
* 3: Apple Extended Keyboard (LShift != RShift)
|
* 3: Apple Extended Keyboard (LShift != RShift)
|
||||||
@ -271,9 +270,8 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
|
|||||||
d->handler = buf[2];
|
d->handler = buf[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_adb_kbd_request_change_addr_and_handler(d->devaddr,
|
trace_adb_device_kbd_request_change_addr_and_handler(
|
||||||
d->handler);
|
d->devaddr, d->handler);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,12 +294,19 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
|
|||||||
olen = 2;
|
olen = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
trace_adb_kbd_readreg(reg, obuf[0], obuf[1]);
|
trace_adb_device_kbd_readreg(reg, obuf[0], obuf[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return olen;
|
return olen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool adb_kbd_has_data(ADBDevice *d)
|
||||||
|
{
|
||||||
|
KBDState *s = ADB_KEYBOARD(d);
|
||||||
|
|
||||||
|
return s->count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* This is where keyboard events enter this file */
|
/* This is where keyboard events enter this file */
|
||||||
static void adb_keyboard_event(DeviceState *dev, QemuConsole *src,
|
static void adb_keyboard_event(DeviceState *dev, QemuConsole *src,
|
||||||
InputEvent *evt)
|
InputEvent *evt)
|
||||||
@ -316,7 +321,7 @@ static void adb_keyboard_event(DeviceState *dev, QemuConsole *src,
|
|||||||
/* FIXME: take handler into account when translating qcode */
|
/* FIXME: take handler into account when translating qcode */
|
||||||
keycode = qcode_to_adb_keycode[qcode];
|
keycode = qcode_to_adb_keycode[qcode];
|
||||||
if (keycode == NO_KEY) { /* We don't want to send this to the guest */
|
if (keycode == NO_KEY) { /* We don't want to send this to the guest */
|
||||||
trace_adb_kbd_no_key();
|
trace_adb_device_kbd_no_key();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (evt->u.key.data->down == false) { /* if key release event */
|
if (evt->u.key.data->down == false) { /* if key release event */
|
||||||
@ -384,6 +389,7 @@ static void adb_kbd_class_init(ObjectClass *oc, void *data)
|
|||||||
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
|
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
|
||||||
|
|
||||||
adc->devreq = adb_kbd_request;
|
adc->devreq = adb_kbd_request;
|
||||||
|
adc->devhasdata = adb_kbd_has_data;
|
||||||
dc->reset = adb_kbd_reset;
|
dc->reset = adb_kbd_reset;
|
||||||
dc->vmsd = &vmstate_adb_kbd;
|
dc->vmsd = &vmstate_adb_kbd;
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
|
|||||||
s->dx = 0;
|
s->dx = 0;
|
||||||
s->dy = 0;
|
s->dy = 0;
|
||||||
s->dz = 0;
|
s->dz = 0;
|
||||||
trace_adb_mouse_flush();
|
trace_adb_device_mouse_flush();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,11 +130,21 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
|
|||||||
olen = 0;
|
olen = 0;
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case ADB_WRITEREG:
|
case ADB_WRITEREG:
|
||||||
trace_adb_mouse_writereg(reg, buf[1]);
|
trace_adb_device_mouse_writereg(reg, buf[1]);
|
||||||
switch (reg) {
|
switch (reg) {
|
||||||
case 2:
|
case 2:
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
/*
|
||||||
|
* MacOS 9 has a bug in its ADB driver whereby after configuring
|
||||||
|
* the ADB bus devices it sends another write of invalid length
|
||||||
|
* to reg 3. Make sure we ignore it to prevent an address clash
|
||||||
|
* with the previous device.
|
||||||
|
*/
|
||||||
|
if (len != 3) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch (buf[2]) {
|
switch (buf[2]) {
|
||||||
case ADB_CMD_SELF_TEST:
|
case ADB_CMD_SELF_TEST:
|
||||||
break;
|
break;
|
||||||
@ -142,13 +152,12 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
|
|||||||
case ADB_CMD_CHANGE_ID_AND_ACT:
|
case ADB_CMD_CHANGE_ID_AND_ACT:
|
||||||
case ADB_CMD_CHANGE_ID_AND_ENABLE:
|
case ADB_CMD_CHANGE_ID_AND_ENABLE:
|
||||||
d->devaddr = buf[1] & 0xf;
|
d->devaddr = buf[1] & 0xf;
|
||||||
trace_adb_mouse_request_change_addr(d->devaddr);
|
trace_adb_device_mouse_request_change_addr(d->devaddr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!d->disable_direct_reg3_writes) {
|
|
||||||
d->devaddr = buf[1] & 0xf;
|
d->devaddr = buf[1] & 0xf;
|
||||||
|
/*
|
||||||
/* we support handlers:
|
* we support handlers:
|
||||||
* 0x01: Classic Apple Mouse Protocol / 100 cpi operations
|
* 0x01: Classic Apple Mouse Protocol / 100 cpi operations
|
||||||
* 0x02: Classic Apple Mouse Protocol / 200 cpi operations
|
* 0x02: Classic Apple Mouse Protocol / 200 cpi operations
|
||||||
* we don't support handlers (at least):
|
* we don't support handlers (at least):
|
||||||
@ -163,9 +172,8 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
|
|||||||
d->handler = buf[2];
|
d->handler = buf[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_adb_mouse_request_change_addr_and_handler(
|
trace_adb_device_mouse_request_change_addr_and_handler(
|
||||||
d->devaddr, d->handler);
|
d->devaddr, d->handler);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,12 +191,20 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
|
|||||||
olen = 2;
|
olen = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
trace_adb_mouse_readreg(reg, obuf[0], obuf[1]);
|
trace_adb_device_mouse_readreg(reg, obuf[0], obuf[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return olen;
|
return olen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool adb_mouse_has_data(ADBDevice *d)
|
||||||
|
{
|
||||||
|
MouseState *s = ADB_MOUSE(d);
|
||||||
|
|
||||||
|
return !(s->last_buttons_state == s->buttons_state &&
|
||||||
|
s->dx == 0 && s->dy == 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void adb_mouse_reset(DeviceState *dev)
|
static void adb_mouse_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
ADBDevice *d = ADB_DEVICE(dev);
|
ADBDevice *d = ADB_DEVICE(dev);
|
||||||
@ -244,6 +260,7 @@ static void adb_mouse_class_init(ObjectClass *oc, void *data)
|
|||||||
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
|
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
|
||||||
|
|
||||||
adc->devreq = adb_mouse_request;
|
adc->devreq = adb_mouse_request;
|
||||||
|
adc->devhasdata = adb_mouse_has_data;
|
||||||
dc->reset = adb_mouse_reset;
|
dc->reset = adb_mouse_reset;
|
||||||
dc->vmsd = &vmstate_adb_mouse;
|
dc->vmsd = &vmstate_adb_mouse;
|
||||||
}
|
}
|
||||||
|
204
hw/input/adb.c
204
hw/input/adb.c
@ -27,20 +27,31 @@
|
|||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
|
#include "qemu/timer.h"
|
||||||
#include "adb-internal.h"
|
#include "adb-internal.h"
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
/* error codes */
|
/* error codes */
|
||||||
#define ADB_RET_NOTPRESENT (-2)
|
#define ADB_RET_NOTPRESENT (-2)
|
||||||
|
|
||||||
|
static const char *adb_commands[] = {
|
||||||
|
"RESET", "FLUSH", "(Reserved 0x2)", "(Reserved 0x3)",
|
||||||
|
"Reserved (0x4)", "(Reserved 0x5)", "(Reserved 0x6)", "(Reserved 0x7)",
|
||||||
|
"LISTEN r0", "LISTEN r1", "LISTEN r2", "LISTEN r3",
|
||||||
|
"TALK r0", "TALK r1", "TALK r2", "TALK r3",
|
||||||
|
};
|
||||||
|
|
||||||
static void adb_device_reset(ADBDevice *d)
|
static void adb_device_reset(ADBDevice *d)
|
||||||
{
|
{
|
||||||
qdev_reset_all(DEVICE(d));
|
qdev_reset_all(DEVICE(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
|
static int do_adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf,
|
||||||
|
int len)
|
||||||
{
|
{
|
||||||
ADBDevice *d;
|
ADBDevice *d;
|
||||||
int devaddr, cmd, i;
|
ADBDeviceClass *adc;
|
||||||
|
int devaddr, cmd, olen, i;
|
||||||
|
|
||||||
cmd = buf[0] & 0xf;
|
cmd = buf[0] & 0xf;
|
||||||
if (cmd == ADB_BUSRESET) {
|
if (cmd == ADB_BUSRESET) {
|
||||||
@ -48,20 +59,53 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
|
|||||||
d = s->devices[i];
|
d = s->devices[i];
|
||||||
adb_device_reset(d);
|
adb_device_reset(d);
|
||||||
}
|
}
|
||||||
|
s->status = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s->pending = 0;
|
||||||
|
for (i = 0; i < s->nb_devices; i++) {
|
||||||
|
d = s->devices[i];
|
||||||
|
adc = ADB_DEVICE_GET_CLASS(d);
|
||||||
|
|
||||||
|
if (adc->devhasdata(d)) {
|
||||||
|
s->pending |= (1 << d->devaddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s->status = 0;
|
||||||
devaddr = buf[0] >> 4;
|
devaddr = buf[0] >> 4;
|
||||||
for (i = 0; i < s->nb_devices; i++) {
|
for (i = 0; i < s->nb_devices; i++) {
|
||||||
d = s->devices[i];
|
d = s->devices[i];
|
||||||
|
adc = ADB_DEVICE_GET_CLASS(d);
|
||||||
|
|
||||||
if (d->devaddr == devaddr) {
|
if (d->devaddr == devaddr) {
|
||||||
ADBDeviceClass *adc = ADB_DEVICE_GET_CLASS(d);
|
olen = adc->devreq(d, obuf, buf, len);
|
||||||
return adc->devreq(d, obuf, buf, len);
|
if (!olen) {
|
||||||
|
s->status |= ADB_STATUS_BUSTIMEOUT;
|
||||||
|
}
|
||||||
|
return olen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s->status |= ADB_STATUS_BUSTIMEOUT;
|
||||||
return ADB_RET_NOTPRESENT;
|
return ADB_RET_NOTPRESENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: move that to cuda ? */
|
int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
trace_adb_bus_request(buf[0] >> 4, adb_commands[buf[0] & 0xf], len);
|
||||||
|
|
||||||
|
assert(s->autopoll_blocked);
|
||||||
|
|
||||||
|
ret = do_adb_request(s, obuf, buf, len);
|
||||||
|
|
||||||
|
trace_adb_bus_request_done(buf[0] >> 4, adb_commands[buf[0] & 0xf], ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
|
int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
|
||||||
{
|
{
|
||||||
ADBDevice *d;
|
ADBDevice *d;
|
||||||
@ -70,17 +114,19 @@ int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
|
|||||||
|
|
||||||
olen = 0;
|
olen = 0;
|
||||||
for (i = 0; i < s->nb_devices; i++) {
|
for (i = 0; i < s->nb_devices; i++) {
|
||||||
if (s->poll_index >= s->nb_devices)
|
if (s->poll_index >= s->nb_devices) {
|
||||||
s->poll_index = 0;
|
s->poll_index = 0;
|
||||||
|
}
|
||||||
d = s->devices[s->poll_index];
|
d = s->devices[s->poll_index];
|
||||||
if ((1 << d->devaddr) & poll_mask) {
|
if ((1 << d->devaddr) & poll_mask) {
|
||||||
buf[0] = ADB_READREG | (d->devaddr << 4);
|
buf[0] = ADB_READREG | (d->devaddr << 4);
|
||||||
olen = adb_request(s, obuf + 1, buf, 1);
|
olen = do_adb_request(s, obuf + 1, buf, 1);
|
||||||
/* if there is data, we poll again the same device */
|
/* if there is data, we poll again the same device */
|
||||||
if (olen > 0) {
|
if (olen > 0) {
|
||||||
|
s->status |= ADB_STATUS_POLLREPLY;
|
||||||
obuf[0] = buf[0];
|
obuf[0] = buf[0];
|
||||||
olen++;
|
olen++;
|
||||||
break;
|
return olen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s->poll_index++;
|
s->poll_index++;
|
||||||
@ -88,10 +134,145 @@ int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
|
|||||||
return olen;
|
return olen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void adb_set_autopoll_enabled(ADBBusState *s, bool enabled)
|
||||||
|
{
|
||||||
|
if (s->autopoll_enabled != enabled) {
|
||||||
|
s->autopoll_enabled = enabled;
|
||||||
|
if (s->autopoll_enabled) {
|
||||||
|
timer_mod(s->autopoll_timer,
|
||||||
|
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
|
||||||
|
s->autopoll_rate_ms);
|
||||||
|
} else {
|
||||||
|
timer_del(s->autopoll_timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void adb_set_autopoll_rate_ms(ADBBusState *s, int rate_ms)
|
||||||
|
{
|
||||||
|
s->autopoll_rate_ms = rate_ms;
|
||||||
|
|
||||||
|
if (s->autopoll_enabled) {
|
||||||
|
timer_mod(s->autopoll_timer,
|
||||||
|
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
|
||||||
|
s->autopoll_rate_ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void adb_set_autopoll_mask(ADBBusState *s, uint16_t mask)
|
||||||
|
{
|
||||||
|
if (s->autopoll_mask != mask) {
|
||||||
|
s->autopoll_mask = mask;
|
||||||
|
if (s->autopoll_enabled && s->autopoll_mask) {
|
||||||
|
timer_mod(s->autopoll_timer,
|
||||||
|
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
|
||||||
|
s->autopoll_rate_ms);
|
||||||
|
} else {
|
||||||
|
timer_del(s->autopoll_timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void adb_autopoll_block(ADBBusState *s)
|
||||||
|
{
|
||||||
|
s->autopoll_blocked = true;
|
||||||
|
trace_adb_bus_autopoll_block(s->autopoll_blocked);
|
||||||
|
|
||||||
|
if (s->autopoll_enabled) {
|
||||||
|
timer_del(s->autopoll_timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void adb_autopoll_unblock(ADBBusState *s)
|
||||||
|
{
|
||||||
|
s->autopoll_blocked = false;
|
||||||
|
trace_adb_bus_autopoll_block(s->autopoll_blocked);
|
||||||
|
|
||||||
|
if (s->autopoll_enabled) {
|
||||||
|
timer_mod(s->autopoll_timer,
|
||||||
|
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
|
||||||
|
s->autopoll_rate_ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void adb_autopoll(void *opaque)
|
||||||
|
{
|
||||||
|
ADBBusState *s = opaque;
|
||||||
|
|
||||||
|
if (!s->autopoll_blocked) {
|
||||||
|
trace_adb_bus_autopoll_cb(s->autopoll_mask);
|
||||||
|
s->autopoll_cb(s->autopoll_cb_opaque);
|
||||||
|
trace_adb_bus_autopoll_cb_done(s->autopoll_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_mod(s->autopoll_timer,
|
||||||
|
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
|
||||||
|
s->autopoll_rate_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
void adb_register_autopoll_callback(ADBBusState *s, void (*cb)(void *opaque),
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
s->autopoll_cb = cb;
|
||||||
|
s->autopoll_cb_opaque = opaque;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_adb_bus = {
|
||||||
|
.name = "adb_bus",
|
||||||
|
.version_id = 0,
|
||||||
|
.minimum_version_id = 0,
|
||||||
|
.fields = (VMStateField[]) {
|
||||||
|
VMSTATE_TIMER_PTR(autopoll_timer, ADBBusState),
|
||||||
|
VMSTATE_BOOL(autopoll_enabled, ADBBusState),
|
||||||
|
VMSTATE_UINT8(autopoll_rate_ms, ADBBusState),
|
||||||
|
VMSTATE_UINT16(autopoll_mask, ADBBusState),
|
||||||
|
VMSTATE_BOOL(autopoll_blocked, ADBBusState),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void adb_bus_reset(BusState *qbus)
|
||||||
|
{
|
||||||
|
ADBBusState *adb_bus = ADB_BUS(qbus);
|
||||||
|
|
||||||
|
adb_bus->autopoll_enabled = false;
|
||||||
|
adb_bus->autopoll_mask = 0xffff;
|
||||||
|
adb_bus->autopoll_rate_ms = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void adb_bus_realize(BusState *qbus, Error **errp)
|
||||||
|
{
|
||||||
|
ADBBusState *adb_bus = ADB_BUS(qbus);
|
||||||
|
|
||||||
|
adb_bus->autopoll_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, adb_autopoll,
|
||||||
|
adb_bus);
|
||||||
|
|
||||||
|
vmstate_register(NULL, -1, &vmstate_adb_bus, adb_bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void adb_bus_unrealize(BusState *qbus)
|
||||||
|
{
|
||||||
|
ADBBusState *adb_bus = ADB_BUS(qbus);
|
||||||
|
|
||||||
|
timer_del(adb_bus->autopoll_timer);
|
||||||
|
|
||||||
|
vmstate_unregister(NULL, &vmstate_adb_bus, adb_bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void adb_bus_class_init(ObjectClass *klass, void *data)
|
||||||
|
{
|
||||||
|
BusClass *k = BUS_CLASS(klass);
|
||||||
|
|
||||||
|
k->realize = adb_bus_realize;
|
||||||
|
k->unrealize = adb_bus_unrealize;
|
||||||
|
k->reset = adb_bus_reset;
|
||||||
|
}
|
||||||
|
|
||||||
static const TypeInfo adb_bus_type_info = {
|
static const TypeInfo adb_bus_type_info = {
|
||||||
.name = TYPE_ADB_BUS,
|
.name = TYPE_ADB_BUS,
|
||||||
.parent = TYPE_BUS,
|
.parent = TYPE_BUS,
|
||||||
.instance_size = sizeof(ADBBusState),
|
.instance_size = sizeof(ADBBusState),
|
||||||
|
.class_init = adb_bus_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
const VMStateDescription vmstate_adb_device = {
|
const VMStateDescription vmstate_adb_device = {
|
||||||
@ -117,18 +298,11 @@ static void adb_device_realizefn(DeviceState *dev, Error **errp)
|
|||||||
bus->devices[bus->nb_devices++] = d;
|
bus->devices[bus->nb_devices++] = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Property adb_device_properties[] = {
|
|
||||||
DEFINE_PROP_BOOL("disable-direct-reg3-writes", ADBDevice,
|
|
||||||
disable_direct_reg3_writes, false),
|
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
|
||||||
};
|
|
||||||
|
|
||||||
static void adb_device_class_init(ObjectClass *oc, void *data)
|
static void adb_device_class_init(ObjectClass *oc, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||||
|
|
||||||
dc->realize = adb_device_realizefn;
|
dc->realize = adb_device_realizefn;
|
||||||
device_class_set_props(dc, adb_device_properties);
|
|
||||||
dc->bus_type = TYPE_ADB_BUS;
|
dc->bus_type = TYPE_ADB_BUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,25 @@
|
|||||||
# See docs/devel/tracing.txt for syntax documentation.
|
# See docs/devel/tracing.txt for syntax documentation.
|
||||||
|
|
||||||
# adb-kbd.c
|
# adb-kbd.c
|
||||||
adb_kbd_no_key(void) "Ignoring NO_KEY"
|
adb_device_kbd_no_key(void) "Ignoring NO_KEY"
|
||||||
adb_kbd_writereg(int reg, uint8_t val) "reg %d val 0x%2.2x"
|
adb_device_kbd_writereg(int reg, uint8_t val) "reg %d val 0x%2.2x"
|
||||||
adb_kbd_readreg(int reg, uint8_t val0, uint8_t val1) "reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x"
|
adb_device_kbd_readreg(int reg, uint8_t val0, uint8_t val1) "reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x"
|
||||||
adb_kbd_request_change_addr(int devaddr) "change addr to 0x%x"
|
adb_device_kbd_request_change_addr(int devaddr) "change addr to 0x%x"
|
||||||
adb_kbd_request_change_addr_and_handler(int devaddr, int handler) "change addr and handler to 0x%x, 0x%x"
|
adb_device_kbd_request_change_addr_and_handler(int devaddr, int handler) "change addr and handler to 0x%x, 0x%x"
|
||||||
|
|
||||||
# adb-mouse.c
|
# adb-mouse.c
|
||||||
adb_mouse_flush(void) "flush"
|
adb_device_mouse_flush(void) "flush"
|
||||||
adb_mouse_writereg(int reg, uint8_t val) "reg %d val 0x%2.2x"
|
adb_device_mouse_writereg(int reg, uint8_t val) "reg %d val 0x%2.2x"
|
||||||
adb_mouse_readreg(int reg, uint8_t val0, uint8_t val1) "reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x"
|
adb_device_mouse_readreg(int reg, uint8_t val0, uint8_t val1) "reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x"
|
||||||
adb_mouse_request_change_addr(int devaddr) "change addr to 0x%x"
|
adb_device_mouse_request_change_addr(int devaddr) "change addr to 0x%x"
|
||||||
adb_mouse_request_change_addr_and_handler(int devaddr, int handler) "change addr and handler to 0x%x, 0x%x"
|
adb_device_mouse_request_change_addr_and_handler(int devaddr, int handler) "change addr and handler to 0x%x, 0x%x"
|
||||||
|
|
||||||
|
# adb.c
|
||||||
|
adb_bus_request(uint8_t addr, const char *cmd, int size) "device 0x%x %s cmdsize=%d"
|
||||||
|
adb_bus_request_done(uint8_t addr, const char *cmd, int size) "device 0x%x %s replysize=%d"
|
||||||
|
adb_bus_autopoll_block(bool blocked) "blocked: %d"
|
||||||
|
adb_bus_autopoll_cb(uint16_t mask) "executing autopoll_cb with autopoll mask 0x%x"
|
||||||
|
adb_bus_autopoll_cb_done(uint16_t mask) "done executing autopoll_cb with autopoll mask 0x%x"
|
||||||
|
|
||||||
# pckbd.c
|
# pckbd.c
|
||||||
pckbd_kbd_read_data(uint32_t val) "0x%02x"
|
pckbd_kbd_read_data(uint32_t val) "0x%02x"
|
||||||
|
@ -599,181 +599,312 @@ static void via1_rtc_update(MacVIAState *m)
|
|||||||
m->cmd = REG_EMPTY;
|
m->cmd = REG_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int adb_via_poll(MacVIAState *s, int state, uint8_t *data)
|
static void adb_via_poll(void *opaque)
|
||||||
{
|
{
|
||||||
if (state != ADB_STATE_IDLE) {
|
MacVIAState *m = opaque;
|
||||||
return 0;
|
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
|
||||||
|
MOS6522State *s = MOS6522(v1s);
|
||||||
|
ADBBusState *adb_bus = &m->adb_bus;
|
||||||
|
uint8_t obuf[9];
|
||||||
|
uint8_t *data = &s->sr;
|
||||||
|
int olen;
|
||||||
|
uint16_t pending;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setting vADBInt below indicates that an autopoll reply has been
|
||||||
|
* received, however we must block autopoll until the point where
|
||||||
|
* the entire reply has been read back to the host
|
||||||
|
*/
|
||||||
|
adb_autopoll_block(adb_bus);
|
||||||
|
|
||||||
|
m->adb_data_in_index = 0;
|
||||||
|
m->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;
|
||||||
|
|
||||||
|
s->b &= ~VIA1B_vADBInt;
|
||||||
|
qemu_irq_raise(m->adb_data_ready);
|
||||||
|
} else if (olen < 0) {
|
||||||
|
/* Bus timeout (device does not exist) */
|
||||||
|
*data = 0xff;
|
||||||
|
s->b |= VIA1B_vADBInt;
|
||||||
|
adb_autopoll_unblock(adb_bus);
|
||||||
|
} else {
|
||||||
|
pending = adb_bus->pending & ~(1 << (m->adb_autopoll_cmd >> 4));
|
||||||
|
|
||||||
|
if (pending) {
|
||||||
|
/*
|
||||||
|
* Bus timeout (device exists but another device has data). Block
|
||||||
|
* autopoll so the OS can read out the first EVEN and first ODD
|
||||||
|
* byte to determine bus timeout and SRQ status
|
||||||
|
*/
|
||||||
|
*data = m->adb_autopoll_cmd;
|
||||||
|
s->b &= ~VIA1B_vADBInt;
|
||||||
|
|
||||||
|
obuf[0] = 0xff;
|
||||||
|
obuf[1] = 0xff;
|
||||||
|
olen = 2;
|
||||||
|
|
||||||
|
memcpy(m->adb_data_in, obuf, olen);
|
||||||
|
m->adb_data_in_size = olen;
|
||||||
|
|
||||||
|
qemu_irq_raise(m->adb_data_ready);
|
||||||
|
} else {
|
||||||
|
/* Bus timeout (device exists but no other device has data) */
|
||||||
|
*data = 0;
|
||||||
|
s->b |= VIA1B_vADBInt;
|
||||||
|
adb_autopoll_unblock(adb_bus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->adb_data_in_size < s->adb_data_in_index) {
|
trace_via1_adb_poll(*data, (s->b & VIA1B_vADBInt) ? "+" : "-",
|
||||||
return 0;
|
adb_bus->status, m->adb_data_in_index, olen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->adb_data_out_index != 0) {
|
static int adb_via_send_len(uint8_t data)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
/* Determine the send length from the given ADB command */
|
||||||
|
uint8_t cmd = data & 0xc;
|
||||||
|
uint8_t reg = data & 0x3;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case 0x8:
|
||||||
|
/* Listen command */
|
||||||
|
switch (reg) {
|
||||||
|
case 2:
|
||||||
|
/* Register 2 is only used for the keyboard */
|
||||||
|
return 3;
|
||||||
|
case 3:
|
||||||
|
/*
|
||||||
|
* Fortunately our devices only implement writes
|
||||||
|
* to register 3 which is fixed at 2 bytes
|
||||||
|
*/
|
||||||
|
return 3;
|
||||||
|
default:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "ADB unknown length for register %d\n",
|
||||||
|
reg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
/* Talk, BusReset */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void adb_via_send(MacVIAState *s, int state, uint8_t data)
|
||||||
|
{
|
||||||
|
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&s->mos6522_via1);
|
||||||
|
MOS6522State *ms = MOS6522(v1s);
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
|
uint16_t autopoll_mask;
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case ADB_STATE_NEW:
|
case ADB_STATE_NEW:
|
||||||
|
/*
|
||||||
|
* Command byte: vADBInt tells host autopoll data already present
|
||||||
|
* in VIA shift register and ADB transceiver
|
||||||
|
*/
|
||||||
|
adb_autopoll_block(adb_bus);
|
||||||
|
|
||||||
|
if (adb_bus->status & ADB_STATUS_POLLREPLY) {
|
||||||
|
/* Tell the host the existing data is from autopoll */
|
||||||
|
ms->b &= ~VIA1B_vADBInt;
|
||||||
|
} else {
|
||||||
|
ms->b |= VIA1B_vADBInt;
|
||||||
s->adb_data_out_index = 0;
|
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;
|
s->adb_data_out[s->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(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;
|
break;
|
||||||
|
|
||||||
|
case ADB_STATE_EVEN:
|
||||||
case ADB_STATE_ODD:
|
case ADB_STATE_ODD:
|
||||||
if (s->adb_data_in_size <= 0) {
|
ms->b |= VIA1B_vADBInt;
|
||||||
|
s->adb_data_out[s->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(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;
|
break;
|
||||||
|
|
||||||
case ADB_STATE_IDLE:
|
case ADB_STATE_IDLE:
|
||||||
if (s->adb_data_out_index == 0) {
|
return;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s->adb_data_in_size = adb_request(&s->adb_bus, s->adb_data_in,
|
/* 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,
|
||||||
s->adb_data_out_index);
|
s->adb_data_out_index);
|
||||||
s->adb_data_out_index = 0;
|
|
||||||
s->adb_data_in_index = 0;
|
s->adb_data_in_index = 0;
|
||||||
if (s->adb_data_in_size < 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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];
|
||||||
|
|
||||||
|
autopoll_mask = 1 << (s->adb_autopoll_cmd >> 4);
|
||||||
|
adb_set_autopoll_mask(adb_bus, autopoll_mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void adb_via_receive(MacVIAState *s, int state, uint8_t *data)
|
||||||
|
{
|
||||||
|
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&s->mos6522_via1);
|
||||||
|
MOS6522State *ms = MOS6522(v1s);
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
|
uint16_t pending;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case ADB_STATE_NEW:
|
||||||
|
ms->b |= VIA1B_vADBInt;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ADB_STATE_IDLE:
|
||||||
|
/*
|
||||||
|
* Since adb_request() will have already consumed the data from the
|
||||||
|
* device, we must detect this extra state change and re-inject the
|
||||||
|
* reponse as either a "fake" autopoll reply or bus timeout
|
||||||
|
* accordingly
|
||||||
|
*/
|
||||||
|
if (s->adb_data_in_index == 0) {
|
||||||
|
if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
|
||||||
*data = 0xff;
|
*data = 0xff;
|
||||||
|
ms->b |= VIA1B_vADBInt;
|
||||||
qemu_irq_raise(s->adb_data_ready);
|
qemu_irq_raise(s->adb_data_ready);
|
||||||
return -1;
|
} else if (s->adb_data_in_size > 0) {
|
||||||
|
adb_bus->status = ADB_STATUS_POLLREPLY;
|
||||||
|
*data = s->adb_autopoll_cmd;
|
||||||
|
ms->b &= ~VIA1B_vADBInt;
|
||||||
|
qemu_irq_raise(s->adb_data_ready);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ms->b |= VIA1B_vADBInt;
|
||||||
|
adb_autopoll_unblock(adb_bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->adb_data_in_size == 0) {
|
trace_via1_adb_receive("IDLE", *data,
|
||||||
return 0;
|
(ms->b & VIA1B_vADBInt) ? "+" : "-", adb_bus->status,
|
||||||
}
|
s->adb_data_in_index, s->adb_data_in_size);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ADB_STATE_EVEN:
|
||||||
|
case ADB_STATE_ODD:
|
||||||
|
switch (s->adb_data_in_index) {
|
||||||
|
case 0:
|
||||||
|
/* First EVEN byte: vADBInt indicates bus timeout */
|
||||||
|
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);
|
||||||
|
|
||||||
|
*data = s->adb_data_in[s->adb_data_in_index++];
|
||||||
|
if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
|
||||||
|
ms->b &= ~VIA1B_vADBInt;
|
||||||
|
} else {
|
||||||
|
ms->b |= VIA1B_vADBInt;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
/* First ODD byte: vADBInt indicates SRQ */
|
||||||
|
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);
|
||||||
|
|
||||||
|
*data = s->adb_data_in[s->adb_data_in_index++];
|
||||||
|
pending = adb_bus->pending & ~(1 << (s->adb_autopoll_cmd >> 4));
|
||||||
|
if (pending) {
|
||||||
|
ms->b &= ~VIA1B_vADBInt;
|
||||||
|
} else {
|
||||||
|
ms->b |= VIA1B_vADBInt;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* Otherwise vADBInt indicates end of data. Note that Linux
|
||||||
|
* specifically checks for the sequence 0x0 0xff to confirm the
|
||||||
|
* end of the poll reply, so provide these extra bytes below to
|
||||||
|
* keep it happy
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (s->adb_data_in_index < s->adb_data_in_size) {
|
||||||
|
/* Next data byte */
|
||||||
|
*data = s->adb_data_in[s->adb_data_in_index++];
|
||||||
|
ms->b |= VIA1B_vADBInt;
|
||||||
|
} else if (s->adb_data_in_index == s->adb_data_in_size) {
|
||||||
|
if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
|
||||||
|
/* Bus timeout (no more data) */
|
||||||
|
*data = 0xff;
|
||||||
|
} else {
|
||||||
|
/* Return 0x0 after reply */
|
||||||
|
*data = 0;
|
||||||
|
}
|
||||||
|
s->adb_data_in_index++;
|
||||||
|
ms->b &= ~VIA1B_vADBInt;
|
||||||
|
} else {
|
||||||
|
/* Bus timeout (no more data) */
|
||||||
|
*data = 0xff;
|
||||||
|
ms->b &= ~VIA1B_vADBInt;
|
||||||
|
adb_bus->status = 0;
|
||||||
|
adb_autopoll_unblock(adb_bus);
|
||||||
|
}
|
||||||
|
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);
|
qemu_irq_raise(s->adb_data_ready);
|
||||||
if (*data == 0xff || *data == 0) {
|
break;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void via1_adb_update(MacVIAState *m)
|
static void via1_adb_update(MacVIAState *m)
|
||||||
{
|
{
|
||||||
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
|
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
|
||||||
MOS6522State *s = MOS6522(v1s);
|
MOS6522State *s = MOS6522(v1s);
|
||||||
int state;
|
int oldstate, state;
|
||||||
int ret;
|
|
||||||
|
|
||||||
|
oldstate = (v1s->last_b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;
|
||||||
state = (s->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;
|
state = (s->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;
|
||||||
|
|
||||||
|
if (state != oldstate) {
|
||||||
if (s->acr & VIA1ACR_vShiftOut) {
|
if (s->acr & VIA1ACR_vShiftOut) {
|
||||||
/* output mode */
|
/* output mode */
|
||||||
ret = adb_via_send(m, state, s->sr);
|
adb_via_send(m, state, s->sr);
|
||||||
if (ret > 0) {
|
|
||||||
s->b &= ~VIA1B_vADBInt;
|
|
||||||
} else {
|
|
||||||
s->b |= VIA1B_vADBInt;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* input mode */
|
/* input mode */
|
||||||
ret = adb_via_receive(m, state, &s->sr);
|
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)
|
static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned size)
|
||||||
{
|
{
|
||||||
MOS6522Q800VIA1State *s = MOS6522_Q800_VIA1(opaque);
|
MOS6522Q800VIA1State *s = MOS6522_Q800_VIA1(opaque);
|
||||||
@ -802,11 +933,21 @@ static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val,
|
|||||||
unsigned size)
|
unsigned size)
|
||||||
{
|
{
|
||||||
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque);
|
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque);
|
||||||
|
MacVIAState *m = container_of(v1s, MacVIAState, mos6522_via1);
|
||||||
MOS6522State *ms = MOS6522(v1s);
|
MOS6522State *ms = MOS6522(v1s);
|
||||||
|
|
||||||
addr = (addr >> 9) & 0xf;
|
addr = (addr >> 9) & 0xf;
|
||||||
mos6522_write(ms, addr, val, size);
|
mos6522_write(ms, addr, val, size);
|
||||||
|
|
||||||
|
switch (addr) {
|
||||||
|
case VIA_REG_B:
|
||||||
|
via1_rtc_update(m);
|
||||||
|
via1_adb_update(m);
|
||||||
|
|
||||||
|
v1s->last_b = ms->b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
via1_one_second_update(v1s);
|
via1_one_second_update(v1s);
|
||||||
via1_VBL_update(v1s);
|
via1_VBL_update(v1s);
|
||||||
}
|
}
|
||||||
@ -854,10 +995,9 @@ static void mac_via_reset(DeviceState *dev)
|
|||||||
{
|
{
|
||||||
MacVIAState *m = MAC_VIA(dev);
|
MacVIAState *m = MAC_VIA(dev);
|
||||||
MOS6522Q800VIA1State *v1s = &m->mos6522_via1;
|
MOS6522Q800VIA1State *v1s = &m->mos6522_via1;
|
||||||
|
ADBBusState *adb_bus = &m->adb_bus;
|
||||||
|
|
||||||
timer_mod(m->adb_poll_timer,
|
adb_set_autopoll_enabled(adb_bus, true);
|
||||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
|
|
||||||
(NANOSECONDS_PER_SECOND / VIA_ADB_POLL_FREQ));
|
|
||||||
|
|
||||||
timer_del(v1s->VBL_timer);
|
timer_del(v1s->VBL_timer);
|
||||||
v1s->next_VBL = 0;
|
v1s->next_VBL = 0;
|
||||||
@ -872,6 +1012,7 @@ static void mac_via_realize(DeviceState *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
MacVIAState *m = MAC_VIA(dev);
|
MacVIAState *m = MAC_VIA(dev);
|
||||||
MOS6522State *ms;
|
MOS6522State *ms;
|
||||||
|
ADBBusState *adb_bus = &m->adb_bus;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -907,7 +1048,7 @@ static void mac_via_realize(DeviceState *dev, Error **errp)
|
|||||||
qemu_get_timedate(&tm, 0);
|
qemu_get_timedate(&tm, 0);
|
||||||
m->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
|
m->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
|
||||||
|
|
||||||
m->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, via_adb_poll, m);
|
adb_register_autopoll_callback(adb_bus, adb_via_poll, m);
|
||||||
m->adb_data_ready = qdev_get_gpio_in_named(dev, "via1-irq",
|
m->adb_data_ready = qdev_get_gpio_in_named(dev, "via1-irq",
|
||||||
VIA1_IRQ_ADB_READY_BIT);
|
VIA1_IRQ_ADB_READY_BIT);
|
||||||
|
|
||||||
@ -980,8 +1121,8 @@ static int mac_via_post_load(void *opaque, int version_id)
|
|||||||
|
|
||||||
static const VMStateDescription vmstate_mac_via = {
|
static const VMStateDescription vmstate_mac_via = {
|
||||||
.name = "mac-via",
|
.name = "mac-via",
|
||||||
.version_id = 1,
|
.version_id = 2,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 2,
|
||||||
.post_load = mac_via_post_load,
|
.post_load = mac_via_post_load,
|
||||||
.fields = (VMStateField[]) {
|
.fields = (VMStateField[]) {
|
||||||
/* VIAs */
|
/* VIAs */
|
||||||
@ -1005,12 +1146,12 @@ static const VMStateDescription vmstate_mac_via = {
|
|||||||
VMSTATE_INT32(wprotect, MacVIAState),
|
VMSTATE_INT32(wprotect, MacVIAState),
|
||||||
VMSTATE_INT32(alt, MacVIAState),
|
VMSTATE_INT32(alt, MacVIAState),
|
||||||
/* ADB */
|
/* ADB */
|
||||||
VMSTATE_TIMER_PTR(adb_poll_timer, MacVIAState),
|
|
||||||
VMSTATE_INT32(adb_data_in_size, MacVIAState),
|
VMSTATE_INT32(adb_data_in_size, MacVIAState),
|
||||||
VMSTATE_INT32(adb_data_in_index, MacVIAState),
|
VMSTATE_INT32(adb_data_in_index, MacVIAState),
|
||||||
VMSTATE_INT32(adb_data_out_index, MacVIAState),
|
VMSTATE_INT32(adb_data_out_index, MacVIAState),
|
||||||
VMSTATE_BUFFER(adb_data_in, MacVIAState),
|
VMSTATE_BUFFER(adb_data_in, MacVIAState),
|
||||||
VMSTATE_BUFFER(adb_data_out, MacVIAState),
|
VMSTATE_BUFFER(adb_data_out, MacVIAState),
|
||||||
|
VMSTATE_UINT8(adb_autopoll_cmd, MacVIAState),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1039,18 +1180,6 @@ static TypeInfo mac_via_info = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* VIA 1 */
|
/* VIA 1 */
|
||||||
static void mos6522_q800_via1_portB_write(MOS6522State *s)
|
|
||||||
{
|
|
||||||
MOS6522Q800VIA1State *v1s = container_of(s, MOS6522Q800VIA1State,
|
|
||||||
parent_obj);
|
|
||||||
MacVIAState *m = container_of(v1s, MacVIAState, mos6522_via1);
|
|
||||||
|
|
||||||
via1_rtc_update(m);
|
|
||||||
via1_adb_update(m);
|
|
||||||
|
|
||||||
v1s->last_b = s->b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mos6522_q800_via1_reset(DeviceState *dev)
|
static void mos6522_q800_via1_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
MOS6522State *ms = MOS6522(dev);
|
MOS6522State *ms = MOS6522(dev);
|
||||||
@ -1073,10 +1202,8 @@ static void mos6522_q800_via1_init(Object *obj)
|
|||||||
static void mos6522_q800_via1_class_init(ObjectClass *oc, void *data)
|
static void mos6522_q800_via1_class_init(ObjectClass *oc, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||||
MOS6522DeviceClass *mdc = MOS6522_DEVICE_CLASS(oc);
|
|
||||||
|
|
||||||
dc->reset = mos6522_q800_via1_reset;
|
dc->reset = mos6522_q800_via1_reset;
|
||||||
mdc->portB_write = mos6522_q800_via1_portB_write;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo mos6522_q800_via1_type_info = {
|
static const TypeInfo mos6522_q800_via1_type_info = {
|
||||||
|
@ -116,6 +116,7 @@ static void cuda_update(CUDAState *s)
|
|||||||
{
|
{
|
||||||
MOS6522CUDAState *mcs = &s->mos6522_cuda;
|
MOS6522CUDAState *mcs = &s->mos6522_cuda;
|
||||||
MOS6522State *ms = MOS6522(mcs);
|
MOS6522State *ms = MOS6522(mcs);
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
int packet_received, len;
|
int packet_received, len;
|
||||||
|
|
||||||
packet_received = 0;
|
packet_received = 0;
|
||||||
@ -126,6 +127,9 @@ static void cuda_update(CUDAState *s)
|
|||||||
/* data output */
|
/* data output */
|
||||||
if ((ms->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
|
if ((ms->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
|
||||||
if (s->data_out_index < sizeof(s->data_out)) {
|
if (s->data_out_index < sizeof(s->data_out)) {
|
||||||
|
if (s->data_out_index == 0) {
|
||||||
|
adb_autopoll_block(adb_bus);
|
||||||
|
}
|
||||||
trace_cuda_data_send(ms->sr);
|
trace_cuda_data_send(ms->sr);
|
||||||
s->data_out[s->data_out_index++] = ms->sr;
|
s->data_out[s->data_out_index++] = ms->sr;
|
||||||
cuda_delay_set_sr_int(s);
|
cuda_delay_set_sr_int(s);
|
||||||
@ -140,6 +144,7 @@ static void cuda_update(CUDAState *s)
|
|||||||
/* indicate end of transfer */
|
/* indicate end of transfer */
|
||||||
if (s->data_in_index >= s->data_in_size) {
|
if (s->data_in_index >= s->data_in_size) {
|
||||||
ms->b = (ms->b | TREQ);
|
ms->b = (ms->b | TREQ);
|
||||||
|
adb_autopoll_unblock(adb_bus);
|
||||||
}
|
}
|
||||||
cuda_delay_set_sr_int(s);
|
cuda_delay_set_sr_int(s);
|
||||||
}
|
}
|
||||||
@ -201,17 +206,16 @@ static void cuda_send_packet_to_host(CUDAState *s,
|
|||||||
static void cuda_adb_poll(void *opaque)
|
static void cuda_adb_poll(void *opaque)
|
||||||
{
|
{
|
||||||
CUDAState *s = opaque;
|
CUDAState *s = opaque;
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
uint8_t obuf[ADB_MAX_OUT_LEN + 2];
|
uint8_t obuf[ADB_MAX_OUT_LEN + 2];
|
||||||
int olen;
|
int olen;
|
||||||
|
|
||||||
olen = adb_poll(&s->adb_bus, obuf + 2, s->adb_poll_mask);
|
olen = adb_poll(adb_bus, obuf + 2, adb_bus->autopoll_mask);
|
||||||
if (olen > 0) {
|
if (olen > 0) {
|
||||||
obuf[0] = ADB_PACKET;
|
obuf[0] = ADB_PACKET;
|
||||||
obuf[1] = 0x40; /* polled data */
|
obuf[1] = 0x40; /* polled data */
|
||||||
cuda_send_packet_to_host(s, obuf, olen + 2);
|
cuda_send_packet_to_host(s, obuf, olen + 2);
|
||||||
}
|
}
|
||||||
timer_mod(s->adb_poll_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
|
|
||||||
(NANOSECONDS_PER_SECOND / (1000 / s->autopoll_rate_ms)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* description of commands */
|
/* description of commands */
|
||||||
@ -227,23 +231,16 @@ static bool cuda_cmd_autopoll(CUDAState *s,
|
|||||||
const uint8_t *in_data, int in_len,
|
const uint8_t *in_data, int in_len,
|
||||||
uint8_t *out_data, int *out_len)
|
uint8_t *out_data, int *out_len)
|
||||||
{
|
{
|
||||||
int autopoll;
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
|
bool autopoll;
|
||||||
|
|
||||||
if (in_len != 1) {
|
if (in_len != 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
autopoll = (in_data[0] != 0);
|
autopoll = (in_data[0] != 0) ? true : false;
|
||||||
if (autopoll != s->autopoll) {
|
|
||||||
s->autopoll = autopoll;
|
adb_set_autopoll_enabled(adb_bus, autopoll);
|
||||||
if (autopoll) {
|
|
||||||
timer_mod(s->adb_poll_timer,
|
|
||||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
|
|
||||||
(NANOSECONDS_PER_SECOND / (1000 / s->autopoll_rate_ms)));
|
|
||||||
} else {
|
|
||||||
timer_del(s->adb_poll_timer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,6 +248,8 @@ static bool cuda_cmd_set_autorate(CUDAState *s,
|
|||||||
const uint8_t *in_data, int in_len,
|
const uint8_t *in_data, int in_len,
|
||||||
uint8_t *out_data, int *out_len)
|
uint8_t *out_data, int *out_len)
|
||||||
{
|
{
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
|
|
||||||
if (in_len != 1) {
|
if (in_len != 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -261,12 +260,7 @@ static bool cuda_cmd_set_autorate(CUDAState *s,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->autopoll_rate_ms = in_data[0];
|
adb_set_autopoll_rate_ms(adb_bus, in_data[0]);
|
||||||
if (s->autopoll) {
|
|
||||||
timer_mod(s->adb_poll_timer,
|
|
||||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
|
|
||||||
(NANOSECONDS_PER_SECOND / (1000 / s->autopoll_rate_ms)));
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,11 +268,16 @@ static bool cuda_cmd_set_device_list(CUDAState *s,
|
|||||||
const uint8_t *in_data, int in_len,
|
const uint8_t *in_data, int in_len,
|
||||||
uint8_t *out_data, int *out_len)
|
uint8_t *out_data, int *out_len)
|
||||||
{
|
{
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
|
uint16_t mask;
|
||||||
|
|
||||||
if (in_len != 2) {
|
if (in_len != 2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->adb_poll_mask = (((uint16_t)in_data[0]) << 8) | in_data[1];
|
mask = (((uint16_t)in_data[0]) << 8) | in_data[1];
|
||||||
|
|
||||||
|
adb_set_autopoll_mask(adb_bus, mask);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,8 +488,8 @@ static const MemoryRegionOps mos6522_cuda_ops = {
|
|||||||
|
|
||||||
static const VMStateDescription vmstate_cuda = {
|
static const VMStateDescription vmstate_cuda = {
|
||||||
.name = "cuda",
|
.name = "cuda",
|
||||||
.version_id = 5,
|
.version_id = 6,
|
||||||
.minimum_version_id = 5,
|
.minimum_version_id = 6,
|
||||||
.fields = (VMStateField[]) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_STRUCT(mos6522_cuda.parent_obj, CUDAState, 0, vmstate_mos6522,
|
VMSTATE_STRUCT(mos6522_cuda.parent_obj, CUDAState, 0, vmstate_mos6522,
|
||||||
MOS6522State),
|
MOS6522State),
|
||||||
@ -499,13 +498,9 @@ static const VMStateDescription vmstate_cuda = {
|
|||||||
VMSTATE_INT32(data_in_size, CUDAState),
|
VMSTATE_INT32(data_in_size, CUDAState),
|
||||||
VMSTATE_INT32(data_in_index, CUDAState),
|
VMSTATE_INT32(data_in_index, CUDAState),
|
||||||
VMSTATE_INT32(data_out_index, CUDAState),
|
VMSTATE_INT32(data_out_index, CUDAState),
|
||||||
VMSTATE_UINT8(autopoll, CUDAState),
|
|
||||||
VMSTATE_UINT8(autopoll_rate_ms, CUDAState),
|
|
||||||
VMSTATE_UINT16(adb_poll_mask, CUDAState),
|
|
||||||
VMSTATE_BUFFER(data_in, CUDAState),
|
VMSTATE_BUFFER(data_in, CUDAState),
|
||||||
VMSTATE_BUFFER(data_out, CUDAState),
|
VMSTATE_BUFFER(data_out, CUDAState),
|
||||||
VMSTATE_UINT32(tick_offset, CUDAState),
|
VMSTATE_UINT32(tick_offset, CUDAState),
|
||||||
VMSTATE_TIMER_PTR(adb_poll_timer, CUDAState),
|
|
||||||
VMSTATE_TIMER_PTR(sr_delay_timer, CUDAState),
|
VMSTATE_TIMER_PTR(sr_delay_timer, CUDAState),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
}
|
}
|
||||||
@ -514,11 +509,13 @@ static const VMStateDescription vmstate_cuda = {
|
|||||||
static void cuda_reset(DeviceState *dev)
|
static void cuda_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
CUDAState *s = CUDA(dev);
|
CUDAState *s = CUDA(dev);
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
|
|
||||||
s->data_in_size = 0;
|
s->data_in_size = 0;
|
||||||
s->data_in_index = 0;
|
s->data_in_index = 0;
|
||||||
s->data_out_index = 0;
|
s->data_out_index = 0;
|
||||||
s->autopoll = 0;
|
|
||||||
|
adb_set_autopoll_enabled(adb_bus, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cuda_realize(DeviceState *dev, Error **errp)
|
static void cuda_realize(DeviceState *dev, Error **errp)
|
||||||
@ -526,6 +523,7 @@ static void cuda_realize(DeviceState *dev, Error **errp)
|
|||||||
CUDAState *s = CUDA(dev);
|
CUDAState *s = CUDA(dev);
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
SysBusDevice *sbd;
|
SysBusDevice *sbd;
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
|
||||||
sysbus_realize(SYS_BUS_DEVICE(&s->mos6522_cuda), &err);
|
sysbus_realize(SYS_BUS_DEVICE(&s->mos6522_cuda), &err);
|
||||||
@ -544,9 +542,7 @@ static void cuda_realize(DeviceState *dev, Error **errp)
|
|||||||
s->sr_delay_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_set_sr_int, s);
|
s->sr_delay_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_set_sr_int, s);
|
||||||
s->sr_delay_ns = 20 * SCALE_US;
|
s->sr_delay_ns = 20 * SCALE_US;
|
||||||
|
|
||||||
s->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s);
|
adb_register_autopoll_callback(adb_bus, cuda_adb_poll, s);
|
||||||
s->adb_poll_mask = 0xffff;
|
|
||||||
s->autopoll_rate_ms = 20;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cuda_init(Object *obj)
|
static void cuda_init(Object *obj)
|
||||||
|
@ -92,10 +92,11 @@ static void pmu_update_extirq(PMUState *s)
|
|||||||
static void pmu_adb_poll(void *opaque)
|
static void pmu_adb_poll(void *opaque)
|
||||||
{
|
{
|
||||||
PMUState *s = opaque;
|
PMUState *s = opaque;
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
int olen;
|
int olen;
|
||||||
|
|
||||||
if (!(s->intbits & PMU_INT_ADB)) {
|
if (!(s->intbits & PMU_INT_ADB)) {
|
||||||
olen = adb_poll(&s->adb_bus, s->adb_reply, s->adb_poll_mask);
|
olen = adb_poll(adb_bus, s->adb_reply, adb_bus->autopoll_mask);
|
||||||
trace_pmu_adb_poll(olen);
|
trace_pmu_adb_poll(olen);
|
||||||
|
|
||||||
if (olen > 0) {
|
if (olen > 0) {
|
||||||
@ -104,9 +105,6 @@ static void pmu_adb_poll(void *opaque)
|
|||||||
pmu_update_extirq(s);
|
pmu_update_extirq(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_mod(s->adb_poll_timer,
|
|
||||||
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 30);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pmu_one_sec_timer(void *opaque)
|
static void pmu_one_sec_timer(void *opaque)
|
||||||
@ -173,18 +171,15 @@ static void pmu_cmd_set_int_mask(PMUState *s,
|
|||||||
|
|
||||||
static void pmu_cmd_set_adb_autopoll(PMUState *s, uint16_t mask)
|
static void pmu_cmd_set_adb_autopoll(PMUState *s, uint16_t mask)
|
||||||
{
|
{
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
|
|
||||||
trace_pmu_cmd_set_adb_autopoll(mask);
|
trace_pmu_cmd_set_adb_autopoll(mask);
|
||||||
|
|
||||||
if (s->autopoll_mask == mask) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->autopoll_mask = mask;
|
|
||||||
if (mask) {
|
if (mask) {
|
||||||
timer_mod(s->adb_poll_timer,
|
adb_set_autopoll_mask(adb_bus, mask);
|
||||||
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 30);
|
adb_set_autopoll_enabled(adb_bus, true);
|
||||||
} else {
|
} else {
|
||||||
timer_del(s->adb_poll_timer);
|
adb_set_autopoll_enabled(adb_bus, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,6 +262,8 @@ static void pmu_cmd_adb_poll_off(PMUState *s,
|
|||||||
const uint8_t *in_data, uint8_t in_len,
|
const uint8_t *in_data, uint8_t in_len,
|
||||||
uint8_t *out_data, uint8_t *out_len)
|
uint8_t *out_data, uint8_t *out_len)
|
||||||
{
|
{
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
|
|
||||||
if (in_len != 0) {
|
if (in_len != 0) {
|
||||||
qemu_log_mask(LOG_GUEST_ERROR,
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
"PMU: ADB POLL OFF command, invalid len: %d want: 0\n",
|
"PMU: ADB POLL OFF command, invalid len: %d want: 0\n",
|
||||||
@ -274,9 +271,8 @@ static void pmu_cmd_adb_poll_off(PMUState *s,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->has_adb && s->autopoll_mask) {
|
if (s->has_adb) {
|
||||||
timer_del(s->adb_poll_timer);
|
adb_set_autopoll_enabled(adb_bus, false);
|
||||||
s->autopoll_mask = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,6 +517,7 @@ static void pmu_update(PMUState *s)
|
|||||||
{
|
{
|
||||||
MOS6522PMUState *mps = &s->mos6522_pmu;
|
MOS6522PMUState *mps = &s->mos6522_pmu;
|
||||||
MOS6522State *ms = MOS6522(mps);
|
MOS6522State *ms = MOS6522(mps);
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
|
|
||||||
/* Only react to changes in reg B */
|
/* Only react to changes in reg B */
|
||||||
if (ms->b == s->last_b) {
|
if (ms->b == s->last_b) {
|
||||||
@ -582,6 +579,7 @@ static void pmu_update(PMUState *s)
|
|||||||
s->cmd_rsp_pos = 0;
|
s->cmd_rsp_pos = 0;
|
||||||
s->cmd_state = pmu_state_cmd;
|
s->cmd_state = pmu_state_cmd;
|
||||||
|
|
||||||
|
adb_autopoll_block(adb_bus);
|
||||||
trace_pmu_debug_protocol_cmd(s->cmd, s->cmdlen, s->rsplen);
|
trace_pmu_debug_protocol_cmd(s->cmd, s->cmdlen, s->rsplen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -640,6 +638,7 @@ static void pmu_update(PMUState *s)
|
|||||||
if (s->cmd_state == pmu_state_rsp && s->rsplen == s->cmd_rsp_pos) {
|
if (s->cmd_state == pmu_state_rsp && s->rsplen == s->cmd_rsp_pos) {
|
||||||
trace_pmu_debug_protocol_cmd_resp_complete(ms->ier);
|
trace_pmu_debug_protocol_cmd_resp_complete(ms->ier);
|
||||||
|
|
||||||
|
adb_autopoll_unblock(adb_bus);
|
||||||
s->cmd_state = pmu_state_idle;
|
s->cmd_state = pmu_state_idle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -684,12 +683,10 @@ static bool pmu_adb_state_needed(void *opaque)
|
|||||||
|
|
||||||
static const VMStateDescription vmstate_pmu_adb = {
|
static const VMStateDescription vmstate_pmu_adb = {
|
||||||
.name = "pmu/adb",
|
.name = "pmu/adb",
|
||||||
.version_id = 0,
|
.version_id = 1,
|
||||||
.minimum_version_id = 0,
|
.minimum_version_id = 1,
|
||||||
.needed = pmu_adb_state_needed,
|
.needed = pmu_adb_state_needed,
|
||||||
.fields = (VMStateField[]) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_UINT16(adb_poll_mask, PMUState),
|
|
||||||
VMSTATE_TIMER_PTR(adb_poll_timer, PMUState),
|
|
||||||
VMSTATE_UINT8(adb_reply_size, PMUState),
|
VMSTATE_UINT8(adb_reply_size, PMUState),
|
||||||
VMSTATE_BUFFER(adb_reply, PMUState),
|
VMSTATE_BUFFER(adb_reply, PMUState),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
@ -698,8 +695,8 @@ static const VMStateDescription vmstate_pmu_adb = {
|
|||||||
|
|
||||||
static const VMStateDescription vmstate_pmu = {
|
static const VMStateDescription vmstate_pmu = {
|
||||||
.name = "pmu",
|
.name = "pmu",
|
||||||
.version_id = 0,
|
.version_id = 1,
|
||||||
.minimum_version_id = 0,
|
.minimum_version_id = 1,
|
||||||
.fields = (VMStateField[]) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_STRUCT(mos6522_pmu.parent_obj, PMUState, 0, vmstate_mos6522,
|
VMSTATE_STRUCT(mos6522_pmu.parent_obj, PMUState, 0, vmstate_mos6522,
|
||||||
MOS6522State),
|
MOS6522State),
|
||||||
@ -714,8 +711,6 @@ static const VMStateDescription vmstate_pmu = {
|
|||||||
VMSTATE_BUFFER(cmd_rsp, PMUState),
|
VMSTATE_BUFFER(cmd_rsp, PMUState),
|
||||||
VMSTATE_UINT8(intbits, PMUState),
|
VMSTATE_UINT8(intbits, PMUState),
|
||||||
VMSTATE_UINT8(intmask, PMUState),
|
VMSTATE_UINT8(intmask, PMUState),
|
||||||
VMSTATE_UINT8(autopoll_rate_ms, PMUState),
|
|
||||||
VMSTATE_UINT8(autopoll_mask, PMUState),
|
|
||||||
VMSTATE_UINT32(tick_offset, PMUState),
|
VMSTATE_UINT32(tick_offset, PMUState),
|
||||||
VMSTATE_TIMER_PTR(one_sec_timer, PMUState),
|
VMSTATE_TIMER_PTR(one_sec_timer, PMUState),
|
||||||
VMSTATE_INT64(one_sec_target, PMUState),
|
VMSTATE_INT64(one_sec_target, PMUState),
|
||||||
@ -735,7 +730,6 @@ static void pmu_reset(DeviceState *dev)
|
|||||||
s->intbits = 0;
|
s->intbits = 0;
|
||||||
|
|
||||||
s->cmd_state = pmu_state_idle;
|
s->cmd_state = pmu_state_idle;
|
||||||
s->autopoll_mask = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pmu_realize(DeviceState *dev, Error **errp)
|
static void pmu_realize(DeviceState *dev, Error **errp)
|
||||||
@ -743,6 +737,7 @@ static void pmu_realize(DeviceState *dev, Error **errp)
|
|||||||
PMUState *s = VIA_PMU(dev);
|
PMUState *s = VIA_PMU(dev);
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
SysBusDevice *sbd;
|
SysBusDevice *sbd;
|
||||||
|
ADBBusState *adb_bus = &s->adb_bus;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
|
||||||
sysbus_realize(SYS_BUS_DEVICE(&s->mos6522_pmu), &err);
|
sysbus_realize(SYS_BUS_DEVICE(&s->mos6522_pmu), &err);
|
||||||
@ -764,9 +759,7 @@ static void pmu_realize(DeviceState *dev, Error **errp)
|
|||||||
if (s->has_adb) {
|
if (s->has_adb) {
|
||||||
qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
|
qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
|
||||||
dev, "adb.0");
|
dev, "adb.0");
|
||||||
s->adb_poll_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, pmu_adb_poll, s);
|
adb_register_autopoll_callback(adb_bus, pmu_adb_poll, s);
|
||||||
s->adb_poll_mask = 0xffff;
|
|
||||||
s->autopoll_rate_ms = 20;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +202,9 @@ via1_rtc_cmd_pram_read(int addr, int value) "addr=%u value=0x%02x"
|
|||||||
via1_rtc_cmd_pram_write(int addr, int value) "addr=%u value=0x%02x"
|
via1_rtc_cmd_pram_write(int addr, int value) "addr=%u value=0x%02x"
|
||||||
via1_rtc_cmd_pram_sect_read(int sector, int offset, int addr, int value) "sector=%u offset=%u addr=%d value=0x%02x"
|
via1_rtc_cmd_pram_sect_read(int sector, int offset, int addr, int value) "sector=%u offset=%u addr=%d value=0x%02x"
|
||||||
via1_rtc_cmd_pram_sect_write(int sector, int offset, int addr, int value) "sector=%u offset=%u addr=%d value=0x%02x"
|
via1_rtc_cmd_pram_sect_write(int sector, int offset, int addr, int value) "sector=%u offset=%u addr=%d value=0x%02x"
|
||||||
|
via1_adb_send(const char *state, uint8_t data, const char *vadbint) "state %s data=0x%02x vADBInt=%s"
|
||||||
|
via1_adb_receive(const char *state, uint8_t data, const char *vadbint, int status, int index, int size) "state %s data=0x%02x vADBInt=%s status=0x%x index=%d size=%d"
|
||||||
|
via1_adb_poll(uint8_t data, const char *vadbint, int status, int index, int size) "data=0x%02x vADBInt=%s status=0x%x index=%d size=%d"
|
||||||
|
|
||||||
# grlib_ahb_apb_pnp.c
|
# grlib_ahb_apb_pnp.c
|
||||||
grlib_ahb_pnp_read(uint64_t addr, uint32_t value) "AHB PnP read addr:0x%03"PRIx64" data:0x%08x"
|
grlib_ahb_pnp_read(uint64_t addr, uint32_t value) "AHB PnP read addr:0x%03"PRIx64" data:0x%08x"
|
||||||
|
@ -404,11 +404,9 @@ static void ppc_core99_init(MachineState *machine)
|
|||||||
|
|
||||||
adb_bus = qdev_get_child_bus(dev, "adb.0");
|
adb_bus = qdev_get_child_bus(dev, "adb.0");
|
||||||
dev = qdev_new(TYPE_ADB_KEYBOARD);
|
dev = qdev_new(TYPE_ADB_KEYBOARD);
|
||||||
qdev_prop_set_bit(dev, "disable-direct-reg3-writes", true);
|
|
||||||
qdev_realize_and_unref(dev, adb_bus, &error_fatal);
|
qdev_realize_and_unref(dev, adb_bus, &error_fatal);
|
||||||
|
|
||||||
dev = qdev_new(TYPE_ADB_MOUSE);
|
dev = qdev_new(TYPE_ADB_MOUSE);
|
||||||
qdev_prop_set_bit(dev, "disable-direct-reg3-writes", true);
|
|
||||||
qdev_realize_and_unref(dev, adb_bus, &error_fatal);
|
qdev_realize_and_unref(dev, adb_bus, &error_fatal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@ typedef struct ADBDevice ADBDevice;
|
|||||||
typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out,
|
typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out,
|
||||||
const uint8_t *buf, int len);
|
const uint8_t *buf, int len);
|
||||||
|
|
||||||
|
typedef bool ADBDeviceHasData(ADBDevice *d);
|
||||||
|
|
||||||
#define TYPE_ADB_DEVICE "adb-device"
|
#define TYPE_ADB_DEVICE "adb-device"
|
||||||
#define ADB_DEVICE(obj) OBJECT_CHECK(ADBDevice, (obj), TYPE_ADB_DEVICE)
|
#define ADB_DEVICE(obj) OBJECT_CHECK(ADBDevice, (obj), TYPE_ADB_DEVICE)
|
||||||
|
|
||||||
@ -49,7 +51,6 @@ struct ADBDevice {
|
|||||||
|
|
||||||
int devaddr;
|
int devaddr;
|
||||||
int handler;
|
int handler;
|
||||||
bool disable_direct_reg3_writes;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ADB_DEVICE_CLASS(cls) \
|
#define ADB_DEVICE_CLASS(cls) \
|
||||||
@ -63,25 +64,48 @@ typedef struct ADBDeviceClass {
|
|||||||
/*< public >*/
|
/*< public >*/
|
||||||
|
|
||||||
ADBDeviceRequest *devreq;
|
ADBDeviceRequest *devreq;
|
||||||
|
ADBDeviceHasData *devhasdata;
|
||||||
} ADBDeviceClass;
|
} ADBDeviceClass;
|
||||||
|
|
||||||
#define TYPE_ADB_BUS "apple-desktop-bus"
|
#define TYPE_ADB_BUS "apple-desktop-bus"
|
||||||
#define ADB_BUS(obj) OBJECT_CHECK(ADBBusState, (obj), TYPE_ADB_BUS)
|
#define ADB_BUS(obj) OBJECT_CHECK(ADBBusState, (obj), TYPE_ADB_BUS)
|
||||||
|
|
||||||
|
#define ADB_STATUS_BUSTIMEOUT 0x1
|
||||||
|
#define ADB_STATUS_POLLREPLY 0x2
|
||||||
|
|
||||||
struct ADBBusState {
|
struct ADBBusState {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
BusState parent_obj;
|
BusState parent_obj;
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
|
|
||||||
ADBDevice *devices[MAX_ADB_DEVICES];
|
ADBDevice *devices[MAX_ADB_DEVICES];
|
||||||
|
uint16_t pending;
|
||||||
int nb_devices;
|
int nb_devices;
|
||||||
int poll_index;
|
int poll_index;
|
||||||
|
uint8_t status;
|
||||||
|
|
||||||
|
QEMUTimer *autopoll_timer;
|
||||||
|
bool autopoll_enabled;
|
||||||
|
bool autopoll_blocked;
|
||||||
|
uint8_t autopoll_rate_ms;
|
||||||
|
uint16_t autopoll_mask;
|
||||||
|
void (*autopoll_cb)(void *opaque);
|
||||||
|
void *autopoll_cb_opaque;
|
||||||
};
|
};
|
||||||
|
|
||||||
int adb_request(ADBBusState *s, uint8_t *buf_out,
|
int adb_request(ADBBusState *s, uint8_t *buf_out,
|
||||||
const uint8_t *buf, int len);
|
const uint8_t *buf, int len);
|
||||||
int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
|
int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
|
||||||
|
|
||||||
|
void adb_autopoll_block(ADBBusState *s);
|
||||||
|
void adb_autopoll_unblock(ADBBusState *s);
|
||||||
|
|
||||||
|
void adb_set_autopoll_enabled(ADBBusState *s, bool enabled);
|
||||||
|
void adb_set_autopoll_rate_ms(ADBBusState *s, int rate_ms);
|
||||||
|
void adb_set_autopoll_mask(ADBBusState *s, uint16_t mask);
|
||||||
|
void adb_register_autopoll_callback(ADBBusState *s, void (*cb)(void *opaque),
|
||||||
|
void *opaque);
|
||||||
|
|
||||||
#define TYPE_ADB_KEYBOARD "adb-keyboard"
|
#define TYPE_ADB_KEYBOARD "adb-keyboard"
|
||||||
#define TYPE_ADB_MOUSE "adb-mouse"
|
#define TYPE_ADB_MOUSE "adb-mouse"
|
||||||
|
|
||||||
|
@ -106,13 +106,13 @@ typedef struct MacVIAState {
|
|||||||
|
|
||||||
/* ADB */
|
/* ADB */
|
||||||
ADBBusState adb_bus;
|
ADBBusState adb_bus;
|
||||||
QEMUTimer *adb_poll_timer;
|
|
||||||
qemu_irq adb_data_ready;
|
qemu_irq adb_data_ready;
|
||||||
int adb_data_in_size;
|
int adb_data_in_size;
|
||||||
int adb_data_in_index;
|
int adb_data_in_index;
|
||||||
int adb_data_out_index;
|
int adb_data_out_index;
|
||||||
uint8_t adb_data_in[128];
|
uint8_t adb_data_in[128];
|
||||||
uint8_t adb_data_out[16];
|
uint8_t adb_data_out[16];
|
||||||
|
uint8_t adb_autopoll_cmd;
|
||||||
} MacVIAState;
|
} MacVIAState;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -95,12 +95,8 @@ typedef struct CUDAState {
|
|||||||
int data_out_index;
|
int data_out_index;
|
||||||
|
|
||||||
qemu_irq irq;
|
qemu_irq irq;
|
||||||
uint16_t adb_poll_mask;
|
|
||||||
uint8_t autopoll_rate_ms;
|
|
||||||
uint8_t autopoll;
|
|
||||||
uint8_t data_in[128];
|
uint8_t data_in[128];
|
||||||
uint8_t data_out[16];
|
uint8_t data_out[16];
|
||||||
QEMUTimer *adb_poll_timer;
|
|
||||||
} CUDAState;
|
} CUDAState;
|
||||||
|
|
||||||
#endif /* CUDA_H */
|
#endif /* CUDA_H */
|
||||||
|
@ -218,10 +218,6 @@ typedef struct PMUState {
|
|||||||
/* ADB */
|
/* ADB */
|
||||||
bool has_adb;
|
bool has_adb;
|
||||||
ADBBusState adb_bus;
|
ADBBusState adb_bus;
|
||||||
uint16_t adb_poll_mask;
|
|
||||||
uint8_t autopoll_rate_ms;
|
|
||||||
uint8_t autopoll_mask;
|
|
||||||
QEMUTimer *adb_poll_timer;
|
|
||||||
uint8_t adb_reply_size;
|
uint8_t adb_reply_size;
|
||||||
uint8_t adb_reply[ADB_MAX_OUT_LEN];
|
uint8_t adb_reply[ADB_MAX_OUT_LEN];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user