target-ppc: move PPC4xx SDRAM controller emulation from ppc405_uc.c to ppc4xx_devs.c
[qemu] / hw / ppc4xx_devs.c
1 /*
2  * QEMU PowerPC 4xx embedded processors shared devices emulation
3  *
4  * Copyright (c) 2007 Jocelyn Mayer
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 #include "hw.h"
25 #include "ppc.h"
26 #include "ppc4xx.h"
27 #include "sysemu.h"
28 #include "qemu-log.h"
29
30 //#define DEBUG_MMIO
31 //#define DEBUG_UNASSIGNED
32 #define DEBUG_UIC
33
34 /*****************************************************************************/
35 /* Generic PowerPC 4xx processor instanciation */
36 CPUState *ppc4xx_init (const char *cpu_model,
37                        clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
38                        uint32_t sysclk)
39 {
40     CPUState *env;
41
42     /* init CPUs */
43     env = cpu_init(cpu_model);
44     if (!env) {
45         fprintf(stderr, "Unable to find PowerPC %s CPU definition\n",
46                 cpu_model);
47         exit(1);
48     }
49     cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
50     cpu_clk->opaque = env;
51     /* Set time-base frequency to sysclk */
52     tb_clk->cb = ppc_emb_timers_init(env, sysclk);
53     tb_clk->opaque = env;
54     ppc_dcr_init(env, NULL, NULL);
55     /* Register qemu callbacks */
56     qemu_register_reset(&cpu_ppc_reset, env);
57
58     return env;
59 }
60
61 /*****************************************************************************/
62 /* Fake device used to map multiple devices in a single memory page */
63 #define MMIO_AREA_BITS 8
64 #define MMIO_AREA_LEN (1 << MMIO_AREA_BITS)
65 #define MMIO_AREA_NB (1 << (TARGET_PAGE_BITS - MMIO_AREA_BITS))
66 #define MMIO_IDX(addr) (((addr) >> MMIO_AREA_BITS) & (MMIO_AREA_NB - 1))
67 struct ppc4xx_mmio_t {
68     target_phys_addr_t base;
69     CPUReadMemoryFunc **mem_read[MMIO_AREA_NB];
70     CPUWriteMemoryFunc **mem_write[MMIO_AREA_NB];
71     void *opaque[MMIO_AREA_NB];
72 };
73
74 static uint32_t unassigned_mmio_readb (void *opaque, target_phys_addr_t addr)
75 {
76 #ifdef DEBUG_UNASSIGNED
77     ppc4xx_mmio_t *mmio;
78
79     mmio = opaque;
80     printf("Unassigned mmio read 0x" PADDRX " base " PADDRX "\n",
81            addr, mmio->base);
82 #endif
83
84     return 0;
85 }
86
87 static void unassigned_mmio_writeb (void *opaque,
88                                     target_phys_addr_t addr, uint32_t val)
89 {
90 #ifdef DEBUG_UNASSIGNED
91     ppc4xx_mmio_t *mmio;
92
93     mmio = opaque;
94     printf("Unassigned mmio write 0x" PADDRX " = 0x%x base " PADDRX "\n",
95            addr, val, mmio->base);
96 #endif
97 }
98
99 static CPUReadMemoryFunc *unassigned_mmio_read[3] = {
100     unassigned_mmio_readb,
101     unassigned_mmio_readb,
102     unassigned_mmio_readb,
103 };
104
105 static CPUWriteMemoryFunc *unassigned_mmio_write[3] = {
106     unassigned_mmio_writeb,
107     unassigned_mmio_writeb,
108     unassigned_mmio_writeb,
109 };
110
111 static uint32_t mmio_readlen (ppc4xx_mmio_t *mmio,
112                               target_phys_addr_t addr, int len)
113 {
114     CPUReadMemoryFunc **mem_read;
115     uint32_t ret;
116     int idx;
117
118     idx = MMIO_IDX(addr);
119 #if defined(DEBUG_MMIO)
120     printf("%s: mmio %p len %d addr " PADDRX " idx %d\n", __func__,
121            mmio, len, addr, idx);
122 #endif
123     mem_read = mmio->mem_read[idx];
124     ret = (*mem_read[len])(mmio->opaque[idx], addr);
125
126     return ret;
127 }
128
129 static void mmio_writelen (ppc4xx_mmio_t *mmio,
130                            target_phys_addr_t addr, uint32_t value, int len)
131 {
132     CPUWriteMemoryFunc **mem_write;
133     int idx;
134
135     idx = MMIO_IDX(addr);
136 #if defined(DEBUG_MMIO)
137     printf("%s: mmio %p len %d addr " PADDRX " idx %d value %08" PRIx32 "\n",
138            __func__, mmio, len, addr, idx, value);
139 #endif
140     mem_write = mmio->mem_write[idx];
141     (*mem_write[len])(mmio->opaque[idx], addr, value);
142 }
143
144 static uint32_t mmio_readb (void *opaque, target_phys_addr_t addr)
145 {
146 #if defined(DEBUG_MMIO)
147     printf("%s: addr " PADDRX "\n", __func__, addr);
148 #endif
149
150     return mmio_readlen(opaque, addr, 0);
151 }
152
153 static void mmio_writeb (void *opaque,
154                          target_phys_addr_t addr, uint32_t value)
155 {
156 #if defined(DEBUG_MMIO)
157     printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);
158 #endif
159     mmio_writelen(opaque, addr, value, 0);
160 }
161
162 static uint32_t mmio_readw (void *opaque, target_phys_addr_t addr)
163 {
164 #if defined(DEBUG_MMIO)
165     printf("%s: addr " PADDRX "\n", __func__, addr);
166 #endif
167
168     return mmio_readlen(opaque, addr, 1);
169 }
170
171 static void mmio_writew (void *opaque,
172                          target_phys_addr_t addr, uint32_t value)
173 {
174 #if defined(DEBUG_MMIO)
175     printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);
176 #endif
177     mmio_writelen(opaque, addr, value, 1);
178 }
179
180 static uint32_t mmio_readl (void *opaque, target_phys_addr_t addr)
181 {
182 #if defined(DEBUG_MMIO)
183     printf("%s: addr " PADDRX "\n", __func__, addr);
184 #endif
185
186     return mmio_readlen(opaque, addr, 2);
187 }
188
189 static void mmio_writel (void *opaque,
190                          target_phys_addr_t addr, uint32_t value)
191 {
192 #if defined(DEBUG_MMIO)
193     printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);
194 #endif
195     mmio_writelen(opaque, addr, value, 2);
196 }
197
198 static CPUReadMemoryFunc *mmio_read[] = {
199     &mmio_readb,
200     &mmio_readw,
201     &mmio_readl,
202 };
203
204 static CPUWriteMemoryFunc *mmio_write[] = {
205     &mmio_writeb,
206     &mmio_writew,
207     &mmio_writel,
208 };
209
210 int ppc4xx_mmio_register (CPUState *env, ppc4xx_mmio_t *mmio,
211                           target_phys_addr_t offset, uint32_t len,
212                           CPUReadMemoryFunc **mem_read,
213                           CPUWriteMemoryFunc **mem_write, void *opaque)
214 {
215     target_phys_addr_t end;
216     int idx, eidx;
217
218     if ((offset + len) > TARGET_PAGE_SIZE)
219         return -1;
220     idx = MMIO_IDX(offset);
221     end = offset + len - 1;
222     eidx = MMIO_IDX(end);
223 #if defined(DEBUG_MMIO)
224     printf("%s: offset " PADDRX " len %08" PRIx32 " " PADDRX " %d %d\n",
225            __func__, offset, len, end, idx, eidx);
226 #endif
227     for (; idx <= eidx; idx++) {
228         mmio->mem_read[idx] = mem_read;
229         mmio->mem_write[idx] = mem_write;
230         mmio->opaque[idx] = opaque;
231     }
232
233     return 0;
234 }
235
236 ppc4xx_mmio_t *ppc4xx_mmio_init (CPUState *env, target_phys_addr_t base)
237 {
238     ppc4xx_mmio_t *mmio;
239     int mmio_memory;
240
241     mmio = qemu_mallocz(sizeof(ppc4xx_mmio_t));
242     if (mmio != NULL) {
243         mmio->base = base;
244         mmio_memory = cpu_register_io_memory(0, mmio_read, mmio_write, mmio);
245 #if defined(DEBUG_MMIO)
246         printf("%s: base " PADDRX " len %08x %d\n", __func__,
247                base, TARGET_PAGE_SIZE, mmio_memory);
248 #endif
249         cpu_register_physical_memory(base, TARGET_PAGE_SIZE, mmio_memory);
250         ppc4xx_mmio_register(env, mmio, 0, TARGET_PAGE_SIZE,
251                              unassigned_mmio_read, unassigned_mmio_write,
252                              mmio);
253     }
254
255     return mmio;
256 }
257
258 /*****************************************************************************/
259 /* "Universal" Interrupt controller */
260 enum {
261     DCR_UICSR  = 0x000,
262     DCR_UICSRS = 0x001,
263     DCR_UICER  = 0x002,
264     DCR_UICCR  = 0x003,
265     DCR_UICPR  = 0x004,
266     DCR_UICTR  = 0x005,
267     DCR_UICMSR = 0x006,
268     DCR_UICVR  = 0x007,
269     DCR_UICVCR = 0x008,
270     DCR_UICMAX = 0x009,
271 };
272
273 #define UIC_MAX_IRQ 32
274 typedef struct ppcuic_t ppcuic_t;
275 struct ppcuic_t {
276     uint32_t dcr_base;
277     int use_vectors;
278     uint32_t level;  /* Remembers the state of level-triggered interrupts. */
279     uint32_t uicsr;  /* Status register */
280     uint32_t uicer;  /* Enable register */
281     uint32_t uiccr;  /* Critical register */
282     uint32_t uicpr;  /* Polarity register */
283     uint32_t uictr;  /* Triggering register */
284     uint32_t uicvcr; /* Vector configuration register */
285     uint32_t uicvr;
286     qemu_irq *irqs;
287 };
288
289 static void ppcuic_trigger_irq (ppcuic_t *uic)
290 {
291     uint32_t ir, cr;
292     int start, end, inc, i;
293
294     /* Trigger interrupt if any is pending */
295     ir = uic->uicsr & uic->uicer & (~uic->uiccr);
296     cr = uic->uicsr & uic->uicer & uic->uiccr;
297 #ifdef DEBUG_UIC
298     if (loglevel & CPU_LOG_INT) {
299         fprintf(logfile, "%s: uicsr %08" PRIx32 " uicer %08" PRIx32
300                 " uiccr %08" PRIx32 "\n"
301                 "   %08" PRIx32 " ir %08" PRIx32 " cr %08" PRIx32 "\n",
302                 __func__, uic->uicsr, uic->uicer, uic->uiccr,
303                 uic->uicsr & uic->uicer, ir, cr);
304     }
305 #endif
306     if (ir != 0x0000000) {
307 #ifdef DEBUG_UIC
308         if (loglevel & CPU_LOG_INT) {
309             fprintf(logfile, "Raise UIC interrupt\n");
310         }
311 #endif
312         qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_INT]);
313     } else {
314 #ifdef DEBUG_UIC
315         if (loglevel & CPU_LOG_INT) {
316             fprintf(logfile, "Lower UIC interrupt\n");
317         }
318 #endif
319         qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_INT]);
320     }
321     /* Trigger critical interrupt if any is pending and update vector */
322     if (cr != 0x0000000) {
323         qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_CINT]);
324         if (uic->use_vectors) {
325             /* Compute critical IRQ vector */
326             if (uic->uicvcr & 1) {
327                 start = 31;
328                 end = 0;
329                 inc = -1;
330             } else {
331                 start = 0;
332                 end = 31;
333                 inc = 1;
334             }
335             uic->uicvr = uic->uicvcr & 0xFFFFFFFC;
336             for (i = start; i <= end; i += inc) {
337                 if (cr & (1 << i)) {
338                     uic->uicvr += (i - start) * 512 * inc;
339                     break;
340                 }
341             }
342         }
343 #ifdef DEBUG_UIC
344         if (loglevel & CPU_LOG_INT) {
345             fprintf(logfile, "Raise UIC critical interrupt - "
346                     "vector %08" PRIx32 "\n", uic->uicvr);
347         }
348 #endif
349     } else {
350 #ifdef DEBUG_UIC
351         if (loglevel & CPU_LOG_INT) {
352             fprintf(logfile, "Lower UIC critical interrupt\n");
353         }
354 #endif
355         qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_CINT]);
356         uic->uicvr = 0x00000000;
357     }
358 }
359
360 static void ppcuic_set_irq (void *opaque, int irq_num, int level)
361 {
362     ppcuic_t *uic;
363     uint32_t mask, sr;
364
365     uic = opaque;
366     mask = 1 << (31-irq_num);
367 #ifdef DEBUG_UIC
368     if (loglevel & CPU_LOG_INT) {
369         fprintf(logfile, "%s: irq %d level %d uicsr %08" PRIx32
370                 " mask %08" PRIx32 " => %08" PRIx32 " %08" PRIx32 "\n",
371                 __func__, irq_num, level,
372                 uic->uicsr, mask, uic->uicsr & mask, level << irq_num);
373     }
374 #endif
375     if (irq_num < 0 || irq_num > 31)
376         return;
377     sr = uic->uicsr;
378
379     /* Update status register */
380     if (uic->uictr & mask) {
381         /* Edge sensitive interrupt */
382         if (level == 1)
383             uic->uicsr |= mask;
384     } else {
385         /* Level sensitive interrupt */
386         if (level == 1) {
387             uic->uicsr |= mask;
388             uic->level |= mask;
389         } else {
390             uic->uicsr &= ~mask;
391             uic->level &= ~mask;
392         }
393     }
394 #ifdef DEBUG_UIC
395     if (loglevel & CPU_LOG_INT) {
396         fprintf(logfile, "%s: irq %d level %d sr %" PRIx32 " => "
397                 "%08" PRIx32 "\n", __func__, irq_num, level, uic->uicsr, sr);
398     }
399 #endif
400     if (sr != uic->uicsr)
401         ppcuic_trigger_irq(uic);
402 }
403
404 static target_ulong dcr_read_uic (void *opaque, int dcrn)
405 {
406     ppcuic_t *uic;
407     target_ulong ret;
408
409     uic = opaque;
410     dcrn -= uic->dcr_base;
411     switch (dcrn) {
412     case DCR_UICSR:
413     case DCR_UICSRS:
414         ret = uic->uicsr;
415         break;
416     case DCR_UICER:
417         ret = uic->uicer;
418         break;
419     case DCR_UICCR:
420         ret = uic->uiccr;
421         break;
422     case DCR_UICPR:
423         ret = uic->uicpr;
424         break;
425     case DCR_UICTR:
426         ret = uic->uictr;
427         break;
428     case DCR_UICMSR:
429         ret = uic->uicsr & uic->uicer;
430         break;
431     case DCR_UICVR:
432         if (!uic->use_vectors)
433             goto no_read;
434         ret = uic->uicvr;
435         break;
436     case DCR_UICVCR:
437         if (!uic->use_vectors)
438             goto no_read;
439         ret = uic->uicvcr;
440         break;
441     default:
442     no_read:
443         ret = 0x00000000;
444         break;
445     }
446
447     return ret;
448 }
449
450 static void dcr_write_uic (void *opaque, int dcrn, target_ulong val)
451 {
452     ppcuic_t *uic;
453
454     uic = opaque;
455     dcrn -= uic->dcr_base;
456 #ifdef DEBUG_UIC
457     if (loglevel & CPU_LOG_INT) {
458         fprintf(logfile, "%s: dcr %d val " ADDRX "\n", __func__, dcrn, val);
459     }
460 #endif
461     switch (dcrn) {
462     case DCR_UICSR:
463         uic->uicsr &= ~val;
464         uic->uicsr |= uic->level;
465         ppcuic_trigger_irq(uic);
466         break;
467     case DCR_UICSRS:
468         uic->uicsr |= val;
469         ppcuic_trigger_irq(uic);
470         break;
471     case DCR_UICER:
472         uic->uicer = val;
473         ppcuic_trigger_irq(uic);
474         break;
475     case DCR_UICCR:
476         uic->uiccr = val;
477         ppcuic_trigger_irq(uic);
478         break;
479     case DCR_UICPR:
480         uic->uicpr = val;
481         break;
482     case DCR_UICTR:
483         uic->uictr = val;
484         ppcuic_trigger_irq(uic);
485         break;
486     case DCR_UICMSR:
487         break;
488     case DCR_UICVR:
489         break;
490     case DCR_UICVCR:
491         uic->uicvcr = val & 0xFFFFFFFD;
492         ppcuic_trigger_irq(uic);
493         break;
494     }
495 }
496
497 static void ppcuic_reset (void *opaque)
498 {
499     ppcuic_t *uic;
500
501     uic = opaque;
502     uic->uiccr = 0x00000000;
503     uic->uicer = 0x00000000;
504     uic->uicpr = 0x00000000;
505     uic->uicsr = 0x00000000;
506     uic->uictr = 0x00000000;
507     if (uic->use_vectors) {
508         uic->uicvcr = 0x00000000;
509         uic->uicvr = 0x0000000;
510     }
511 }
512
513 qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
514                        uint32_t dcr_base, int has_ssr, int has_vr)
515 {
516     ppcuic_t *uic;
517     int i;
518
519     uic = qemu_mallocz(sizeof(ppcuic_t));
520     if (uic != NULL) {
521         uic->dcr_base = dcr_base;
522         uic->irqs = irqs;
523         if (has_vr)
524             uic->use_vectors = 1;
525         for (i = 0; i < DCR_UICMAX; i++) {
526             ppc_dcr_register(env, dcr_base + i, uic,
527                              &dcr_read_uic, &dcr_write_uic);
528         }
529         qemu_register_reset(ppcuic_reset, uic);
530         ppcuic_reset(uic);
531     }
532
533     return qemu_allocate_irqs(&ppcuic_set_irq, uic, UIC_MAX_IRQ);
534 }
535
536 /*****************************************************************************/
537 /* SDRAM controller */
538 typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
539 struct ppc4xx_sdram_t {
540     uint32_t addr;
541     int nbanks;
542     target_phys_addr_t ram_bases[4];
543     target_phys_addr_t ram_sizes[4];
544     uint32_t besr0;
545     uint32_t besr1;
546     uint32_t bear;
547     uint32_t cfg;
548     uint32_t status;
549     uint32_t rtr;
550     uint32_t pmit;
551     uint32_t bcr[4];
552     uint32_t tr;
553     uint32_t ecccfg;
554     uint32_t eccesr;
555     qemu_irq irq;
556 };
557
558 enum {
559     SDRAM0_CFGADDR = 0x010,
560     SDRAM0_CFGDATA = 0x011,
561 };
562
563 /* XXX: TOFIX: some patches have made this code become inconsistent:
564  *      there are type inconsistencies, mixing target_phys_addr_t, target_ulong
565  *      and uint32_t
566  */
567 static uint32_t sdram_bcr (target_phys_addr_t ram_base,
568                            target_phys_addr_t ram_size)
569 {
570     uint32_t bcr;
571
572     switch (ram_size) {
573     case (4 * 1024 * 1024):
574         bcr = 0x00000000;
575         break;
576     case (8 * 1024 * 1024):
577         bcr = 0x00020000;
578         break;
579     case (16 * 1024 * 1024):
580         bcr = 0x00040000;
581         break;
582     case (32 * 1024 * 1024):
583         bcr = 0x00060000;
584         break;
585     case (64 * 1024 * 1024):
586         bcr = 0x00080000;
587         break;
588     case (128 * 1024 * 1024):
589         bcr = 0x000A0000;
590         break;
591     case (256 * 1024 * 1024):
592         bcr = 0x000C0000;
593         break;
594     default:
595         printf("%s: invalid RAM size " PADDRX "\n", __func__, ram_size);
596         return 0x00000000;
597     }
598     bcr |= ram_base & 0xFF800000;
599     bcr |= 1;
600
601     return bcr;
602 }
603
604 static always_inline target_phys_addr_t sdram_base (uint32_t bcr)
605 {
606     return bcr & 0xFF800000;
607 }
608
609 static target_ulong sdram_size (uint32_t bcr)
610 {
611     target_ulong size;
612     int sh;
613
614     sh = (bcr >> 17) & 0x7;
615     if (sh == 7)
616         size = -1;
617     else
618         size = (4 * 1024 * 1024) << sh;
619
620     return size;
621 }
622
623 static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled)
624 {
625     if (*bcrp & 0x00000001) {
626         /* Unmap RAM */
627 #ifdef DEBUG_SDRAM
628         printf("%s: unmap RAM area " PADDRX " " ADDRX "\n",
629                __func__, sdram_base(*bcrp), sdram_size(*bcrp));
630 #endif
631         cpu_register_physical_memory(sdram_base(*bcrp), sdram_size(*bcrp),
632                                      IO_MEM_UNASSIGNED);
633     }
634     *bcrp = bcr & 0xFFDEE001;
635     if (enabled && (bcr & 0x00000001)) {
636 #ifdef DEBUG_SDRAM
637         printf("%s: Map RAM area " PADDRX " " ADDRX "\n",
638                __func__, sdram_base(bcr), sdram_size(bcr));
639 #endif
640         cpu_register_physical_memory(sdram_base(bcr), sdram_size(bcr),
641                                      sdram_base(bcr) | IO_MEM_RAM);
642     }
643 }
644
645 static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
646 {
647     int i;
648
649     for (i = 0; i < sdram->nbanks; i++) {
650         if (sdram->ram_sizes[i] != 0) {
651             sdram_set_bcr(&sdram->bcr[i],
652                           sdram_bcr(sdram->ram_bases[i], sdram->ram_sizes[i]),
653                           1);
654         } else {
655             sdram_set_bcr(&sdram->bcr[i], 0x00000000, 0);
656         }
657     }
658 }
659
660 static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
661 {
662     int i;
663
664     for (i = 0; i < sdram->nbanks; i++) {
665 #ifdef DEBUG_SDRAM
666         printf("%s: Unmap RAM area " PADDRX " " ADDRX "\n",
667                __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
668 #endif
669         cpu_register_physical_memory(sdram_base(sdram->bcr[i]),
670                                      sdram_size(sdram->bcr[i]),
671                                      IO_MEM_UNASSIGNED);
672     }
673 }
674
675 static target_ulong dcr_read_sdram (void *opaque, int dcrn)
676 {
677     ppc4xx_sdram_t *sdram;
678     target_ulong ret;
679
680     sdram = opaque;
681     switch (dcrn) {
682     case SDRAM0_CFGADDR:
683         ret = sdram->addr;
684         break;
685     case SDRAM0_CFGDATA:
686         switch (sdram->addr) {
687         case 0x00: /* SDRAM_BESR0 */
688             ret = sdram->besr0;
689             break;
690         case 0x08: /* SDRAM_BESR1 */
691             ret = sdram->besr1;
692             break;
693         case 0x10: /* SDRAM_BEAR */
694             ret = sdram->bear;
695             break;
696         case 0x20: /* SDRAM_CFG */
697             ret = sdram->cfg;
698             break;
699         case 0x24: /* SDRAM_STATUS */
700             ret = sdram->status;
701             break;
702         case 0x30: /* SDRAM_RTR */
703             ret = sdram->rtr;
704             break;
705         case 0x34: /* SDRAM_PMIT */
706             ret = sdram->pmit;
707             break;
708         case 0x40: /* SDRAM_B0CR */
709             ret = sdram->bcr[0];
710             break;
711         case 0x44: /* SDRAM_B1CR */
712             ret = sdram->bcr[1];
713             break;
714         case 0x48: /* SDRAM_B2CR */
715             ret = sdram->bcr[2];
716             break;
717         case 0x4C: /* SDRAM_B3CR */
718             ret = sdram->bcr[3];
719             break;
720         case 0x80: /* SDRAM_TR */
721             ret = -1; /* ? */
722             break;
723         case 0x94: /* SDRAM_ECCCFG */
724             ret = sdram->ecccfg;
725             break;
726         case 0x98: /* SDRAM_ECCESR */
727             ret = sdram->eccesr;
728             break;
729         default: /* Error */
730             ret = -1;
731             break;
732         }
733         break;
734     default:
735         /* Avoid gcc warning */
736         ret = 0x00000000;
737         break;
738     }
739
740     return ret;
741 }
742
743 static void dcr_write_sdram (void *opaque, int dcrn, target_ulong val)
744 {
745     ppc4xx_sdram_t *sdram;
746
747     sdram = opaque;
748     switch (dcrn) {
749     case SDRAM0_CFGADDR:
750         sdram->addr = val;
751         break;
752     case SDRAM0_CFGDATA:
753         switch (sdram->addr) {
754         case 0x00: /* SDRAM_BESR0 */
755             sdram->besr0 &= ~val;
756             break;
757         case 0x08: /* SDRAM_BESR1 */
758             sdram->besr1 &= ~val;
759             break;
760         case 0x10: /* SDRAM_BEAR */
761             sdram->bear = val;
762             break;
763         case 0x20: /* SDRAM_CFG */
764             val &= 0xFFE00000;
765             if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {
766 #ifdef DEBUG_SDRAM
767                 printf("%s: enable SDRAM controller\n", __func__);
768 #endif
769                 /* validate all RAM mappings */
770                 sdram_map_bcr(sdram);
771                 sdram->status &= ~0x80000000;
772             } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {
773 #ifdef DEBUG_SDRAM
774                 printf("%s: disable SDRAM controller\n", __func__);
775 #endif
776                 /* invalidate all RAM mappings */
777                 sdram_unmap_bcr(sdram);
778                 sdram->status |= 0x80000000;
779             }
780             if (!(sdram->cfg & 0x40000000) && (val & 0x40000000))
781                 sdram->status |= 0x40000000;
782             else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000))
783                 sdram->status &= ~0x40000000;
784             sdram->cfg = val;
785             break;
786         case 0x24: /* SDRAM_STATUS */
787             /* Read-only register */
788             break;
789         case 0x30: /* SDRAM_RTR */
790             sdram->rtr = val & 0x3FF80000;
791             break;
792         case 0x34: /* SDRAM_PMIT */
793             sdram->pmit = (val & 0xF8000000) | 0x07C00000;
794             break;
795         case 0x40: /* SDRAM_B0CR */
796             sdram_set_bcr(&sdram->bcr[0], val, sdram->cfg & 0x80000000);
797             break;
798         case 0x44: /* SDRAM_B1CR */
799             sdram_set_bcr(&sdram->bcr[1], val, sdram->cfg & 0x80000000);
800             break;
801         case 0x48: /* SDRAM_B2CR */
802             sdram_set_bcr(&sdram->bcr[2], val, sdram->cfg & 0x80000000);
803             break;
804         case 0x4C: /* SDRAM_B3CR */
805             sdram_set_bcr(&sdram->bcr[3], val, sdram->cfg & 0x80000000);
806             break;
807         case 0x80: /* SDRAM_TR */
808             sdram->tr = val & 0x018FC01F;
809             break;
810         case 0x94: /* SDRAM_ECCCFG */
811             sdram->ecccfg = val & 0x00F00000;
812             break;
813         case 0x98: /* SDRAM_ECCESR */
814             val &= 0xFFF0F000;
815             if (sdram->eccesr == 0 && val != 0)
816                 qemu_irq_raise(sdram->irq);
817             else if (sdram->eccesr != 0 && val == 0)
818                 qemu_irq_lower(sdram->irq);
819             sdram->eccesr = val;
820             break;
821         default: /* Error */
822             break;
823         }
824         break;
825     }
826 }
827
828 static void sdram_reset (void *opaque)
829 {
830     ppc4xx_sdram_t *sdram;
831
832     sdram = opaque;
833     sdram->addr = 0x00000000;
834     sdram->bear = 0x00000000;
835     sdram->besr0 = 0x00000000; /* No error */
836     sdram->besr1 = 0x00000000; /* No error */
837     sdram->cfg = 0x00000000;
838     sdram->ecccfg = 0x00000000; /* No ECC */
839     sdram->eccesr = 0x00000000; /* No error */
840     sdram->pmit = 0x07C00000;
841     sdram->rtr = 0x05F00000;
842     sdram->tr = 0x00854009;
843     /* We pre-initialize RAM banks */
844     sdram->status = 0x00000000;
845     sdram->cfg = 0x00800000;
846     sdram_unmap_bcr(sdram);
847 }
848
849 void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
850                         target_phys_addr_t *ram_bases,
851                         target_phys_addr_t *ram_sizes,
852                         int do_init)
853 {
854     ppc4xx_sdram_t *sdram;
855
856     sdram = qemu_mallocz(sizeof(ppc4xx_sdram_t));
857     if (sdram != NULL) {
858         sdram->irq = irq;
859         sdram->nbanks = nbanks;
860         memset(sdram->ram_bases, 0, 4 * sizeof(target_phys_addr_t));
861         memcpy(sdram->ram_bases, ram_bases,
862                nbanks * sizeof(target_phys_addr_t));
863         memset(sdram->ram_sizes, 0, 4 * sizeof(target_phys_addr_t));
864         memcpy(sdram->ram_sizes, ram_sizes,
865                nbanks * sizeof(target_phys_addr_t));
866         sdram_reset(sdram);
867         qemu_register_reset(&sdram_reset, sdram);
868         ppc_dcr_register(env, SDRAM0_CFGADDR,
869                          sdram, &dcr_read_sdram, &dcr_write_sdram);
870         ppc_dcr_register(env, SDRAM0_CFGDATA,
871                          sdram, &dcr_read_sdram, &dcr_write_sdram);
872         if (do_init)
873             sdram_map_bcr(sdram);
874     }
875 }