Statistics
| Branch: | Revision:

root / hw / parallel.c @ 5fafdf24

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 "vl.h"
26

    
27
//#define DEBUG_PARALLEL
28

    
29
#ifdef DEBUG_PARALLEL
30
#define pdebug(fmt, arg...) printf("pp: " fmt, ##arg)
31
#else
32
#define pdebug(fmt, arg...) ((void)0)
33
#endif
34

    
35
#define PARA_REG_DATA 0
36
#define PARA_REG_STS 1
37
#define PARA_REG_CTR 2
38
#define PARA_REG_EPP_ADDR 3
39
#define PARA_REG_EPP_DATA 4
40

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

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

    
61
#define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
62

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

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

    
87
static void
88
parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
89
{
90
    ParallelState *s = opaque;
91
   
92
    pdebug("write addr=0x%02x val=0x%02x\n", addr, val);
93

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

    
124
static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
125
{
126
    ParallelState *s = opaque;
127
    uint8_t parm = val;
128

    
129
    /* Sometimes programs do several writes for timing purposes on old
130
       HW. Take care not to waste time on writes that do nothing. */
131

    
132
    s->last_read_offset = ~0U;
133

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

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

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

    
233
static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
234
{
235
    ParallelState *s = opaque;
236
    uint32_t ret = 0xff;
237

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

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

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

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

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

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

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

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

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

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

    
430
    s = qemu_mallocz(sizeof(ParallelState));
431
    if (!s)
432
        return NULL;
433
    parallel_reset(s, irq, chr);
434

    
435
    if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
436
        s->hw_driver = 1;
437
        s->status = dummy;
438
    }
439

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

    
457
/* Memory mapped interface */
458
uint32_t parallel_mm_readb (void *opaque, target_phys_addr_t addr)
459
{
460
    ParallelState *s = opaque;
461

    
462
    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift) & 0xFF;
463
}
464

    
465
void parallel_mm_writeb (void *opaque,
466
                       target_phys_addr_t addr, uint32_t value)
467
{
468
    ParallelState *s = opaque;
469

    
470
    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value & 0xFF);
471
}
472

    
473
uint32_t parallel_mm_readw (void *opaque, target_phys_addr_t addr)
474
{
475
    ParallelState *s = opaque;
476

    
477
    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
478
}
479

    
480
void parallel_mm_writew (void *opaque,
481
                       target_phys_addr_t addr, uint32_t value)
482
{
483
    ParallelState *s = opaque;
484

    
485
    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value & 0xFFFF);
486
}
487

    
488
uint32_t parallel_mm_readl (void *opaque, target_phys_addr_t addr)
489
{
490
    ParallelState *s = opaque;
491

    
492
    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift);
493
}
494

    
495
void parallel_mm_writel (void *opaque,
496
                       target_phys_addr_t addr, uint32_t value)
497
{
498
    ParallelState *s = opaque;
499

    
500
    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value);
501
}
502

    
503
static CPUReadMemoryFunc *parallel_mm_read_sw[] = {
504
    &parallel_mm_readb,
505
    &parallel_mm_readw,
506
    &parallel_mm_readl,
507
};
508

    
509
static CPUWriteMemoryFunc *parallel_mm_write_sw[] = {
510
    &parallel_mm_writeb,
511
    &parallel_mm_writew,
512
    &parallel_mm_writel,
513
};
514

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

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

    
528
    io_sw = cpu_register_io_memory(0, parallel_mm_read_sw, parallel_mm_write_sw, s);
529
    cpu_register_physical_memory(base, 8 << it_shift, io_sw);
530
    return s;
531
}