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