qemu/hw/parallel.c
<<
>>
Prefs
   1/*
   2 * QEMU Parallel PORT emulation
   3 *
   4 * Copyright (c) 2003-2005 Fabrice Bellard
   5 * Copyright (c) 2007 Marko Kohtala
   6 *
   7 * Permission is hereby granted, free of charge, to any person obtaining a copy
   8 * of this software and associated documentation files (the "Software"), to deal
   9 * in the Software without restriction, including without limitation the rights
  10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 * copies of the Software, and to permit persons to whom the Software is
  12 * furnished to do so, subject to the following conditions:
  13 *
  14 * The above copyright notice and this permission notice shall be included in
  15 * all copies or substantial portions of the Software.
  16 *
  17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 * THE SOFTWARE.
  24 */
  25#include "hw.h"
  26#include "qemu-char.h"
  27#include "isa.h"
  28#include "pc.h"
  29#include "sysemu.h"
  30
  31//#define DEBUG_PARALLEL
  32
  33#ifdef DEBUG_PARALLEL
  34#define pdebug(fmt, ...) printf("pp: " fmt, ## __VA_ARGS__)
  35#else
  36#define pdebug(fmt, ...) ((void)0)
  37#endif
  38
  39#define PARA_REG_DATA 0
  40#define PARA_REG_STS 1
  41#define PARA_REG_CTR 2
  42#define PARA_REG_EPP_ADDR 3
  43#define PARA_REG_EPP_DATA 4
  44
  45/*
  46 * These are the definitions for the Printer Status Register
  47 */
  48#define PARA_STS_BUSY   0x80    /* Busy complement */
  49#define PARA_STS_ACK    0x40    /* Acknowledge */
  50#define PARA_STS_PAPER  0x20    /* Out of paper */
  51#define PARA_STS_ONLINE 0x10    /* Online */
  52#define PARA_STS_ERROR  0x08    /* Error complement */
  53#define PARA_STS_TMOUT  0x01    /* EPP timeout */
  54
  55/*
  56 * These are the definitions for the Printer Control Register
  57 */
  58#define PARA_CTR_DIR    0x20    /* Direction (1=read, 0=write) */
  59#define PARA_CTR_INTEN  0x10    /* IRQ Enable */
  60#define PARA_CTR_SELECT 0x08    /* Select In complement */
  61#define PARA_CTR_INIT   0x04    /* Initialize Printer complement */
  62#define PARA_CTR_AUTOLF 0x02    /* Auto linefeed complement */
  63#define PARA_CTR_STROBE 0x01    /* Strobe complement */
  64
  65#define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
  66
  67typedef struct ParallelState {
  68    uint8_t dataw;
  69    uint8_t datar;
  70    uint8_t status;
  71    uint8_t control;
  72    qemu_irq irq;
  73    int irq_pending;
  74    CharDriverState *chr;
  75    int hw_driver;
  76    int epp_timeout;
  77    uint32_t last_read_offset; /* For debugging */
  78    /* Memory-mapped interface */
  79    int it_shift;
  80} ParallelState;
  81
  82typedef struct ISAParallelState {
  83    ISADevice dev;
  84    uint32_t index;
  85    uint32_t iobase;
  86    uint32_t isairq;
  87    ParallelState state;
  88} ISAParallelState;
  89
  90static void parallel_update_irq(ParallelState *s)
  91{
  92    if (s->irq_pending)
  93        qemu_irq_raise(s->irq);
  94    else
  95        qemu_irq_lower(s->irq);
  96}
  97
  98static void
  99parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
 100{
 101    ParallelState *s = opaque;
 102
 103    pdebug("write addr=0x%02x val=0x%02x\n", addr, val);
 104
 105    addr &= 7;
 106    switch(addr) {
 107    case PARA_REG_DATA:
 108        s->dataw = val;
 109        parallel_update_irq(s);
 110        break;
 111    case PARA_REG_CTR:
 112        val |= 0xc0;
 113        if ((val & PARA_CTR_INIT) == 0 ) {
 114            s->status = PARA_STS_BUSY;
 115            s->status |= PARA_STS_ACK;
 116            s->status |= PARA_STS_ONLINE;
 117            s->status |= PARA_STS_ERROR;
 118        }
 119        else if (val & PARA_CTR_SELECT) {
 120            if (val & PARA_CTR_STROBE) {
 121                s->status &= ~PARA_STS_BUSY;
 122                if ((s->control & PARA_CTR_STROBE) == 0)
 123                    qemu_chr_fe_write(s->chr, &s->dataw, 1);
 124            } else {
 125                if (s->control & PARA_CTR_INTEN) {
 126                    s->irq_pending = 1;
 127                }
 128            }
 129        }
 130        parallel_update_irq(s);
 131        s->control = val;
 132        break;
 133    }
 134}
 135
 136static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
 137{
 138    ParallelState *s = opaque;
 139    uint8_t parm = val;
 140    int dir;
 141
 142    /* Sometimes programs do several writes for timing purposes on old
 143       HW. Take care not to waste time on writes that do nothing. */
 144
 145    s->last_read_offset = ~0U;
 146
 147    addr &= 7;
 148    switch(addr) {
 149    case PARA_REG_DATA:
 150        if (s->dataw == val)
 151            return;
 152        pdebug("wd%02x\n", val);
 153        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
 154        s->dataw = val;
 155        break;
 156    case PARA_REG_STS:
 157        pdebug("ws%02x\n", val);
 158        if (val & PARA_STS_TMOUT)
 159            s->epp_timeout = 0;
 160        break;
 161    case PARA_REG_CTR:
 162        val |= 0xc0;
 163        if (s->control == val)
 164            return;
 165        pdebug("wc%02x\n", val);
 166
 167        if ((val & PARA_CTR_DIR) != (s->control & PARA_CTR_DIR)) {
 168            if (val & PARA_CTR_DIR) {
 169                dir = 1;
 170            } else {
 171                dir = 0;
 172            }
 173            qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
 174            parm &= ~PARA_CTR_DIR;
 175        }
 176
 177        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
 178        s->control = val;
 179        break;
 180    case PARA_REG_EPP_ADDR:
 181        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
 182            /* Controls not correct for EPP address cycle, so do nothing */
 183            pdebug("wa%02x s\n", val);
 184        else {
 185            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
 186            if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
 187                s->epp_timeout = 1;
 188                pdebug("wa%02x t\n", val);
 189            }
 190            else
 191                pdebug("wa%02x\n", val);
 192        }
 193        break;
 194    case PARA_REG_EPP_DATA:
 195        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
 196            /* Controls not correct for EPP data cycle, so do nothing */
 197            pdebug("we%02x s\n", val);
 198        else {
 199            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
 200            if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
 201                s->epp_timeout = 1;
 202                pdebug("we%02x t\n", val);
 203            }
 204            else
 205                pdebug("we%02x\n", val);
 206        }
 207        break;
 208    }
 209}
 210
 211static void
 212parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val)
 213{
 214    ParallelState *s = opaque;
 215    uint16_t eppdata = cpu_to_le16(val);
 216    int err;
 217    struct ParallelIOArg ioarg = {
 218        .buffer = &eppdata, .count = sizeof(eppdata)
 219    };
 220    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
 221        /* Controls not correct for EPP data cycle, so do nothing */
 222        pdebug("we%04x s\n", val);
 223        return;
 224    }
 225    err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
 226    if (err) {
 227        s->epp_timeout = 1;
 228        pdebug("we%04x t\n", val);
 229    }
 230    else
 231        pdebug("we%04x\n", val);
 232}
 233
 234static void
 235parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val)
 236{
 237    ParallelState *s = opaque;
 238    uint32_t eppdata = cpu_to_le32(val);
 239    int err;
 240    struct ParallelIOArg ioarg = {
 241        .buffer = &eppdata, .count = sizeof(eppdata)
 242    };
 243    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
 244        /* Controls not correct for EPP data cycle, so do nothing */
 245        pdebug("we%08x s\n", val);
 246        return;
 247    }
 248    err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
 249    if (err) {
 250        s->epp_timeout = 1;
 251        pdebug("we%08x t\n", val);
 252    }
 253    else
 254        pdebug("we%08x\n", val);
 255}
 256
 257static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
 258{
 259    ParallelState *s = opaque;
 260    uint32_t ret = 0xff;
 261
 262    addr &= 7;
 263    switch(addr) {
 264    case PARA_REG_DATA:
 265        if (s->control & PARA_CTR_DIR)
 266            ret = s->datar;
 267        else
 268            ret = s->dataw;
 269        break;
 270    case PARA_REG_STS:
 271        ret = s->status;
 272        s->irq_pending = 0;
 273        if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
 274            /* XXX Fixme: wait 5 microseconds */
 275            if (s->status & PARA_STS_ACK)
 276                s->status &= ~PARA_STS_ACK;
 277            else {
 278                /* XXX Fixme: wait 5 microseconds */
 279                s->status |= PARA_STS_ACK;
 280                s->status |= PARA_STS_BUSY;
 281            }
 282        }
 283        parallel_update_irq(s);
 284        break;
 285    case PARA_REG_CTR:
 286        ret = s->control;
 287        break;
 288    }
 289    pdebug("read addr=0x%02x val=0x%02x\n", addr, ret);
 290    return ret;
 291}
 292
 293static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
 294{
 295    ParallelState *s = opaque;
 296    uint8_t ret = 0xff;
 297    addr &= 7;
 298    switch(addr) {
 299    case PARA_REG_DATA:
 300        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
 301        if (s->last_read_offset != addr || s->datar != ret)
 302            pdebug("rd%02x\n", ret);
 303        s->datar = ret;
 304        break;
 305    case PARA_REG_STS:
 306        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
 307        ret &= ~PARA_STS_TMOUT;
 308        if (s->epp_timeout)
 309            ret |= PARA_STS_TMOUT;
 310        if (s->last_read_offset != addr || s->status != ret)
 311            pdebug("rs%02x\n", ret);
 312        s->status = ret;
 313        break;
 314    case PARA_REG_CTR:
 315        /* s->control has some bits fixed to 1. It is zero only when
 316           it has not been yet written to.  */
 317        if (s->control == 0) {
 318            qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
 319            if (s->last_read_offset != addr)
 320                pdebug("rc%02x\n", ret);
 321            s->control = ret;
 322        }
 323        else {
 324            ret = s->control;
 325            if (s->last_read_offset != addr)
 326                pdebug("rc%02x\n", ret);
 327        }
 328        break;
 329    case PARA_REG_EPP_ADDR:
 330        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
 331            /* Controls not correct for EPP addr cycle, so do nothing */
 332            pdebug("ra%02x s\n", ret);
 333        else {
 334            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
 335            if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
 336                s->epp_timeout = 1;
 337                pdebug("ra%02x t\n", ret);
 338            }
 339            else
 340                pdebug("ra%02x\n", ret);
 341        }
 342        break;
 343    case PARA_REG_EPP_DATA:
 344        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
 345            /* Controls not correct for EPP data cycle, so do nothing */
 346            pdebug("re%02x s\n", ret);
 347        else {
 348            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
 349            if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
 350                s->epp_timeout = 1;
 351                pdebug("re%02x t\n", ret);
 352            }
 353            else
 354                pdebug("re%02x\n", ret);
 355        }
 356        break;
 357    }
 358    s->last_read_offset = addr;
 359    return ret;
 360}
 361
 362static uint32_t
 363parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr)
 364{
 365    ParallelState *s = opaque;
 366    uint32_t ret;
 367    uint16_t eppdata = ~0;
 368    int err;
 369    struct ParallelIOArg ioarg = {
 370        .buffer = &eppdata, .count = sizeof(eppdata)
 371    };
 372    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
 373        /* Controls not correct for EPP data cycle, so do nothing */
 374        pdebug("re%04x s\n", eppdata);
 375        return eppdata;
 376    }
 377    err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
 378    ret = le16_to_cpu(eppdata);
 379
 380    if (err) {
 381        s->epp_timeout = 1;
 382        pdebug("re%04x t\n", ret);
 383    }
 384    else
 385        pdebug("re%04x\n", ret);
 386    return ret;
 387}
 388
 389static uint32_t
 390parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr)
 391{
 392    ParallelState *s = opaque;
 393    uint32_t ret;
 394    uint32_t eppdata = ~0U;
 395    int err;
 396    struct ParallelIOArg ioarg = {
 397        .buffer = &eppdata, .count = sizeof(eppdata)
 398    };
 399    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
 400        /* Controls not correct for EPP data cycle, so do nothing */
 401        pdebug("re%08x s\n", eppdata);
 402        return eppdata;
 403    }
 404    err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
 405    ret = le32_to_cpu(eppdata);
 406
 407    if (err) {
 408        s->epp_timeout = 1;
 409        pdebug("re%08x t\n", ret);
 410    }
 411    else
 412        pdebug("re%08x\n", ret);
 413    return ret;
 414}
 415
 416static void parallel_ioport_ecp_write(void *opaque, uint32_t addr, uint32_t val)
 417{
 418    pdebug("wecp%d=%02x\n", addr & 7, val);
 419}
 420
 421static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
 422{
 423    uint8_t ret = 0xff;
 424
 425    pdebug("recp%d:%02x\n", addr & 7, ret);
 426    return ret;
 427}
 428
 429static void parallel_reset(void *opaque)
 430{
 431    ParallelState *s = opaque;
 432
 433    s->datar = ~0;
 434    s->dataw = ~0;
 435    s->status = PARA_STS_BUSY;
 436    s->status |= PARA_STS_ACK;
 437    s->status |= PARA_STS_ONLINE;
 438    s->status |= PARA_STS_ERROR;
 439    s->status |= PARA_STS_TMOUT;
 440    s->control = PARA_CTR_SELECT;
 441    s->control |= PARA_CTR_INIT;
 442    s->control |= 0xc0;
 443    s->irq_pending = 0;
 444    s->hw_driver = 0;
 445    s->epp_timeout = 0;
 446    s->last_read_offset = ~0U;
 447}
 448
 449static const int isa_parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
 450
 451static const MemoryRegionPortio isa_parallel_portio_hw_list[] = {
 452    { 0, 8, 1,
 453      .read = parallel_ioport_read_hw,
 454      .write = parallel_ioport_write_hw },
 455    { 4, 1, 2,
 456      .read = parallel_ioport_eppdata_read_hw2,
 457      .write = parallel_ioport_eppdata_write_hw2 },
 458    { 4, 1, 4,
 459      .read = parallel_ioport_eppdata_read_hw4,
 460      .write = parallel_ioport_eppdata_write_hw4 },
 461    { 0x400, 8, 1,
 462      .read = parallel_ioport_ecp_read,
 463      .write = parallel_ioport_ecp_write },
 464    PORTIO_END_OF_LIST(),
 465};
 466
 467static const MemoryRegionPortio isa_parallel_portio_sw_list[] = {
 468    { 0, 8, 1,
 469      .read = parallel_ioport_read_sw,
 470      .write = parallel_ioport_write_sw },
 471    PORTIO_END_OF_LIST(),
 472};
 473
 474static int parallel_isa_initfn(ISADevice *dev)
 475{
 476    static int index;
 477    ISAParallelState *isa = DO_UPCAST(ISAParallelState, dev, dev);
 478    ParallelState *s = &isa->state;
 479    int base;
 480    uint8_t dummy;
 481
 482    if (!s->chr) {
 483        fprintf(stderr, "Can't create parallel device, empty char device\n");
 484        exit(1);
 485    }
 486
 487    if (isa->index == -1)
 488        isa->index = index;
 489    if (isa->index >= MAX_PARALLEL_PORTS)
 490        return -1;
 491    if (isa->iobase == -1)
 492        isa->iobase = isa_parallel_io[isa->index];
 493    index++;
 494
 495    base = isa->iobase;
 496    isa_init_irq(dev, &s->irq, isa->isairq);
 497    qemu_register_reset(parallel_reset, s);
 498
 499    if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
 500        s->hw_driver = 1;
 501        s->status = dummy;
 502    }
 503
 504    isa_register_portio_list(dev, base,
 505                             (s->hw_driver
 506                              ? &isa_parallel_portio_hw_list[0]
 507                              : &isa_parallel_portio_sw_list[0]),
 508                             s, "parallel");
 509    return 0;
 510}
 511
 512/* Memory mapped interface */
 513static uint32_t parallel_mm_readb (void *opaque, target_phys_addr_t addr)
 514{
 515    ParallelState *s = opaque;
 516
 517    return parallel_ioport_read_sw(s, addr >> s->it_shift) & 0xFF;
 518}
 519
 520static void parallel_mm_writeb (void *opaque,
 521                                target_phys_addr_t addr, uint32_t value)
 522{
 523    ParallelState *s = opaque;
 524
 525    parallel_ioport_write_sw(s, addr >> s->it_shift, value & 0xFF);
 526}
 527
 528static uint32_t parallel_mm_readw (void *opaque, target_phys_addr_t addr)
 529{
 530    ParallelState *s = opaque;
 531
 532    return parallel_ioport_read_sw(s, addr >> s->it_shift) & 0xFFFF;
 533}
 534
 535static void parallel_mm_writew (void *opaque,
 536                                target_phys_addr_t addr, uint32_t value)
 537{
 538    ParallelState *s = opaque;
 539
 540    parallel_ioport_write_sw(s, addr >> s->it_shift, value & 0xFFFF);
 541}
 542
 543static uint32_t parallel_mm_readl (void *opaque, target_phys_addr_t addr)
 544{
 545    ParallelState *s = opaque;
 546
 547    return parallel_ioport_read_sw(s, addr >> s->it_shift);
 548}
 549
 550static void parallel_mm_writel (void *opaque,
 551                                target_phys_addr_t addr, uint32_t value)
 552{
 553    ParallelState *s = opaque;
 554
 555    parallel_ioport_write_sw(s, addr >> s->it_shift, value);
 556}
 557
 558static CPUReadMemoryFunc * const parallel_mm_read_sw[] = {
 559    &parallel_mm_readb,
 560    &parallel_mm_readw,
 561    &parallel_mm_readl,
 562};
 563
 564static CPUWriteMemoryFunc * const parallel_mm_write_sw[] = {
 565    &parallel_mm_writeb,
 566    &parallel_mm_writew,
 567    &parallel_mm_writel,
 568};
 569
 570/* If fd is zero, it means that the parallel device uses the console */
 571bool parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq,
 572                      CharDriverState *chr)
 573{
 574    ParallelState *s;
 575    int io_sw;
 576
 577    s = g_malloc0(sizeof(ParallelState));
 578    s->irq = irq;
 579    s->chr = chr;
 580    s->it_shift = it_shift;
 581    qemu_register_reset(parallel_reset, s);
 582
 583    io_sw = cpu_register_io_memory(parallel_mm_read_sw, parallel_mm_write_sw,
 584                                   s, DEVICE_NATIVE_ENDIAN);
 585    cpu_register_physical_memory(base, 8 << it_shift, io_sw);
 586    return true;
 587}
 588
 589static ISADeviceInfo parallel_isa_info = {
 590    .qdev.name  = "isa-parallel",
 591    .qdev.size  = sizeof(ISAParallelState),
 592    .init       = parallel_isa_initfn,
 593    .qdev.props = (Property[]) {
 594        DEFINE_PROP_UINT32("index", ISAParallelState, index,   -1),
 595        DEFINE_PROP_HEX32("iobase", ISAParallelState, iobase,  -1),
 596        DEFINE_PROP_UINT32("irq",   ISAParallelState, isairq,  7),
 597        DEFINE_PROP_CHR("chardev",  ISAParallelState, state.chr),
 598        DEFINE_PROP_END_OF_LIST(),
 599    },
 600};
 601
 602static void parallel_register_devices(void)
 603{
 604    isa_qdev_register(&parallel_isa_info);
 605}
 606
 607device_init(parallel_register_devices)
 608