~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/rc4030.c

  • Committer: blueswir1
  • Date: 2007-09-25 17:28:42 UTC
  • Revision ID: git-v1:c2efc95d45fd4c76d4650a34a2a2676b87a93ac4
 Fix monitor expressions


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3238 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * QEMU JAZZ RC4030 chipset
3
 
 *
4
 
 * Copyright (c) 2007-2008 Hervé Poussineau
5
 
 *
6
 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 
 * of this software and associated documentation files (the "Software"), to deal
8
 
 * in the Software without restriction, including without limitation the rights
9
 
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 
 * copies of the Software, and to permit persons to whom the Software is
11
 
 * furnished to do so, subject to the following conditions:
12
 
 *
13
 
 * The above copyright notice and this permission notice shall be included in
14
 
 * all copies or substantial portions of the Software.
15
 
 *
16
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 
 * THE SOFTWARE.
23
 
 */
24
 
 
25
 
#include "hw.h"
26
 
#include "qemu-timer.h"
27
 
 
28
 
//#define DEBUG_RC4030
29
 
 
30
 
#ifdef DEBUG_RC4030
31
 
static const char* irq_names[] = { "parallel", "floppy", "sound", "video",
32
 
            "network", "scsi", "keyboard", "mouse", "serial0", "serial1" };
33
 
#endif
34
 
 
35
 
typedef struct rc4030State
36
 
{
37
 
    uint32_t config; /* 0x0000: RC4030 config register */
38
 
    uint32_t invalid_address_register; /* 0x0010: Invalid Address register */
39
 
 
40
 
    /* DMA */
41
 
    uint32_t dma_regs[8][4];
42
 
    uint32_t dma_tl_base; /* 0x0018: DMA transl. table base */
43
 
    uint32_t dma_tl_limit; /* 0x0020: DMA transl. table limit */
44
 
 
45
 
    /* cache */
46
 
    uint32_t remote_failed_address; /* 0x0038: Remote Failed Address */
47
 
    uint32_t memory_failed_address; /* 0x0040: Memory Failed Address */
48
 
    uint32_t cache_ptag; /* 0x0048: I/O Cache Physical Tag */
49
 
    uint32_t cache_ltag; /* 0x0050: I/O Cache Logical Tag */
50
 
    uint32_t cache_bmask; /* 0x0058: I/O Cache Byte Mask */
51
 
    uint32_t cache_bwin; /* 0x0060: I/O Cache Buffer Window */
52
 
 
53
 
    uint32_t offset208;
54
 
    uint32_t offset210;
55
 
    uint32_t nvram_protect; /* 0x0220: NV ram protect register */
56
 
    uint32_t offset238;
57
 
    uint32_t rem_speed[15];
58
 
    uint32_t imr_jazz; /* Local bus int enable mask */
59
 
    uint32_t isr_jazz; /* Local bus int source */
60
 
 
61
 
    /* timer */
62
 
    QEMUTimer *periodic_timer;
63
 
    uint32_t itr; /* Interval timer reload */
64
 
 
65
 
    uint32_t dummy32;
66
 
    qemu_irq timer_irq;
67
 
    qemu_irq jazz_bus_irq;
68
 
} rc4030State;
69
 
 
70
 
static void set_next_tick(rc4030State *s)
71
 
{
72
 
    qemu_irq_lower(s->timer_irq);
73
 
    uint32_t hz;
74
 
 
75
 
    hz = 1000 / (s->itr + 1);
76
 
 
77
 
    qemu_mod_timer(s->periodic_timer, qemu_get_clock(vm_clock) + ticks_per_sec / hz);
78
 
}
79
 
 
80
 
/* called for accesses to rc4030 */
81
 
static uint32_t rc4030_readl(void *opaque, target_phys_addr_t addr)
82
 
{
83
 
    rc4030State *s = opaque;
84
 
    uint32_t val;
85
 
 
86
 
    addr &= 0x3fff;
87
 
    switch (addr & ~0x3) {
88
 
    /* Global config register */
89
 
    case 0x0000:
90
 
        val = s->config;
91
 
        break;
92
 
    /* Invalid Address register */
93
 
    case 0x0010:
94
 
        val = s->invalid_address_register;
95
 
        break;
96
 
    /* DMA transl. table base */
97
 
    case 0x0018:
98
 
        val = s->dma_tl_base;
99
 
        break;
100
 
    /* DMA transl. table limit */
101
 
    case 0x0020:
102
 
        val = s->dma_tl_limit;
103
 
        break;
104
 
    /* Remote Failed Address */
105
 
    case 0x0038:
106
 
        val = s->remote_failed_address;
107
 
        break;
108
 
    /* Memory Failed Address */
109
 
    case 0x0040:
110
 
        val = s->memory_failed_address;
111
 
        break;
112
 
    /* I/O Cache Byte Mask */
113
 
    case 0x0058:
114
 
        val = s->cache_bmask;
115
 
        /* HACK */
116
 
        if (s->cache_bmask == (uint32_t)-1)
117
 
            s->cache_bmask = 0;
118
 
        break;
119
 
    /* Remote Speed Registers */
120
 
    case 0x0070:
121
 
    case 0x0078:
122
 
    case 0x0080:
123
 
    case 0x0088:
124
 
    case 0x0090:
125
 
    case 0x0098:
126
 
    case 0x00a0:
127
 
    case 0x00a8:
128
 
    case 0x00b0:
129
 
    case 0x00b8:
130
 
    case 0x00c0:
131
 
    case 0x00c8:
132
 
    case 0x00d0:
133
 
    case 0x00d8:
134
 
    case 0x00e0:
135
 
        val = s->rem_speed[(addr - 0x0070) >> 3];
136
 
        break;
137
 
    /* DMA channel base address */
138
 
    case 0x0100:
139
 
    case 0x0108:
140
 
    case 0x0110:
141
 
    case 0x0118:
142
 
    case 0x0120:
143
 
    case 0x0128:
144
 
    case 0x0130:
145
 
    case 0x0138:
146
 
    case 0x0140:
147
 
    case 0x0148:
148
 
    case 0x0150:
149
 
    case 0x0158:
150
 
    case 0x0160:
151
 
    case 0x0168:
152
 
    case 0x0170:
153
 
    case 0x0178:
154
 
    case 0x0180:
155
 
    case 0x0188:
156
 
    case 0x0190:
157
 
    case 0x0198:
158
 
    case 0x01a0:
159
 
    case 0x01a8:
160
 
    case 0x01b0:
161
 
    case 0x01b8:
162
 
    case 0x01c0:
163
 
    case 0x01c8:
164
 
    case 0x01d0:
165
 
    case 0x01d8:
166
 
    case 0x01e0:
167
 
    case 0x1e8:
168
 
    case 0x01f0:
169
 
    case 0x01f8:
170
 
        {
171
 
            int entry = (addr - 0x0100) >> 5;
172
 
            int idx = (addr & 0x1f) >> 3;
173
 
            val = s->dma_regs[entry][idx];
174
 
        }
175
 
        break;
176
 
    /* Offset 0x0208 */
177
 
    case 0x0208:
178
 
        val = s->offset208;
179
 
        break;
180
 
    /* Offset 0x0210 */
181
 
    case 0x0210:
182
 
        val = s->offset210;
183
 
        break;
184
 
    /* NV ram protect register */
185
 
    case 0x0220:
186
 
        val = s->nvram_protect;
187
 
        break;
188
 
    /* Interval timer count */
189
 
    case 0x0230:
190
 
        val = s->dummy32;
191
 
        qemu_irq_lower(s->timer_irq);
192
 
        break;
193
 
    /* Offset 0x0238 */
194
 
    case 0x0238:
195
 
        val = s->offset238;
196
 
        break;
197
 
    default:
198
 
#ifdef DEBUG_RC4030
199
 
        printf("rc4030: invalid read [" TARGET_FMT_lx "]\n", addr);
200
 
#endif
201
 
        val = 0;
202
 
        break;
203
 
    }
204
 
 
205
 
#ifdef DEBUG_RC4030
206
 
    if ((addr & ~3) != 0x230)
207
 
        printf("rc4030: read 0x%02x at " TARGET_FMT_lx "\n", val, addr);
208
 
#endif
209
 
 
210
 
    return val;
211
 
}
212
 
 
213
 
static uint32_t rc4030_readw(void *opaque, target_phys_addr_t addr)
214
 
{
215
 
    uint32_t v = rc4030_readl(opaque, addr & ~0x3);
216
 
    if (addr & 0x2)
217
 
        return v >> 16;
218
 
    else
219
 
        return v & 0xffff;
220
 
}
221
 
 
222
 
static uint32_t rc4030_readb(void *opaque, target_phys_addr_t addr)
223
 
{
224
 
    uint32_t v = rc4030_readl(opaque, addr & ~0x3);
225
 
    return (v >> (8 * (addr & 0x3))) & 0xff;
226
 
}
227
 
 
228
 
static void rc4030_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
229
 
{
230
 
    rc4030State *s = opaque;
231
 
    addr &= 0x3fff;
232
 
 
233
 
#ifdef DEBUG_RC4030
234
 
    printf("rc4030: write 0x%02x at " TARGET_FMT_lx "\n", val, addr);
235
 
#endif
236
 
 
237
 
    switch (addr & ~0x3) {
238
 
    /* Global config register */
239
 
    case 0x0000:
240
 
        s->config = val;
241
 
        break;
242
 
    /* DMA transl. table base */
243
 
    case 0x0018:
244
 
        s->dma_tl_base = val;
245
 
        break;
246
 
    /* DMA transl. table limit */
247
 
    case 0x0020:
248
 
        s->dma_tl_limit = val;
249
 
        break;
250
 
    /* I/O Cache Physical Tag */
251
 
    case 0x0048:
252
 
        s->cache_ptag = val;
253
 
        break;
254
 
    /* I/O Cache Logical Tag */
255
 
    case 0x0050:
256
 
        s->cache_ltag = val;
257
 
        break;
258
 
    /* I/O Cache Byte Mask */
259
 
    case 0x0058:
260
 
        s->cache_bmask |= val; /* HACK */
261
 
        break;
262
 
    /* I/O Cache Buffer Window */
263
 
    case 0x0060:
264
 
        s->cache_bwin = val;
265
 
        /* HACK */
266
 
        if (s->cache_ltag == 0x80000001 && s->cache_bmask == 0xf0f0f0f) {
267
 
            target_phys_addr_t dests[] = { 4, 0, 8, 0x10 };
268
 
            static int current = 0;
269
 
            target_phys_addr_t dest = 0 + dests[current];
270
 
            uint8_t buf;
271
 
            current = (current + 1) % (sizeof(dests)/sizeof(dests[0]));
272
 
            buf = s->cache_bwin - 1;
273
 
            cpu_physical_memory_rw(dest, &buf, 1, 1);
274
 
        }
275
 
        break;
276
 
    /* Remote Speed Registers */
277
 
    case 0x0070:
278
 
    case 0x0078:
279
 
    case 0x0080:
280
 
    case 0x0088:
281
 
    case 0x0090:
282
 
    case 0x0098:
283
 
    case 0x00a0:
284
 
    case 0x00a8:
285
 
    case 0x00b0:
286
 
    case 0x00b8:
287
 
    case 0x00c0:
288
 
    case 0x00c8:
289
 
    case 0x00d0:
290
 
    case 0x00d8:
291
 
    case 0x00e0:
292
 
        s->rem_speed[(addr - 0x0070) >> 3] = val;
293
 
        break;
294
 
    /* DMA channel base address */
295
 
    case 0x0100:
296
 
    case 0x0108:
297
 
    case 0x0110:
298
 
    case 0x0118:
299
 
    case 0x0120:
300
 
    case 0x0128:
301
 
    case 0x0130:
302
 
    case 0x0138:
303
 
    case 0x0140:
304
 
    case 0x0148:
305
 
    case 0x0150:
306
 
    case 0x0158:
307
 
    case 0x0160:
308
 
    case 0x0168:
309
 
    case 0x0170:
310
 
    case 0x0178:
311
 
    case 0x0180:
312
 
    case 0x0188:
313
 
    case 0x0190:
314
 
    case 0x0198:
315
 
    case 0x01a0:
316
 
    case 0x01a8:
317
 
    case 0x01b0:
318
 
    case 0x01b8:
319
 
    case 0x01c0:
320
 
    case 0x01c8:
321
 
    case 0x01d0:
322
 
    case 0x01d8:
323
 
    case 0x01e0:
324
 
    case 0x1e8:
325
 
    case 0x01f0:
326
 
    case 0x01f8:
327
 
        {
328
 
            int entry = (addr - 0x0100) >> 5;
329
 
            int idx = (addr & 0x1f) >> 3;
330
 
            s->dma_regs[entry][idx] = val;
331
 
        }
332
 
        break;
333
 
    /* Offset 0x0210 */
334
 
    case 0x0210:
335
 
        s->offset210 = val;
336
 
        break;
337
 
    /* Interval timer reload */
338
 
    case 0x0228:
339
 
        s->itr = val;
340
 
        qemu_irq_lower(s->timer_irq);
341
 
        set_next_tick(s);
342
 
        break;
343
 
    default:
344
 
#ifdef DEBUG_RC4030
345
 
        printf("rc4030: invalid write of 0x%02x at [" TARGET_FMT_lx "]\n", val, addr);
346
 
#endif
347
 
        break;
348
 
    }
349
 
}
350
 
 
351
 
static void rc4030_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
352
 
{
353
 
    uint32_t old_val = rc4030_readl(opaque, addr & ~0x3);
354
 
 
355
 
    if (addr & 0x2)
356
 
        val = (val << 16) | (old_val & 0x0000ffff);
357
 
    else
358
 
        val = val | (old_val & 0xffff0000);
359
 
    rc4030_writel(opaque, addr & ~0x3, val);
360
 
}
361
 
 
362
 
static void rc4030_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
363
 
{
364
 
    uint32_t old_val = rc4030_readl(opaque, addr & ~0x3);
365
 
 
366
 
    switch (addr & 3) {
367
 
    case 0:
368
 
        val = val | (old_val & 0xffffff00);
369
 
        break;
370
 
    case 1:
371
 
        val = (val << 8) | (old_val & 0xffff00ff);
372
 
        break;
373
 
    case 2:
374
 
        val = (val << 16) | (old_val & 0xff00ffff);
375
 
        break;
376
 
    case 3:
377
 
        val = (val << 24) | (old_val & 0x00ffffff);
378
 
        break;
379
 
    }
380
 
    rc4030_writel(opaque, addr & ~0x3, val);
381
 
}
382
 
 
383
 
static CPUReadMemoryFunc *rc4030_read[3] = {
384
 
    rc4030_readb,
385
 
    rc4030_readw,
386
 
    rc4030_readl,
387
 
};
388
 
 
389
 
static CPUWriteMemoryFunc *rc4030_write[3] = {
390
 
    rc4030_writeb,
391
 
    rc4030_writew,
392
 
    rc4030_writel,
393
 
};
394
 
 
395
 
static void update_jazz_irq(rc4030State *s)
396
 
{
397
 
    uint16_t pending;
398
 
 
399
 
    pending = s->isr_jazz & s->imr_jazz;
400
 
 
401
 
#ifdef DEBUG_RC4030
402
 
    if (s->isr_jazz != 0) {
403
 
        uint32_t irq = 0;
404
 
        printf("jazz pending:");
405
 
        for (irq = 0; irq < sizeof(irq_names)/sizeof(irq_names[0]); irq++) {
406
 
            if (s->isr_jazz & (1 << irq)) {
407
 
                printf(" %s", irq_names[irq]);
408
 
                if (!(s->imr_jazz & (1 << irq))) {
409
 
                    printf("(ignored)");
410
 
                }
411
 
            }
412
 
        }
413
 
        printf("\n");
414
 
    }
415
 
#endif
416
 
 
417
 
    if (pending != 0)
418
 
        qemu_irq_raise(s->jazz_bus_irq);
419
 
    else
420
 
        qemu_irq_lower(s->jazz_bus_irq);
421
 
}
422
 
 
423
 
static void rc4030_irq_jazz_request(void *opaque, int irq, int level)
424
 
{
425
 
    rc4030State *s = opaque;
426
 
 
427
 
    if (level) {
428
 
        s->isr_jazz |= 1 << irq;
429
 
    } else {
430
 
        s->isr_jazz &= ~(1 << irq);
431
 
    }
432
 
 
433
 
    update_jazz_irq(s);
434
 
}
435
 
 
436
 
static void rc4030_periodic_timer(void *opaque)
437
 
{
438
 
    rc4030State *s = opaque;
439
 
 
440
 
    set_next_tick(s);
441
 
    qemu_irq_raise(s->timer_irq);
442
 
}
443
 
 
444
 
static uint32_t int_readb(void *opaque, target_phys_addr_t addr)
445
 
{
446
 
    rc4030State *s = opaque;
447
 
    uint32_t val;
448
 
    uint32_t irq;
449
 
    addr &= 0xfff;
450
 
 
451
 
    switch (addr) {
452
 
    case 0x00: {
453
 
        /* Local bus int source */
454
 
        uint32_t pending = s->isr_jazz & s->imr_jazz;
455
 
        val = 0;
456
 
        irq = 0;
457
 
        while (pending) {
458
 
            if (pending & 1) {
459
 
                //printf("returning irq %s\n", irq_names[irq]);
460
 
                val = (irq + 1) << 2;
461
 
                break;
462
 
            }
463
 
            irq++;
464
 
            pending >>= 1;
465
 
        }
466
 
        break;
467
 
    }
468
 
    default:
469
 
#ifdef DEBUG_RC4030
470
 
            printf("rc4030: (interrupt controller) invalid read [" TARGET_FMT_lx "]\n", addr);
471
 
#endif
472
 
            val = 0;
473
 
    }
474
 
 
475
 
#ifdef DEBUG_RC4030
476
 
    printf("rc4030: (interrupt controller) read 0x%02x at " TARGET_FMT_lx "\n", val, addr);
477
 
#endif
478
 
 
479
 
    return val;
480
 
}
481
 
 
482
 
static uint32_t int_readw(void *opaque, target_phys_addr_t addr)
483
 
{
484
 
    uint32_t v;
485
 
    v = int_readb(opaque, addr);
486
 
    v |= int_readb(opaque, addr + 1) << 8;
487
 
    return v;
488
 
}
489
 
 
490
 
static uint32_t int_readl(void *opaque, target_phys_addr_t addr)
491
 
{
492
 
    uint32_t v;
493
 
    v = int_readb(opaque, addr);
494
 
    v |= int_readb(opaque, addr + 1) << 8;
495
 
    v |= int_readb(opaque, addr + 2) << 16;
496
 
    v |= int_readb(opaque, addr + 3) << 24;
497
 
    return v;
498
 
}
499
 
 
500
 
static void int_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
501
 
{
502
 
    rc4030State *s = opaque;
503
 
    addr &= 0xfff;
504
 
 
505
 
#ifdef DEBUG_RC4030
506
 
    printf("rc4030: (interrupt controller) write 0x%02x at " TARGET_FMT_lx "\n", val, addr);
507
 
#endif
508
 
 
509
 
    switch (addr) {
510
 
    /* Local bus int enable mask */
511
 
    case 0x02:
512
 
        s->imr_jazz = (s->imr_jazz & 0xff00) | (val << 0); update_jazz_irq(s);
513
 
        break;
514
 
    case 0x03:
515
 
        s->imr_jazz = (s->imr_jazz & 0x00ff) | (val << 8); update_jazz_irq(s);
516
 
        break;
517
 
    default:
518
 
#ifdef DEBUG_RC4030
519
 
        printf("rc4030: (interrupt controller) invalid write of 0x%02x at [" TARGET_FMT_lx "]\n", val, addr);
520
 
#endif
521
 
        break;
522
 
    }
523
 
}
524
 
 
525
 
static void int_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
526
 
{
527
 
    int_writeb(opaque, addr, val & 0xff);
528
 
    int_writeb(opaque, addr + 1, (val >> 8) & 0xff);
529
 
}
530
 
 
531
 
static void int_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
532
 
{
533
 
    int_writeb(opaque, addr, val & 0xff);
534
 
    int_writeb(opaque, addr + 1, (val >> 8) & 0xff);
535
 
    int_writeb(opaque, addr + 2, (val >> 16) & 0xff);
536
 
    int_writeb(opaque, addr + 3, (val >> 24) & 0xff);
537
 
}
538
 
 
539
 
static CPUReadMemoryFunc *int_read[3] = {
540
 
    int_readb,
541
 
    int_readw,
542
 
    int_readl,
543
 
};
544
 
 
545
 
static CPUWriteMemoryFunc *int_write[3] = {
546
 
    int_writeb,
547
 
    int_writew,
548
 
    int_writel,
549
 
};
550
 
 
551
 
#define G364_512KB_RAM (0x0)
552
 
#define G364_2MB_RAM   (0x1)
553
 
#define G364_8MB_RAM   (0x2)
554
 
#define G364_32MB_RAM  (0x3)
555
 
 
556
 
static void rc4030_reset(void *opaque)
557
 
{
558
 
    rc4030State *s = opaque;
559
 
    int i;
560
 
 
561
 
    s->config = (G364_2MB_RAM << 8) | 0x04;
562
 
    s->invalid_address_register = 0;
563
 
 
564
 
    memset(s->dma_regs, 0, sizeof(s->dma_regs));
565
 
    s->dma_tl_base = s->dma_tl_limit = 0;
566
 
 
567
 
    s->remote_failed_address = s->memory_failed_address = 0;
568
 
    s->cache_ptag = s->cache_ltag = 0;
569
 
    s->cache_bmask = s->cache_bwin = 0;
570
 
 
571
 
    s->offset208 = 0;
572
 
    s->offset210 = 0x18186;
573
 
    s->nvram_protect = 7;
574
 
    s->offset238 = 7;
575
 
    for (i = 0; i < 15; i++)
576
 
        s->rem_speed[i] = 7;
577
 
    s->imr_jazz = s->isr_jazz = 0;
578
 
 
579
 
    s->itr = 0;
580
 
    s->dummy32 = 0;
581
 
 
582
 
    qemu_irq_lower(s->timer_irq);
583
 
    qemu_irq_lower(s->jazz_bus_irq);
584
 
}
585
 
 
586
 
qemu_irq *rc4030_init(qemu_irq timer, qemu_irq jazz_bus)
587
 
{
588
 
    rc4030State *s;
589
 
    int s_chipset, s_int;
590
 
 
591
 
    s = qemu_mallocz(sizeof(rc4030State));
592
 
    if (!s)
593
 
        return NULL;
594
 
 
595
 
    s->periodic_timer = qemu_new_timer(vm_clock, rc4030_periodic_timer, s);
596
 
    s->timer_irq = timer;
597
 
    s->jazz_bus_irq = jazz_bus;
598
 
 
599
 
    qemu_register_reset(rc4030_reset, s);
600
 
    rc4030_reset(s);
601
 
 
602
 
    s_chipset = cpu_register_io_memory(0, rc4030_read, rc4030_write, s);
603
 
    cpu_register_physical_memory(0x80000000, 0x300, s_chipset);
604
 
    s_int = cpu_register_io_memory(0, int_read, int_write, s);
605
 
    cpu_register_physical_memory(0xf0000000, 0x00001000, s_int);
606
 
 
607
 
    return qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16);
608
 
}