Revision 61b24405 hw/ppc405_uc.c

b/hw/ppc405_uc.c
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 {

Also available in: Unified diff