cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

parallel.c (20545B)


      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
     26#include "qemu/osdep.h"
     27#include "qapi/error.h"
     28#include "qemu/module.h"
     29#include "chardev/char-parallel.h"
     30#include "chardev/char-fe.h"
     31#include "hw/acpi/aml-build.h"
     32#include "hw/irq.h"
     33#include "hw/isa/isa.h"
     34#include "hw/qdev-properties.h"
     35#include "hw/qdev-properties-system.h"
     36#include "migration/vmstate.h"
     37#include "hw/char/parallel.h"
     38#include "sysemu/reset.h"
     39#include "sysemu/sysemu.h"
     40#include "trace.h"
     41#include "qom/object.h"
     42
     43//#define DEBUG_PARALLEL
     44
     45#ifdef DEBUG_PARALLEL
     46#define pdebug(fmt, ...) printf("pp: " fmt, ## __VA_ARGS__)
     47#else
     48#define pdebug(fmt, ...) ((void)0)
     49#endif
     50
     51#define PARA_REG_DATA 0
     52#define PARA_REG_STS 1
     53#define PARA_REG_CTR 2
     54#define PARA_REG_EPP_ADDR 3
     55#define PARA_REG_EPP_DATA 4
     56
     57/*
     58 * These are the definitions for the Printer Status Register
     59 */
     60#define PARA_STS_BUSY	0x80	/* Busy complement */
     61#define PARA_STS_ACK	0x40	/* Acknowledge */
     62#define PARA_STS_PAPER	0x20	/* Out of paper */
     63#define PARA_STS_ONLINE	0x10	/* Online */
     64#define PARA_STS_ERROR	0x08	/* Error complement */
     65#define PARA_STS_TMOUT	0x01	/* EPP timeout */
     66
     67/*
     68 * These are the definitions for the Printer Control Register
     69 */
     70#define PARA_CTR_DIR	0x20	/* Direction (1=read, 0=write) */
     71#define PARA_CTR_INTEN	0x10	/* IRQ Enable */
     72#define PARA_CTR_SELECT	0x08	/* Select In complement */
     73#define PARA_CTR_INIT	0x04	/* Initialize Printer complement */
     74#define PARA_CTR_AUTOLF	0x02	/* Auto linefeed complement */
     75#define PARA_CTR_STROBE	0x01	/* Strobe complement */
     76
     77#define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
     78
     79typedef struct ParallelState {
     80    MemoryRegion iomem;
     81    uint8_t dataw;
     82    uint8_t datar;
     83    uint8_t status;
     84    uint8_t control;
     85    qemu_irq irq;
     86    int irq_pending;
     87    CharBackend chr;
     88    int hw_driver;
     89    int epp_timeout;
     90    uint32_t last_read_offset; /* For debugging */
     91    /* Memory-mapped interface */
     92    int it_shift;
     93    PortioList portio_list;
     94} ParallelState;
     95
     96#define TYPE_ISA_PARALLEL "isa-parallel"
     97OBJECT_DECLARE_SIMPLE_TYPE(ISAParallelState, ISA_PARALLEL)
     98
     99struct ISAParallelState {
    100    ISADevice parent_obj;
    101
    102    uint32_t index;
    103    uint32_t iobase;
    104    uint32_t isairq;
    105    ParallelState state;
    106};
    107
    108static void parallel_update_irq(ParallelState *s)
    109{
    110    if (s->irq_pending)
    111        qemu_irq_raise(s->irq);
    112    else
    113        qemu_irq_lower(s->irq);
    114}
    115
    116static void
    117parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
    118{
    119    ParallelState *s = opaque;
    120
    121    addr &= 7;
    122    trace_parallel_ioport_write("SW", addr, val);
    123    switch(addr) {
    124    case PARA_REG_DATA:
    125        s->dataw = val;
    126        parallel_update_irq(s);
    127        break;
    128    case PARA_REG_CTR:
    129        val |= 0xc0;
    130        if ((val & PARA_CTR_INIT) == 0 ) {
    131            s->status = PARA_STS_BUSY;
    132            s->status |= PARA_STS_ACK;
    133            s->status |= PARA_STS_ONLINE;
    134            s->status |= PARA_STS_ERROR;
    135        }
    136        else if (val & PARA_CTR_SELECT) {
    137            if (val & PARA_CTR_STROBE) {
    138                s->status &= ~PARA_STS_BUSY;
    139                if ((s->control & PARA_CTR_STROBE) == 0)
    140                    /* XXX this blocks entire thread. Rewrite to use
    141                     * qemu_chr_fe_write and background I/O callbacks */
    142                    qemu_chr_fe_write_all(&s->chr, &s->dataw, 1);
    143            } else {
    144                if (s->control & PARA_CTR_INTEN) {
    145                    s->irq_pending = 1;
    146                }
    147            }
    148        }
    149        parallel_update_irq(s);
    150        s->control = val;
    151        break;
    152    }
    153}
    154
    155static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
    156{
    157    ParallelState *s = opaque;
    158    uint8_t parm = val;
    159    int dir;
    160
    161    /* Sometimes programs do several writes for timing purposes on old
    162       HW. Take care not to waste time on writes that do nothing. */
    163
    164    s->last_read_offset = ~0U;
    165
    166    addr &= 7;
    167    trace_parallel_ioport_write("HW", addr, val);
    168    switch(addr) {
    169    case PARA_REG_DATA:
    170        if (s->dataw == val)
    171            return;
    172        pdebug("wd%02x\n", val);
    173        qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
    174        s->dataw = val;
    175        break;
    176    case PARA_REG_STS:
    177        pdebug("ws%02x\n", val);
    178        if (val & PARA_STS_TMOUT)
    179            s->epp_timeout = 0;
    180        break;
    181    case PARA_REG_CTR:
    182        val |= 0xc0;
    183        if (s->control == val)
    184            return;
    185        pdebug("wc%02x\n", val);
    186
    187        if ((val & PARA_CTR_DIR) != (s->control & PARA_CTR_DIR)) {
    188            if (val & PARA_CTR_DIR) {
    189                dir = 1;
    190            } else {
    191                dir = 0;
    192            }
    193            qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
    194            parm &= ~PARA_CTR_DIR;
    195        }
    196
    197        qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
    198        s->control = val;
    199        break;
    200    case PARA_REG_EPP_ADDR:
    201        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
    202            /* Controls not correct for EPP address cycle, so do nothing */
    203            pdebug("wa%02x s\n", val);
    204        else {
    205            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
    206            if (qemu_chr_fe_ioctl(&s->chr,
    207                                  CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
    208                s->epp_timeout = 1;
    209                pdebug("wa%02x t\n", val);
    210            }
    211            else
    212                pdebug("wa%02x\n", val);
    213        }
    214        break;
    215    case PARA_REG_EPP_DATA:
    216        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
    217            /* Controls not correct for EPP data cycle, so do nothing */
    218            pdebug("we%02x s\n", val);
    219        else {
    220            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
    221            if (qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
    222                s->epp_timeout = 1;
    223                pdebug("we%02x t\n", val);
    224            }
    225            else
    226                pdebug("we%02x\n", val);
    227        }
    228        break;
    229    }
    230}
    231
    232static void
    233parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val)
    234{
    235    ParallelState *s = opaque;
    236    uint16_t eppdata = cpu_to_le16(val);
    237    int err;
    238    struct ParallelIOArg ioarg = {
    239        .buffer = &eppdata, .count = sizeof(eppdata)
    240    };
    241
    242    trace_parallel_ioport_write("EPP", addr, val);
    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%04x 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%04x t\n", val);
    252    }
    253    else
    254        pdebug("we%04x\n", val);
    255}
    256
    257static void
    258parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val)
    259{
    260    ParallelState *s = opaque;
    261    uint32_t eppdata = cpu_to_le32(val);
    262    int err;
    263    struct ParallelIOArg ioarg = {
    264        .buffer = &eppdata, .count = sizeof(eppdata)
    265    };
    266
    267    trace_parallel_ioport_write("EPP", addr, val);
    268    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
    269        /* Controls not correct for EPP data cycle, so do nothing */
    270        pdebug("we%08x s\n", val);
    271        return;
    272    }
    273    err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
    274    if (err) {
    275        s->epp_timeout = 1;
    276        pdebug("we%08x t\n", val);
    277    }
    278    else
    279        pdebug("we%08x\n", val);
    280}
    281
    282static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
    283{
    284    ParallelState *s = opaque;
    285    uint32_t ret = 0xff;
    286
    287    addr &= 7;
    288    switch(addr) {
    289    case PARA_REG_DATA:
    290        if (s->control & PARA_CTR_DIR)
    291            ret = s->datar;
    292        else
    293            ret = s->dataw;
    294        break;
    295    case PARA_REG_STS:
    296        ret = s->status;
    297        s->irq_pending = 0;
    298        if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
    299            /* XXX Fixme: wait 5 microseconds */
    300            if (s->status & PARA_STS_ACK)
    301                s->status &= ~PARA_STS_ACK;
    302            else {
    303                /* XXX Fixme: wait 5 microseconds */
    304                s->status |= PARA_STS_ACK;
    305                s->status |= PARA_STS_BUSY;
    306            }
    307        }
    308        parallel_update_irq(s);
    309        break;
    310    case PARA_REG_CTR:
    311        ret = s->control;
    312        break;
    313    }
    314    trace_parallel_ioport_read("SW", addr, ret);
    315    return ret;
    316}
    317
    318static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
    319{
    320    ParallelState *s = opaque;
    321    uint8_t ret = 0xff;
    322    addr &= 7;
    323    switch(addr) {
    324    case PARA_REG_DATA:
    325        qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
    326        if (s->last_read_offset != addr || s->datar != ret)
    327            pdebug("rd%02x\n", ret);
    328        s->datar = ret;
    329        break;
    330    case PARA_REG_STS:
    331        qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
    332        ret &= ~PARA_STS_TMOUT;
    333        if (s->epp_timeout)
    334            ret |= PARA_STS_TMOUT;
    335        if (s->last_read_offset != addr || s->status != ret)
    336            pdebug("rs%02x\n", ret);
    337        s->status = ret;
    338        break;
    339    case PARA_REG_CTR:
    340        /* s->control has some bits fixed to 1. It is zero only when
    341           it has not been yet written to.  */
    342        if (s->control == 0) {
    343            qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
    344            if (s->last_read_offset != addr)
    345                pdebug("rc%02x\n", ret);
    346            s->control = ret;
    347        }
    348        else {
    349            ret = s->control;
    350            if (s->last_read_offset != addr)
    351                pdebug("rc%02x\n", ret);
    352        }
    353        break;
    354    case PARA_REG_EPP_ADDR:
    355        if ((s->control & (PARA_CTR_DIR | PARA_CTR_SIGNAL)) !=
    356            (PARA_CTR_DIR | PARA_CTR_INIT))
    357            /* Controls not correct for EPP addr cycle, so do nothing */
    358            pdebug("ra%02x s\n", ret);
    359        else {
    360            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
    361            if (qemu_chr_fe_ioctl(&s->chr,
    362                                  CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
    363                s->epp_timeout = 1;
    364                pdebug("ra%02x t\n", ret);
    365            }
    366            else
    367                pdebug("ra%02x\n", ret);
    368        }
    369        break;
    370    case PARA_REG_EPP_DATA:
    371        if ((s->control & (PARA_CTR_DIR | PARA_CTR_SIGNAL)) !=
    372            (PARA_CTR_DIR | PARA_CTR_INIT))
    373            /* Controls not correct for EPP data cycle, so do nothing */
    374            pdebug("re%02x s\n", ret);
    375        else {
    376            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
    377            if (qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
    378                s->epp_timeout = 1;
    379                pdebug("re%02x t\n", ret);
    380            }
    381            else
    382                pdebug("re%02x\n", ret);
    383        }
    384        break;
    385    }
    386    trace_parallel_ioport_read("HW", addr, ret);
    387    s->last_read_offset = addr;
    388    return ret;
    389}
    390
    391static uint32_t
    392parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr)
    393{
    394    ParallelState *s = opaque;
    395    uint32_t ret;
    396    uint16_t eppdata = ~0;
    397    int err;
    398    struct ParallelIOArg ioarg = {
    399        .buffer = &eppdata, .count = sizeof(eppdata)
    400    };
    401    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
    402        /* Controls not correct for EPP data cycle, so do nothing */
    403        pdebug("re%04x s\n", eppdata);
    404        return eppdata;
    405    }
    406    err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
    407    ret = le16_to_cpu(eppdata);
    408
    409    if (err) {
    410        s->epp_timeout = 1;
    411        pdebug("re%04x t\n", ret);
    412    }
    413    else
    414        pdebug("re%04x\n", ret);
    415    trace_parallel_ioport_read("EPP", addr, ret);
    416    return ret;
    417}
    418
    419static uint32_t
    420parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr)
    421{
    422    ParallelState *s = opaque;
    423    uint32_t ret;
    424    uint32_t eppdata = ~0U;
    425    int err;
    426    struct ParallelIOArg ioarg = {
    427        .buffer = &eppdata, .count = sizeof(eppdata)
    428    };
    429    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
    430        /* Controls not correct for EPP data cycle, so do nothing */
    431        pdebug("re%08x s\n", eppdata);
    432        return eppdata;
    433    }
    434    err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
    435    ret = le32_to_cpu(eppdata);
    436
    437    if (err) {
    438        s->epp_timeout = 1;
    439        pdebug("re%08x t\n", ret);
    440    }
    441    else
    442        pdebug("re%08x\n", ret);
    443    trace_parallel_ioport_read("EPP", addr, ret);
    444    return ret;
    445}
    446
    447static void parallel_ioport_ecp_write(void *opaque, uint32_t addr, uint32_t val)
    448{
    449    trace_parallel_ioport_write("ECP", addr & 7, val);
    450    pdebug("wecp%d=%02x\n", addr & 7, val);
    451}
    452
    453static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
    454{
    455    uint8_t ret = 0xff;
    456
    457    trace_parallel_ioport_read("ECP", addr & 7, ret);
    458    pdebug("recp%d:%02x\n", addr & 7, ret);
    459    return ret;
    460}
    461
    462static void parallel_reset(void *opaque)
    463{
    464    ParallelState *s = opaque;
    465
    466    s->datar = ~0;
    467    s->dataw = ~0;
    468    s->status = PARA_STS_BUSY;
    469    s->status |= PARA_STS_ACK;
    470    s->status |= PARA_STS_ONLINE;
    471    s->status |= PARA_STS_ERROR;
    472    s->status |= PARA_STS_TMOUT;
    473    s->control = PARA_CTR_SELECT;
    474    s->control |= PARA_CTR_INIT;
    475    s->control |= 0xc0;
    476    s->irq_pending = 0;
    477    s->hw_driver = 0;
    478    s->epp_timeout = 0;
    479    s->last_read_offset = ~0U;
    480}
    481
    482static const int isa_parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
    483
    484static const MemoryRegionPortio isa_parallel_portio_hw_list[] = {
    485    { 0, 8, 1,
    486      .read = parallel_ioport_read_hw,
    487      .write = parallel_ioport_write_hw },
    488    { 4, 1, 2,
    489      .read = parallel_ioport_eppdata_read_hw2,
    490      .write = parallel_ioport_eppdata_write_hw2 },
    491    { 4, 1, 4,
    492      .read = parallel_ioport_eppdata_read_hw4,
    493      .write = parallel_ioport_eppdata_write_hw4 },
    494    { 0x400, 8, 1,
    495      .read = parallel_ioport_ecp_read,
    496      .write = parallel_ioport_ecp_write },
    497    PORTIO_END_OF_LIST(),
    498};
    499
    500static const MemoryRegionPortio isa_parallel_portio_sw_list[] = {
    501    { 0, 8, 1,
    502      .read = parallel_ioport_read_sw,
    503      .write = parallel_ioport_write_sw },
    504    PORTIO_END_OF_LIST(),
    505};
    506
    507
    508static const VMStateDescription vmstate_parallel_isa = {
    509    .name = "parallel_isa",
    510    .version_id = 1,
    511    .minimum_version_id = 1,
    512    .fields      = (VMStateField[]) {
    513        VMSTATE_UINT8(state.dataw, ISAParallelState),
    514        VMSTATE_UINT8(state.datar, ISAParallelState),
    515        VMSTATE_UINT8(state.status, ISAParallelState),
    516        VMSTATE_UINT8(state.control, ISAParallelState),
    517        VMSTATE_INT32(state.irq_pending, ISAParallelState),
    518        VMSTATE_INT32(state.epp_timeout, ISAParallelState),
    519        VMSTATE_END_OF_LIST()
    520    }
    521};
    522
    523static int parallel_can_receive(void *opaque)
    524{
    525     return 1;
    526}
    527
    528static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
    529{
    530    static int index;
    531    ISADevice *isadev = ISA_DEVICE(dev);
    532    ISAParallelState *isa = ISA_PARALLEL(dev);
    533    ParallelState *s = &isa->state;
    534    int base;
    535    uint8_t dummy;
    536
    537    if (!qemu_chr_fe_backend_connected(&s->chr)) {
    538        error_setg(errp, "Can't create parallel device, empty char device");
    539        return;
    540    }
    541
    542    if (isa->index == -1) {
    543        isa->index = index;
    544    }
    545    if (isa->index >= MAX_PARALLEL_PORTS) {
    546        error_setg(errp, "Max. supported number of parallel ports is %d.",
    547                   MAX_PARALLEL_PORTS);
    548        return;
    549    }
    550    if (isa->iobase == -1) {
    551        isa->iobase = isa_parallel_io[isa->index];
    552    }
    553    index++;
    554
    555    base = isa->iobase;
    556    isa_init_irq(isadev, &s->irq, isa->isairq);
    557    qemu_register_reset(parallel_reset, s);
    558
    559    qemu_chr_fe_set_handlers(&s->chr, parallel_can_receive, NULL,
    560                             NULL, NULL, s, NULL, true);
    561    if (qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
    562        s->hw_driver = 1;
    563        s->status = dummy;
    564    }
    565
    566    isa_register_portio_list(isadev, &s->portio_list, base,
    567                             (s->hw_driver
    568                              ? &isa_parallel_portio_hw_list[0]
    569                              : &isa_parallel_portio_sw_list[0]),
    570                             s, "parallel");
    571}
    572
    573static void parallel_isa_build_aml(ISADevice *isadev, Aml *scope)
    574{
    575    ISAParallelState *isa = ISA_PARALLEL(isadev);
    576    Aml *dev;
    577    Aml *crs;
    578
    579    crs = aml_resource_template();
    580    aml_append(crs, aml_io(AML_DECODE16, isa->iobase, isa->iobase, 0x08, 0x08));
    581    aml_append(crs, aml_irq_no_flags(isa->isairq));
    582
    583    dev = aml_device("LPT%d", isa->index + 1);
    584    aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0400")));
    585    aml_append(dev, aml_name_decl("_UID", aml_int(isa->index + 1)));
    586    aml_append(dev, aml_name_decl("_STA", aml_int(0xf)));
    587    aml_append(dev, aml_name_decl("_CRS", crs));
    588
    589    aml_append(scope, dev);
    590}
    591
    592/* Memory mapped interface */
    593static uint64_t parallel_mm_readfn(void *opaque, hwaddr addr, unsigned size)
    594{
    595    ParallelState *s = opaque;
    596
    597    return parallel_ioport_read_sw(s, addr >> s->it_shift) &
    598        MAKE_64BIT_MASK(0, size * 8);
    599}
    600
    601static void parallel_mm_writefn(void *opaque, hwaddr addr,
    602                                uint64_t value, unsigned size)
    603{
    604    ParallelState *s = opaque;
    605
    606    parallel_ioport_write_sw(s, addr >> s->it_shift,
    607                             value & MAKE_64BIT_MASK(0, size * 8));
    608}
    609
    610static const MemoryRegionOps parallel_mm_ops = {
    611    .read = parallel_mm_readfn,
    612    .write = parallel_mm_writefn,
    613    .valid.min_access_size = 1,
    614    .valid.max_access_size = 4,
    615    .endianness = DEVICE_NATIVE_ENDIAN,
    616};
    617
    618/* If fd is zero, it means that the parallel device uses the console */
    619bool parallel_mm_init(MemoryRegion *address_space,
    620                      hwaddr base, int it_shift, qemu_irq irq,
    621                      Chardev *chr)
    622{
    623    ParallelState *s;
    624
    625    s = g_malloc0(sizeof(ParallelState));
    626    s->irq = irq;
    627    qemu_chr_fe_init(&s->chr, chr, &error_abort);
    628    s->it_shift = it_shift;
    629    qemu_register_reset(parallel_reset, s);
    630
    631    memory_region_init_io(&s->iomem, NULL, &parallel_mm_ops, s,
    632                          "parallel", 8 << it_shift);
    633    memory_region_add_subregion(address_space, base, &s->iomem);
    634    return true;
    635}
    636
    637static Property parallel_isa_properties[] = {
    638    DEFINE_PROP_UINT32("index", ISAParallelState, index,   -1),
    639    DEFINE_PROP_UINT32("iobase", ISAParallelState, iobase,  -1),
    640    DEFINE_PROP_UINT32("irq",   ISAParallelState, isairq,  7),
    641    DEFINE_PROP_CHR("chardev",  ISAParallelState, state.chr),
    642    DEFINE_PROP_END_OF_LIST(),
    643};
    644
    645static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
    646{
    647    DeviceClass *dc = DEVICE_CLASS(klass);
    648    ISADeviceClass *isa = ISA_DEVICE_CLASS(klass);
    649
    650    dc->realize = parallel_isa_realizefn;
    651    dc->vmsd = &vmstate_parallel_isa;
    652    isa->build_aml = parallel_isa_build_aml;
    653    device_class_set_props(dc, parallel_isa_properties);
    654    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
    655}
    656
    657static const TypeInfo parallel_isa_info = {
    658    .name          = TYPE_ISA_PARALLEL,
    659    .parent        = TYPE_ISA_DEVICE,
    660    .instance_size = sizeof(ISAParallelState),
    661    .class_init    = parallel_isa_class_initfn,
    662};
    663
    664static void parallel_register_types(void)
    665{
    666    type_register_static(&parallel_isa_info);
    667}
    668
    669type_init(parallel_register_types)