rtoss - Blame information for rev 79

Subversion Repositories:
Rev:
Rev Author Line No. Line
74 roytam 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, ...) printf("pp: " fmt, ## __VA_ARGS__)
34 #else
35 #define pdebug(fmt, ...) ((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     int it_shift;
79 };
80  
77 roytam 81 typedef struct ISAParallelState {
82     ISADevice dev;
79 roytam 83     uint32_t index;
77 roytam 84     uint32_t iobase;
85     uint32_t isairq;
86     ParallelState state;
87 } ISAParallelState;
88  
74 roytam 89 static void parallel_update_irq(ParallelState *s)
90 {
91     if (s->irq_pending)
92         qemu_irq_raise(s->irq);
93     else
94         qemu_irq_lower(s->irq);
95 }
96  
97 static void
98 parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
99 {
100     ParallelState *s = opaque;
101  
102     pdebug("write addr=0x%02x val=0x%02x\n", addr, val);
103  
104     addr &= 7;
105     switch(addr) {
106     case PARA_REG_DATA:
107         s->dataw = val;
108         parallel_update_irq(s);
109         break;
110     case PARA_REG_CTR:
111         val |= 0xc0;
112         if ((val & PARA_CTR_INIT) == 0 ) {
113             s->status = PARA_STS_BUSY;
114             s->status |= PARA_STS_ACK;
115             s->status |= PARA_STS_ONLINE;
116             s->status |= PARA_STS_ERROR;
117         }
118         else if (val & PARA_CTR_SELECT) {
119             if (val & PARA_CTR_STROBE) {
120                 s->status &= ~PARA_STS_BUSY;
121                 if ((s->control & PARA_CTR_STROBE) == 0)
122                     qemu_chr_write(s->chr, &s->dataw, 1);
123             } else {
124                 if (s->control & PARA_CTR_INTEN) {
125                     s->irq_pending = 1;
126                 }
127             }
128         }
129         parallel_update_irq(s);
130         s->control = val;
131         break;
132     }
133 }
134  
135 static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
136 {
137     ParallelState *s = opaque;
138     uint8_t parm = val;
139     int dir;
140  
141     /* Sometimes programs do several writes for timing purposes on old
142        HW. Take care not to waste time on writes that do nothing. */
143  
144     s->last_read_offset = ~0U;
145  
146     addr &= 7;
147     switch(addr) {
148     case PARA_REG_DATA:
149         if (s->dataw == val)
150             return;
151         pdebug("wd%02x\n", val);
152         qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
153         s->dataw = val;
154         break;
155     case PARA_REG_STS:
156         pdebug("ws%02x\n", val);
157         if (val & PARA_STS_TMOUT)
158             s->epp_timeout = 0;
159         break;
160     case PARA_REG_CTR:
161         val |= 0xc0;
162         if (s->control == val)
163             return;
164         pdebug("wc%02x\n", val);
165  
166         if ((val & PARA_CTR_DIR) != (s->control & PARA_CTR_DIR)) {
167             if (val & PARA_CTR_DIR) {
168                 dir = 1;
169             } else {
170                 dir = 0;
171             }
172             qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
173             parm &= ~PARA_CTR_DIR;
174         }
175  
176         qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
177         s->control = val;
178         break;
179     case PARA_REG_EPP_ADDR:
180         if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
181             /* Controls not correct for EPP address cycle, so do nothing */
182             pdebug("wa%02x s\n", val);
183         else {
184             struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
185             if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
186                 s->epp_timeout = 1;
187                 pdebug("wa%02x t\n", val);
188             }
189             else
190                 pdebug("wa%02x\n", val);
191         }
192         break;
193     case PARA_REG_EPP_DATA:
194         if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
195             /* Controls not correct for EPP data cycle, so do nothing */
196             pdebug("we%02x s\n", val);
197         else {
198             struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
199             if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
200                 s->epp_timeout = 1;
201                 pdebug("we%02x t\n", val);
202             }
203             else
204                 pdebug("we%02x\n", val);
205         }
206         break;
207     }
208 }
209  
210 static void
211 parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val)
212 {
213     ParallelState *s = opaque;
214     uint16_t eppdata = cpu_to_le16(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%04x 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%04x t\n", val);
228     }
229     else
230         pdebug("we%04x\n", val);
231 }
232  
233 static void
234 parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val)
235 {
236     ParallelState *s = opaque;
237     uint32_t eppdata = cpu_to_le32(val);
238     int err;
239     struct ParallelIOArg ioarg = {
240         .buffer = &eppdata, .count = sizeof(eppdata)
241     };
242     if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
243         /* Controls not correct for EPP data cycle, so do nothing */
244         pdebug("we%08x s\n", val);
245         return;
246     }
247     err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
248     if (err) {
249         s->epp_timeout = 1;
250         pdebug("we%08x t\n", val);
251     }
252     else
253         pdebug("we%08x\n", val);
254 }
255  
256 static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
257 {
258     ParallelState *s = opaque;
259     uint32_t ret = 0xff;
260  
261     addr &= 7;
262     switch(addr) {
263     case PARA_REG_DATA:
264         if (s->control & PARA_CTR_DIR)
265             ret = s->datar;
266         else
267             ret = s->dataw;
268         break;
269     case PARA_REG_STS:
270         ret = s->status;
271         s->irq_pending = 0;
272         if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
273             /* XXX Fixme: wait 5 microseconds */
274             if (s->status & PARA_STS_ACK)
275                 s->status &= ~PARA_STS_ACK;
276             else {
277                 /* XXX Fixme: wait 5 microseconds */
278                 s->status |= PARA_STS_ACK;
279                 s->status |= PARA_STS_BUSY;
280             }
281         }
282         parallel_update_irq(s);
283         break;
284     case PARA_REG_CTR:
285         ret = s->control;
286         break;
287     }
288     pdebug("read addr=0x%02x val=0x%02x\n", addr, ret);
289     return ret;
290 }
291  
292 static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
293 {
294     ParallelState *s = opaque;
295     uint8_t ret = 0xff;
296     addr &= 7;
297     switch(addr) {
298     case PARA_REG_DATA:
299         qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
300         if (s->last_read_offset != addr || s->datar != ret)
301             pdebug("rd%02x\n", ret);
302         s->datar = ret;
303         break;
304     case PARA_REG_STS:
305         qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
306         ret &= ~PARA_STS_TMOUT;
307         if (s->epp_timeout)
308             ret |= PARA_STS_TMOUT;
309         if (s->last_read_offset != addr || s->status != ret)
310             pdebug("rs%02x\n", ret);
311         s->status = ret;
312         break;
313     case PARA_REG_CTR:
314         /* s->control has some bits fixed to 1. It is zero only when
315            it has not been yet written to.  */
316         if (s->control == 0) {
317             qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
318             if (s->last_read_offset != addr)
319                 pdebug("rc%02x\n", ret);
320             s->control = ret;
321         }
322         else {
323             ret = s->control;
324             if (s->last_read_offset != addr)
325                 pdebug("rc%02x\n", ret);
326         }
327         break;
328     case PARA_REG_EPP_ADDR:
329         if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
330             /* Controls not correct for EPP addr cycle, so do nothing */
331             pdebug("ra%02x s\n", ret);
332         else {
333             struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
334             if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
335                 s->epp_timeout = 1;
336                 pdebug("ra%02x t\n", ret);
337             }
338             else
339                 pdebug("ra%02x\n", ret);
340         }
341         break;
342     case PARA_REG_EPP_DATA:
343         if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
344             /* Controls not correct for EPP data cycle, so do nothing */
345             pdebug("re%02x s\n", ret);
346         else {
347             struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
348             if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
349                 s->epp_timeout = 1;
350                 pdebug("re%02x t\n", ret);
351             }
352             else
353                 pdebug("re%02x\n", ret);
354         }
355         break;
356     }
357     s->last_read_offset = addr;
358     return ret;
359 }
360  
361 static uint32_t
362 parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr)
363 {
364     ParallelState *s = opaque;
365     uint32_t ret;
366     uint16_t eppdata = ~0;
367     int err;
368     struct ParallelIOArg ioarg = {
369         .buffer = &eppdata, .count = sizeof(eppdata)
370     };
371     if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
372         /* Controls not correct for EPP data cycle, so do nothing */
373         pdebug("re%04x s\n", eppdata);
374         return eppdata;
375     }
376     err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
377     ret = le16_to_cpu(eppdata);
378  
379     if (err) {
380         s->epp_timeout = 1;
381         pdebug("re%04x t\n", ret);
382     }
383     else
384         pdebug("re%04x\n", ret);
385     return ret;
386 }
387  
388 static uint32_t
389 parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr)
390 {
391     ParallelState *s = opaque;
392     uint32_t ret;
393     uint32_t eppdata = ~0U;
394     int err;
395     struct ParallelIOArg ioarg = {
396         .buffer = &eppdata, .count = sizeof(eppdata)
397     };
398     if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
399         /* Controls not correct for EPP data cycle, so do nothing */
400         pdebug("re%08x s\n", eppdata);
401         return eppdata;
402     }
403     err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
404     ret = le32_to_cpu(eppdata);
405  
406     if (err) {
407         s->epp_timeout = 1;
408         pdebug("re%08x t\n", ret);
409     }
410     else
411         pdebug("re%08x\n", ret);
412     return ret;
413 }
414  
415 static void parallel_ioport_ecp_write(void *opaque, uint32_t addr, uint32_t val)
416 {
417     addr &= 7;
418     pdebug("wecp%d=%02x\n", addr, val);
419 }
420  
421 static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
422 {
423     uint8_t ret = 0xff;
424     addr &= 7;
425     pdebug("recp%d:%02x\n", addr, ret);
426     return ret;
427 }
428  
429 static 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  
79 roytam 449 static const int isa_parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
450  
77 roytam 451 static int parallel_isa_initfn(ISADevice *dev)
74 roytam 452 {
79 roytam 453     static int index;
77 roytam 454     ISAParallelState *isa = DO_UPCAST(ISAParallelState, dev, dev);
455     ParallelState *s = &isa->state;
79 roytam 456     int base;
74 roytam 457     uint8_t dummy;
458  
77 roytam 459     if (!s->chr) {
460         fprintf(stderr, "Can't create parallel device, empty char device\n");
461         exit(1);
462     }
463  
79 roytam 464     if (isa->index == -1)
465         isa->index = index;
466     if (isa->index >= MAX_PARALLEL_PORTS)
467         return -1;
468     if (isa->iobase == -1)
469         isa->iobase = isa_parallel_io[isa->index];
470     index++;
471  
472     base = isa->iobase;
77 roytam 473     isa_init_irq(dev, &s->irq, isa->isairq);
74 roytam 474     parallel_reset(s);
475     qemu_register_reset(parallel_reset, s);
476  
77 roytam 477     if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
74 roytam 478         s->hw_driver = 1;
479         s->status = dummy;
480     }
481  
482     if (s->hw_driver) {
483         register_ioport_write(base, 8, 1, parallel_ioport_write_hw, s);
484         register_ioport_read(base, 8, 1, parallel_ioport_read_hw, s);
485         register_ioport_write(base+4, 1, 2, parallel_ioport_eppdata_write_hw2, s);
486         register_ioport_read(base+4, 1, 2, parallel_ioport_eppdata_read_hw2, s);
487         register_ioport_write(base+4, 1, 4, parallel_ioport_eppdata_write_hw4, s);
488         register_ioport_read(base+4, 1, 4, parallel_ioport_eppdata_read_hw4, s);
489         register_ioport_write(base+0x400, 8, 1, parallel_ioport_ecp_write, s);
490         register_ioport_read(base+0x400, 8, 1, parallel_ioport_ecp_read, s);
491     }
492     else {
493         register_ioport_write(base, 8, 1, parallel_ioport_write_sw, s);
494         register_ioport_read(base, 8, 1, parallel_ioport_read_sw, s);
495     }
77 roytam 496     return 0;
74 roytam 497 }
498  
77 roytam 499 ParallelState *parallel_init(int index, CharDriverState *chr)
500 {
501     ISADevice *dev;
502  
503     dev = isa_create("isa-parallel");
79 roytam 504     qdev_prop_set_uint32(&dev->qdev, "index", index);
77 roytam 505     qdev_prop_set_chr(&dev->qdev, "chardev", chr);
506     if (qdev_init(&dev->qdev) < 0)
507         return NULL;
508     return &DO_UPCAST(ISAParallelState, dev, dev)->state;
509 }
510  
74 roytam 511 /* Memory mapped interface */
512 static uint32_t parallel_mm_readb (void *opaque, target_phys_addr_t addr)
513 {
514     ParallelState *s = opaque;
515  
516     return parallel_ioport_read_sw(s, addr >> s->it_shift) & 0xFF;
517 }
518  
519 static void parallel_mm_writeb (void *opaque,
520                                 target_phys_addr_t addr, uint32_t value)
521 {
522     ParallelState *s = opaque;
523  
524     parallel_ioport_write_sw(s, addr >> s->it_shift, value & 0xFF);
525 }
526  
527 static uint32_t parallel_mm_readw (void *opaque, target_phys_addr_t addr)
528 {
529     ParallelState *s = opaque;
530  
531     return parallel_ioport_read_sw(s, addr >> s->it_shift) & 0xFFFF;
532 }
533  
534 static void parallel_mm_writew (void *opaque,
535                                 target_phys_addr_t addr, uint32_t value)
536 {
537     ParallelState *s = opaque;
538  
539     parallel_ioport_write_sw(s, addr >> s->it_shift, value & 0xFFFF);
540 }
541  
542 static uint32_t parallel_mm_readl (void *opaque, target_phys_addr_t addr)
543 {
544     ParallelState *s = opaque;
545  
546     return parallel_ioport_read_sw(s, addr >> s->it_shift);
547 }
548  
549 static void parallel_mm_writel (void *opaque,
550                                 target_phys_addr_t addr, uint32_t value)
551 {
552     ParallelState *s = opaque;
553  
554     parallel_ioport_write_sw(s, addr >> s->it_shift, value);
555 }
556  
557 static CPUReadMemoryFunc * const parallel_mm_read_sw[] = {
558     &parallel_mm_readb,
559     &parallel_mm_readw,
560     &parallel_mm_readl,
561 };
562  
563 static CPUWriteMemoryFunc * const parallel_mm_write_sw[] = {
564     &parallel_mm_writeb,
565     &parallel_mm_writew,
566     &parallel_mm_writel,
567 };
568  
569 /* If fd is zero, it means that the parallel device uses the console */
570 ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, CharDriverState *chr)
571 {
572     ParallelState *s;
573     int io_sw;
574  
575     s = qemu_mallocz(sizeof(ParallelState));
576     s->irq = irq;
577     s->chr = chr;
578     s->it_shift = it_shift;
579     parallel_reset(s);
580     qemu_register_reset(parallel_reset, s);
581  
582     io_sw = cpu_register_io_memory(parallel_mm_read_sw, parallel_mm_write_sw, s);
583     cpu_register_physical_memory(base, 8 << it_shift, io_sw);
584     return s;
585 }
77 roytam 586  
587 static ISADeviceInfo parallel_isa_info = {
588     .qdev.name  = "isa-parallel",
589     .qdev.size  = sizeof(ISAParallelState),
590     .init       = parallel_isa_initfn,
591     .qdev.props = (Property[]) {
79 roytam 592         DEFINE_PROP_HEX32("index",  ISAParallelState, index,   -1),
593         DEFINE_PROP_HEX32("iobase", ISAParallelState, iobase,  -1),
77 roytam 594         DEFINE_PROP_UINT32("irq",   ISAParallelState, isairq,  7),
595         DEFINE_PROP_CHR("chardev",  ISAParallelState, state.chr),
596         DEFINE_PROP_END_OF_LIST(),
597     },
598 };
599  
600 static void parallel_register_devices(void)
601 {
602     isa_qdev_register(&parallel_isa_info);
603 }
604  
605 device_init(parallel_register_devices)