Commit 61b244050334f88de5bed0c8cd8af8503aaa0931

Authored by aurel32
1 parent f5d6f51b

target-ppc: move PPC4xx SDRAM controller emulation from ppc405_uc.c to ppc4xx_devs.c

The SDRAM controller is shared across almost all 405 and 440 embedded
processors, with some slight differences such as the sizes supported for each
memory bank.

Code movement only; no functional changes.

Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6061 c046a42c-6fe2-441c-8c8c-71466251a162
hw/ppc405.h
@@ -66,11 +66,6 @@ void ppc4xx_pob_init (CPUState *env); @@ -66,11 +66,6 @@ void ppc4xx_pob_init (CPUState *env);
66 /* OPB arbitrer */ 66 /* OPB arbitrer */
67 void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio, 67 void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio,
68 target_phys_addr_t offset); 68 target_phys_addr_t offset);
69 -/* SDRAM controller */  
70 -void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,  
71 - target_phys_addr_t *ram_bases,  
72 - target_phys_addr_t *ram_sizes,  
73 - int do_init);  
74 /* Peripheral controller */ 69 /* Peripheral controller */
75 void ppc405_ebc_init (CPUState *env); 70 void ppc405_ebc_init (CPUState *env);
76 /* DMA controller */ 71 /* DMA controller */
hw/ppc405_uc.c
@@ -401,347 +401,6 @@ void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio, @@ -401,347 +401,6 @@ void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio,
401 /* XXX: TODO */ 401 /* XXX: TODO */
402 402
403 /*****************************************************************************/ 403 /*****************************************************************************/
404 -/* SDRAM controller */  
405 -typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;  
406 -struct ppc4xx_sdram_t {  
407 - uint32_t addr;  
408 - int nbanks;  
409 - target_phys_addr_t ram_bases[4];  
410 - target_phys_addr_t ram_sizes[4];  
411 - uint32_t besr0;  
412 - uint32_t besr1;  
413 - uint32_t bear;  
414 - uint32_t cfg;  
415 - uint32_t status;  
416 - uint32_t rtr;  
417 - uint32_t pmit;  
418 - uint32_t bcr[4];  
419 - uint32_t tr;  
420 - uint32_t ecccfg;  
421 - uint32_t eccesr;  
422 - qemu_irq irq;  
423 -};  
424 -  
425 -enum {  
426 - SDRAM0_CFGADDR = 0x010,  
427 - SDRAM0_CFGDATA = 0x011,  
428 -};  
429 -  
430 -/* XXX: TOFIX: some patches have made this code become inconsistent:  
431 - * there are type inconsistencies, mixing target_phys_addr_t, target_ulong  
432 - * and uint32_t  
433 - */  
434 -static uint32_t sdram_bcr (target_phys_addr_t ram_base,  
435 - target_phys_addr_t ram_size)  
436 -{  
437 - uint32_t bcr;  
438 -  
439 - switch (ram_size) {  
440 - case (4 * 1024 * 1024):  
441 - bcr = 0x00000000;  
442 - break;  
443 - case (8 * 1024 * 1024):  
444 - bcr = 0x00020000;  
445 - break;  
446 - case (16 * 1024 * 1024):  
447 - bcr = 0x00040000;  
448 - break;  
449 - case (32 * 1024 * 1024):  
450 - bcr = 0x00060000;  
451 - break;  
452 - case (64 * 1024 * 1024):  
453 - bcr = 0x00080000;  
454 - break;  
455 - case (128 * 1024 * 1024):  
456 - bcr = 0x000A0000;  
457 - break;  
458 - case (256 * 1024 * 1024):  
459 - bcr = 0x000C0000;  
460 - break;  
461 - default:  
462 - printf("%s: invalid RAM size " PADDRX "\n", __func__, ram_size);  
463 - return 0x00000000;  
464 - }  
465 - bcr |= ram_base & 0xFF800000;  
466 - bcr |= 1;  
467 -  
468 - return bcr;  
469 -}  
470 -  
471 -static always_inline target_phys_addr_t sdram_base (uint32_t bcr)  
472 -{  
473 - return bcr & 0xFF800000;  
474 -}  
475 -  
476 -static target_ulong sdram_size (uint32_t bcr)  
477 -{  
478 - target_ulong size;  
479 - int sh;  
480 -  
481 - sh = (bcr >> 17) & 0x7;  
482 - if (sh == 7)  
483 - size = -1;  
484 - else  
485 - size = (4 * 1024 * 1024) << sh;  
486 -  
487 - return size;  
488 -}  
489 -  
490 -static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled)  
491 -{  
492 - if (*bcrp & 0x00000001) {  
493 - /* Unmap RAM */  
494 -#ifdef DEBUG_SDRAM  
495 - printf("%s: unmap RAM area " PADDRX " " ADDRX "\n",  
496 - __func__, sdram_base(*bcrp), sdram_size(*bcrp));  
497 -#endif  
498 - cpu_register_physical_memory(sdram_base(*bcrp), sdram_size(*bcrp),  
499 - IO_MEM_UNASSIGNED);  
500 - }  
501 - *bcrp = bcr & 0xFFDEE001;  
502 - if (enabled && (bcr & 0x00000001)) {  
503 -#ifdef DEBUG_SDRAM  
504 - printf("%s: Map RAM area " PADDRX " " ADDRX "\n",  
505 - __func__, sdram_base(bcr), sdram_size(bcr));  
506 -#endif  
507 - cpu_register_physical_memory(sdram_base(bcr), sdram_size(bcr),  
508 - sdram_base(bcr) | IO_MEM_RAM);  
509 - }  
510 -}  
511 -  
512 -static void sdram_map_bcr (ppc4xx_sdram_t *sdram)  
513 -{  
514 - int i;  
515 -  
516 - for (i = 0; i < sdram->nbanks; i++) {  
517 - if (sdram->ram_sizes[i] != 0) {  
518 - sdram_set_bcr(&sdram->bcr[i],  
519 - sdram_bcr(sdram->ram_bases[i], sdram->ram_sizes[i]),  
520 - 1);  
521 - } else {  
522 - sdram_set_bcr(&sdram->bcr[i], 0x00000000, 0);  
523 - }  
524 - }  
525 -}  
526 -  
527 -static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)  
528 -{  
529 - int i;  
530 -  
531 - for (i = 0; i < sdram->nbanks; i++) {  
532 -#ifdef DEBUG_SDRAM  
533 - printf("%s: Unmap RAM area " PADDRX " " ADDRX "\n",  
534 - __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));  
535 -#endif  
536 - cpu_register_physical_memory(sdram_base(sdram->bcr[i]),  
537 - sdram_size(sdram->bcr[i]),  
538 - IO_MEM_UNASSIGNED);  
539 - }  
540 -}  
541 -  
542 -static target_ulong dcr_read_sdram (void *opaque, int dcrn)  
543 -{  
544 - ppc4xx_sdram_t *sdram;  
545 - target_ulong ret;  
546 -  
547 - sdram = opaque;  
548 - switch (dcrn) {  
549 - case SDRAM0_CFGADDR:  
550 - ret = sdram->addr;  
551 - break;  
552 - case SDRAM0_CFGDATA:  
553 - switch (sdram->addr) {  
554 - case 0x00: /* SDRAM_BESR0 */  
555 - ret = sdram->besr0;  
556 - break;  
557 - case 0x08: /* SDRAM_BESR1 */  
558 - ret = sdram->besr1;  
559 - break;  
560 - case 0x10: /* SDRAM_BEAR */  
561 - ret = sdram->bear;  
562 - break;  
563 - case 0x20: /* SDRAM_CFG */  
564 - ret = sdram->cfg;  
565 - break;  
566 - case 0x24: /* SDRAM_STATUS */  
567 - ret = sdram->status;  
568 - break;  
569 - case 0x30: /* SDRAM_RTR */  
570 - ret = sdram->rtr;  
571 - break;  
572 - case 0x34: /* SDRAM_PMIT */  
573 - ret = sdram->pmit;  
574 - break;  
575 - case 0x40: /* SDRAM_B0CR */  
576 - ret = sdram->bcr[0];  
577 - break;  
578 - case 0x44: /* SDRAM_B1CR */  
579 - ret = sdram->bcr[1];  
580 - break;  
581 - case 0x48: /* SDRAM_B2CR */  
582 - ret = sdram->bcr[2];  
583 - break;  
584 - case 0x4C: /* SDRAM_B3CR */  
585 - ret = sdram->bcr[3];  
586 - break;  
587 - case 0x80: /* SDRAM_TR */  
588 - ret = -1; /* ? */  
589 - break;  
590 - case 0x94: /* SDRAM_ECCCFG */  
591 - ret = sdram->ecccfg;  
592 - break;  
593 - case 0x98: /* SDRAM_ECCESR */  
594 - ret = sdram->eccesr;  
595 - break;  
596 - default: /* Error */  
597 - ret = -1;  
598 - break;  
599 - }  
600 - break;  
601 - default:  
602 - /* Avoid gcc warning */  
603 - ret = 0x00000000;  
604 - break;  
605 - }  
606 -  
607 - return ret;  
608 -}  
609 -  
610 -static void dcr_write_sdram (void *opaque, int dcrn, target_ulong val)  
611 -{  
612 - ppc4xx_sdram_t *sdram;  
613 -  
614 - sdram = opaque;  
615 - switch (dcrn) {  
616 - case SDRAM0_CFGADDR:  
617 - sdram->addr = val;  
618 - break;  
619 - case SDRAM0_CFGDATA:  
620 - switch (sdram->addr) {  
621 - case 0x00: /* SDRAM_BESR0 */  
622 - sdram->besr0 &= ~val;  
623 - break;  
624 - case 0x08: /* SDRAM_BESR1 */  
625 - sdram->besr1 &= ~val;  
626 - break;  
627 - case 0x10: /* SDRAM_BEAR */  
628 - sdram->bear = val;  
629 - break;  
630 - case 0x20: /* SDRAM_CFG */  
631 - val &= 0xFFE00000;  
632 - if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {  
633 -#ifdef DEBUG_SDRAM  
634 - printf("%s: enable SDRAM controller\n", __func__);  
635 -#endif  
636 - /* validate all RAM mappings */  
637 - sdram_map_bcr(sdram);  
638 - sdram->status &= ~0x80000000;  
639 - } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {  
640 -#ifdef DEBUG_SDRAM  
641 - printf("%s: disable SDRAM controller\n", __func__);  
642 -#endif  
643 - /* invalidate all RAM mappings */  
644 - sdram_unmap_bcr(sdram);  
645 - sdram->status |= 0x80000000;  
646 - }  
647 - if (!(sdram->cfg & 0x40000000) && (val & 0x40000000))  
648 - sdram->status |= 0x40000000;  
649 - else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000))  
650 - sdram->status &= ~0x40000000;  
651 - sdram->cfg = val;  
652 - break;  
653 - case 0x24: /* SDRAM_STATUS */  
654 - /* Read-only register */  
655 - break;  
656 - case 0x30: /* SDRAM_RTR */  
657 - sdram->rtr = val & 0x3FF80000;  
658 - break;  
659 - case 0x34: /* SDRAM_PMIT */  
660 - sdram->pmit = (val & 0xF8000000) | 0x07C00000;  
661 - break;  
662 - case 0x40: /* SDRAM_B0CR */  
663 - sdram_set_bcr(&sdram->bcr[0], val, sdram->cfg & 0x80000000);  
664 - break;  
665 - case 0x44: /* SDRAM_B1CR */  
666 - sdram_set_bcr(&sdram->bcr[1], val, sdram->cfg & 0x80000000);  
667 - break;  
668 - case 0x48: /* SDRAM_B2CR */  
669 - sdram_set_bcr(&sdram->bcr[2], val, sdram->cfg & 0x80000000);  
670 - break;  
671 - case 0x4C: /* SDRAM_B3CR */  
672 - sdram_set_bcr(&sdram->bcr[3], val, sdram->cfg & 0x80000000);  
673 - break;  
674 - case 0x80: /* SDRAM_TR */  
675 - sdram->tr = val & 0x018FC01F;  
676 - break;  
677 - case 0x94: /* SDRAM_ECCCFG */  
678 - sdram->ecccfg = val & 0x00F00000;  
679 - break;  
680 - case 0x98: /* SDRAM_ECCESR */  
681 - val &= 0xFFF0F000;  
682 - if (sdram->eccesr == 0 && val != 0)  
683 - qemu_irq_raise(sdram->irq);  
684 - else if (sdram->eccesr != 0 && val == 0)  
685 - qemu_irq_lower(sdram->irq);  
686 - sdram->eccesr = val;  
687 - break;  
688 - default: /* Error */  
689 - break;  
690 - }  
691 - break;  
692 - }  
693 -}  
694 -  
695 -static void sdram_reset (void *opaque)  
696 -{  
697 - ppc4xx_sdram_t *sdram;  
698 -  
699 - sdram = opaque;  
700 - sdram->addr = 0x00000000;  
701 - sdram->bear = 0x00000000;  
702 - sdram->besr0 = 0x00000000; /* No error */  
703 - sdram->besr1 = 0x00000000; /* No error */  
704 - sdram->cfg = 0x00000000;  
705 - sdram->ecccfg = 0x00000000; /* No ECC */  
706 - sdram->eccesr = 0x00000000; /* No error */  
707 - sdram->pmit = 0x07C00000;  
708 - sdram->rtr = 0x05F00000;  
709 - sdram->tr = 0x00854009;  
710 - /* We pre-initialize RAM banks */  
711 - sdram->status = 0x00000000;  
712 - sdram->cfg = 0x00800000;  
713 - sdram_unmap_bcr(sdram);  
714 -}  
715 -  
716 -void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,  
717 - target_phys_addr_t *ram_bases,  
718 - target_phys_addr_t *ram_sizes,  
719 - int do_init)  
720 -{  
721 - ppc4xx_sdram_t *sdram;  
722 -  
723 - sdram = qemu_mallocz(sizeof(ppc4xx_sdram_t));  
724 - if (sdram != NULL) {  
725 - sdram->irq = irq;  
726 - sdram->nbanks = nbanks;  
727 - memset(sdram->ram_bases, 0, 4 * sizeof(target_phys_addr_t));  
728 - memcpy(sdram->ram_bases, ram_bases,  
729 - nbanks * sizeof(target_phys_addr_t));  
730 - memset(sdram->ram_sizes, 0, 4 * sizeof(target_phys_addr_t));  
731 - memcpy(sdram->ram_sizes, ram_sizes,  
732 - nbanks * sizeof(target_phys_addr_t));  
733 - sdram_reset(sdram);  
734 - qemu_register_reset(&sdram_reset, sdram);  
735 - ppc_dcr_register(env, SDRAM0_CFGADDR,  
736 - sdram, &dcr_read_sdram, &dcr_write_sdram);  
737 - ppc_dcr_register(env, SDRAM0_CFGDATA,  
738 - sdram, &dcr_read_sdram, &dcr_write_sdram);  
739 - if (do_init)  
740 - sdram_map_bcr(sdram);  
741 - }  
742 -}  
743 -  
744 -/*****************************************************************************/  
745 /* Peripheral controller */ 404 /* Peripheral controller */
746 typedef struct ppc4xx_ebc_t ppc4xx_ebc_t; 405 typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
747 struct ppc4xx_ebc_t { 406 struct ppc4xx_ebc_t {
hw/ppc4xx.h
@@ -48,6 +48,11 @@ enum { @@ -48,6 +48,11 @@ enum {
48 qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs, 48 qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
49 uint32_t dcr_base, int has_ssr, int has_vr); 49 uint32_t dcr_base, int has_ssr, int has_vr);
50 50
  51 +void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
  52 + target_phys_addr_t *ram_bases,
  53 + target_phys_addr_t *ram_sizes,
  54 + int do_init);
  55 +
51 PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], 56 PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
52 target_phys_addr_t config_space, 57 target_phys_addr_t config_space,
53 target_phys_addr_t int_ack, 58 target_phys_addr_t int_ack,
hw/ppc4xx_devs.c
@@ -532,3 +532,344 @@ qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs, @@ -532,3 +532,344 @@ qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
532 532
533 return qemu_allocate_irqs(&ppcuic_set_irq, uic, UIC_MAX_IRQ); 533 return qemu_allocate_irqs(&ppcuic_set_irq, uic, UIC_MAX_IRQ);
534 } 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 +}