packing update
[qemu] / hw / rc4030.c
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 "mips.h"
27 #include "qemu-timer.h"
28
29 /********************************************************/
30 /* debug rc4030 */
31
32 //#define DEBUG_RC4030
33 //#define DEBUG_RC4030_DMA
34
35 #ifdef DEBUG_RC4030
36 #define DPRINTF(fmt, args...) \
37 do { printf("rc4030: " fmt , ##args); } while (0)
38 static const char* irq_names[] = { "parallel", "floppy", "sound", "video",
39             "network", "scsi", "keyboard", "mouse", "serial0", "serial1" };
40 #else
41 #define DPRINTF(fmt, args...)
42 #endif
43
44 #define RC4030_ERROR(fmt, args...) \
45 do { fprintf(stderr, "rc4030 ERROR: %s: " fmt, __func__ , ##args); } while (0)
46
47 /********************************************************/
48 /* rc4030 emulation                                     */
49
50 typedef struct dma_pagetable_entry {
51     int32_t frame;
52     int32_t owner;
53 } __attribute__((packed)) dma_pagetable_entry;
54
55 #define DMA_PAGESIZE    4096
56 #define DMA_REG_ENABLE  1
57 #define DMA_REG_COUNT   2
58 #define DMA_REG_ADDRESS 3
59
60 #define DMA_FLAG_ENABLE     0x0001
61 #define DMA_FLAG_MEM_TO_DEV 0x0002
62 #define DMA_FLAG_TC_INTR    0x0100
63 #define DMA_FLAG_MEM_INTR   0x0200
64 #define DMA_FLAG_ADDR_INTR  0x0400
65
66 typedef struct rc4030State
67 {
68     uint32_t config; /* 0x0000: RC4030 config register */
69     uint32_t invalid_address_register; /* 0x0010: Invalid Address register */
70
71     /* DMA */
72     uint32_t dma_regs[8][4];
73     uint32_t dma_tl_base; /* 0x0018: DMA transl. table base */
74     uint32_t dma_tl_limit; /* 0x0020: DMA transl. table limit */
75
76     /* cache */
77     uint32_t remote_failed_address; /* 0x0038: Remote Failed Address */
78     uint32_t memory_failed_address; /* 0x0040: Memory Failed Address */
79     uint32_t cache_ptag; /* 0x0048: I/O Cache Physical Tag */
80     uint32_t cache_ltag; /* 0x0050: I/O Cache Logical Tag */
81     uint32_t cache_bmask; /* 0x0058: I/O Cache Byte Mask */
82     uint32_t cache_bwin; /* 0x0060: I/O Cache Buffer Window */
83
84     uint32_t offset210;
85     uint32_t nvram_protect; /* 0x0220: NV ram protect register */
86     uint32_t offset238;
87     uint32_t rem_speed[15];
88     uint32_t imr_jazz; /* Local bus int enable mask */
89     uint32_t isr_jazz; /* Local bus int source */
90
91     /* timer */
92     QEMUTimer *periodic_timer;
93     uint32_t itr; /* Interval timer reload */
94
95     qemu_irq timer_irq;
96     qemu_irq jazz_bus_irq;
97 } rc4030State;
98
99 static void set_next_tick(rc4030State *s)
100 {
101     qemu_irq_lower(s->timer_irq);
102     uint32_t tm_hz;
103
104     tm_hz = 1000 / (s->itr + 1);
105
106     qemu_mod_timer(s->periodic_timer, qemu_get_clock(vm_clock) + ticks_per_sec / tm_hz);
107 }
108
109 /* called for accesses to rc4030 */
110 static uint32_t rc4030_readl(void *opaque, target_phys_addr_t addr)
111 {
112     rc4030State *s = opaque;
113     uint32_t val;
114
115     addr &= 0x3fff;
116     switch (addr & ~0x3) {
117     /* Global config register */
118     case 0x0000:
119         val = s->config;
120         break;
121     /* Invalid Address register */
122     case 0x0010:
123         val = s->invalid_address_register;
124         break;
125     /* DMA transl. table base */
126     case 0x0018:
127         val = s->dma_tl_base;
128         break;
129     /* DMA transl. table limit */
130     case 0x0020:
131         val = s->dma_tl_limit;
132         break;
133     /* Remote Failed Address */
134     case 0x0038:
135         val = s->remote_failed_address;
136         break;
137     /* Memory Failed Address */
138     case 0x0040:
139         val = s->memory_failed_address;
140         break;
141     /* I/O Cache Byte Mask */
142     case 0x0058:
143         val = s->cache_bmask;
144         /* HACK */
145         if (s->cache_bmask == (uint32_t)-1)
146             s->cache_bmask = 0;
147         break;
148     /* Remote Speed Registers */
149     case 0x0070:
150     case 0x0078:
151     case 0x0080:
152     case 0x0088:
153     case 0x0090:
154     case 0x0098:
155     case 0x00a0:
156     case 0x00a8:
157     case 0x00b0:
158     case 0x00b8:
159     case 0x00c0:
160     case 0x00c8:
161     case 0x00d0:
162     case 0x00d8:
163     case 0x00e0:
164         val = s->rem_speed[(addr - 0x0070) >> 3];
165         break;
166     /* DMA channel base address */
167     case 0x0100:
168     case 0x0108:
169     case 0x0110:
170     case 0x0118:
171     case 0x0120:
172     case 0x0128:
173     case 0x0130:
174     case 0x0138:
175     case 0x0140:
176     case 0x0148:
177     case 0x0150:
178     case 0x0158:
179     case 0x0160:
180     case 0x0168:
181     case 0x0170:
182     case 0x0178:
183     case 0x0180:
184     case 0x0188:
185     case 0x0190:
186     case 0x0198:
187     case 0x01a0:
188     case 0x01a8:
189     case 0x01b0:
190     case 0x01b8:
191     case 0x01c0:
192     case 0x01c8:
193     case 0x01d0:
194     case 0x01d8:
195     case 0x01e0:
196     case 0x01e8:
197     case 0x01f0:
198     case 0x01f8:
199         {
200             int entry = (addr - 0x0100) >> 5;
201             int idx = (addr & 0x1f) >> 3;
202             val = s->dma_regs[entry][idx];
203         }
204         break;
205     /* Offset 0x0208 */
206     case 0x0208:
207         val = 0;
208         break;
209     /* Offset 0x0210 */
210     case 0x0210:
211         val = s->offset210;
212         break;
213     /* NV ram protect register */
214     case 0x0220:
215         val = s->nvram_protect;
216         break;
217     /* Interval timer count */
218     case 0x0230:
219         val = 0;
220         qemu_irq_lower(s->timer_irq);
221         break;
222     /* Offset 0x0238 */
223     case 0x0238:
224         val = s->offset238;
225         break;
226     default:
227         RC4030_ERROR("invalid read [" TARGET_FMT_plx "]\n", addr);
228         val = 0;
229         break;
230     }
231
232     if ((addr & ~3) != 0x230)
233         DPRINTF("read 0x%02x at " TARGET_FMT_plx "\n", val, addr);
234
235     return val;
236 }
237
238 static uint32_t rc4030_readw(void *opaque, target_phys_addr_t addr)
239 {
240     uint32_t v = rc4030_readl(opaque, addr & ~0x3);
241     if (addr & 0x2)
242         return v >> 16;
243     else
244         return v & 0xffff;
245 }
246
247 static uint32_t rc4030_readb(void *opaque, target_phys_addr_t addr)
248 {
249     uint32_t v = rc4030_readl(opaque, addr & ~0x3);
250     return (v >> (8 * (addr & 0x3))) & 0xff;
251 }
252
253 static void rc4030_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
254 {
255     rc4030State *s = opaque;
256     addr &= 0x3fff;
257
258     DPRINTF("write 0x%02x at " TARGET_FMT_plx "\n", val, addr);
259
260     switch (addr & ~0x3) {
261     /* Global config register */
262     case 0x0000:
263         s->config = val;
264         break;
265     /* DMA transl. table base */
266     case 0x0018:
267         s->dma_tl_base = val;
268         break;
269     /* DMA transl. table limit */
270     case 0x0020:
271         s->dma_tl_limit = val;
272         break;
273     /* DMA transl. table invalidated */
274     case 0x0028:
275         break;
276     /* Cache Maintenance */
277     case 0x0030:
278         RC4030_ERROR("Cache maintenance not handled yet (val 0x%02x)\n", val);
279         break;
280     /* I/O Cache Physical Tag */
281     case 0x0048:
282         s->cache_ptag = val;
283         break;
284     /* I/O Cache Logical Tag */
285     case 0x0050:
286         s->cache_ltag = val;
287         break;
288     /* I/O Cache Byte Mask */
289     case 0x0058:
290         s->cache_bmask |= val; /* HACK */
291         break;
292     /* I/O Cache Buffer Window */
293     case 0x0060:
294         s->cache_bwin = val;
295         /* HACK */
296         if (s->cache_ltag == 0x80000001 && s->cache_bmask == 0xf0f0f0f) {
297             target_phys_addr_t dests[] = { 4, 0, 8, 0x10 };
298             static int current = 0;
299             target_phys_addr_t dest = 0 + dests[current];
300             uint8_t buf;
301             current = (current + 1) % (ARRAY_SIZE(dests));
302             buf = s->cache_bwin - 1;
303             cpu_physical_memory_rw(dest, &buf, 1, 1);
304         }
305         break;
306     /* Remote Speed Registers */
307     case 0x0070:
308     case 0x0078:
309     case 0x0080:
310     case 0x0088:
311     case 0x0090:
312     case 0x0098:
313     case 0x00a0:
314     case 0x00a8:
315     case 0x00b0:
316     case 0x00b8:
317     case 0x00c0:
318     case 0x00c8:
319     case 0x00d0:
320     case 0x00d8:
321     case 0x00e0:
322         s->rem_speed[(addr - 0x0070) >> 3] = val;
323         break;
324     /* DMA channel base address */
325     case 0x0100:
326     case 0x0108:
327     case 0x0110:
328     case 0x0118:
329     case 0x0120:
330     case 0x0128:
331     case 0x0130:
332     case 0x0138:
333     case 0x0140:
334     case 0x0148:
335     case 0x0150:
336     case 0x0158:
337     case 0x0160:
338     case 0x0168:
339     case 0x0170:
340     case 0x0178:
341     case 0x0180:
342     case 0x0188:
343     case 0x0190:
344     case 0x0198:
345     case 0x01a0:
346     case 0x01a8:
347     case 0x01b0:
348     case 0x01b8:
349     case 0x01c0:
350     case 0x01c8:
351     case 0x01d0:
352     case 0x01d8:
353     case 0x01e0:
354     case 0x01e8:
355     case 0x01f0:
356     case 0x01f8:
357         {
358             int entry = (addr - 0x0100) >> 5;
359             int idx = (addr & 0x1f) >> 3;
360             s->dma_regs[entry][idx] = val;
361         }
362         break;
363     /* Offset 0x0210 */
364     case 0x0210:
365         s->offset210 = val;
366         break;
367     /* Interval timer reload */
368     case 0x0228:
369         s->itr = val;
370         qemu_irq_lower(s->timer_irq);
371         set_next_tick(s);
372         break;
373     default:
374         RC4030_ERROR("invalid write of 0x%02x at [" TARGET_FMT_plx "]\n", val, addr);
375         break;
376     }
377 }
378
379 static void rc4030_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
380 {
381     uint32_t old_val = rc4030_readl(opaque, addr & ~0x3);
382
383     if (addr & 0x2)
384         val = (val << 16) | (old_val & 0x0000ffff);
385     else
386         val = val | (old_val & 0xffff0000);
387     rc4030_writel(opaque, addr & ~0x3, val);
388 }
389
390 static void rc4030_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
391 {
392     uint32_t old_val = rc4030_readl(opaque, addr & ~0x3);
393
394     switch (addr & 3) {
395     case 0:
396         val = val | (old_val & 0xffffff00);
397         break;
398     case 1:
399         val = (val << 8) | (old_val & 0xffff00ff);
400         break;
401     case 2:
402         val = (val << 16) | (old_val & 0xff00ffff);
403         break;
404     case 3:
405         val = (val << 24) | (old_val & 0x00ffffff);
406         break;
407     }
408     rc4030_writel(opaque, addr & ~0x3, val);
409 }
410
411 static CPUReadMemoryFunc *rc4030_read[3] = {
412     rc4030_readb,
413     rc4030_readw,
414     rc4030_readl,
415 };
416
417 static CPUWriteMemoryFunc *rc4030_write[3] = {
418     rc4030_writeb,
419     rc4030_writew,
420     rc4030_writel,
421 };
422
423 static void update_jazz_irq(rc4030State *s)
424 {
425     uint16_t pending;
426
427     pending = s->isr_jazz & s->imr_jazz;
428
429 #ifdef DEBUG_RC4030
430     if (s->isr_jazz != 0) {
431         uint32_t irq = 0;
432         DPRINTF("pending irqs:");
433         for (irq = 0; irq < ARRAY_SIZE(irq_names); irq++) {
434             if (s->isr_jazz & (1 << irq)) {
435                 printf(" %s", irq_names[irq]);
436                 if (!(s->imr_jazz & (1 << irq))) {
437                     printf("(ignored)");
438                 }
439             }
440         }
441         printf("\n");
442     }
443 #endif
444
445     if (pending != 0)
446         qemu_irq_raise(s->jazz_bus_irq);
447     else
448         qemu_irq_lower(s->jazz_bus_irq);
449 }
450
451 static void rc4030_irq_jazz_request(void *opaque, int irq, int level)
452 {
453     rc4030State *s = opaque;
454
455     if (level) {
456         s->isr_jazz |= 1 << irq;
457     } else {
458         s->isr_jazz &= ~(1 << irq);
459     }
460
461     update_jazz_irq(s);
462 }
463
464 static void rc4030_periodic_timer(void *opaque)
465 {
466     rc4030State *s = opaque;
467
468     set_next_tick(s);
469     qemu_irq_raise(s->timer_irq);
470 }
471
472 static uint32_t jazzio_readw(void *opaque, target_phys_addr_t addr)
473 {
474     rc4030State *s = opaque;
475     uint32_t val;
476     uint32_t irq;
477     addr &= 0xfff;
478
479     switch (addr) {
480     /* Local bus int source */
481     case 0x00: {
482         uint32_t pending = s->isr_jazz & s->imr_jazz;
483         val = 0;
484         irq = 0;
485         while (pending) {
486             if (pending & 1) {
487                 DPRINTF("returning irq %s\n", irq_names[irq]);
488                 val = (irq + 1) << 2;
489                 break;
490             }
491             irq++;
492             pending >>= 1;
493         }
494         break;
495     }
496     /* Local bus int enable mask */
497     case 0x02:
498         val = s->imr_jazz;
499         break;
500     default:
501         RC4030_ERROR("(jazz io controller) invalid read [" TARGET_FMT_plx "]\n", addr);
502         val = 0;
503     }
504
505     DPRINTF("(jazz io controller) read 0x%04x at " TARGET_FMT_plx "\n", val, addr);
506
507     return val;
508 }
509
510 static uint32_t jazzio_readb(void *opaque, target_phys_addr_t addr)
511 {
512     uint32_t v;
513     v = jazzio_readw(opaque, addr & ~0x1);
514     return (v >> (8 * (addr & 0x1))) & 0xff;
515 }
516
517 static uint32_t jazzio_readl(void *opaque, target_phys_addr_t addr)
518 {
519     uint32_t v;
520     v = jazzio_readw(opaque, addr);
521     v |= jazzio_readw(opaque, addr + 2) << 16;
522     return v;
523 }
524
525 static void jazzio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
526 {
527     rc4030State *s = opaque;
528     addr &= 0xfff;
529
530     DPRINTF("(jazz io controller) write 0x%04x at " TARGET_FMT_plx "\n", val, addr);
531
532     switch (addr) {
533     /* Local bus int enable mask */
534     case 0x02:
535         s->imr_jazz = val;
536         update_jazz_irq(s);
537         break;
538     default:
539         RC4030_ERROR("(jazz io controller) invalid write of 0x%04x at [" TARGET_FMT_plx "]\n", val, addr);
540         break;
541     }
542 }
543
544 static void jazzio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
545 {
546     uint32_t old_val = jazzio_readw(opaque, addr & ~0x1);
547
548     switch (addr & 1) {
549     case 0:
550         val = val | (old_val & 0xff00);
551         break;
552     case 1:
553         val = (val << 8) | (old_val & 0x00ff);
554         break;
555     }
556     jazzio_writew(opaque, addr & ~0x1, val);
557 }
558
559 static void jazzio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
560 {
561     jazzio_writew(opaque, addr, val & 0xffff);
562     jazzio_writew(opaque, addr + 2, (val >> 16) & 0xffff);
563 }
564
565 static CPUReadMemoryFunc *jazzio_read[3] = {
566     jazzio_readb,
567     jazzio_readw,
568     jazzio_readl,
569 };
570
571 static CPUWriteMemoryFunc *jazzio_write[3] = {
572     jazzio_writeb,
573     jazzio_writew,
574     jazzio_writel,
575 };
576
577 static void rc4030_reset(void *opaque)
578 {
579     rc4030State *s = opaque;
580     int i;
581
582     s->config = 0x410; /* some boards seem to accept 0x104 too */
583     s->invalid_address_register = 0;
584
585     memset(s->dma_regs, 0, sizeof(s->dma_regs));
586     s->dma_tl_base = s->dma_tl_limit = 0;
587
588     s->remote_failed_address = s->memory_failed_address = 0;
589     s->cache_ptag = s->cache_ltag = 0;
590     s->cache_bmask = s->cache_bwin = 0;
591
592     s->offset210 = 0x18186;
593     s->nvram_protect = 7;
594     s->offset238 = 7;
595     for (i = 0; i < 15; i++)
596         s->rem_speed[i] = 7;
597     s->imr_jazz = s->isr_jazz = 0;
598
599     s->itr = 0;
600
601     qemu_irq_lower(s->timer_irq);
602     qemu_irq_lower(s->jazz_bus_irq);
603 }
604
605 static int rc4030_load(QEMUFile *f, void *opaque, int version_id)
606 {
607     rc4030State* s = opaque;
608     int i, j;
609
610     if (version_id != 1)
611         return -EINVAL;
612
613     s->config = qemu_get_be32(f);
614     s->invalid_address_register = qemu_get_be32(f);
615     for (i = 0; i < 8; i++)
616         for (j = 0; j < 4; j++)
617             s->dma_regs[i][j] = qemu_get_be32(f);
618     s->dma_tl_base = qemu_get_be32(f);
619     s->dma_tl_limit = qemu_get_be32(f);
620     s->remote_failed_address = qemu_get_be32(f);
621     s->memory_failed_address = qemu_get_be32(f);
622     s->cache_ptag = qemu_get_be32(f);
623     s->cache_ltag = qemu_get_be32(f);
624     s->cache_bmask = qemu_get_be32(f);
625     s->cache_bwin = qemu_get_be32(f);
626     s->offset210 = qemu_get_be32(f);
627     s->nvram_protect = qemu_get_be32(f);
628     s->offset238 = qemu_get_be32(f);
629     for (i = 0; i < 15; i++)
630         s->rem_speed[i] = qemu_get_be32(f);
631     s->imr_jazz = qemu_get_be32(f);
632     s->isr_jazz = qemu_get_be32(f);
633     s->itr = qemu_get_be32(f);
634
635     set_next_tick(s);
636     update_jazz_irq(s);
637
638     return 0;
639 }
640
641 static void rc4030_save(QEMUFile *f, void *opaque)
642 {
643     rc4030State* s = opaque;
644     int i, j;
645
646     qemu_put_be32(f, s->config);
647     qemu_put_be32(f, s->invalid_address_register);
648     for (i = 0; i < 8; i++)
649         for (j = 0; j < 4; j++)
650             qemu_put_be32(f, s->dma_regs[i][j]);
651     qemu_put_be32(f, s->dma_tl_base);
652     qemu_put_be32(f, s->dma_tl_limit);
653     qemu_put_be32(f, s->remote_failed_address);
654     qemu_put_be32(f, s->memory_failed_address);
655     qemu_put_be32(f, s->cache_ptag);
656     qemu_put_be32(f, s->cache_ltag);
657     qemu_put_be32(f, s->cache_bmask);
658     qemu_put_be32(f, s->cache_bwin);
659     qemu_put_be32(f, s->offset210);
660     qemu_put_be32(f, s->nvram_protect);
661     qemu_put_be32(f, s->offset238);
662     for (i = 0; i < 15; i++)
663         qemu_put_be32(f, s->rem_speed[i]);
664     qemu_put_be32(f, s->imr_jazz);
665     qemu_put_be32(f, s->isr_jazz);
666     qemu_put_be32(f, s->itr);
667 }
668
669 static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int is_write)
670 {
671     rc4030State *s = opaque;
672     target_phys_addr_t entry_addr;
673     target_phys_addr_t dma_addr, phys_addr;
674     dma_pagetable_entry entry;
675     int index, dev_to_mem;
676     int ncpy, i;
677
678     s->dma_regs[n][DMA_REG_ENABLE] &= ~(DMA_FLAG_TC_INTR | DMA_FLAG_MEM_INTR | DMA_FLAG_ADDR_INTR);
679
680     /* Check DMA channel consistency */
681     dev_to_mem = (s->dma_regs[n][DMA_REG_ENABLE] & DMA_FLAG_MEM_TO_DEV) ? 0 : 1;
682     if (!(s->dma_regs[n][DMA_REG_ENABLE] & DMA_FLAG_ENABLE) ||
683         (is_write != dev_to_mem)) {
684         s->dma_regs[n][DMA_REG_ENABLE] |= DMA_FLAG_MEM_INTR;
685         return;
686     }
687
688     if (len > s->dma_regs[n][DMA_REG_COUNT])
689         len = s->dma_regs[n][DMA_REG_COUNT];
690
691     dma_addr = s->dma_regs[n][DMA_REG_ADDRESS];
692     i = 0;
693     for (;;) {
694         if (i == len) {
695             s->dma_regs[n][DMA_REG_ENABLE] |= DMA_FLAG_TC_INTR;
696             break;
697         }
698
699         ncpy = DMA_PAGESIZE - (dma_addr & (DMA_PAGESIZE - 1));
700         if (ncpy > len - i)
701             ncpy = len - i;
702
703         /* Get DMA translation table entry */
704         index = dma_addr / DMA_PAGESIZE;
705         if (index >= s->dma_tl_limit / sizeof(dma_pagetable_entry)) {
706             s->dma_regs[n][DMA_REG_ENABLE] |= DMA_FLAG_MEM_INTR;
707             break;
708         }
709         entry_addr = s->dma_tl_base + index * sizeof(dma_pagetable_entry);
710         /* XXX: not sure. should we really use only lowest bits? */
711         entry_addr &= 0x7fffffff;
712         cpu_physical_memory_rw(entry_addr, (uint8_t *)&entry, sizeof(entry), 0);
713
714         /* Read/write data at right place */
715         phys_addr = entry.frame + (dma_addr & (DMA_PAGESIZE - 1));
716         cpu_physical_memory_rw(phys_addr, &buf[i], ncpy, is_write);
717
718         i += ncpy;
719         dma_addr += ncpy;
720         s->dma_regs[n][DMA_REG_COUNT] -= ncpy;
721     }
722
723 #ifdef DEBUG_RC4030_DMA
724     {
725         int i, j;
726         printf("rc4030 dma: Copying %d bytes %s host %p\n",
727             len, is_write ? "from" : "to", buf);
728         for (i = 0; i < len; i += 16) {
729             int n = min(16, len - i);
730             for (j = 0; j < n; j++)
731                 printf("%02x ", buf[i + j]);
732             while (j++ < 16)
733                 printf("   ");
734             printf("| ");
735             for (j = 0; j < n; j++)
736                 printf("%c", isprint(buf[i + j]) ? buf[i + j] : '.');
737             printf("\n");
738         }
739     }
740 #endif
741 }
742
743 struct rc4030DMAState {
744     void *opaque;
745     int n;
746 };
747
748 static void rc4030_dma_read(void *dma, uint8_t *buf, int len)
749 {
750     rc4030_dma s = dma;
751     rc4030_do_dma(s->opaque, s->n, buf, len, 0);
752 }
753
754 static void rc4030_dma_write(void *dma, uint8_t *buf, int len)
755 {
756     rc4030_dma s = dma;
757     rc4030_do_dma(s->opaque, s->n, buf, len, 1);
758 }
759
760 static rc4030_dma *rc4030_allocate_dmas(void *opaque, int n)
761 {
762     rc4030_dma *s;
763     struct rc4030DMAState *p;
764     int i;
765
766     s = (rc4030_dma *)qemu_mallocz(sizeof(rc4030_dma) * n);
767     p = (struct rc4030DMAState *)qemu_mallocz(sizeof(struct rc4030DMAState) * n);
768     for (i = 0; i < n; i++) {
769         p->opaque = opaque;
770         p->n = i;
771         s[i] = p;
772         p++;
773     }
774     return s;
775 }
776
777 qemu_irq *rc4030_init(qemu_irq timer, qemu_irq jazz_bus,
778                       rc4030_dma **dmas,
779                       rc4030_dma_function *dma_read, rc4030_dma_function *dma_write)
780 {
781     rc4030State *s;
782     int s_chipset, s_jazzio;
783
784     s = qemu_mallocz(sizeof(rc4030State));
785
786     *dmas = rc4030_allocate_dmas(s, 4);
787     *dma_read = rc4030_dma_read;
788     *dma_write = rc4030_dma_write;
789
790     s->periodic_timer = qemu_new_timer(vm_clock, rc4030_periodic_timer, s);
791     s->timer_irq = timer;
792     s->jazz_bus_irq = jazz_bus;
793
794     qemu_register_reset(rc4030_reset, s);
795     register_savevm("rc4030", 0, 1, rc4030_save, rc4030_load, s);
796     rc4030_reset(s);
797
798     s_chipset = cpu_register_io_memory(0, rc4030_read, rc4030_write, s);
799     cpu_register_physical_memory(0x80000000, 0x300, s_chipset);
800     s_jazzio = cpu_register_io_memory(0, jazzio_read, jazzio_write, s);
801     cpu_register_physical_memory(0xf0000000, 0x00001000, s_jazzio);
802
803     return qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16);
804 }