Statistics
| Branch: | Revision:

root / hw / parallel.c @ a5f1b965

History | View | Annotate | Download (16 kB)

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

    
30
//#define DEBUG_PARALLEL
31

    
32
#ifdef DEBUG_PARALLEL
33
#define pdebug(fmt, arg...) printf("pp: " fmt, ##arg)
34
#else
35
#define pdebug(fmt, arg...) ((void)0)
36
#endif
37

    
38
#define PARA_REG_DATA 0
39
#define PARA_REG_STS 1
40
#define PARA_REG_CTR 2
41
#define PARA_REG_EPP_ADDR 3
42
#define PARA_REG_EPP_DATA 4
43

    
44
/*
45
 * These are the definitions for the Printer Status Register
46
 */
47
#define PARA_STS_BUSY        0x80        /* Busy complement */
48
#define PARA_STS_ACK        0x40        /* Acknowledge */
49
#define PARA_STS_PAPER        0x20        /* Out of paper */
50
#define PARA_STS_ONLINE        0x10        /* Online */
51
#define PARA_STS_ERROR        0x08        /* Error complement */
52
#define PARA_STS_TMOUT        0x01        /* EPP timeout */
53

    
54
/*
55
 * These are the definitions for the Printer Control Register
56
 */
57
#define PARA_CTR_DIR        0x20        /* Direction (1=read, 0=write) */
58
#define PARA_CTR_INTEN        0x10        /* IRQ Enable */
59
#define PARA_CTR_SELECT        0x08        /* Select In complement */
60
#define PARA_CTR_INIT        0x04        /* Initialize Printer complement */
61
#define PARA_CTR_AUTOLF        0x02        /* Auto linefeed complement */
62
#define PARA_CTR_STROBE        0x01        /* Strobe complement */
63

    
64
#define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
65

    
66
struct ParallelState {
67
    uint8_t dataw;
68
    uint8_t datar;
69
    uint8_t status;
70
    uint8_t control;
71
    qemu_irq irq;
72
    int irq_pending;
73
    CharDriverState *chr;
74
    int hw_driver;
75
    int epp_timeout;
76
    uint32_t last_read_offset; /* For debugging */
77
    /* Memory-mapped interface */
78
    target_phys_addr_t base;
79
    int it_shift;
80
};
81

    
82
static void parallel_update_irq(ParallelState *s)
83
{
84
    if (s->irq_pending)
85
        qemu_irq_raise(s->irq);
86
    else
87
        qemu_irq_lower(s->irq);
88
}
89

    
90
static void
91
parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
92
{
93
    ParallelState *s = opaque;
94

    
95
    pdebug("write addr=0x%02x val=0x%02x\n", addr, val);
96

    
97
    addr &= 7;
98
    switch(addr) {
99
    case PARA_REG_DATA:
100
        s->dataw = val;
101
        parallel_update_irq(s);
102
        break;
103
    case PARA_REG_CTR:
104
        val |= 0xc0;
105
        if ((val & PARA_CTR_INIT) == 0 ) {
106
            s->status = PARA_STS_BUSY;
107
            s->status |= PARA_STS_ACK;
108
            s->status |= PARA_STS_ONLINE;
109
            s->status |= PARA_STS_ERROR;
110
        }
111
        else if (val & PARA_CTR_SELECT) {
112
            if (val & PARA_CTR_STROBE) {
113
                s->status &= ~PARA_STS_BUSY;
114
                if ((s->control & PARA_CTR_STROBE) == 0)
115
                    qemu_chr_write(s->chr, &s->dataw, 1);
116
            } else {
117
                if (s->control & PARA_CTR_INTEN) {
118
                    s->irq_pending = 1;
119
                }
120
            }
121
        }
122
        parallel_update_irq(s);
123
        s->control = val;
124
        break;
125
    }
126
}
127

    
128
static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
129
{
130
    ParallelState *s = opaque;
131
    uint8_t parm = val;
132

    
133
    /* Sometimes programs do several writes for timing purposes on old
134
       HW. Take care not to waste time on writes that do nothing. */
135

    
136
    s->last_read_offset = ~0U;
137

    
138
    addr &= 7;
139
    switch(addr) {
140
    case PARA_REG_DATA:
141
        if (s->dataw == val)
142
            return;
143
        pdebug("wd%02x\n", val);
144
        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
145
        s->dataw = val;
146
        break;
147
    case PARA_REG_STS:
148
        pdebug("ws%02x\n", val);
149
        if (val & PARA_STS_TMOUT)
150
            s->epp_timeout = 0;
151
        break;
152
    case PARA_REG_CTR:
153
        val |= 0xc0;
154
        if (s->control == val)
155
            return;
156
        pdebug("wc%02x\n", val);
157
        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
158
        s->control = val;
159
        break;
160
    case PARA_REG_EPP_ADDR:
161
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
162
            /* Controls not correct for EPP address cycle, so do nothing */
163
            pdebug("wa%02x s\n", val);
164
        else {
165
            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
166
            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
167
                s->epp_timeout = 1;
168
                pdebug("wa%02x t\n", val);
169
            }
170
            else
171
                pdebug("wa%02x\n", val);
172
        }
173
        break;
174
    case PARA_REG_EPP_DATA:
175
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
176
            /* Controls not correct for EPP data cycle, so do nothing */
177
            pdebug("we%02x s\n", val);
178
        else {
179
            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
180
            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
181
                s->epp_timeout = 1;
182
                pdebug("we%02x t\n", val);
183
            }
184
            else
185
                pdebug("we%02x\n", val);
186
        }
187
        break;
188
    }
189
}
190

    
191
static void
192
parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val)
193
{
194
    ParallelState *s = opaque;
195
    uint16_t eppdata = cpu_to_le16(val);
196
    int err;
197
    struct ParallelIOArg ioarg = {
198
        .buffer = &eppdata, .count = sizeof(eppdata)
199
    };
200
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
201
        /* Controls not correct for EPP data cycle, so do nothing */
202
        pdebug("we%04x s\n", val);
203
        return;
204
    }
205
    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
206
    if (err) {
207
        s->epp_timeout = 1;
208
        pdebug("we%04x t\n", val);
209
    }
210
    else
211
        pdebug("we%04x\n", val);
212
}
213

    
214
static void
215
parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val)
216
{
217
    ParallelState *s = opaque;
218
    uint32_t eppdata = cpu_to_le32(val);
219
    int err;
220
    struct ParallelIOArg ioarg = {
221
        .buffer = &eppdata, .count = sizeof(eppdata)
222
    };
223
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
224
        /* Controls not correct for EPP data cycle, so do nothing */
225
        pdebug("we%08x s\n", val);
226
        return;
227
    }
228
    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
229
    if (err) {
230
        s->epp_timeout = 1;
231
        pdebug("we%08x t\n", val);
232
    }
233
    else
234
        pdebug("we%08x\n", val);
235
}
236

    
237
static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
238
{
239
    ParallelState *s = opaque;
240
    uint32_t ret = 0xff;
241

    
242
    addr &= 7;
243
    switch(addr) {
244
    case PARA_REG_DATA:
245
        if (s->control & PARA_CTR_DIR)
246
            ret = s->datar;
247
        else
248
            ret = s->dataw;
249
        break;
250
    case PARA_REG_STS:
251
        ret = s->status;
252
        s->irq_pending = 0;
253
        if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
254
            /* XXX Fixme: wait 5 microseconds */
255
            if (s->status & PARA_STS_ACK)
256
                s->status &= ~PARA_STS_ACK;
257
            else {
258
                /* XXX Fixme: wait 5 microseconds */
259
                s->status |= PARA_STS_ACK;
260
                s->status |= PARA_STS_BUSY;
261
            }
262
        }
263
        parallel_update_irq(s);
264
        break;
265
    case PARA_REG_CTR:
266
        ret = s->control;
267
        break;
268
    }
269
    pdebug("read addr=0x%02x val=0x%02x\n", addr, ret);
270
    return ret;
271
}
272

    
273
static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
274
{
275
    ParallelState *s = opaque;
276
    uint8_t ret = 0xff;
277
    addr &= 7;
278
    switch(addr) {
279
    case PARA_REG_DATA:
280
        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
281
        if (s->last_read_offset != addr || s->datar != ret)
282
            pdebug("rd%02x\n", ret);
283
        s->datar = ret;
284
        break;
285
    case PARA_REG_STS:
286
        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
287
        ret &= ~PARA_STS_TMOUT;
288
        if (s->epp_timeout)
289
            ret |= PARA_STS_TMOUT;
290
        if (s->last_read_offset != addr || s->status != ret)
291
            pdebug("rs%02x\n", ret);
292
        s->status = ret;
293
        break;
294
    case PARA_REG_CTR:
295
        /* s->control has some bits fixed to 1. It is zero only when
296
           it has not been yet written to.  */
297
        if (s->control == 0) {
298
            qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
299
            if (s->last_read_offset != addr)
300
                pdebug("rc%02x\n", ret);
301
            s->control = ret;
302
        }
303
        else {
304
            ret = s->control;
305
            if (s->last_read_offset != addr)
306
                pdebug("rc%02x\n", ret);
307
        }
308
        break;
309
    case PARA_REG_EPP_ADDR:
310
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
311
            /* Controls not correct for EPP addr cycle, so do nothing */
312
            pdebug("ra%02x s\n", ret);
313
        else {
314
            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
315
            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
316
                s->epp_timeout = 1;
317
                pdebug("ra%02x t\n", ret);
318
            }
319
            else
320
                pdebug("ra%02x\n", ret);
321
        }
322
        break;
323
    case PARA_REG_EPP_DATA:
324
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
325
            /* Controls not correct for EPP data cycle, so do nothing */
326
            pdebug("re%02x s\n", ret);
327
        else {
328
            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
329
            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
330
                s->epp_timeout = 1;
331
                pdebug("re%02x t\n", ret);
332
            }
333
            else
334
                pdebug("re%02x\n", ret);
335
        }
336
        break;
337
    }
338
    s->last_read_offset = addr;
339
    return ret;
340
}
341

    
342
static uint32_t
343
parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr)
344
{
345
    ParallelState *s = opaque;
346
    uint32_t ret;
347
    uint16_t eppdata = ~0;
348
    int err;
349
    struct ParallelIOArg ioarg = {
350
        .buffer = &eppdata, .count = sizeof(eppdata)
351
    };
352
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
353
        /* Controls not correct for EPP data cycle, so do nothing */
354
        pdebug("re%04x s\n", eppdata);
355
        return eppdata;
356
    }
357
    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
358
    ret = le16_to_cpu(eppdata);
359

    
360
    if (err) {
361
        s->epp_timeout = 1;
362
        pdebug("re%04x t\n", ret);
363
    }
364
    else
365
        pdebug("re%04x\n", ret);
366
    return ret;
367
}
368

    
369
static uint32_t
370
parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr)
371
{
372
    ParallelState *s = opaque;
373
    uint32_t ret;
374
    uint32_t eppdata = ~0U;
375
    int err;
376
    struct ParallelIOArg ioarg = {
377
        .buffer = &eppdata, .count = sizeof(eppdata)
378
    };
379
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
380
        /* Controls not correct for EPP data cycle, so do nothing */
381
        pdebug("re%08x s\n", eppdata);
382
        return eppdata;
383
    }
384
    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
385
    ret = le32_to_cpu(eppdata);
386

    
387
    if (err) {
388
        s->epp_timeout = 1;
389
        pdebug("re%08x t\n", ret);
390
    }
391
    else
392
        pdebug("re%08x\n", ret);
393
    return ret;
394
}
395

    
396
static void parallel_ioport_ecp_write(void *opaque, uint32_t addr, uint32_t val)
397
{
398
    addr &= 7;
399
    pdebug("wecp%d=%02x\n", addr, val);
400
}
401

    
402
static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
403
{
404
    uint8_t ret = 0xff;
405
    addr &= 7;
406
    pdebug("recp%d:%02x\n", addr, ret);
407
    return ret;
408
}
409

    
410
static void parallel_reset(ParallelState *s, qemu_irq irq, CharDriverState *chr)
411
{
412
    s->datar = ~0;
413
    s->dataw = ~0;
414
    s->status = PARA_STS_BUSY;
415
    s->status |= PARA_STS_ACK;
416
    s->status |= PARA_STS_ONLINE;
417
    s->status |= PARA_STS_ERROR;
418
    s->status |= PARA_STS_TMOUT;
419
    s->control = PARA_CTR_SELECT;
420
    s->control |= PARA_CTR_INIT;
421
    s->control |= 0xc0;
422
    s->irq = irq;
423
    s->irq_pending = 0;
424
    s->chr = chr;
425
    s->hw_driver = 0;
426
    s->epp_timeout = 0;
427
    s->last_read_offset = ~0U;
428
}
429

    
430
/* If fd is zero, it means that the parallel device uses the console */
431
ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr)
432
{
433
    ParallelState *s;
434
    uint8_t dummy;
435

    
436
    s = qemu_mallocz(sizeof(ParallelState));
437
    if (!s)
438
        return NULL;
439
    parallel_reset(s, irq, chr);
440

    
441
    if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
442
        s->hw_driver = 1;
443
        s->status = dummy;
444
    }
445

    
446
    if (s->hw_driver) {
447
        register_ioport_write(base, 8, 1, parallel_ioport_write_hw, s);
448
        register_ioport_read(base, 8, 1, parallel_ioport_read_hw, s);
449
        register_ioport_write(base+4, 1, 2, parallel_ioport_eppdata_write_hw2, s);
450
        register_ioport_read(base+4, 1, 2, parallel_ioport_eppdata_read_hw2, s);
451
        register_ioport_write(base+4, 1, 4, parallel_ioport_eppdata_write_hw4, s);
452
        register_ioport_read(base+4, 1, 4, parallel_ioport_eppdata_read_hw4, s);
453
        register_ioport_write(base+0x400, 8, 1, parallel_ioport_ecp_write, s);
454
        register_ioport_read(base+0x400, 8, 1, parallel_ioport_ecp_read, s);
455
    }
456
    else {
457
        register_ioport_write(base, 8, 1, parallel_ioport_write_sw, s);
458
        register_ioport_read(base, 8, 1, parallel_ioport_read_sw, s);
459
    }
460
    return s;
461
}
462

    
463
/* Memory mapped interface */
464
static uint32_t parallel_mm_readb (void *opaque, target_phys_addr_t addr)
465
{
466
    ParallelState *s = opaque;
467

    
468
    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift) & 0xFF;
469
}
470

    
471
static void parallel_mm_writeb (void *opaque,
472
                                target_phys_addr_t addr, uint32_t value)
473
{
474
    ParallelState *s = opaque;
475

    
476
    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value & 0xFF);
477
}
478

    
479
static uint32_t parallel_mm_readw (void *opaque, target_phys_addr_t addr)
480
{
481
    ParallelState *s = opaque;
482

    
483
    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
484
}
485

    
486
static void parallel_mm_writew (void *opaque,
487
                                target_phys_addr_t addr, uint32_t value)
488
{
489
    ParallelState *s = opaque;
490

    
491
    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value & 0xFFFF);
492
}
493

    
494
static uint32_t parallel_mm_readl (void *opaque, target_phys_addr_t addr)
495
{
496
    ParallelState *s = opaque;
497

    
498
    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift);
499
}
500

    
501
static void parallel_mm_writel (void *opaque,
502
                                target_phys_addr_t addr, uint32_t value)
503
{
504
    ParallelState *s = opaque;
505

    
506
    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value);
507
}
508

    
509
static CPUReadMemoryFunc *parallel_mm_read_sw[] = {
510
    &parallel_mm_readb,
511
    &parallel_mm_readw,
512
    &parallel_mm_readl,
513
};
514

    
515
static CPUWriteMemoryFunc *parallel_mm_write_sw[] = {
516
    &parallel_mm_writeb,
517
    &parallel_mm_writew,
518
    &parallel_mm_writel,
519
};
520

    
521
/* If fd is zero, it means that the parallel device uses the console */
522
ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, CharDriverState *chr)
523
{
524
    ParallelState *s;
525
    int io_sw;
526

    
527
    s = qemu_mallocz(sizeof(ParallelState));
528
    if (!s)
529
        return NULL;
530
    parallel_reset(s, irq, chr);
531
    s->base = base;
532
    s->it_shift = it_shift;
533

    
534
    io_sw = cpu_register_io_memory(0, parallel_mm_read_sw, parallel_mm_write_sw, s);
535
    cpu_register_physical_memory(base, 8 << it_shift, io_sw);
536
    return s;
537
}