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