qemu/hw/misc/mac_via.c
<<
>>
Prefs
   1/*
   2 * QEMU m68k Macintosh VIA device support
   3 *
   4 * Copyright (c) 2011-2018 Laurent Vivier
   5 * Copyright (c) 2018 Mark Cave-Ayland
   6 *
   7 * Some parts from hw/misc/macio/cuda.c
   8 *
   9 * Copyright (c) 2004-2007 Fabrice Bellard
  10 * Copyright (c) 2007 Jocelyn Mayer
  11 *
  12 * some parts from linux-2.6.29, arch/m68k/include/asm/mac_via.h
  13 *
  14 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  15 * See the COPYING file in the top-level directory.
  16 */
  17
  18#include "qemu/osdep.h"
  19#include "qemu-common.h"
  20#include "migration/vmstate.h"
  21#include "hw/sysbus.h"
  22#include "hw/irq.h"
  23#include "qemu/timer.h"
  24#include "hw/misc/mac_via.h"
  25#include "hw/misc/mos6522.h"
  26#include "hw/input/adb.h"
  27#include "sysemu/runstate.h"
  28#include "qapi/error.h"
  29#include "qemu/cutils.h"
  30#include "hw/qdev-properties.h"
  31#include "sysemu/block-backend.h"
  32#include "trace.h"
  33#include "qemu/log.h"
  34
  35/*
  36 * VIAs: There are two in every machine,
  37 */
  38
  39#define VIA_SIZE (0x2000)
  40
  41/*
  42 * Not all of these are true post MacII I think.
  43 * CSA: probably the ones CHRP marks as 'unused' change purposes
  44 * when the IWM becomes the SWIM.
  45 * http://www.rs6000.ibm.com/resource/technology/chrpio/via5.mak.html
  46 * ftp://ftp.austin.ibm.com/pub/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf
  47 *
  48 * also, http://developer.apple.com/technotes/hw/hw_09.html claims the
  49 * following changes for IIfx:
  50 * VIA1A_vSccWrReq not available and that VIA1A_vSync has moved to an IOP.
  51 * Also, "All of the functionality of VIA2 has been moved to other chips".
  52 */
  53
  54#define VIA1A_vSccWrReq 0x80   /*
  55                                * SCC write. (input)
  56                                * [CHRP] SCC WREQ: Reflects the state of the
  57                                * Wait/Request pins from the SCC.
  58                                * [Macintosh Family Hardware]
  59                                * as CHRP on SE/30,II,IIx,IIcx,IIci.
  60                                * on IIfx, "0 means an active request"
  61                                */
  62#define VIA1A_vRev8     0x40   /*
  63                                * Revision 8 board ???
  64                                * [CHRP] En WaitReqB: Lets the WaitReq_L
  65                                * signal from port B of the SCC appear on
  66                                * the PA7 input pin. Output.
  67                                * [Macintosh Family] On the SE/30, this
  68                                * is the bit to flip screen buffers.
  69                                * 0=alternate, 1=main.
  70                                * on II,IIx,IIcx,IIci,IIfx this is a bit
  71                                * for Rev ID. 0=II,IIx, 1=IIcx,IIci,IIfx
  72                                */
  73#define VIA1A_vHeadSel  0x20   /*
  74                                * Head select for IWM.
  75                                * [CHRP] unused.
  76                                * [Macintosh Family] "Floppy disk
  77                                * state-control line SEL" on all but IIfx
  78                                */
  79#define VIA1A_vOverlay  0x10   /*
  80                                * [Macintosh Family] On SE/30,II,IIx,IIcx
  81                                * this bit enables the "Overlay" address
  82                                * map in the address decoders as it is on
  83                                * reset for mapping the ROM over the reset
  84                                * vector. 1=use overlay map.
  85                                * On the IIci,IIfx it is another bit of the
  86                                * CPU ID: 0=normal IIci, 1=IIci with parity
  87                                * feature or IIfx.
  88                                * [CHRP] En WaitReqA: Lets the WaitReq_L
  89                                * signal from port A of the SCC appear
  90                                * on the PA7 input pin (CHRP). Output.
  91                                * [MkLinux] "Drive Select"
  92                                *  (with 0x20 being 'disk head select')
  93                                */
  94#define VIA1A_vSync     0x08   /*
  95                                * [CHRP] Sync Modem: modem clock select:
  96                                * 1: select the external serial clock to
  97                                *    drive the SCC's /RTxCA pin.
  98                                * 0: Select the 3.6864MHz clock to drive
  99                                *    the SCC cell.
 100                                * [Macintosh Family] Correct on all but IIfx
 101                                */
 102
 103/*
 104 * Macintosh Family Hardware sez: bits 0-2 of VIA1A are volume control
 105 * on Macs which had the PWM sound hardware.  Reserved on newer models.
 106 * On IIci,IIfx, bits 1-2 are the rest of the CPU ID:
 107 * bit 2: 1=IIci, 0=IIfx
 108 * bit 1: 1 on both IIci and IIfx.
 109 * MkLinux sez bit 0 is 'burnin flag' in this case.
 110 * CHRP sez: VIA1A bits 0-2 and 5 are 'unused': if programmed as
 111 * inputs, these bits will read 0.
 112 */
 113#define VIA1A_vVolume   0x07    /* Audio volume mask for PWM */
 114#define VIA1A_CPUID0    0x02    /* CPU id bit 0 on RBV, others */
 115#define VIA1A_CPUID1    0x04    /* CPU id bit 0 on RBV, others */
 116#define VIA1A_CPUID2    0x10    /* CPU id bit 0 on RBV, others */
 117#define VIA1A_CPUID3    0x40    /* CPU id bit 0 on RBV, others */
 118
 119/*
 120 * Info on VIA1B is from Macintosh Family Hardware & MkLinux.
 121 * CHRP offers no info.
 122 */
 123#define VIA1B_vSound   0x80    /*
 124                                * Sound enable (for compatibility with
 125                                * PWM hardware) 0=enabled.
 126                                * Also, on IIci w/parity, shows parity error
 127                                * 0=error, 1=OK.
 128                                */
 129#define VIA1B_vMystery 0x40    /*
 130                                * On IIci, parity enable. 0=enabled,1=disabled
 131                                * On SE/30, vertical sync interrupt enable.
 132                                * 0=enabled. This vSync interrupt shows up
 133                                * as a slot $E interrupt.
 134                                */
 135#define VIA1B_vADBS2   0x20    /* ADB state input bit 1 (unused on IIfx) */
 136#define VIA1B_vADBS1   0x10    /* ADB state input bit 0 (unused on IIfx) */
 137#define VIA1B_vADBInt  0x08    /* ADB interrupt 0=interrupt (unused on IIfx)*/
 138#define VIA1B_vRTCEnb  0x04    /* Enable Real time clock. 0=enabled. */
 139#define VIA1B_vRTCClk  0x02    /* Real time clock serial-clock line. */
 140#define VIA1B_vRTCData 0x01    /* Real time clock serial-data line. */
 141
 142/*
 143 *    VIA2 A register is the interrupt lines raised off the nubus
 144 *    slots.
 145 *      The below info is from 'Macintosh Family Hardware.'
 146 *      MkLinux calls the 'IIci internal video IRQ' below the 'RBV slot 0 irq.'
 147 *      It also notes that the slot $9 IRQ is the 'Ethernet IRQ' and
 148 *      defines the 'Video IRQ' as 0x40 for the 'EVR' VIA work-alike.
 149 *      Perhaps OSS uses vRAM1 and vRAM2 for ADB.
 150 */
 151
 152#define VIA2A_vRAM1    0x80    /* RAM size bit 1 (IIci: reserved) */
 153#define VIA2A_vRAM0    0x40    /* RAM size bit 0 (IIci: internal video IRQ) */
 154#define VIA2A_vIRQE    0x20    /* IRQ from slot $E */
 155#define VIA2A_vIRQD    0x10    /* IRQ from slot $D */
 156#define VIA2A_vIRQC    0x08    /* IRQ from slot $C */
 157#define VIA2A_vIRQB    0x04    /* IRQ from slot $B */
 158#define VIA2A_vIRQA    0x02    /* IRQ from slot $A */
 159#define VIA2A_vIRQ9    0x01    /* IRQ from slot $9 */
 160
 161/*
 162 * RAM size bits decoded as follows:
 163 * bit1 bit0  size of ICs in bank A
 164 *  0    0    256 kbit
 165 *  0    1    1 Mbit
 166 *  1    0    4 Mbit
 167 *  1    1   16 Mbit
 168 */
 169
 170/*
 171 *    Register B has the fun stuff in it
 172 */
 173
 174#define VIA2B_vVBL    0x80    /*
 175                               * VBL output to VIA1 (60.15Hz) driven by
 176                               * timer T1.
 177                               * on IIci, parity test: 0=test mode.
 178                               * [MkLinux] RBV_PARODD: 1=odd,0=even.
 179                               */
 180#define VIA2B_vSndJck 0x40    /*
 181                               * External sound jack status.
 182                               * 0=plug is inserted.  On SE/30, always 0
 183                               */
 184#define VIA2B_vTfr0   0x20    /* Transfer mode bit 0 ack from NuBus */
 185#define VIA2B_vTfr1   0x10    /* Transfer mode bit 1 ack from NuBus */
 186#define VIA2B_vMode32 0x08    /*
 187                               * 24/32bit switch - doubles as cache flush
 188                               * on II, AMU/PMMU control.
 189                               *   if AMU, 0=24bit to 32bit translation
 190                               *   if PMMU, 1=PMMU is accessing page table.
 191                               * on SE/30 tied low.
 192                               * on IIx,IIcx,IIfx, unused.
 193                               * on IIci/RBV, cache control. 0=flush cache.
 194                               */
 195#define VIA2B_vPower  0x04   /*
 196                              * Power off, 0=shut off power.
 197                              * on SE/30 this signal sent to PDS card.
 198                              */
 199#define VIA2B_vBusLk  0x02   /*
 200                              * Lock NuBus transactions, 0=locked.
 201                              * on SE/30 sent to PDS card.
 202                              */
 203#define VIA2B_vCDis   0x01   /*
 204                              * Cache control. On IIci, 1=disable cache card
 205                              * on others, 0=disable processor's instruction
 206                              * and data caches.
 207                              */
 208
 209/* interrupt flags */
 210
 211#define IRQ_SET         0x80
 212
 213/* common */
 214
 215#define VIA_IRQ_TIMER1      0x40
 216#define VIA_IRQ_TIMER2      0x20
 217
 218/*
 219 * Apple sez: http://developer.apple.com/technotes/ov/ov_04.html
 220 * Another example of a valid function that has no ROM support is the use
 221 * of the alternate video page for page-flipping animation. Since there
 222 * is no ROM call to flip pages, it is necessary to go play with the
 223 * right bit in the VIA chip (6522 Versatile Interface Adapter).
 224 * [CSA: don't know which one this is, but it's one of 'em!]
 225 */
 226
 227/*
 228 *    6522 registers - see databook.
 229 * CSA: Assignments for VIA1 confirmed from CHRP spec.
 230 */
 231
 232/* partial address decode.  0xYYXX : XX part for RBV, YY part for VIA */
 233/* Note: 15 VIA regs, 8 RBV regs */
 234
 235#define vBufB    0x0000  /* [VIA/RBV]  Register B */
 236#define vBufAH   0x0200  /* [VIA only] Buffer A, with handshake. DON'T USE! */
 237#define vDirB    0x0400  /* [VIA only] Data Direction Register B. */
 238#define vDirA    0x0600  /* [VIA only] Data Direction Register A. */
 239#define vT1CL    0x0800  /* [VIA only] Timer one counter low. */
 240#define vT1CH    0x0a00  /* [VIA only] Timer one counter high. */
 241#define vT1LL    0x0c00  /* [VIA only] Timer one latches low. */
 242#define vT1LH    0x0e00  /* [VIA only] Timer one latches high. */
 243#define vT2CL    0x1000  /* [VIA only] Timer two counter low. */
 244#define vT2CH    0x1200  /* [VIA only] Timer two counter high. */
 245#define vSR      0x1400  /* [VIA only] Shift register. */
 246#define vACR     0x1600  /* [VIA only] Auxilary control register. */
 247#define vPCR     0x1800  /* [VIA only] Peripheral control register. */
 248                         /*
 249                          *           CHRP sez never ever to *write* this.
 250                          *            Mac family says never to *change* this.
 251                          * In fact we need to initialize it once at start.
 252                          */
 253#define vIFR     0x1a00  /* [VIA/RBV]  Interrupt flag register. */
 254#define vIER     0x1c00  /* [VIA/RBV]  Interrupt enable register. */
 255#define vBufA    0x1e00  /* [VIA/RBV] register A (no handshake) */
 256
 257/* from linux 2.6 drivers/macintosh/via-macii.c */
 258
 259/* Bits in ACR */
 260
 261#define VIA1ACR_vShiftCtrl         0x1c        /* Shift register control bits */
 262#define VIA1ACR_vShiftExtClk       0x0c        /* Shift on external clock */
 263#define VIA1ACR_vShiftOut          0x10        /* Shift out if 1 */
 264
 265/*
 266 * Apple Macintosh Family Hardware Refenece
 267 * Table 19-10 ADB transaction states
 268 */
 269
 270#define ADB_STATE_NEW       0
 271#define ADB_STATE_EVEN      1
 272#define ADB_STATE_ODD       2
 273#define ADB_STATE_IDLE      3
 274
 275#define VIA1B_vADB_StateMask    (VIA1B_vADBS1 | VIA1B_vADBS2)
 276#define VIA1B_vADB_StateShift   4
 277
 278#define VIA_TIMER_FREQ (783360)
 279#define VIA_ADB_POLL_FREQ 50 /* XXX: not real */
 280
 281/* VIA returns time offset from Jan 1, 1904, not 1970 */
 282#define RTC_OFFSET 2082844800
 283
 284enum {
 285    REG_0,
 286    REG_1,
 287    REG_2,
 288    REG_3,
 289    REG_TEST,
 290    REG_WPROTECT,
 291    REG_PRAM_ADDR,
 292    REG_PRAM_ADDR_LAST = REG_PRAM_ADDR + 19,
 293    REG_PRAM_SECT,
 294    REG_PRAM_SECT_LAST = REG_PRAM_SECT + 7,
 295    REG_INVALID,
 296    REG_EMPTY = 0xff,
 297};
 298
 299static void via1_VBL_update(MOS6522Q800VIA1State *v1s)
 300{
 301    MOS6522State *s = MOS6522(v1s);
 302
 303    /* 60 Hz irq */
 304    v1s->next_VBL = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 16630) /
 305                    16630 * 16630;
 306
 307    if (s->ier & VIA1_IRQ_VBLANK) {
 308        timer_mod(v1s->VBL_timer, v1s->next_VBL);
 309    } else {
 310        timer_del(v1s->VBL_timer);
 311    }
 312}
 313
 314static void via1_one_second_update(MOS6522Q800VIA1State *v1s)
 315{
 316    MOS6522State *s = MOS6522(v1s);
 317
 318    v1s->next_second = (qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000) /
 319                       1000 * 1000;
 320    if (s->ier & VIA1_IRQ_ONE_SECOND) {
 321        timer_mod(v1s->one_second_timer, v1s->next_second);
 322    } else {
 323        timer_del(v1s->one_second_timer);
 324    }
 325}
 326
 327static void via1_VBL(void *opaque)
 328{
 329    MOS6522Q800VIA1State *v1s = opaque;
 330    MOS6522State *s = MOS6522(v1s);
 331    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
 332
 333    s->ifr |= VIA1_IRQ_VBLANK;
 334    mdc->update_irq(s);
 335
 336    via1_VBL_update(v1s);
 337}
 338
 339static void via1_one_second(void *opaque)
 340{
 341    MOS6522Q800VIA1State *v1s = opaque;
 342    MOS6522State *s = MOS6522(v1s);
 343    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
 344
 345    s->ifr |= VIA1_IRQ_ONE_SECOND;
 346    mdc->update_irq(s);
 347
 348    via1_one_second_update(v1s);
 349}
 350
 351static void via1_irq_request(void *opaque, int irq, int level)
 352{
 353    MOS6522Q800VIA1State *v1s = opaque;
 354    MOS6522State *s = MOS6522(v1s);
 355    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
 356
 357    if (level) {
 358        s->ifr |= 1 << irq;
 359    } else {
 360        s->ifr &= ~(1 << irq);
 361    }
 362
 363    mdc->update_irq(s);
 364}
 365
 366static void via2_irq_request(void *opaque, int irq, int level)
 367{
 368    MOS6522Q800VIA2State *v2s = opaque;
 369    MOS6522State *s = MOS6522(v2s);
 370    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
 371
 372    if (level) {
 373        s->ifr |= 1 << irq;
 374    } else {
 375        s->ifr &= ~(1 << irq);
 376    }
 377
 378    mdc->update_irq(s);
 379}
 380
 381
 382static void pram_update(MacVIAState *m)
 383{
 384    if (m->blk) {
 385        if (blk_pwrite(m->blk, 0, m->mos6522_via1.PRAM,
 386                       sizeof(m->mos6522_via1.PRAM), 0) < 0) {
 387            qemu_log("pram_update: cannot write to file\n");
 388        }
 389    }
 390}
 391
 392/*
 393 * RTC Commands
 394 *
 395 * Command byte    Register addressed by the command
 396 *
 397 * z0000001        Seconds register 0 (lowest-order byte)
 398 * z0000101        Seconds register 1
 399 * z0001001        Seconds register 2
 400 * z0001101        Seconds register 3 (highest-order byte)
 401 * 00110001        Test register (write-only)
 402 * 00110101        Write-Protect Register (write-only)
 403 * z010aa01        RAM address 100aa ($10-$13) (first 20 bytes only)
 404 * z1aaaa01        RAM address 0aaaa ($00-$0F) (first 20 bytes only)
 405 * z0111aaa        Extended memory designator and sector number
 406 *
 407 * For a read request, z=1, for a write z=0
 408 * The letter a indicates bits whose value depend on what parameter
 409 * RAM byte you want to address
 410 */
 411static int via1_rtc_compact_cmd(uint8_t value)
 412{
 413    uint8_t read = value & 0x80;
 414
 415    value &= 0x7f;
 416
 417    /* the last 2 bits of a command byte must always be 0b01 ... */
 418    if ((value & 0x78) == 0x38) {
 419        /* except for the extended memory designator */
 420        return read | (REG_PRAM_SECT + (value & 0x07));
 421    }
 422    if ((value & 0x03) == 0x01) {
 423        value >>= 2;
 424        if ((value & 0x1c) == 0) {
 425            /* seconds registers */
 426            return read | (REG_0 + (value & 0x03));
 427        } else if ((value == 0x0c) && !read) {
 428            return REG_TEST;
 429        } else if ((value == 0x0d) && !read) {
 430            return REG_WPROTECT;
 431        } else if ((value & 0x1c) == 0x08) {
 432            /* RAM address 0x10 to 0x13 */
 433            return read | (REG_PRAM_ADDR + 0x10 + (value & 0x03));
 434        } else if ((value & 0x43) == 0x41) {
 435            /* RAM address 0x00 to 0x0f */
 436            return read | (REG_PRAM_ADDR + (value & 0x0f));
 437        }
 438    }
 439    return REG_INVALID;
 440}
 441
 442static void via1_rtc_update(MacVIAState *m)
 443{
 444    MOS6522Q800VIA1State *v1s = &m->mos6522_via1;
 445    MOS6522State *s = MOS6522(v1s);
 446    int cmd, sector, addr;
 447    uint32_t time;
 448
 449    if (s->b & VIA1B_vRTCEnb) {
 450        return;
 451    }
 452
 453    if (s->dirb & VIA1B_vRTCData) {
 454        /* send bits to the RTC */
 455        if (!(v1s->last_b & VIA1B_vRTCClk) && (s->b & VIA1B_vRTCClk)) {
 456            m->data_out <<= 1;
 457            m->data_out |= s->b & VIA1B_vRTCData;
 458            m->data_out_cnt++;
 459        }
 460        trace_via1_rtc_update_data_out(m->data_out_cnt, m->data_out);
 461    } else {
 462        trace_via1_rtc_update_data_in(m->data_in_cnt, m->data_in);
 463        /* receive bits from the RTC */
 464        if ((v1s->last_b & VIA1B_vRTCClk) &&
 465            !(s->b & VIA1B_vRTCClk) &&
 466            m->data_in_cnt) {
 467            s->b = (s->b & ~VIA1B_vRTCData) |
 468                   ((m->data_in >> 7) & VIA1B_vRTCData);
 469            m->data_in <<= 1;
 470            m->data_in_cnt--;
 471        }
 472        return;
 473    }
 474
 475    if (m->data_out_cnt != 8) {
 476        return;
 477    }
 478
 479    m->data_out_cnt = 0;
 480
 481    trace_via1_rtc_internal_status(m->cmd, m->alt, m->data_out);
 482    /* first byte: it's a command */
 483    if (m->cmd == REG_EMPTY) {
 484
 485        cmd = via1_rtc_compact_cmd(m->data_out);
 486        trace_via1_rtc_internal_cmd(cmd);
 487
 488        if (cmd == REG_INVALID) {
 489            trace_via1_rtc_cmd_invalid(m->data_out);
 490            return;
 491        }
 492
 493        if (cmd & 0x80) { /* this is a read command */
 494            switch (cmd & 0x7f) {
 495            case REG_0...REG_3: /* seconds registers */
 496                /*
 497                 * register 0 is lowest-order byte
 498                 * register 3 is highest-order byte
 499                 */
 500
 501                time = m->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)
 502                       / NANOSECONDS_PER_SECOND);
 503                trace_via1_rtc_internal_time(time);
 504                m->data_in = (time >> ((cmd & 0x03) << 3)) & 0xff;
 505                m->data_in_cnt = 8;
 506                trace_via1_rtc_cmd_seconds_read((cmd & 0x7f) - REG_0,
 507                                                m->data_in);
 508                break;
 509            case REG_PRAM_ADDR...REG_PRAM_ADDR_LAST:
 510                /* PRAM address 0x00 -> 0x13 */
 511                m->data_in = v1s->PRAM[(cmd & 0x7f) - REG_PRAM_ADDR];
 512                m->data_in_cnt = 8;
 513                trace_via1_rtc_cmd_pram_read((cmd & 0x7f) - REG_PRAM_ADDR,
 514                                             m->data_in);
 515                break;
 516            case REG_PRAM_SECT...REG_PRAM_SECT_LAST:
 517                /*
 518                 * extended memory designator and sector number
 519                 * the only two-byte read command
 520                 */
 521                trace_via1_rtc_internal_set_cmd(cmd);
 522                m->cmd = cmd;
 523                break;
 524            default:
 525                g_assert_not_reached();
 526                break;
 527            }
 528            return;
 529        }
 530
 531        /* this is a write command, needs a parameter */
 532        if (cmd == REG_WPROTECT || !m->wprotect) {
 533            trace_via1_rtc_internal_set_cmd(cmd);
 534            m->cmd = cmd;
 535        } else {
 536            trace_via1_rtc_internal_ignore_cmd(cmd);
 537        }
 538        return;
 539    }
 540
 541    /* second byte: it's a parameter */
 542    if (m->alt == REG_EMPTY) {
 543        switch (m->cmd & 0x7f) {
 544        case REG_0...REG_3: /* seconds register */
 545            /* FIXME */
 546            trace_via1_rtc_cmd_seconds_write(m->cmd - REG_0, m->data_out);
 547            m->cmd = REG_EMPTY;
 548            break;
 549        case REG_TEST:
 550            /* device control: nothing to do */
 551            trace_via1_rtc_cmd_test_write(m->data_out);
 552            m->cmd = REG_EMPTY;
 553            break;
 554        case REG_WPROTECT:
 555            /* Write Protect register */
 556            trace_via1_rtc_cmd_wprotect_write(m->data_out);
 557            m->wprotect = !!(m->data_out & 0x80);
 558            m->cmd = REG_EMPTY;
 559            break;
 560        case REG_PRAM_ADDR...REG_PRAM_ADDR_LAST:
 561            /* PRAM address 0x00 -> 0x13 */
 562            trace_via1_rtc_cmd_pram_write(m->cmd - REG_PRAM_ADDR, m->data_out);
 563            v1s->PRAM[m->cmd - REG_PRAM_ADDR] = m->data_out;
 564            pram_update(m);
 565            m->cmd = REG_EMPTY;
 566            break;
 567        case REG_PRAM_SECT...REG_PRAM_SECT_LAST:
 568            addr = (m->data_out >> 2) & 0x1f;
 569            sector = (m->cmd & 0x7f) - REG_PRAM_SECT;
 570            if (m->cmd & 0x80) {
 571                /* it's a read */
 572                m->data_in = v1s->PRAM[sector * 32 + addr];
 573                m->data_in_cnt = 8;
 574                trace_via1_rtc_cmd_pram_sect_read(sector, addr,
 575                                                  sector * 32 + addr,
 576                                                  m->data_in);
 577                m->cmd = REG_EMPTY;
 578            } else {
 579                /* it's a write, we need one more parameter */
 580                trace_via1_rtc_internal_set_alt(addr, sector, addr);
 581                m->alt = addr;
 582            }
 583            break;
 584        default:
 585            g_assert_not_reached();
 586            break;
 587        }
 588        return;
 589    }
 590
 591    /* third byte: it's the data of a REG_PRAM_SECT write */
 592    g_assert(REG_PRAM_SECT <= m->cmd && m->cmd <= REG_PRAM_SECT_LAST);
 593    sector = m->cmd - REG_PRAM_SECT;
 594    v1s->PRAM[sector * 32 + m->alt] = m->data_out;
 595    pram_update(m);
 596    trace_via1_rtc_cmd_pram_sect_write(sector, m->alt, sector * 32 + m->alt,
 597                                       m->data_out);
 598    m->alt = REG_EMPTY;
 599    m->cmd = REG_EMPTY;
 600}
 601
 602static int adb_via_poll(MacVIAState *s, int state, uint8_t *data)
 603{
 604    if (state != ADB_STATE_IDLE) {
 605        return 0;
 606    }
 607
 608    if (s->adb_data_in_size < s->adb_data_in_index) {
 609        return 0;
 610    }
 611
 612    if (s->adb_data_out_index != 0) {
 613        return 0;
 614    }
 615
 616    s->adb_data_in_index = 0;
 617    s->adb_data_out_index = 0;
 618    s->adb_data_in_size = adb_poll(&s->adb_bus, s->adb_data_in, 0xffff);
 619
 620    if (s->adb_data_in_size) {
 621        *data = s->adb_data_in[s->adb_data_in_index++];
 622        qemu_irq_raise(s->adb_data_ready);
 623    }
 624
 625    return s->adb_data_in_size;
 626}
 627
 628static int adb_via_send(MacVIAState *s, int state, uint8_t data)
 629{
 630    switch (state) {
 631    case ADB_STATE_NEW:
 632        s->adb_data_out_index = 0;
 633        break;
 634    case ADB_STATE_EVEN:
 635        if ((s->adb_data_out_index & 1) == 0) {
 636            return 0;
 637        }
 638        break;
 639    case ADB_STATE_ODD:
 640        if (s->adb_data_out_index & 1) {
 641            return 0;
 642        }
 643        break;
 644    case ADB_STATE_IDLE:
 645        return 0;
 646    }
 647
 648    assert(s->adb_data_out_index < sizeof(s->adb_data_out) - 1);
 649
 650    s->adb_data_out[s->adb_data_out_index++] = data;
 651    qemu_irq_raise(s->adb_data_ready);
 652    return 1;
 653}
 654
 655static int adb_via_receive(MacVIAState *s, int state, uint8_t *data)
 656{
 657    switch (state) {
 658    case ADB_STATE_NEW:
 659        return 0;
 660
 661    case ADB_STATE_EVEN:
 662        if (s->adb_data_in_size <= 0) {
 663            qemu_irq_raise(s->adb_data_ready);
 664            return 0;
 665        }
 666
 667        if (s->adb_data_in_index >= s->adb_data_in_size) {
 668            *data = 0;
 669            qemu_irq_raise(s->adb_data_ready);
 670            return 1;
 671        }
 672
 673        if ((s->adb_data_in_index & 1) == 0) {
 674            return 0;
 675        }
 676
 677        break;
 678
 679    case ADB_STATE_ODD:
 680        if (s->adb_data_in_size <= 0) {
 681            qemu_irq_raise(s->adb_data_ready);
 682            return 0;
 683        }
 684
 685        if (s->adb_data_in_index >= s->adb_data_in_size) {
 686            *data = 0;
 687            qemu_irq_raise(s->adb_data_ready);
 688            return 1;
 689        }
 690
 691        if (s->adb_data_in_index & 1) {
 692            return 0;
 693        }
 694
 695        break;
 696
 697    case ADB_STATE_IDLE:
 698        if (s->adb_data_out_index == 0) {
 699            return 0;
 700        }
 701
 702        s->adb_data_in_size = adb_request(&s->adb_bus, s->adb_data_in,
 703                                          s->adb_data_out,
 704                                          s->adb_data_out_index);
 705        s->adb_data_out_index = 0;
 706        s->adb_data_in_index = 0;
 707        if (s->adb_data_in_size < 0) {
 708            *data = 0xff;
 709            qemu_irq_raise(s->adb_data_ready);
 710            return -1;
 711        }
 712
 713        if (s->adb_data_in_size == 0) {
 714            return 0;
 715        }
 716
 717        break;
 718    }
 719
 720    assert(s->adb_data_in_index < sizeof(s->adb_data_in) - 1);
 721
 722    *data = s->adb_data_in[s->adb_data_in_index++];
 723    qemu_irq_raise(s->adb_data_ready);
 724    if (*data == 0xff || *data == 0) {
 725        return 0;
 726    }
 727    return 1;
 728}
 729
 730static void via1_adb_update(MacVIAState *m)
 731{
 732    MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
 733    MOS6522State *s = MOS6522(v1s);
 734    int state;
 735    int ret;
 736
 737    state = (s->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;
 738
 739    if (s->acr & VIA1ACR_vShiftOut) {
 740        /* output mode */
 741        ret = adb_via_send(m, state, s->sr);
 742        if (ret > 0) {
 743            s->b &= ~VIA1B_vADBInt;
 744        } else {
 745            s->b |= VIA1B_vADBInt;
 746        }
 747    } else {
 748        /* input mode */
 749        ret = adb_via_receive(m, state, &s->sr);
 750        if (ret > 0 && s->sr != 0xff) {
 751            s->b &= ~VIA1B_vADBInt;
 752        } else {
 753            s->b |= VIA1B_vADBInt;
 754        }
 755    }
 756}
 757
 758static void via_adb_poll(void *opaque)
 759{
 760    MacVIAState *m = opaque;
 761    MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
 762    MOS6522State *s = MOS6522(v1s);
 763    int state;
 764
 765    if (s->b & VIA1B_vADBInt) {
 766        state = (s->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;
 767        if (adb_via_poll(m, state, &s->sr)) {
 768            s->b &= ~VIA1B_vADBInt;
 769        }
 770    }
 771
 772    timer_mod(m->adb_poll_timer,
 773              qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
 774              (NANOSECONDS_PER_SECOND / VIA_ADB_POLL_FREQ));
 775}
 776
 777static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned size)
 778{
 779    MOS6522Q800VIA1State *s = MOS6522_Q800_VIA1(opaque);
 780    MOS6522State *ms = MOS6522(s);
 781    int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
 782
 783    /*
 784     * If IRQs are disabled, timers are disabled, but we need to update
 785     * VIA1_IRQ_VBLANK and VIA1_IRQ_ONE_SECOND bits in the IFR
 786     */
 787
 788    if (now >= s->next_VBL) {
 789        ms->ifr |= VIA1_IRQ_VBLANK;
 790        via1_VBL_update(s);
 791    }
 792    if (now >= s->next_second) {
 793        ms->ifr |= VIA1_IRQ_ONE_SECOND;
 794        via1_one_second_update(s);
 795    }
 796
 797    addr = (addr >> 9) & 0xf;
 798    return mos6522_read(ms, addr, size);
 799}
 800
 801static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val,
 802                                    unsigned size)
 803{
 804    MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque);
 805    MOS6522State *ms = MOS6522(v1s);
 806
 807    addr = (addr >> 9) & 0xf;
 808    mos6522_write(ms, addr, val, size);
 809
 810    via1_one_second_update(v1s);
 811    via1_VBL_update(v1s);
 812}
 813
 814static const MemoryRegionOps mos6522_q800_via1_ops = {
 815    .read = mos6522_q800_via1_read,
 816    .write = mos6522_q800_via1_write,
 817    .endianness = DEVICE_BIG_ENDIAN,
 818    .valid = {
 819        .min_access_size = 1,
 820        .max_access_size = 1,
 821    },
 822};
 823
 824static uint64_t mos6522_q800_via2_read(void *opaque, hwaddr addr, unsigned size)
 825{
 826    MOS6522Q800VIA2State *s = MOS6522_Q800_VIA2(opaque);
 827    MOS6522State *ms = MOS6522(s);
 828
 829    addr = (addr >> 9) & 0xf;
 830    return mos6522_read(ms, addr, size);
 831}
 832
 833static void mos6522_q800_via2_write(void *opaque, hwaddr addr, uint64_t val,
 834                                    unsigned size)
 835{
 836    MOS6522Q800VIA2State *s = MOS6522_Q800_VIA2(opaque);
 837    MOS6522State *ms = MOS6522(s);
 838
 839    addr = (addr >> 9) & 0xf;
 840    mos6522_write(ms, addr, val, size);
 841}
 842
 843static const MemoryRegionOps mos6522_q800_via2_ops = {
 844    .read = mos6522_q800_via2_read,
 845    .write = mos6522_q800_via2_write,
 846    .endianness = DEVICE_BIG_ENDIAN,
 847    .valid = {
 848        .min_access_size = 1,
 849        .max_access_size = 1,
 850    },
 851};
 852
 853static void mac_via_reset(DeviceState *dev)
 854{
 855    MacVIAState *m = MAC_VIA(dev);
 856    MOS6522Q800VIA1State *v1s = &m->mos6522_via1;
 857
 858    timer_mod(m->adb_poll_timer,
 859              qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
 860              (NANOSECONDS_PER_SECOND / VIA_ADB_POLL_FREQ));
 861
 862    timer_del(v1s->VBL_timer);
 863    v1s->next_VBL = 0;
 864    timer_del(v1s->one_second_timer);
 865    v1s->next_second = 0;
 866
 867    m->cmd = REG_EMPTY;
 868    m->alt = REG_EMPTY;
 869}
 870
 871static void mac_via_realize(DeviceState *dev, Error **errp)
 872{
 873    MacVIAState *m = MAC_VIA(dev);
 874    MOS6522State *ms;
 875    struct tm tm;
 876    int ret;
 877
 878    /* Init VIAs 1 and 2 */
 879    sysbus_init_child_obj(OBJECT(dev), "via1", &m->mos6522_via1,
 880                          sizeof(m->mos6522_via1), TYPE_MOS6522_Q800_VIA1);
 881
 882    sysbus_init_child_obj(OBJECT(dev), "via2", &m->mos6522_via2,
 883                          sizeof(m->mos6522_via2), TYPE_MOS6522_Q800_VIA2);
 884
 885    /* Pass through mos6522 output IRQs */
 886    ms = MOS6522(&m->mos6522_via1);
 887    object_property_add_alias(OBJECT(dev), "irq[0]", OBJECT(ms),
 888                              SYSBUS_DEVICE_GPIO_IRQ "[0]", &error_abort);
 889    ms = MOS6522(&m->mos6522_via2);
 890    object_property_add_alias(OBJECT(dev), "irq[1]", OBJECT(ms),
 891                              SYSBUS_DEVICE_GPIO_IRQ "[0]", &error_abort);
 892
 893    /* Pass through mos6522 input IRQs */
 894    qdev_pass_gpios(DEVICE(&m->mos6522_via1), dev, "via1-irq");
 895    qdev_pass_gpios(DEVICE(&m->mos6522_via2), dev, "via2-irq");
 896
 897    /* VIA 1 */
 898    m->mos6522_via1.one_second_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
 899                                                     via1_one_second,
 900                                                     &m->mos6522_via1);
 901    m->mos6522_via1.VBL_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, via1_VBL,
 902                                              &m->mos6522_via1);
 903
 904    qemu_get_timedate(&tm, 0);
 905    m->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
 906
 907    m->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, via_adb_poll, m);
 908    m->adb_data_ready = qdev_get_gpio_in_named(dev, "via1-irq",
 909                                               VIA1_IRQ_ADB_READY_BIT);
 910
 911    if (m->blk) {
 912        int64_t len = blk_getlength(m->blk);
 913        if (len < 0) {
 914            error_setg_errno(errp, -len,
 915                             "could not get length of backing image");
 916            return;
 917        }
 918        ret = blk_set_perm(m->blk,
 919                           BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE,
 920                           BLK_PERM_ALL, errp);
 921        if (ret < 0) {
 922            return;
 923        }
 924
 925        len = blk_pread(m->blk, 0, m->mos6522_via1.PRAM,
 926                        sizeof(m->mos6522_via1.PRAM));
 927        if (len != sizeof(m->mos6522_via1.PRAM)) {
 928            error_setg(errp, "can't read PRAM contents");
 929            return;
 930        }
 931    }
 932}
 933
 934static void mac_via_init(Object *obj)
 935{
 936    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 937    MacVIAState *m = MAC_VIA(obj);
 938
 939    /* MMIO */
 940    memory_region_init(&m->mmio, obj, "mac-via", 2 * VIA_SIZE);
 941    sysbus_init_mmio(sbd, &m->mmio);
 942
 943    memory_region_init_io(&m->via1mem, obj, &mos6522_q800_via1_ops,
 944                          &m->mos6522_via1, "via1", VIA_SIZE);
 945    memory_region_add_subregion(&m->mmio, 0x0, &m->via1mem);
 946
 947    memory_region_init_io(&m->via2mem, obj, &mos6522_q800_via2_ops,
 948                          &m->mos6522_via2, "via2", VIA_SIZE);
 949    memory_region_add_subregion(&m->mmio, VIA_SIZE, &m->via2mem);
 950
 951    /* ADB */
 952    qbus_create_inplace((BusState *)&m->adb_bus, sizeof(m->adb_bus),
 953                        TYPE_ADB_BUS, DEVICE(obj), "adb.0");
 954}
 955
 956static void postload_update_cb(void *opaque, int running, RunState state)
 957{
 958    MacVIAState *m = MAC_VIA(opaque);
 959
 960    qemu_del_vm_change_state_handler(m->vmstate);
 961    m->vmstate = NULL;
 962
 963    pram_update(m);
 964}
 965
 966static int mac_via_post_load(void *opaque, int version_id)
 967{
 968    MacVIAState *m = MAC_VIA(opaque);
 969
 970    if (m->blk) {
 971        m->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
 972                                                      m);
 973    }
 974
 975    return 0;
 976}
 977
 978static const VMStateDescription vmstate_mac_via = {
 979    .name = "mac-via",
 980    .version_id = 1,
 981    .minimum_version_id = 1,
 982    .post_load = mac_via_post_load,
 983    .fields = (VMStateField[]) {
 984        /* VIAs */
 985        VMSTATE_STRUCT(mos6522_via1.parent_obj, MacVIAState, 0, vmstate_mos6522,
 986                       MOS6522State),
 987        VMSTATE_UINT8(mos6522_via1.last_b, MacVIAState),
 988        VMSTATE_BUFFER(mos6522_via1.PRAM, MacVIAState),
 989        VMSTATE_TIMER_PTR(mos6522_via1.one_second_timer, MacVIAState),
 990        VMSTATE_INT64(mos6522_via1.next_second, MacVIAState),
 991        VMSTATE_TIMER_PTR(mos6522_via1.VBL_timer, MacVIAState),
 992        VMSTATE_INT64(mos6522_via1.next_VBL, MacVIAState),
 993        VMSTATE_STRUCT(mos6522_via2.parent_obj, MacVIAState, 0, vmstate_mos6522,
 994                       MOS6522State),
 995        /* RTC */
 996        VMSTATE_UINT32(tick_offset, MacVIAState),
 997        VMSTATE_UINT8(data_out, MacVIAState),
 998        VMSTATE_INT32(data_out_cnt, MacVIAState),
 999        VMSTATE_UINT8(data_in, MacVIAState),
1000        VMSTATE_UINT8(data_in_cnt, MacVIAState),
1001        VMSTATE_UINT8(cmd, MacVIAState),
1002        VMSTATE_INT32(wprotect, MacVIAState),
1003        VMSTATE_INT32(alt, MacVIAState),
1004        /* ADB */
1005        VMSTATE_TIMER_PTR(adb_poll_timer, MacVIAState),
1006        VMSTATE_INT32(adb_data_in_size, MacVIAState),
1007        VMSTATE_INT32(adb_data_in_index, MacVIAState),
1008        VMSTATE_INT32(adb_data_out_index, MacVIAState),
1009        VMSTATE_BUFFER(adb_data_in, MacVIAState),
1010        VMSTATE_BUFFER(adb_data_out, MacVIAState),
1011        VMSTATE_END_OF_LIST()
1012    }
1013};
1014
1015static Property mac_via_properties[] = {
1016    DEFINE_PROP_DRIVE("drive", MacVIAState, blk),
1017    DEFINE_PROP_END_OF_LIST(),
1018};
1019
1020static void mac_via_class_init(ObjectClass *oc, void *data)
1021{
1022    DeviceClass *dc = DEVICE_CLASS(oc);
1023
1024    dc->realize = mac_via_realize;
1025    dc->reset = mac_via_reset;
1026    dc->vmsd = &vmstate_mac_via;
1027    device_class_set_props(dc, mac_via_properties);
1028}
1029
1030static TypeInfo mac_via_info = {
1031    .name = TYPE_MAC_VIA,
1032    .parent = TYPE_SYS_BUS_DEVICE,
1033    .instance_size = sizeof(MacVIAState),
1034    .instance_init = mac_via_init,
1035    .class_init = mac_via_class_init,
1036};
1037
1038/* VIA 1 */
1039static void mos6522_q800_via1_portB_write(MOS6522State *s)
1040{
1041    MOS6522Q800VIA1State *v1s = container_of(s, MOS6522Q800VIA1State,
1042                                             parent_obj);
1043    MacVIAState *m = container_of(v1s, MacVIAState, mos6522_via1);
1044
1045    via1_rtc_update(m);
1046    via1_adb_update(m);
1047
1048    v1s->last_b = s->b;
1049}
1050
1051static void mos6522_q800_via1_reset(DeviceState *dev)
1052{
1053    MOS6522State *ms = MOS6522(dev);
1054    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms);
1055
1056    mdc->parent_reset(dev);
1057
1058    ms->timers[0].frequency = VIA_TIMER_FREQ;
1059    ms->timers[1].frequency = VIA_TIMER_FREQ;
1060
1061    ms->b = VIA1B_vADB_StateMask | VIA1B_vADBInt | VIA1B_vRTCEnb;
1062}
1063
1064static void mos6522_q800_via1_init(Object *obj)
1065{
1066    qdev_init_gpio_in_named(DEVICE(obj), via1_irq_request, "via1-irq",
1067                            VIA1_IRQ_NB);
1068}
1069
1070static void mos6522_q800_via1_class_init(ObjectClass *oc, void *data)
1071{
1072    DeviceClass *dc = DEVICE_CLASS(oc);
1073    MOS6522DeviceClass *mdc = MOS6522_DEVICE_CLASS(oc);
1074
1075    dc->reset = mos6522_q800_via1_reset;
1076    mdc->portB_write = mos6522_q800_via1_portB_write;
1077}
1078
1079static const TypeInfo mos6522_q800_via1_type_info = {
1080    .name = TYPE_MOS6522_Q800_VIA1,
1081    .parent = TYPE_MOS6522,
1082    .instance_size = sizeof(MOS6522Q800VIA1State),
1083    .instance_init = mos6522_q800_via1_init,
1084    .class_init = mos6522_q800_via1_class_init,
1085};
1086
1087/* VIA 2 */
1088static void mos6522_q800_via2_portB_write(MOS6522State *s)
1089{
1090    if (s->dirb & VIA2B_vPower && (s->b & VIA2B_vPower) == 0) {
1091        /* shutdown */
1092        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
1093    }
1094}
1095
1096static void mos6522_q800_via2_reset(DeviceState *dev)
1097{
1098    MOS6522State *ms = MOS6522(dev);
1099    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms);
1100
1101    mdc->parent_reset(dev);
1102
1103    ms->timers[0].frequency = VIA_TIMER_FREQ;
1104    ms->timers[1].frequency = VIA_TIMER_FREQ;
1105
1106    ms->dirb = 0;
1107    ms->b = 0;
1108}
1109
1110static void mos6522_q800_via2_init(Object *obj)
1111{
1112    qdev_init_gpio_in_named(DEVICE(obj), via2_irq_request, "via2-irq",
1113                            VIA2_IRQ_NB);
1114}
1115
1116static void mos6522_q800_via2_class_init(ObjectClass *oc, void *data)
1117{
1118    DeviceClass *dc = DEVICE_CLASS(oc);
1119    MOS6522DeviceClass *mdc = MOS6522_DEVICE_CLASS(oc);
1120
1121    dc->reset = mos6522_q800_via2_reset;
1122    mdc->portB_write = mos6522_q800_via2_portB_write;
1123}
1124
1125static const TypeInfo mos6522_q800_via2_type_info = {
1126    .name = TYPE_MOS6522_Q800_VIA2,
1127    .parent = TYPE_MOS6522,
1128    .instance_size = sizeof(MOS6522Q800VIA2State),
1129    .instance_init = mos6522_q800_via2_init,
1130    .class_init = mos6522_q800_via2_class_init,
1131};
1132
1133static void mac_via_register_types(void)
1134{
1135    type_register_static(&mos6522_q800_via1_type_info);
1136    type_register_static(&mos6522_q800_via2_type_info);
1137    type_register_static(&mac_via_info);
1138}
1139
1140type_init(mac_via_register_types);
1141