Commit 61b244050334f88de5bed0c8cd8af8503aaa0931
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
Showing
4 changed files
with
346 additions
and
346 deletions
hw/ppc405.h
... | ... | @@ -66,11 +66,6 @@ void ppc4xx_pob_init (CPUState *env); |
66 | 66 | /* OPB arbitrer */ |
67 | 67 | void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio, |
68 | 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 | 69 | /* Peripheral controller */ |
75 | 70 | void ppc405_ebc_init (CPUState *env); |
76 | 71 | /* DMA controller */ | ... | ... |
hw/ppc405_uc.c
... | ... | @@ -401,347 +401,6 @@ void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio, |
401 | 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 | 404 | /* Peripheral controller */ |
746 | 405 | typedef struct ppc4xx_ebc_t ppc4xx_ebc_t; |
747 | 406 | struct ppc4xx_ebc_t { | ... | ... |
hw/ppc4xx.h
... | ... | @@ -48,6 +48,11 @@ enum { |
48 | 48 | qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs, |
49 | 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 | 56 | PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], |
52 | 57 | target_phys_addr_t config_space, |
53 | 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 | 532 | |
533 | 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 | +} | ... | ... |