Statistics
| Branch: | Revision:

root / hw / parallel.c @ 87ecb68b

History | View | Annotate | Download (15.8 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
        if ((val & PARA_CTR_INIT) == 0 ) {
105
            s->status = PARA_STS_BUSY;
106
            s->status |= PARA_STS_ACK;
107
            s->status |= PARA_STS_ONLINE;
108
            s->status |= PARA_STS_ERROR;
109
        }
110
        else if (val & PARA_CTR_SELECT) {
111
            if (val & PARA_CTR_STROBE) {
112
                s->status &= ~PARA_STS_BUSY;
113
                if ((s->control & PARA_CTR_STROBE) == 0)
114
                    qemu_chr_write(s->chr, &s->dataw, 1);
115
            } else {
116
                if (s->control & PARA_CTR_INTEN) {
117
                    s->irq_pending = 1;
118
                }
119
            }
120
        }
121
        parallel_update_irq(s);
122
        s->control = val;
123
        break;
124
    }
125
}
126

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

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

    
135
    s->last_read_offset = ~0U;
136

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
433
    s = qemu_mallocz(sizeof(ParallelState));
434
    if (!s)
435
        return NULL;
436
    parallel_reset(s, irq, chr);
437

    
438
    if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
439
        s->hw_driver = 1;
440
        s->status = dummy;
441
    }
442

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

    
460
/* Memory mapped interface */
461
uint32_t parallel_mm_readb (void *opaque, target_phys_addr_t addr)
462
{
463
    ParallelState *s = opaque;
464

    
465
    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift) & 0xFF;
466
}
467

    
468
void parallel_mm_writeb (void *opaque,
469
                       target_phys_addr_t addr, uint32_t value)
470
{
471
    ParallelState *s = opaque;
472

    
473
    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value & 0xFF);
474
}
475

    
476
uint32_t parallel_mm_readw (void *opaque, target_phys_addr_t addr)
477
{
478
    ParallelState *s = opaque;
479

    
480
    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
481
}
482

    
483
void parallel_mm_writew (void *opaque,
484
                       target_phys_addr_t addr, uint32_t value)
485
{
486
    ParallelState *s = opaque;
487

    
488
    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value & 0xFFFF);
489
}
490

    
491
uint32_t parallel_mm_readl (void *opaque, target_phys_addr_t addr)
492
{
493
    ParallelState *s = opaque;
494

    
495
    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift);
496
}
497

    
498
void parallel_mm_writel (void *opaque,
499
                       target_phys_addr_t addr, uint32_t value)
500
{
501
    ParallelState *s = opaque;
502

    
503
    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value);
504
}
505

    
506
static CPUReadMemoryFunc *parallel_mm_read_sw[] = {
507
    &parallel_mm_readb,
508
    &parallel_mm_readw,
509
    &parallel_mm_readl,
510
};
511

    
512
static CPUWriteMemoryFunc *parallel_mm_write_sw[] = {
513
    &parallel_mm_writeb,
514
    &parallel_mm_writew,
515
    &parallel_mm_writel,
516
};
517

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

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

    
531
    io_sw = cpu_register_io_memory(0, parallel_mm_read_sw, parallel_mm_write_sw, s);
532
    cpu_register_physical_memory(base, 8 << it_shift, io_sw);
533
    return s;
534
}