~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to hw/parallel.c

Tags: upstream-0.9.0+20070816
ImportĀ upstreamĀ versionĀ 0.9.0+20070816

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * QEMU Parallel PORT emulation
3
3
 * 
4
4
 * Copyright (c) 2003-2005 Fabrice Bellard
 
5
 * Copyright (c) 2007 Marko Kohtala
5
6
 * 
6
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
8
 * of this software and associated documentation files (the "Software"), to deal
25
26
 
26
27
//#define DEBUG_PARALLEL
27
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
 
28
41
/*
29
42
 * These are the definitions for the Printer Status Register
30
43
 */
33
46
#define PARA_STS_PAPER  0x20    /* Out of paper */
34
47
#define PARA_STS_ONLINE 0x10    /* Online */
35
48
#define PARA_STS_ERROR  0x08    /* Error complement */
 
49
#define PARA_STS_TMOUT  0x01    /* EPP timeout */
36
50
 
37
51
/*
38
52
 * These are the definitions for the Printer Control Register
39
53
 */
 
54
#define PARA_CTR_DIR    0x20    /* Direction (1=read, 0=write) */
40
55
#define PARA_CTR_INTEN  0x10    /* IRQ Enable */
41
56
#define PARA_CTR_SELECT 0x08    /* Select In complement */
42
57
#define PARA_CTR_INIT   0x04    /* Initialize Printer complement */
43
58
#define PARA_CTR_AUTOLF 0x02    /* Auto linefeed complement */
44
59
#define PARA_CTR_STROBE 0x01    /* Strobe complement */
45
60
 
 
61
#define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
 
62
 
46
63
struct ParallelState {
47
 
    uint8_t data;
48
 
    uint8_t status; /* read only register */
 
64
    uint8_t dataw;
 
65
    uint8_t datar;
 
66
    uint8_t status;
49
67
    uint8_t control;
50
 
    int irq;
 
68
    qemu_irq irq;
51
69
    int irq_pending;
52
70
    CharDriverState *chr;
53
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;
54
77
};
55
78
 
56
79
static void parallel_update_irq(ParallelState *s)
57
80
{
58
81
    if (s->irq_pending)
59
 
        pic_set_irq(s->irq, 1);
 
82
        qemu_irq_raise(s->irq);
60
83
    else
61
 
        pic_set_irq(s->irq, 0);
 
84
        qemu_irq_lower(s->irq);
62
85
}
63
86
 
64
 
static void parallel_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 
87
static void
 
88
parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
65
89
{
66
90
    ParallelState *s = opaque;
67
91
    
 
92
    pdebug("write addr=0x%02x val=0x%02x\n", addr, val);
 
93
 
68
94
    addr &= 7;
69
 
#ifdef DEBUG_PARALLEL
70
 
    printf("parallel: write addr=0x%02x val=0x%02x\n", addr, val);
71
 
#endif
72
95
    switch(addr) {
73
 
    case 0:
74
 
        if (s->hw_driver) {
75
 
            s->data = val;
76
 
            qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &s->data);
77
 
        } else {
78
 
            s->data = val;
79
 
            parallel_update_irq(s);
 
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;
80
106
        }
81
 
        break;
82
 
    case 2:
83
 
        if (s->hw_driver) {
84
 
            s->control = val;
85
 
            qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &s->control);
86
 
        } else {
87
 
            if ((val & PARA_CTR_INIT) == 0 ) {
88
 
                s->status = PARA_STS_BUSY;
89
 
                s->status |= PARA_STS_ACK;
90
 
                s->status |= PARA_STS_ONLINE;
91
 
                s->status |= PARA_STS_ERROR;
92
 
            }
93
 
            else if (val & PARA_CTR_SELECT) {
94
 
                if (val & PARA_CTR_STROBE) {
95
 
                    s->status &= ~PARA_STS_BUSY;
96
 
                    if ((s->control & PARA_CTR_STROBE) == 0)
97
 
                        qemu_chr_write(s->chr, &s->data, 1);
98
 
                } else {
99
 
                    if (s->control & PARA_CTR_INTEN) {
100
 
                        s->irq_pending = 1;
101
 
                    }
 
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;
102
115
                }
103
116
            }
104
 
            parallel_update_irq(s);
105
 
            s->control = val;
106
 
        }
107
 
        break;
108
 
    }
109
 
}
110
 
 
111
 
static uint32_t parallel_ioport_read(void *opaque, uint32_t addr)
 
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)
112
234
{
113
235
    ParallelState *s = opaque;
114
236
    uint32_t ret = 0xff;
115
237
 
116
238
    addr &= 7;
117
239
    switch(addr) {
118
 
    case 0:
119
 
        if (s->hw_driver) {
120
 
            qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &s->data);
121
 
        } 
122
 
        ret = s->data; 
 
240
    case PARA_REG_DATA:
 
241
        if (s->control & PARA_CTR_DIR)
 
242
            ret = s->datar;
 
243
        else
 
244
            ret = s->dataw;
123
245
        break;
124
 
    case 1:
125
 
        if (s->hw_driver) {
126
 
            qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &s->status);
127
 
            ret = s->status; 
128
 
        } else {
129
 
            ret = s->status;
130
 
            s->irq_pending = 0;
131
 
            if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
 
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 {
132
254
                /* XXX Fixme: wait 5 microseconds */
133
 
                if (s->status & PARA_STS_ACK)
134
 
                    s->status &= ~PARA_STS_ACK;
135
 
                else {
136
 
                    /* XXX Fixme: wait 5 microseconds */
137
 
                    s->status |= PARA_STS_ACK;
138
 
                    s->status |= PARA_STS_BUSY;
139
 
                }
 
255
                s->status |= PARA_STS_ACK;
 
256
                s->status |= PARA_STS_BUSY;
140
257
            }
141
 
            parallel_update_irq(s);
142
258
        }
 
259
        parallel_update_irq(s);
143
260
        break;
144
 
    case 2:
145
 
        if (s->hw_driver) {
146
 
            qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &s->control);
147
 
        }
 
261
    case PARA_REG_CTR:
148
262
        ret = s->control;
149
263
        break;
150
264
    }
151
 
#ifdef DEBUG_PARALLEL
152
 
    printf("parallel: read addr=0x%02x val=0x%02x\n", addr, ret);
153
 
#endif
154
 
    return ret;
155
 
}
156
 
 
157
 
/* If fd is zero, it means that the parallel device uses the console */
158
 
ParallelState *parallel_init(int base, int irq, CharDriverState *chr)
159
 
{
160
 
    ParallelState *s;
161
 
    uint8_t dummy;
162
 
 
163
 
    s = qemu_mallocz(sizeof(ParallelState));
164
 
    if (!s)
165
 
        return NULL;
166
 
    s->chr = chr;
167
 
    s->hw_driver = 0;
168
 
    if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0)
169
 
        s->hw_driver = 1;
170
 
 
171
 
    s->irq = irq;
172
 
    s->data = 0;
 
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;
173
410
    s->status = PARA_STS_BUSY;
174
411
    s->status |= PARA_STS_ACK;
175
412
    s->status |= PARA_STS_ONLINE;
176
413
    s->status |= PARA_STS_ERROR;
177
414
    s->control = PARA_CTR_SELECT;
178
415
    s->control |= PARA_CTR_INIT;
179
 
 
180
 
    register_ioport_write(base, 8, 1, parallel_ioport_write, s);
181
 
    register_ioport_read(base, 8, 1, parallel_ioport_read, s);
 
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);
182
530
    return s;
183
531
}