qemu/hw/ppc/ppc4xx_devs.c
<<
>>
Prefs
   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
  25#include "qemu/osdep.h"
  26#include "qemu/units.h"
  27#include "sysemu/reset.h"
  28#include "cpu.h"
  29#include "hw/irq.h"
  30#include "hw/ppc/ppc.h"
  31#include "hw/ppc/ppc4xx.h"
  32#include "hw/boards.h"
  33#include "qemu/log.h"
  34#include "exec/address-spaces.h"
  35#include "qemu/error-report.h"
  36
  37/*#define DEBUG_UIC*/
  38
  39#ifdef DEBUG_UIC
  40#  define LOG_UIC(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__)
  41#else
  42#  define LOG_UIC(...) do { } while (0)
  43#endif
  44
  45static void ppc4xx_reset(void *opaque)
  46{
  47    PowerPCCPU *cpu = opaque;
  48
  49    cpu_reset(CPU(cpu));
  50}
  51
  52/*****************************************************************************/
  53/* Generic PowerPC 4xx processor instantiation */
  54PowerPCCPU *ppc4xx_init(const char *cpu_type,
  55                        clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
  56                        uint32_t sysclk)
  57{
  58    PowerPCCPU *cpu;
  59    CPUPPCState *env;
  60
  61    /* init CPUs */
  62    cpu = POWERPC_CPU(cpu_create(cpu_type));
  63    env = &cpu->env;
  64
  65    cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
  66    cpu_clk->opaque = env;
  67    /* Set time-base frequency to sysclk */
  68    tb_clk->cb = ppc_40x_timers_init(env, sysclk, PPC_INTERRUPT_PIT);
  69    tb_clk->opaque = env;
  70    ppc_dcr_init(env, NULL, NULL);
  71    /* Register qemu callbacks */
  72    qemu_register_reset(ppc4xx_reset, cpu);
  73
  74    return cpu;
  75}
  76
  77/*****************************************************************************/
  78/* "Universal" Interrupt controller */
  79enum {
  80    DCR_UICSR  = 0x000,
  81    DCR_UICSRS = 0x001,
  82    DCR_UICER  = 0x002,
  83    DCR_UICCR  = 0x003,
  84    DCR_UICPR  = 0x004,
  85    DCR_UICTR  = 0x005,
  86    DCR_UICMSR = 0x006,
  87    DCR_UICVR  = 0x007,
  88    DCR_UICVCR = 0x008,
  89    DCR_UICMAX = 0x009,
  90};
  91
  92#define UIC_MAX_IRQ 32
  93typedef struct ppcuic_t ppcuic_t;
  94struct ppcuic_t {
  95    uint32_t dcr_base;
  96    int use_vectors;
  97    uint32_t level;  /* Remembers the state of level-triggered interrupts. */
  98    uint32_t uicsr;  /* Status register */
  99    uint32_t uicer;  /* Enable register */
 100    uint32_t uiccr;  /* Critical register */
 101    uint32_t uicpr;  /* Polarity register */
 102    uint32_t uictr;  /* Triggering register */
 103    uint32_t uicvcr; /* Vector configuration register */
 104    uint32_t uicvr;
 105    qemu_irq *irqs;
 106};
 107
 108static void ppcuic_trigger_irq (ppcuic_t *uic)
 109{
 110    uint32_t ir, cr;
 111    int start, end, inc, i;
 112
 113    /* Trigger interrupt if any is pending */
 114    ir = uic->uicsr & uic->uicer & (~uic->uiccr);
 115    cr = uic->uicsr & uic->uicer & uic->uiccr;
 116    LOG_UIC("%s: uicsr %08" PRIx32 " uicer %08" PRIx32
 117                " uiccr %08" PRIx32 "\n"
 118                "   %08" PRIx32 " ir %08" PRIx32 " cr %08" PRIx32 "\n",
 119                __func__, uic->uicsr, uic->uicer, uic->uiccr,
 120                uic->uicsr & uic->uicer, ir, cr);
 121    if (ir != 0x0000000) {
 122        LOG_UIC("Raise UIC interrupt\n");
 123        qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_INT]);
 124    } else {
 125        LOG_UIC("Lower UIC interrupt\n");
 126        qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_INT]);
 127    }
 128    /* Trigger critical interrupt if any is pending and update vector */
 129    if (cr != 0x0000000) {
 130        qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_CINT]);
 131        if (uic->use_vectors) {
 132            /* Compute critical IRQ vector */
 133            if (uic->uicvcr & 1) {
 134                start = 31;
 135                end = 0;
 136                inc = -1;
 137            } else {
 138                start = 0;
 139                end = 31;
 140                inc = 1;
 141            }
 142            uic->uicvr = uic->uicvcr & 0xFFFFFFFC;
 143            for (i = start; i <= end; i += inc) {
 144                if (cr & (1 << i)) {
 145                    uic->uicvr += (i - start) * 512 * inc;
 146                    break;
 147                }
 148            }
 149        }
 150        LOG_UIC("Raise UIC critical interrupt - "
 151                    "vector %08" PRIx32 "\n", uic->uicvr);
 152    } else {
 153        LOG_UIC("Lower UIC critical interrupt\n");
 154        qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_CINT]);
 155        uic->uicvr = 0x00000000;
 156    }
 157}
 158
 159static void ppcuic_set_irq (void *opaque, int irq_num, int level)
 160{
 161    ppcuic_t *uic;
 162    uint32_t mask, sr;
 163
 164    uic = opaque;
 165    mask = 1U << (31-irq_num);
 166    LOG_UIC("%s: irq %d level %d uicsr %08" PRIx32
 167                " mask %08" PRIx32 " => %08" PRIx32 " %08" PRIx32 "\n",
 168                __func__, irq_num, level,
 169                uic->uicsr, mask, uic->uicsr & mask, level << irq_num);
 170    if (irq_num < 0 || irq_num > 31)
 171        return;
 172    sr = uic->uicsr;
 173
 174    /* Update status register */
 175    if (uic->uictr & mask) {
 176        /* Edge sensitive interrupt */
 177        if (level == 1)
 178            uic->uicsr |= mask;
 179    } else {
 180        /* Level sensitive interrupt */
 181        if (level == 1) {
 182            uic->uicsr |= mask;
 183            uic->level |= mask;
 184        } else {
 185            uic->uicsr &= ~mask;
 186            uic->level &= ~mask;
 187        }
 188    }
 189    LOG_UIC("%s: irq %d level %d sr %" PRIx32 " => "
 190                "%08" PRIx32 "\n", __func__, irq_num, level, uic->uicsr, sr);
 191    if (sr != uic->uicsr)
 192        ppcuic_trigger_irq(uic);
 193}
 194
 195static uint32_t dcr_read_uic (void *opaque, int dcrn)
 196{
 197    ppcuic_t *uic;
 198    uint32_t ret;
 199
 200    uic = opaque;
 201    dcrn -= uic->dcr_base;
 202    switch (dcrn) {
 203    case DCR_UICSR:
 204    case DCR_UICSRS:
 205        ret = uic->uicsr;
 206        break;
 207    case DCR_UICER:
 208        ret = uic->uicer;
 209        break;
 210    case DCR_UICCR:
 211        ret = uic->uiccr;
 212        break;
 213    case DCR_UICPR:
 214        ret = uic->uicpr;
 215        break;
 216    case DCR_UICTR:
 217        ret = uic->uictr;
 218        break;
 219    case DCR_UICMSR:
 220        ret = uic->uicsr & uic->uicer;
 221        break;
 222    case DCR_UICVR:
 223        if (!uic->use_vectors)
 224            goto no_read;
 225        ret = uic->uicvr;
 226        break;
 227    case DCR_UICVCR:
 228        if (!uic->use_vectors)
 229            goto no_read;
 230        ret = uic->uicvcr;
 231        break;
 232    default:
 233    no_read:
 234        ret = 0x00000000;
 235        break;
 236    }
 237
 238    return ret;
 239}
 240
 241static void dcr_write_uic (void *opaque, int dcrn, uint32_t val)
 242{
 243    ppcuic_t *uic;
 244
 245    uic = opaque;
 246    dcrn -= uic->dcr_base;
 247    LOG_UIC("%s: dcr %d val 0x%x\n", __func__, dcrn, val);
 248    switch (dcrn) {
 249    case DCR_UICSR:
 250        uic->uicsr &= ~val;
 251        uic->uicsr |= uic->level;
 252        ppcuic_trigger_irq(uic);
 253        break;
 254    case DCR_UICSRS:
 255        uic->uicsr |= val;
 256        ppcuic_trigger_irq(uic);
 257        break;
 258    case DCR_UICER:
 259        uic->uicer = val;
 260        ppcuic_trigger_irq(uic);
 261        break;
 262    case DCR_UICCR:
 263        uic->uiccr = val;
 264        ppcuic_trigger_irq(uic);
 265        break;
 266    case DCR_UICPR:
 267        uic->uicpr = val;
 268        break;
 269    case DCR_UICTR:
 270        uic->uictr = val;
 271        ppcuic_trigger_irq(uic);
 272        break;
 273    case DCR_UICMSR:
 274        break;
 275    case DCR_UICVR:
 276        break;
 277    case DCR_UICVCR:
 278        uic->uicvcr = val & 0xFFFFFFFD;
 279        ppcuic_trigger_irq(uic);
 280        break;
 281    }
 282}
 283
 284static void ppcuic_reset (void *opaque)
 285{
 286    ppcuic_t *uic;
 287
 288    uic = opaque;
 289    uic->uiccr = 0x00000000;
 290    uic->uicer = 0x00000000;
 291    uic->uicpr = 0x00000000;
 292    uic->uicsr = 0x00000000;
 293    uic->uictr = 0x00000000;
 294    if (uic->use_vectors) {
 295        uic->uicvcr = 0x00000000;
 296        uic->uicvr = 0x0000000;
 297    }
 298}
 299
 300qemu_irq *ppcuic_init (CPUPPCState *env, qemu_irq *irqs,
 301                       uint32_t dcr_base, int has_ssr, int has_vr)
 302{
 303    ppcuic_t *uic;
 304    int i;
 305
 306    uic = g_malloc0(sizeof(ppcuic_t));
 307    uic->dcr_base = dcr_base;
 308    uic->irqs = irqs;
 309    if (has_vr)
 310        uic->use_vectors = 1;
 311    for (i = 0; i < DCR_UICMAX; i++) {
 312        ppc_dcr_register(env, dcr_base + i, uic,
 313                         &dcr_read_uic, &dcr_write_uic);
 314    }
 315    qemu_register_reset(ppcuic_reset, uic);
 316
 317    return qemu_allocate_irqs(&ppcuic_set_irq, uic, UIC_MAX_IRQ);
 318}
 319
 320/*****************************************************************************/
 321/* SDRAM controller */
 322typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
 323struct ppc4xx_sdram_t {
 324    uint32_t addr;
 325    int nbanks;
 326    MemoryRegion containers[4]; /* used for clipping */
 327    MemoryRegion *ram_memories;
 328    hwaddr ram_bases[4];
 329    hwaddr ram_sizes[4];
 330    uint32_t besr0;
 331    uint32_t besr1;
 332    uint32_t bear;
 333    uint32_t cfg;
 334    uint32_t status;
 335    uint32_t rtr;
 336    uint32_t pmit;
 337    uint32_t bcr[4];
 338    uint32_t tr;
 339    uint32_t ecccfg;
 340    uint32_t eccesr;
 341    qemu_irq irq;
 342};
 343
 344enum {
 345    SDRAM0_CFGADDR = 0x010,
 346    SDRAM0_CFGDATA = 0x011,
 347};
 348
 349/* XXX: TOFIX: some patches have made this code become inconsistent:
 350 *      there are type inconsistencies, mixing hwaddr, target_ulong
 351 *      and uint32_t
 352 */
 353static uint32_t sdram_bcr (hwaddr ram_base,
 354                           hwaddr ram_size)
 355{
 356    uint32_t bcr;
 357
 358    switch (ram_size) {
 359    case 4 * MiB:
 360        bcr = 0x00000000;
 361        break;
 362    case 8 * MiB:
 363        bcr = 0x00020000;
 364        break;
 365    case 16 * MiB:
 366        bcr = 0x00040000;
 367        break;
 368    case 32 * MiB:
 369        bcr = 0x00060000;
 370        break;
 371    case 64 * MiB:
 372        bcr = 0x00080000;
 373        break;
 374    case 128 * MiB:
 375        bcr = 0x000A0000;
 376        break;
 377    case 256 * MiB:
 378        bcr = 0x000C0000;
 379        break;
 380    default:
 381        printf("%s: invalid RAM size " TARGET_FMT_plx "\n", __func__,
 382               ram_size);
 383        return 0x00000000;
 384    }
 385    bcr |= ram_base & 0xFF800000;
 386    bcr |= 1;
 387
 388    return bcr;
 389}
 390
 391static inline hwaddr sdram_base(uint32_t bcr)
 392{
 393    return bcr & 0xFF800000;
 394}
 395
 396static target_ulong sdram_size (uint32_t bcr)
 397{
 398    target_ulong size;
 399    int sh;
 400
 401    sh = (bcr >> 17) & 0x7;
 402    if (sh == 7)
 403        size = -1;
 404    else
 405        size = (4 * MiB) << sh;
 406
 407    return size;
 408}
 409
 410static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
 411                          uint32_t bcr, int enabled)
 412{
 413    if (sdram->bcr[i] & 0x00000001) {
 414        /* Unmap RAM */
 415#ifdef DEBUG_SDRAM
 416        printf("%s: unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
 417               __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
 418#endif
 419        memory_region_del_subregion(get_system_memory(),
 420                                    &sdram->containers[i]);
 421        memory_region_del_subregion(&sdram->containers[i],
 422                                    &sdram->ram_memories[i]);
 423        object_unparent(OBJECT(&sdram->containers[i]));
 424    }
 425    sdram->bcr[i] = bcr & 0xFFDEE001;
 426    if (enabled && (bcr & 0x00000001)) {
 427#ifdef DEBUG_SDRAM
 428        printf("%s: Map RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
 429               __func__, sdram_base(bcr), sdram_size(bcr));
 430#endif
 431        memory_region_init(&sdram->containers[i], NULL, "sdram-containers",
 432                           sdram_size(bcr));
 433        memory_region_add_subregion(&sdram->containers[i], 0,
 434                                    &sdram->ram_memories[i]);
 435        memory_region_add_subregion(get_system_memory(),
 436                                    sdram_base(bcr),
 437                                    &sdram->containers[i]);
 438    }
 439}
 440
 441static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
 442{
 443    int i;
 444
 445    for (i = 0; i < sdram->nbanks; i++) {
 446        if (sdram->ram_sizes[i] != 0) {
 447            sdram_set_bcr(sdram, i, sdram_bcr(sdram->ram_bases[i],
 448                                              sdram->ram_sizes[i]), 1);
 449        } else {
 450            sdram_set_bcr(sdram, i, 0x00000000, 0);
 451        }
 452    }
 453}
 454
 455static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
 456{
 457    int i;
 458
 459    for (i = 0; i < sdram->nbanks; i++) {
 460#ifdef DEBUG_SDRAM
 461        printf("%s: Unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
 462               __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
 463#endif
 464        memory_region_del_subregion(get_system_memory(),
 465                                    &sdram->ram_memories[i]);
 466    }
 467}
 468
 469static uint32_t dcr_read_sdram (void *opaque, int dcrn)
 470{
 471    ppc4xx_sdram_t *sdram;
 472    uint32_t ret;
 473
 474    sdram = opaque;
 475    switch (dcrn) {
 476    case SDRAM0_CFGADDR:
 477        ret = sdram->addr;
 478        break;
 479    case SDRAM0_CFGDATA:
 480        switch (sdram->addr) {
 481        case 0x00: /* SDRAM_BESR0 */
 482            ret = sdram->besr0;
 483            break;
 484        case 0x08: /* SDRAM_BESR1 */
 485            ret = sdram->besr1;
 486            break;
 487        case 0x10: /* SDRAM_BEAR */
 488            ret = sdram->bear;
 489            break;
 490        case 0x20: /* SDRAM_CFG */
 491            ret = sdram->cfg;
 492            break;
 493        case 0x24: /* SDRAM_STATUS */
 494            ret = sdram->status;
 495            break;
 496        case 0x30: /* SDRAM_RTR */
 497            ret = sdram->rtr;
 498            break;
 499        case 0x34: /* SDRAM_PMIT */
 500            ret = sdram->pmit;
 501            break;
 502        case 0x40: /* SDRAM_B0CR */
 503            ret = sdram->bcr[0];
 504            break;
 505        case 0x44: /* SDRAM_B1CR */
 506            ret = sdram->bcr[1];
 507            break;
 508        case 0x48: /* SDRAM_B2CR */
 509            ret = sdram->bcr[2];
 510            break;
 511        case 0x4C: /* SDRAM_B3CR */
 512            ret = sdram->bcr[3];
 513            break;
 514        case 0x80: /* SDRAM_TR */
 515            ret = -1; /* ? */
 516            break;
 517        case 0x94: /* SDRAM_ECCCFG */
 518            ret = sdram->ecccfg;
 519            break;
 520        case 0x98: /* SDRAM_ECCESR */
 521            ret = sdram->eccesr;
 522            break;
 523        default: /* Error */
 524            ret = -1;
 525            break;
 526        }
 527        break;
 528    default:
 529        /* Avoid gcc warning */
 530        ret = 0x00000000;
 531        break;
 532    }
 533
 534    return ret;
 535}
 536
 537static void dcr_write_sdram (void *opaque, int dcrn, uint32_t val)
 538{
 539    ppc4xx_sdram_t *sdram;
 540
 541    sdram = opaque;
 542    switch (dcrn) {
 543    case SDRAM0_CFGADDR:
 544        sdram->addr = val;
 545        break;
 546    case SDRAM0_CFGDATA:
 547        switch (sdram->addr) {
 548        case 0x00: /* SDRAM_BESR0 */
 549            sdram->besr0 &= ~val;
 550            break;
 551        case 0x08: /* SDRAM_BESR1 */
 552            sdram->besr1 &= ~val;
 553            break;
 554        case 0x10: /* SDRAM_BEAR */
 555            sdram->bear = val;
 556            break;
 557        case 0x20: /* SDRAM_CFG */
 558            val &= 0xFFE00000;
 559            if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {
 560#ifdef DEBUG_SDRAM
 561                printf("%s: enable SDRAM controller\n", __func__);
 562#endif
 563                /* validate all RAM mappings */
 564                sdram_map_bcr(sdram);
 565                sdram->status &= ~0x80000000;
 566            } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {
 567#ifdef DEBUG_SDRAM
 568                printf("%s: disable SDRAM controller\n", __func__);
 569#endif
 570                /* invalidate all RAM mappings */
 571                sdram_unmap_bcr(sdram);
 572                sdram->status |= 0x80000000;
 573            }
 574            if (!(sdram->cfg & 0x40000000) && (val & 0x40000000))
 575                sdram->status |= 0x40000000;
 576            else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000))
 577                sdram->status &= ~0x40000000;
 578            sdram->cfg = val;
 579            break;
 580        case 0x24: /* SDRAM_STATUS */
 581            /* Read-only register */
 582            break;
 583        case 0x30: /* SDRAM_RTR */
 584            sdram->rtr = val & 0x3FF80000;
 585            break;
 586        case 0x34: /* SDRAM_PMIT */
 587            sdram->pmit = (val & 0xF8000000) | 0x07C00000;
 588            break;
 589        case 0x40: /* SDRAM_B0CR */
 590            sdram_set_bcr(sdram, 0, val, sdram->cfg & 0x80000000);
 591            break;
 592        case 0x44: /* SDRAM_B1CR */
 593            sdram_set_bcr(sdram, 1, val, sdram->cfg & 0x80000000);
 594            break;
 595        case 0x48: /* SDRAM_B2CR */
 596            sdram_set_bcr(sdram, 2, val, sdram->cfg & 0x80000000);
 597            break;
 598        case 0x4C: /* SDRAM_B3CR */
 599            sdram_set_bcr(sdram, 3, val, sdram->cfg & 0x80000000);
 600            break;
 601        case 0x80: /* SDRAM_TR */
 602            sdram->tr = val & 0x018FC01F;
 603            break;
 604        case 0x94: /* SDRAM_ECCCFG */
 605            sdram->ecccfg = val & 0x00F00000;
 606            break;
 607        case 0x98: /* SDRAM_ECCESR */
 608            val &= 0xFFF0F000;
 609            if (sdram->eccesr == 0 && val != 0)
 610                qemu_irq_raise(sdram->irq);
 611            else if (sdram->eccesr != 0 && val == 0)
 612                qemu_irq_lower(sdram->irq);
 613            sdram->eccesr = val;
 614            break;
 615        default: /* Error */
 616            break;
 617        }
 618        break;
 619    }
 620}
 621
 622static void sdram_reset (void *opaque)
 623{
 624    ppc4xx_sdram_t *sdram;
 625
 626    sdram = opaque;
 627    sdram->addr = 0x00000000;
 628    sdram->bear = 0x00000000;
 629    sdram->besr0 = 0x00000000; /* No error */
 630    sdram->besr1 = 0x00000000; /* No error */
 631    sdram->cfg = 0x00000000;
 632    sdram->ecccfg = 0x00000000; /* No ECC */
 633    sdram->eccesr = 0x00000000; /* No error */
 634    sdram->pmit = 0x07C00000;
 635    sdram->rtr = 0x05F00000;
 636    sdram->tr = 0x00854009;
 637    /* We pre-initialize RAM banks */
 638    sdram->status = 0x00000000;
 639    sdram->cfg = 0x00800000;
 640}
 641
 642void ppc4xx_sdram_init (CPUPPCState *env, qemu_irq irq, int nbanks,
 643                        MemoryRegion *ram_memories,
 644                        hwaddr *ram_bases,
 645                        hwaddr *ram_sizes,
 646                        int do_init)
 647{
 648    ppc4xx_sdram_t *sdram;
 649
 650    sdram = g_malloc0(sizeof(ppc4xx_sdram_t));
 651    sdram->irq = irq;
 652    sdram->nbanks = nbanks;
 653    sdram->ram_memories = ram_memories;
 654    memset(sdram->ram_bases, 0, 4 * sizeof(hwaddr));
 655    memcpy(sdram->ram_bases, ram_bases,
 656           nbanks * sizeof(hwaddr));
 657    memset(sdram->ram_sizes, 0, 4 * sizeof(hwaddr));
 658    memcpy(sdram->ram_sizes, ram_sizes,
 659           nbanks * sizeof(hwaddr));
 660    qemu_register_reset(&sdram_reset, sdram);
 661    ppc_dcr_register(env, SDRAM0_CFGADDR,
 662                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 663    ppc_dcr_register(env, SDRAM0_CFGDATA,
 664                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 665    if (do_init)
 666        sdram_map_bcr(sdram);
 667}
 668
 669/* Fill in consecutive SDRAM banks with 'ram_size' bytes of memory.
 670 *
 671 * sdram_bank_sizes[] must be 0-terminated.
 672 *
 673 * The 4xx SDRAM controller supports a small number of banks, and each bank
 674 * must be one of a small set of sizes. The number of banks and the supported
 675 * sizes varies by SoC. */
 676ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
 677                               MemoryRegion ram_memories[],
 678                               hwaddr ram_bases[],
 679                               hwaddr ram_sizes[],
 680                               const ram_addr_t sdram_bank_sizes[])
 681{
 682    MemoryRegion *ram = g_malloc0(sizeof(*ram));
 683    ram_addr_t size_left = ram_size;
 684    ram_addr_t base = 0;
 685    ram_addr_t bank_size;
 686    int i;
 687    int j;
 688
 689    for (i = 0; i < nr_banks; i++) {
 690        for (j = 0; sdram_bank_sizes[j] != 0; j++) {
 691            bank_size = sdram_bank_sizes[j];
 692            if (bank_size <= size_left) {
 693                size_left -= bank_size;
 694            }
 695        }
 696        if (!size_left) {
 697            /* No need to use the remaining banks. */
 698            break;
 699        }
 700    }
 701
 702    ram_size -= size_left;
 703    if (size_left) {
 704        error_report("Truncating memory to %" PRId64 " MiB to fit SDRAM"
 705                     " controller limits", ram_size / MiB);
 706    }
 707
 708    memory_region_allocate_system_memory(ram, NULL, "ppc4xx.sdram", ram_size);
 709
 710    size_left = ram_size;
 711    for (i = 0; i < nr_banks && size_left; i++) {
 712        for (j = 0; sdram_bank_sizes[j] != 0; j++) {
 713            bank_size = sdram_bank_sizes[j];
 714
 715            if (bank_size <= size_left) {
 716                char name[32];
 717                snprintf(name, sizeof(name), "ppc4xx.sdram%d", i);
 718                memory_region_init_alias(&ram_memories[i], NULL, name, ram,
 719                                         base, bank_size);
 720                ram_bases[i] = base;
 721                ram_sizes[i] = bank_size;
 722                base += bank_size;
 723                size_left -= bank_size;
 724                break;
 725            }
 726        }
 727    }
 728
 729    return ram_size;
 730}
 731
 732/*****************************************************************************/
 733/* MAL */
 734
 735enum {
 736    MAL0_CFG      = 0x180,
 737    MAL0_ESR      = 0x181,
 738    MAL0_IER      = 0x182,
 739    MAL0_TXCASR   = 0x184,
 740    MAL0_TXCARR   = 0x185,
 741    MAL0_TXEOBISR = 0x186,
 742    MAL0_TXDEIR   = 0x187,
 743    MAL0_RXCASR   = 0x190,
 744    MAL0_RXCARR   = 0x191,
 745    MAL0_RXEOBISR = 0x192,
 746    MAL0_RXDEIR   = 0x193,
 747    MAL0_TXCTP0R  = 0x1A0,
 748    MAL0_RXCTP0R  = 0x1C0,
 749    MAL0_RCBS0    = 0x1E0,
 750    MAL0_RCBS1    = 0x1E1,
 751};
 752
 753typedef struct ppc4xx_mal_t ppc4xx_mal_t;
 754struct ppc4xx_mal_t {
 755    qemu_irq irqs[4];
 756    uint32_t cfg;
 757    uint32_t esr;
 758    uint32_t ier;
 759    uint32_t txcasr;
 760    uint32_t txcarr;
 761    uint32_t txeobisr;
 762    uint32_t txdeir;
 763    uint32_t rxcasr;
 764    uint32_t rxcarr;
 765    uint32_t rxeobisr;
 766    uint32_t rxdeir;
 767    uint32_t *txctpr;
 768    uint32_t *rxctpr;
 769    uint32_t *rcbs;
 770    uint8_t  txcnum;
 771    uint8_t  rxcnum;
 772};
 773
 774static void ppc4xx_mal_reset(void *opaque)
 775{
 776    ppc4xx_mal_t *mal;
 777
 778    mal = opaque;
 779    mal->cfg = 0x0007C000;
 780    mal->esr = 0x00000000;
 781    mal->ier = 0x00000000;
 782    mal->rxcasr = 0x00000000;
 783    mal->rxdeir = 0x00000000;
 784    mal->rxeobisr = 0x00000000;
 785    mal->txcasr = 0x00000000;
 786    mal->txdeir = 0x00000000;
 787    mal->txeobisr = 0x00000000;
 788}
 789
 790static uint32_t dcr_read_mal(void *opaque, int dcrn)
 791{
 792    ppc4xx_mal_t *mal;
 793    uint32_t ret;
 794
 795    mal = opaque;
 796    switch (dcrn) {
 797    case MAL0_CFG:
 798        ret = mal->cfg;
 799        break;
 800    case MAL0_ESR:
 801        ret = mal->esr;
 802        break;
 803    case MAL0_IER:
 804        ret = mal->ier;
 805        break;
 806    case MAL0_TXCASR:
 807        ret = mal->txcasr;
 808        break;
 809    case MAL0_TXCARR:
 810        ret = mal->txcarr;
 811        break;
 812    case MAL0_TXEOBISR:
 813        ret = mal->txeobisr;
 814        break;
 815    case MAL0_TXDEIR:
 816        ret = mal->txdeir;
 817        break;
 818    case MAL0_RXCASR:
 819        ret = mal->rxcasr;
 820        break;
 821    case MAL0_RXCARR:
 822        ret = mal->rxcarr;
 823        break;
 824    case MAL0_RXEOBISR:
 825        ret = mal->rxeobisr;
 826        break;
 827    case MAL0_RXDEIR:
 828        ret = mal->rxdeir;
 829        break;
 830    default:
 831        ret = 0;
 832        break;
 833    }
 834    if (dcrn >= MAL0_TXCTP0R && dcrn < MAL0_TXCTP0R + mal->txcnum) {
 835        ret = mal->txctpr[dcrn - MAL0_TXCTP0R];
 836    }
 837    if (dcrn >= MAL0_RXCTP0R && dcrn < MAL0_RXCTP0R + mal->rxcnum) {
 838        ret = mal->rxctpr[dcrn - MAL0_RXCTP0R];
 839    }
 840    if (dcrn >= MAL0_RCBS0 && dcrn < MAL0_RCBS0 + mal->rxcnum) {
 841        ret = mal->rcbs[dcrn - MAL0_RCBS0];
 842    }
 843
 844    return ret;
 845}
 846
 847static void dcr_write_mal(void *opaque, int dcrn, uint32_t val)
 848{
 849    ppc4xx_mal_t *mal;
 850
 851    mal = opaque;
 852    switch (dcrn) {
 853    case MAL0_CFG:
 854        if (val & 0x80000000) {
 855            ppc4xx_mal_reset(mal);
 856        }
 857        mal->cfg = val & 0x00FFC087;
 858        break;
 859    case MAL0_ESR:
 860        /* Read/clear */
 861        mal->esr &= ~val;
 862        break;
 863    case MAL0_IER:
 864        mal->ier = val & 0x0000001F;
 865        break;
 866    case MAL0_TXCASR:
 867        mal->txcasr = val & 0xF0000000;
 868        break;
 869    case MAL0_TXCARR:
 870        mal->txcarr = val & 0xF0000000;
 871        break;
 872    case MAL0_TXEOBISR:
 873        /* Read/clear */
 874        mal->txeobisr &= ~val;
 875        break;
 876    case MAL0_TXDEIR:
 877        /* Read/clear */
 878        mal->txdeir &= ~val;
 879        break;
 880    case MAL0_RXCASR:
 881        mal->rxcasr = val & 0xC0000000;
 882        break;
 883    case MAL0_RXCARR:
 884        mal->rxcarr = val & 0xC0000000;
 885        break;
 886    case MAL0_RXEOBISR:
 887        /* Read/clear */
 888        mal->rxeobisr &= ~val;
 889        break;
 890    case MAL0_RXDEIR:
 891        /* Read/clear */
 892        mal->rxdeir &= ~val;
 893        break;
 894    }
 895    if (dcrn >= MAL0_TXCTP0R && dcrn < MAL0_TXCTP0R + mal->txcnum) {
 896        mal->txctpr[dcrn - MAL0_TXCTP0R] = val;
 897    }
 898    if (dcrn >= MAL0_RXCTP0R && dcrn < MAL0_RXCTP0R + mal->rxcnum) {
 899        mal->rxctpr[dcrn - MAL0_RXCTP0R] = val;
 900    }
 901    if (dcrn >= MAL0_RCBS0 && dcrn < MAL0_RCBS0 + mal->rxcnum) {
 902        mal->rcbs[dcrn - MAL0_RCBS0] = val & 0x000000FF;
 903    }
 904}
 905
 906void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
 907                     qemu_irq irqs[4])
 908{
 909    ppc4xx_mal_t *mal;
 910    int i;
 911
 912    assert(txcnum <= 32 && rxcnum <= 32);
 913    mal = g_malloc0(sizeof(*mal));
 914    mal->txcnum = txcnum;
 915    mal->rxcnum = rxcnum;
 916    mal->txctpr = g_new0(uint32_t, txcnum);
 917    mal->rxctpr = g_new0(uint32_t, rxcnum);
 918    mal->rcbs = g_new0(uint32_t, rxcnum);
 919    for (i = 0; i < 4; i++) {
 920        mal->irqs[i] = irqs[i];
 921    }
 922    qemu_register_reset(&ppc4xx_mal_reset, mal);
 923    ppc_dcr_register(env, MAL0_CFG,
 924                     mal, &dcr_read_mal, &dcr_write_mal);
 925    ppc_dcr_register(env, MAL0_ESR,
 926                     mal, &dcr_read_mal, &dcr_write_mal);
 927    ppc_dcr_register(env, MAL0_IER,
 928                     mal, &dcr_read_mal, &dcr_write_mal);
 929    ppc_dcr_register(env, MAL0_TXCASR,
 930                     mal, &dcr_read_mal, &dcr_write_mal);
 931    ppc_dcr_register(env, MAL0_TXCARR,
 932                     mal, &dcr_read_mal, &dcr_write_mal);
 933    ppc_dcr_register(env, MAL0_TXEOBISR,
 934                     mal, &dcr_read_mal, &dcr_write_mal);
 935    ppc_dcr_register(env, MAL0_TXDEIR,
 936                     mal, &dcr_read_mal, &dcr_write_mal);
 937    ppc_dcr_register(env, MAL0_RXCASR,
 938                     mal, &dcr_read_mal, &dcr_write_mal);
 939    ppc_dcr_register(env, MAL0_RXCARR,
 940                     mal, &dcr_read_mal, &dcr_write_mal);
 941    ppc_dcr_register(env, MAL0_RXEOBISR,
 942                     mal, &dcr_read_mal, &dcr_write_mal);
 943    ppc_dcr_register(env, MAL0_RXDEIR,
 944                     mal, &dcr_read_mal, &dcr_write_mal);
 945    for (i = 0; i < txcnum; i++) {
 946        ppc_dcr_register(env, MAL0_TXCTP0R + i,
 947                         mal, &dcr_read_mal, &dcr_write_mal);
 948    }
 949    for (i = 0; i < rxcnum; i++) {
 950        ppc_dcr_register(env, MAL0_RXCTP0R + i,
 951                         mal, &dcr_read_mal, &dcr_write_mal);
 952    }
 953    for (i = 0; i < rxcnum; i++) {
 954        ppc_dcr_register(env, MAL0_RCBS0 + i,
 955                         mal, &dcr_read_mal, &dcr_write_mal);
 956    }
 957}
 958