qemu/hw/ppc/ppc405_uc.c
<<
>>
Prefs
   1/*
   2 * QEMU PowerPC 405 embedded processors 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 "hw/hw.h"
  25#include "hw/ppc/ppc.h"
  26#include "hw/boards.h"
  27#include "ppc405.h"
  28#include "hw/char/serial.h"
  29#include "qemu/timer.h"
  30#include "sysemu/sysemu.h"
  31#include "qemu/log.h"
  32#include "exec/address-spaces.h"
  33
  34//#define DEBUG_OPBA
  35//#define DEBUG_SDRAM
  36//#define DEBUG_GPIO
  37//#define DEBUG_SERIAL
  38//#define DEBUG_OCM
  39//#define DEBUG_I2C
  40//#define DEBUG_GPT
  41//#define DEBUG_MAL
  42//#define DEBUG_CLOCKS
  43//#define DEBUG_CLOCKS_LL
  44
  45ram_addr_t ppc405_set_bootinfo (CPUPPCState *env, ppc4xx_bd_info_t *bd,
  46                                uint32_t flags)
  47{
  48    CPUState *cs = CPU(ppc_env_get_cpu(env));
  49    ram_addr_t bdloc;
  50    int i, n;
  51
  52    /* We put the bd structure at the top of memory */
  53    if (bd->bi_memsize >= 0x01000000UL)
  54        bdloc = 0x01000000UL - sizeof(struct ppc4xx_bd_info_t);
  55    else
  56        bdloc = bd->bi_memsize - sizeof(struct ppc4xx_bd_info_t);
  57    stl_be_phys(cs->as, bdloc + 0x00, bd->bi_memstart);
  58    stl_be_phys(cs->as, bdloc + 0x04, bd->bi_memsize);
  59    stl_be_phys(cs->as, bdloc + 0x08, bd->bi_flashstart);
  60    stl_be_phys(cs->as, bdloc + 0x0C, bd->bi_flashsize);
  61    stl_be_phys(cs->as, bdloc + 0x10, bd->bi_flashoffset);
  62    stl_be_phys(cs->as, bdloc + 0x14, bd->bi_sramstart);
  63    stl_be_phys(cs->as, bdloc + 0x18, bd->bi_sramsize);
  64    stl_be_phys(cs->as, bdloc + 0x1C, bd->bi_bootflags);
  65    stl_be_phys(cs->as, bdloc + 0x20, bd->bi_ipaddr);
  66    for (i = 0; i < 6; i++) {
  67        stb_phys(cs->as, bdloc + 0x24 + i, bd->bi_enetaddr[i]);
  68    }
  69    stw_be_phys(cs->as, bdloc + 0x2A, bd->bi_ethspeed);
  70    stl_be_phys(cs->as, bdloc + 0x2C, bd->bi_intfreq);
  71    stl_be_phys(cs->as, bdloc + 0x30, bd->bi_busfreq);
  72    stl_be_phys(cs->as, bdloc + 0x34, bd->bi_baudrate);
  73    for (i = 0; i < 4; i++) {
  74        stb_phys(cs->as, bdloc + 0x38 + i, bd->bi_s_version[i]);
  75    }
  76    for (i = 0; i < 32; i++) {
  77        stb_phys(cs->as, bdloc + 0x3C + i, bd->bi_r_version[i]);
  78    }
  79    stl_be_phys(cs->as, bdloc + 0x5C, bd->bi_plb_busfreq);
  80    stl_be_phys(cs->as, bdloc + 0x60, bd->bi_pci_busfreq);
  81    for (i = 0; i < 6; i++) {
  82        stb_phys(cs->as, bdloc + 0x64 + i, bd->bi_pci_enetaddr[i]);
  83    }
  84    n = 0x6A;
  85    if (flags & 0x00000001) {
  86        for (i = 0; i < 6; i++)
  87            stb_phys(cs->as, bdloc + n++, bd->bi_pci_enetaddr2[i]);
  88    }
  89    stl_be_phys(cs->as, bdloc + n, bd->bi_opbfreq);
  90    n += 4;
  91    for (i = 0; i < 2; i++) {
  92        stl_be_phys(cs->as, bdloc + n, bd->bi_iic_fast[i]);
  93        n += 4;
  94    }
  95
  96    return bdloc;
  97}
  98
  99/*****************************************************************************/
 100/* Shared peripherals */
 101
 102/*****************************************************************************/
 103/* Peripheral local bus arbitrer */
 104enum {
 105    PLB0_BESR = 0x084,
 106    PLB0_BEAR = 0x086,
 107    PLB0_ACR  = 0x087,
 108};
 109
 110typedef struct ppc4xx_plb_t ppc4xx_plb_t;
 111struct ppc4xx_plb_t {
 112    uint32_t acr;
 113    uint32_t bear;
 114    uint32_t besr;
 115};
 116
 117static uint32_t dcr_read_plb (void *opaque, int dcrn)
 118{
 119    ppc4xx_plb_t *plb;
 120    uint32_t ret;
 121
 122    plb = opaque;
 123    switch (dcrn) {
 124    case PLB0_ACR:
 125        ret = plb->acr;
 126        break;
 127    case PLB0_BEAR:
 128        ret = plb->bear;
 129        break;
 130    case PLB0_BESR:
 131        ret = plb->besr;
 132        break;
 133    default:
 134        /* Avoid gcc warning */
 135        ret = 0;
 136        break;
 137    }
 138
 139    return ret;
 140}
 141
 142static void dcr_write_plb (void *opaque, int dcrn, uint32_t val)
 143{
 144    ppc4xx_plb_t *plb;
 145
 146    plb = opaque;
 147    switch (dcrn) {
 148    case PLB0_ACR:
 149        /* We don't care about the actual parameters written as
 150         * we don't manage any priorities on the bus
 151         */
 152        plb->acr = val & 0xF8000000;
 153        break;
 154    case PLB0_BEAR:
 155        /* Read only */
 156        break;
 157    case PLB0_BESR:
 158        /* Write-clear */
 159        plb->besr &= ~val;
 160        break;
 161    }
 162}
 163
 164static void ppc4xx_plb_reset (void *opaque)
 165{
 166    ppc4xx_plb_t *plb;
 167
 168    plb = opaque;
 169    plb->acr = 0x00000000;
 170    plb->bear = 0x00000000;
 171    plb->besr = 0x00000000;
 172}
 173
 174static void ppc4xx_plb_init(CPUPPCState *env)
 175{
 176    ppc4xx_plb_t *plb;
 177
 178    plb = g_malloc0(sizeof(ppc4xx_plb_t));
 179    ppc_dcr_register(env, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
 180    ppc_dcr_register(env, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb);
 181    ppc_dcr_register(env, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb);
 182    qemu_register_reset(ppc4xx_plb_reset, plb);
 183}
 184
 185/*****************************************************************************/
 186/* PLB to OPB bridge */
 187enum {
 188    POB0_BESR0 = 0x0A0,
 189    POB0_BESR1 = 0x0A2,
 190    POB0_BEAR  = 0x0A4,
 191};
 192
 193typedef struct ppc4xx_pob_t ppc4xx_pob_t;
 194struct ppc4xx_pob_t {
 195    uint32_t bear;
 196    uint32_t besr0;
 197    uint32_t besr1;
 198};
 199
 200static uint32_t dcr_read_pob (void *opaque, int dcrn)
 201{
 202    ppc4xx_pob_t *pob;
 203    uint32_t ret;
 204
 205    pob = opaque;
 206    switch (dcrn) {
 207    case POB0_BEAR:
 208        ret = pob->bear;
 209        break;
 210    case POB0_BESR0:
 211        ret = pob->besr0;
 212        break;
 213    case POB0_BESR1:
 214        ret = pob->besr1;
 215        break;
 216    default:
 217        /* Avoid gcc warning */
 218        ret = 0;
 219        break;
 220    }
 221
 222    return ret;
 223}
 224
 225static void dcr_write_pob (void *opaque, int dcrn, uint32_t val)
 226{
 227    ppc4xx_pob_t *pob;
 228
 229    pob = opaque;
 230    switch (dcrn) {
 231    case POB0_BEAR:
 232        /* Read only */
 233        break;
 234    case POB0_BESR0:
 235        /* Write-clear */
 236        pob->besr0 &= ~val;
 237        break;
 238    case POB0_BESR1:
 239        /* Write-clear */
 240        pob->besr1 &= ~val;
 241        break;
 242    }
 243}
 244
 245static void ppc4xx_pob_reset (void *opaque)
 246{
 247    ppc4xx_pob_t *pob;
 248
 249    pob = opaque;
 250    /* No error */
 251    pob->bear = 0x00000000;
 252    pob->besr0 = 0x0000000;
 253    pob->besr1 = 0x0000000;
 254}
 255
 256static void ppc4xx_pob_init(CPUPPCState *env)
 257{
 258    ppc4xx_pob_t *pob;
 259
 260    pob = g_malloc0(sizeof(ppc4xx_pob_t));
 261    ppc_dcr_register(env, POB0_BEAR, pob, &dcr_read_pob, &dcr_write_pob);
 262    ppc_dcr_register(env, POB0_BESR0, pob, &dcr_read_pob, &dcr_write_pob);
 263    ppc_dcr_register(env, POB0_BESR1, pob, &dcr_read_pob, &dcr_write_pob);
 264    qemu_register_reset(ppc4xx_pob_reset, pob);
 265}
 266
 267/*****************************************************************************/
 268/* OPB arbitrer */
 269typedef struct ppc4xx_opba_t ppc4xx_opba_t;
 270struct ppc4xx_opba_t {
 271    MemoryRegion io;
 272    uint8_t cr;
 273    uint8_t pr;
 274};
 275
 276static uint32_t opba_readb (void *opaque, hwaddr addr)
 277{
 278    ppc4xx_opba_t *opba;
 279    uint32_t ret;
 280
 281#ifdef DEBUG_OPBA
 282    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
 283#endif
 284    opba = opaque;
 285    switch (addr) {
 286    case 0x00:
 287        ret = opba->cr;
 288        break;
 289    case 0x01:
 290        ret = opba->pr;
 291        break;
 292    default:
 293        ret = 0x00;
 294        break;
 295    }
 296
 297    return ret;
 298}
 299
 300static void opba_writeb (void *opaque,
 301                         hwaddr addr, uint32_t value)
 302{
 303    ppc4xx_opba_t *opba;
 304
 305#ifdef DEBUG_OPBA
 306    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
 307           value);
 308#endif
 309    opba = opaque;
 310    switch (addr) {
 311    case 0x00:
 312        opba->cr = value & 0xF8;
 313        break;
 314    case 0x01:
 315        opba->pr = value & 0xFF;
 316        break;
 317    default:
 318        break;
 319    }
 320}
 321
 322static uint32_t opba_readw (void *opaque, hwaddr addr)
 323{
 324    uint32_t ret;
 325
 326#ifdef DEBUG_OPBA
 327    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
 328#endif
 329    ret = opba_readb(opaque, addr) << 8;
 330    ret |= opba_readb(opaque, addr + 1);
 331
 332    return ret;
 333}
 334
 335static void opba_writew (void *opaque,
 336                         hwaddr addr, uint32_t value)
 337{
 338#ifdef DEBUG_OPBA
 339    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
 340           value);
 341#endif
 342    opba_writeb(opaque, addr, value >> 8);
 343    opba_writeb(opaque, addr + 1, value);
 344}
 345
 346static uint32_t opba_readl (void *opaque, hwaddr addr)
 347{
 348    uint32_t ret;
 349
 350#ifdef DEBUG_OPBA
 351    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
 352#endif
 353    ret = opba_readb(opaque, addr) << 24;
 354    ret |= opba_readb(opaque, addr + 1) << 16;
 355
 356    return ret;
 357}
 358
 359static void opba_writel (void *opaque,
 360                         hwaddr addr, uint32_t value)
 361{
 362#ifdef DEBUG_OPBA
 363    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
 364           value);
 365#endif
 366    opba_writeb(opaque, addr, value >> 24);
 367    opba_writeb(opaque, addr + 1, value >> 16);
 368}
 369
 370static const MemoryRegionOps opba_ops = {
 371    .old_mmio = {
 372        .read = { opba_readb, opba_readw, opba_readl, },
 373        .write = { opba_writeb, opba_writew, opba_writel, },
 374    },
 375    .endianness = DEVICE_NATIVE_ENDIAN,
 376};
 377
 378static void ppc4xx_opba_reset (void *opaque)
 379{
 380    ppc4xx_opba_t *opba;
 381
 382    opba = opaque;
 383    opba->cr = 0x00; /* No dynamic priorities - park disabled */
 384    opba->pr = 0x11;
 385}
 386
 387static void ppc4xx_opba_init(hwaddr base)
 388{
 389    ppc4xx_opba_t *opba;
 390
 391    opba = g_malloc0(sizeof(ppc4xx_opba_t));
 392#ifdef DEBUG_OPBA
 393    printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 394#endif
 395    memory_region_init_io(&opba->io, NULL, &opba_ops, opba, "opba", 0x002);
 396    memory_region_add_subregion(get_system_memory(), base, &opba->io);
 397    qemu_register_reset(ppc4xx_opba_reset, opba);
 398}
 399
 400/*****************************************************************************/
 401/* Code decompression controller */
 402/* XXX: TODO */
 403
 404/*****************************************************************************/
 405/* Peripheral controller */
 406typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
 407struct ppc4xx_ebc_t {
 408    uint32_t addr;
 409    uint32_t bcr[8];
 410    uint32_t bap[8];
 411    uint32_t bear;
 412    uint32_t besr0;
 413    uint32_t besr1;
 414    uint32_t cfg;
 415};
 416
 417enum {
 418    EBC0_CFGADDR = 0x012,
 419    EBC0_CFGDATA = 0x013,
 420};
 421
 422static uint32_t dcr_read_ebc (void *opaque, int dcrn)
 423{
 424    ppc4xx_ebc_t *ebc;
 425    uint32_t ret;
 426
 427    ebc = opaque;
 428    switch (dcrn) {
 429    case EBC0_CFGADDR:
 430        ret = ebc->addr;
 431        break;
 432    case EBC0_CFGDATA:
 433        switch (ebc->addr) {
 434        case 0x00: /* B0CR */
 435            ret = ebc->bcr[0];
 436            break;
 437        case 0x01: /* B1CR */
 438            ret = ebc->bcr[1];
 439            break;
 440        case 0x02: /* B2CR */
 441            ret = ebc->bcr[2];
 442            break;
 443        case 0x03: /* B3CR */
 444            ret = ebc->bcr[3];
 445            break;
 446        case 0x04: /* B4CR */
 447            ret = ebc->bcr[4];
 448            break;
 449        case 0x05: /* B5CR */
 450            ret = ebc->bcr[5];
 451            break;
 452        case 0x06: /* B6CR */
 453            ret = ebc->bcr[6];
 454            break;
 455        case 0x07: /* B7CR */
 456            ret = ebc->bcr[7];
 457            break;
 458        case 0x10: /* B0AP */
 459            ret = ebc->bap[0];
 460            break;
 461        case 0x11: /* B1AP */
 462            ret = ebc->bap[1];
 463            break;
 464        case 0x12: /* B2AP */
 465            ret = ebc->bap[2];
 466            break;
 467        case 0x13: /* B3AP */
 468            ret = ebc->bap[3];
 469            break;
 470        case 0x14: /* B4AP */
 471            ret = ebc->bap[4];
 472            break;
 473        case 0x15: /* B5AP */
 474            ret = ebc->bap[5];
 475            break;
 476        case 0x16: /* B6AP */
 477            ret = ebc->bap[6];
 478            break;
 479        case 0x17: /* B7AP */
 480            ret = ebc->bap[7];
 481            break;
 482        case 0x20: /* BEAR */
 483            ret = ebc->bear;
 484            break;
 485        case 0x21: /* BESR0 */
 486            ret = ebc->besr0;
 487            break;
 488        case 0x22: /* BESR1 */
 489            ret = ebc->besr1;
 490            break;
 491        case 0x23: /* CFG */
 492            ret = ebc->cfg;
 493            break;
 494        default:
 495            ret = 0x00000000;
 496            break;
 497        }
 498        break;
 499    default:
 500        ret = 0x00000000;
 501        break;
 502    }
 503
 504    return ret;
 505}
 506
 507static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
 508{
 509    ppc4xx_ebc_t *ebc;
 510
 511    ebc = opaque;
 512    switch (dcrn) {
 513    case EBC0_CFGADDR:
 514        ebc->addr = val;
 515        break;
 516    case EBC0_CFGDATA:
 517        switch (ebc->addr) {
 518        case 0x00: /* B0CR */
 519            break;
 520        case 0x01: /* B1CR */
 521            break;
 522        case 0x02: /* B2CR */
 523            break;
 524        case 0x03: /* B3CR */
 525            break;
 526        case 0x04: /* B4CR */
 527            break;
 528        case 0x05: /* B5CR */
 529            break;
 530        case 0x06: /* B6CR */
 531            break;
 532        case 0x07: /* B7CR */
 533            break;
 534        case 0x10: /* B0AP */
 535            break;
 536        case 0x11: /* B1AP */
 537            break;
 538        case 0x12: /* B2AP */
 539            break;
 540        case 0x13: /* B3AP */
 541            break;
 542        case 0x14: /* B4AP */
 543            break;
 544        case 0x15: /* B5AP */
 545            break;
 546        case 0x16: /* B6AP */
 547            break;
 548        case 0x17: /* B7AP */
 549            break;
 550        case 0x20: /* BEAR */
 551            break;
 552        case 0x21: /* BESR0 */
 553            break;
 554        case 0x22: /* BESR1 */
 555            break;
 556        case 0x23: /* CFG */
 557            break;
 558        default:
 559            break;
 560        }
 561        break;
 562    default:
 563        break;
 564    }
 565}
 566
 567static void ebc_reset (void *opaque)
 568{
 569    ppc4xx_ebc_t *ebc;
 570    int i;
 571
 572    ebc = opaque;
 573    ebc->addr = 0x00000000;
 574    ebc->bap[0] = 0x7F8FFE80;
 575    ebc->bcr[0] = 0xFFE28000;
 576    for (i = 0; i < 8; i++) {
 577        ebc->bap[i] = 0x00000000;
 578        ebc->bcr[i] = 0x00000000;
 579    }
 580    ebc->besr0 = 0x00000000;
 581    ebc->besr1 = 0x00000000;
 582    ebc->cfg = 0x80400000;
 583}
 584
 585static void ppc405_ebc_init(CPUPPCState *env)
 586{
 587    ppc4xx_ebc_t *ebc;
 588
 589    ebc = g_malloc0(sizeof(ppc4xx_ebc_t));
 590    qemu_register_reset(&ebc_reset, ebc);
 591    ppc_dcr_register(env, EBC0_CFGADDR,
 592                     ebc, &dcr_read_ebc, &dcr_write_ebc);
 593    ppc_dcr_register(env, EBC0_CFGDATA,
 594                     ebc, &dcr_read_ebc, &dcr_write_ebc);
 595}
 596
 597/*****************************************************************************/
 598/* DMA controller */
 599enum {
 600    DMA0_CR0 = 0x100,
 601    DMA0_CT0 = 0x101,
 602    DMA0_DA0 = 0x102,
 603    DMA0_SA0 = 0x103,
 604    DMA0_SG0 = 0x104,
 605    DMA0_CR1 = 0x108,
 606    DMA0_CT1 = 0x109,
 607    DMA0_DA1 = 0x10A,
 608    DMA0_SA1 = 0x10B,
 609    DMA0_SG1 = 0x10C,
 610    DMA0_CR2 = 0x110,
 611    DMA0_CT2 = 0x111,
 612    DMA0_DA2 = 0x112,
 613    DMA0_SA2 = 0x113,
 614    DMA0_SG2 = 0x114,
 615    DMA0_CR3 = 0x118,
 616    DMA0_CT3 = 0x119,
 617    DMA0_DA3 = 0x11A,
 618    DMA0_SA3 = 0x11B,
 619    DMA0_SG3 = 0x11C,
 620    DMA0_SR  = 0x120,
 621    DMA0_SGC = 0x123,
 622    DMA0_SLP = 0x125,
 623    DMA0_POL = 0x126,
 624};
 625
 626typedef struct ppc405_dma_t ppc405_dma_t;
 627struct ppc405_dma_t {
 628    qemu_irq irqs[4];
 629    uint32_t cr[4];
 630    uint32_t ct[4];
 631    uint32_t da[4];
 632    uint32_t sa[4];
 633    uint32_t sg[4];
 634    uint32_t sr;
 635    uint32_t sgc;
 636    uint32_t slp;
 637    uint32_t pol;
 638};
 639
 640static uint32_t dcr_read_dma (void *opaque, int dcrn)
 641{
 642    return 0;
 643}
 644
 645static void dcr_write_dma (void *opaque, int dcrn, uint32_t val)
 646{
 647}
 648
 649static void ppc405_dma_reset (void *opaque)
 650{
 651    ppc405_dma_t *dma;
 652    int i;
 653
 654    dma = opaque;
 655    for (i = 0; i < 4; i++) {
 656        dma->cr[i] = 0x00000000;
 657        dma->ct[i] = 0x00000000;
 658        dma->da[i] = 0x00000000;
 659        dma->sa[i] = 0x00000000;
 660        dma->sg[i] = 0x00000000;
 661    }
 662    dma->sr = 0x00000000;
 663    dma->sgc = 0x00000000;
 664    dma->slp = 0x7C000000;
 665    dma->pol = 0x00000000;
 666}
 667
 668static void ppc405_dma_init(CPUPPCState *env, qemu_irq irqs[4])
 669{
 670    ppc405_dma_t *dma;
 671
 672    dma = g_malloc0(sizeof(ppc405_dma_t));
 673    memcpy(dma->irqs, irqs, 4 * sizeof(qemu_irq));
 674    qemu_register_reset(&ppc405_dma_reset, dma);
 675    ppc_dcr_register(env, DMA0_CR0,
 676                     dma, &dcr_read_dma, &dcr_write_dma);
 677    ppc_dcr_register(env, DMA0_CT0,
 678                     dma, &dcr_read_dma, &dcr_write_dma);
 679    ppc_dcr_register(env, DMA0_DA0,
 680                     dma, &dcr_read_dma, &dcr_write_dma);
 681    ppc_dcr_register(env, DMA0_SA0,
 682                     dma, &dcr_read_dma, &dcr_write_dma);
 683    ppc_dcr_register(env, DMA0_SG0,
 684                     dma, &dcr_read_dma, &dcr_write_dma);
 685    ppc_dcr_register(env, DMA0_CR1,
 686                     dma, &dcr_read_dma, &dcr_write_dma);
 687    ppc_dcr_register(env, DMA0_CT1,
 688                     dma, &dcr_read_dma, &dcr_write_dma);
 689    ppc_dcr_register(env, DMA0_DA1,
 690                     dma, &dcr_read_dma, &dcr_write_dma);
 691    ppc_dcr_register(env, DMA0_SA1,
 692                     dma, &dcr_read_dma, &dcr_write_dma);
 693    ppc_dcr_register(env, DMA0_SG1,
 694                     dma, &dcr_read_dma, &dcr_write_dma);
 695    ppc_dcr_register(env, DMA0_CR2,
 696                     dma, &dcr_read_dma, &dcr_write_dma);
 697    ppc_dcr_register(env, DMA0_CT2,
 698                     dma, &dcr_read_dma, &dcr_write_dma);
 699    ppc_dcr_register(env, DMA0_DA2,
 700                     dma, &dcr_read_dma, &dcr_write_dma);
 701    ppc_dcr_register(env, DMA0_SA2,
 702                     dma, &dcr_read_dma, &dcr_write_dma);
 703    ppc_dcr_register(env, DMA0_SG2,
 704                     dma, &dcr_read_dma, &dcr_write_dma);
 705    ppc_dcr_register(env, DMA0_CR3,
 706                     dma, &dcr_read_dma, &dcr_write_dma);
 707    ppc_dcr_register(env, DMA0_CT3,
 708                     dma, &dcr_read_dma, &dcr_write_dma);
 709    ppc_dcr_register(env, DMA0_DA3,
 710                     dma, &dcr_read_dma, &dcr_write_dma);
 711    ppc_dcr_register(env, DMA0_SA3,
 712                     dma, &dcr_read_dma, &dcr_write_dma);
 713    ppc_dcr_register(env, DMA0_SG3,
 714                     dma, &dcr_read_dma, &dcr_write_dma);
 715    ppc_dcr_register(env, DMA0_SR,
 716                     dma, &dcr_read_dma, &dcr_write_dma);
 717    ppc_dcr_register(env, DMA0_SGC,
 718                     dma, &dcr_read_dma, &dcr_write_dma);
 719    ppc_dcr_register(env, DMA0_SLP,
 720                     dma, &dcr_read_dma, &dcr_write_dma);
 721    ppc_dcr_register(env, DMA0_POL,
 722                     dma, &dcr_read_dma, &dcr_write_dma);
 723}
 724
 725/*****************************************************************************/
 726/* GPIO */
 727typedef struct ppc405_gpio_t ppc405_gpio_t;
 728struct ppc405_gpio_t {
 729    MemoryRegion io;
 730    uint32_t or;
 731    uint32_t tcr;
 732    uint32_t osrh;
 733    uint32_t osrl;
 734    uint32_t tsrh;
 735    uint32_t tsrl;
 736    uint32_t odr;
 737    uint32_t ir;
 738    uint32_t rr1;
 739    uint32_t isr1h;
 740    uint32_t isr1l;
 741};
 742
 743static uint32_t ppc405_gpio_readb (void *opaque, hwaddr addr)
 744{
 745#ifdef DEBUG_GPIO
 746    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
 747#endif
 748
 749    return 0;
 750}
 751
 752static void ppc405_gpio_writeb (void *opaque,
 753                                hwaddr addr, uint32_t value)
 754{
 755#ifdef DEBUG_GPIO
 756    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
 757           value);
 758#endif
 759}
 760
 761static uint32_t ppc405_gpio_readw (void *opaque, hwaddr addr)
 762{
 763#ifdef DEBUG_GPIO
 764    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
 765#endif
 766
 767    return 0;
 768}
 769
 770static void ppc405_gpio_writew (void *opaque,
 771                                hwaddr addr, uint32_t value)
 772{
 773#ifdef DEBUG_GPIO
 774    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
 775           value);
 776#endif
 777}
 778
 779static uint32_t ppc405_gpio_readl (void *opaque, hwaddr addr)
 780{
 781#ifdef DEBUG_GPIO
 782    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
 783#endif
 784
 785    return 0;
 786}
 787
 788static void ppc405_gpio_writel (void *opaque,
 789                                hwaddr addr, uint32_t value)
 790{
 791#ifdef DEBUG_GPIO
 792    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
 793           value);
 794#endif
 795}
 796
 797static const MemoryRegionOps ppc405_gpio_ops = {
 798    .old_mmio = {
 799        .read = { ppc405_gpio_readb, ppc405_gpio_readw, ppc405_gpio_readl, },
 800        .write = { ppc405_gpio_writeb, ppc405_gpio_writew, ppc405_gpio_writel, },
 801    },
 802    .endianness = DEVICE_NATIVE_ENDIAN,
 803};
 804
 805static void ppc405_gpio_reset (void *opaque)
 806{
 807}
 808
 809static void ppc405_gpio_init(hwaddr base)
 810{
 811    ppc405_gpio_t *gpio;
 812
 813    gpio = g_malloc0(sizeof(ppc405_gpio_t));
 814#ifdef DEBUG_GPIO
 815    printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 816#endif
 817    memory_region_init_io(&gpio->io, NULL, &ppc405_gpio_ops, gpio, "pgio", 0x038);
 818    memory_region_add_subregion(get_system_memory(), base, &gpio->io);
 819    qemu_register_reset(&ppc405_gpio_reset, gpio);
 820}
 821
 822/*****************************************************************************/
 823/* On Chip Memory */
 824enum {
 825    OCM0_ISARC   = 0x018,
 826    OCM0_ISACNTL = 0x019,
 827    OCM0_DSARC   = 0x01A,
 828    OCM0_DSACNTL = 0x01B,
 829};
 830
 831typedef struct ppc405_ocm_t ppc405_ocm_t;
 832struct ppc405_ocm_t {
 833    MemoryRegion ram;
 834    MemoryRegion isarc_ram;
 835    MemoryRegion dsarc_ram;
 836    uint32_t isarc;
 837    uint32_t isacntl;
 838    uint32_t dsarc;
 839    uint32_t dsacntl;
 840};
 841
 842static void ocm_update_mappings (ppc405_ocm_t *ocm,
 843                                 uint32_t isarc, uint32_t isacntl,
 844                                 uint32_t dsarc, uint32_t dsacntl)
 845{
 846#ifdef DEBUG_OCM
 847    printf("OCM update ISA %08" PRIx32 " %08" PRIx32 " (%08" PRIx32
 848           " %08" PRIx32 ") DSA %08" PRIx32 " %08" PRIx32
 849           " (%08" PRIx32 " %08" PRIx32 ")\n",
 850           isarc, isacntl, dsarc, dsacntl,
 851           ocm->isarc, ocm->isacntl, ocm->dsarc, ocm->dsacntl);
 852#endif
 853    if (ocm->isarc != isarc ||
 854        (ocm->isacntl & 0x80000000) != (isacntl & 0x80000000)) {
 855        if (ocm->isacntl & 0x80000000) {
 856            /* Unmap previously assigned memory region */
 857            printf("OCM unmap ISA %08" PRIx32 "\n", ocm->isarc);
 858            memory_region_del_subregion(get_system_memory(), &ocm->isarc_ram);
 859        }
 860        if (isacntl & 0x80000000) {
 861            /* Map new instruction memory region */
 862#ifdef DEBUG_OCM
 863            printf("OCM map ISA %08" PRIx32 "\n", isarc);
 864#endif
 865            memory_region_add_subregion(get_system_memory(), isarc,
 866                                        &ocm->isarc_ram);
 867        }
 868    }
 869    if (ocm->dsarc != dsarc ||
 870        (ocm->dsacntl & 0x80000000) != (dsacntl & 0x80000000)) {
 871        if (ocm->dsacntl & 0x80000000) {
 872            /* Beware not to unmap the region we just mapped */
 873            if (!(isacntl & 0x80000000) || ocm->dsarc != isarc) {
 874                /* Unmap previously assigned memory region */
 875#ifdef DEBUG_OCM
 876                printf("OCM unmap DSA %08" PRIx32 "\n", ocm->dsarc);
 877#endif
 878                memory_region_del_subregion(get_system_memory(),
 879                                            &ocm->dsarc_ram);
 880            }
 881        }
 882        if (dsacntl & 0x80000000) {
 883            /* Beware not to remap the region we just mapped */
 884            if (!(isacntl & 0x80000000) || dsarc != isarc) {
 885                /* Map new data memory region */
 886#ifdef DEBUG_OCM
 887                printf("OCM map DSA %08" PRIx32 "\n", dsarc);
 888#endif
 889                memory_region_add_subregion(get_system_memory(), dsarc,
 890                                            &ocm->dsarc_ram);
 891            }
 892        }
 893    }
 894}
 895
 896static uint32_t dcr_read_ocm (void *opaque, int dcrn)
 897{
 898    ppc405_ocm_t *ocm;
 899    uint32_t ret;
 900
 901    ocm = opaque;
 902    switch (dcrn) {
 903    case OCM0_ISARC:
 904        ret = ocm->isarc;
 905        break;
 906    case OCM0_ISACNTL:
 907        ret = ocm->isacntl;
 908        break;
 909    case OCM0_DSARC:
 910        ret = ocm->dsarc;
 911        break;
 912    case OCM0_DSACNTL:
 913        ret = ocm->dsacntl;
 914        break;
 915    default:
 916        ret = 0;
 917        break;
 918    }
 919
 920    return ret;
 921}
 922
 923static void dcr_write_ocm (void *opaque, int dcrn, uint32_t val)
 924{
 925    ppc405_ocm_t *ocm;
 926    uint32_t isarc, dsarc, isacntl, dsacntl;
 927
 928    ocm = opaque;
 929    isarc = ocm->isarc;
 930    dsarc = ocm->dsarc;
 931    isacntl = ocm->isacntl;
 932    dsacntl = ocm->dsacntl;
 933    switch (dcrn) {
 934    case OCM0_ISARC:
 935        isarc = val & 0xFC000000;
 936        break;
 937    case OCM0_ISACNTL:
 938        isacntl = val & 0xC0000000;
 939        break;
 940    case OCM0_DSARC:
 941        isarc = val & 0xFC000000;
 942        break;
 943    case OCM0_DSACNTL:
 944        isacntl = val & 0xC0000000;
 945        break;
 946    }
 947    ocm_update_mappings(ocm, isarc, isacntl, dsarc, dsacntl);
 948    ocm->isarc = isarc;
 949    ocm->dsarc = dsarc;
 950    ocm->isacntl = isacntl;
 951    ocm->dsacntl = dsacntl;
 952}
 953
 954static void ocm_reset (void *opaque)
 955{
 956    ppc405_ocm_t *ocm;
 957    uint32_t isarc, dsarc, isacntl, dsacntl;
 958
 959    ocm = opaque;
 960    isarc = 0x00000000;
 961    isacntl = 0x00000000;
 962    dsarc = 0x00000000;
 963    dsacntl = 0x00000000;
 964    ocm_update_mappings(ocm, isarc, isacntl, dsarc, dsacntl);
 965    ocm->isarc = isarc;
 966    ocm->dsarc = dsarc;
 967    ocm->isacntl = isacntl;
 968    ocm->dsacntl = dsacntl;
 969}
 970
 971static void ppc405_ocm_init(CPUPPCState *env)
 972{
 973    ppc405_ocm_t *ocm;
 974
 975    ocm = g_malloc0(sizeof(ppc405_ocm_t));
 976    /* XXX: Size is 4096 or 0x04000000 */
 977    memory_region_init_ram(&ocm->isarc_ram, NULL, "ppc405.ocm", 4096,
 978                           &error_fatal);
 979    vmstate_register_ram_global(&ocm->isarc_ram);
 980    memory_region_init_alias(&ocm->dsarc_ram, NULL, "ppc405.dsarc", &ocm->isarc_ram,
 981                             0, 4096);
 982    qemu_register_reset(&ocm_reset, ocm);
 983    ppc_dcr_register(env, OCM0_ISARC,
 984                     ocm, &dcr_read_ocm, &dcr_write_ocm);
 985    ppc_dcr_register(env, OCM0_ISACNTL,
 986                     ocm, &dcr_read_ocm, &dcr_write_ocm);
 987    ppc_dcr_register(env, OCM0_DSARC,
 988                     ocm, &dcr_read_ocm, &dcr_write_ocm);
 989    ppc_dcr_register(env, OCM0_DSACNTL,
 990                     ocm, &dcr_read_ocm, &dcr_write_ocm);
 991}
 992
 993/*****************************************************************************/
 994/* I2C controller */
 995typedef struct ppc4xx_i2c_t ppc4xx_i2c_t;
 996struct ppc4xx_i2c_t {
 997    qemu_irq irq;
 998    MemoryRegion iomem;
 999    uint8_t mdata;
1000    uint8_t lmadr;
1001    uint8_t hmadr;
1002    uint8_t cntl;
1003    uint8_t mdcntl;
1004    uint8_t sts;
1005    uint8_t extsts;
1006    uint8_t sdata;
1007    uint8_t lsadr;
1008    uint8_t hsadr;
1009    uint8_t clkdiv;
1010    uint8_t intrmsk;
1011    uint8_t xfrcnt;
1012    uint8_t xtcntlss;
1013    uint8_t directcntl;
1014};
1015
1016static uint32_t ppc4xx_i2c_readb (void *opaque, hwaddr addr)
1017{
1018    ppc4xx_i2c_t *i2c;
1019    uint32_t ret;
1020
1021#ifdef DEBUG_I2C
1022    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
1023#endif
1024    i2c = opaque;
1025    switch (addr) {
1026    case 0x00:
1027        //        i2c_readbyte(&i2c->mdata);
1028        ret = i2c->mdata;
1029        break;
1030    case 0x02:
1031        ret = i2c->sdata;
1032        break;
1033    case 0x04:
1034        ret = i2c->lmadr;
1035        break;
1036    case 0x05:
1037        ret = i2c->hmadr;
1038        break;
1039    case 0x06:
1040        ret = i2c->cntl;
1041        break;
1042    case 0x07:
1043        ret = i2c->mdcntl;
1044        break;
1045    case 0x08:
1046        ret = i2c->sts;
1047        break;
1048    case 0x09:
1049        ret = i2c->extsts;
1050        break;
1051    case 0x0A:
1052        ret = i2c->lsadr;
1053        break;
1054    case 0x0B:
1055        ret = i2c->hsadr;
1056        break;
1057    case 0x0C:
1058        ret = i2c->clkdiv;
1059        break;
1060    case 0x0D:
1061        ret = i2c->intrmsk;
1062        break;
1063    case 0x0E:
1064        ret = i2c->xfrcnt;
1065        break;
1066    case 0x0F:
1067        ret = i2c->xtcntlss;
1068        break;
1069    case 0x10:
1070        ret = i2c->directcntl;
1071        break;
1072    default:
1073        ret = 0x00;
1074        break;
1075    }
1076#ifdef DEBUG_I2C
1077    printf("%s: addr " TARGET_FMT_plx " %02" PRIx32 "\n", __func__, addr, ret);
1078#endif
1079
1080    return ret;
1081}
1082
1083static void ppc4xx_i2c_writeb (void *opaque,
1084                               hwaddr addr, uint32_t value)
1085{
1086    ppc4xx_i2c_t *i2c;
1087
1088#ifdef DEBUG_I2C
1089    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
1090           value);
1091#endif
1092    i2c = opaque;
1093    switch (addr) {
1094    case 0x00:
1095        i2c->mdata = value;
1096        //        i2c_sendbyte(&i2c->mdata);
1097        break;
1098    case 0x02:
1099        i2c->sdata = value;
1100        break;
1101    case 0x04:
1102        i2c->lmadr = value;
1103        break;
1104    case 0x05:
1105        i2c->hmadr = value;
1106        break;
1107    case 0x06:
1108        i2c->cntl = value;
1109        break;
1110    case 0x07:
1111        i2c->mdcntl = value & 0xDF;
1112        break;
1113    case 0x08:
1114        i2c->sts &= ~(value & 0x0A);
1115        break;
1116    case 0x09:
1117        i2c->extsts &= ~(value & 0x8F);
1118        break;
1119    case 0x0A:
1120        i2c->lsadr = value;
1121        break;
1122    case 0x0B:
1123        i2c->hsadr = value;
1124        break;
1125    case 0x0C:
1126        i2c->clkdiv = value;
1127        break;
1128    case 0x0D:
1129        i2c->intrmsk = value;
1130        break;
1131    case 0x0E:
1132        i2c->xfrcnt = value & 0x77;
1133        break;
1134    case 0x0F:
1135        i2c->xtcntlss = value;
1136        break;
1137    case 0x10:
1138        i2c->directcntl = value & 0x7;
1139        break;
1140    }
1141}
1142
1143static uint32_t ppc4xx_i2c_readw (void *opaque, hwaddr addr)
1144{
1145    uint32_t ret;
1146
1147#ifdef DEBUG_I2C
1148    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
1149#endif
1150    ret = ppc4xx_i2c_readb(opaque, addr) << 8;
1151    ret |= ppc4xx_i2c_readb(opaque, addr + 1);
1152
1153    return ret;
1154}
1155
1156static void ppc4xx_i2c_writew (void *opaque,
1157                               hwaddr addr, uint32_t value)
1158{
1159#ifdef DEBUG_I2C
1160    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
1161           value);
1162#endif
1163    ppc4xx_i2c_writeb(opaque, addr, value >> 8);
1164    ppc4xx_i2c_writeb(opaque, addr + 1, value);
1165}
1166
1167static uint32_t ppc4xx_i2c_readl (void *opaque, hwaddr addr)
1168{
1169    uint32_t ret;
1170
1171#ifdef DEBUG_I2C
1172    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
1173#endif
1174    ret = ppc4xx_i2c_readb(opaque, addr) << 24;
1175    ret |= ppc4xx_i2c_readb(opaque, addr + 1) << 16;
1176    ret |= ppc4xx_i2c_readb(opaque, addr + 2) << 8;
1177    ret |= ppc4xx_i2c_readb(opaque, addr + 3);
1178
1179    return ret;
1180}
1181
1182static void ppc4xx_i2c_writel (void *opaque,
1183                               hwaddr addr, uint32_t value)
1184{
1185#ifdef DEBUG_I2C
1186    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
1187           value);
1188#endif
1189    ppc4xx_i2c_writeb(opaque, addr, value >> 24);
1190    ppc4xx_i2c_writeb(opaque, addr + 1, value >> 16);
1191    ppc4xx_i2c_writeb(opaque, addr + 2, value >> 8);
1192    ppc4xx_i2c_writeb(opaque, addr + 3, value);
1193}
1194
1195static const MemoryRegionOps i2c_ops = {
1196    .old_mmio = {
1197        .read = { ppc4xx_i2c_readb, ppc4xx_i2c_readw, ppc4xx_i2c_readl, },
1198        .write = { ppc4xx_i2c_writeb, ppc4xx_i2c_writew, ppc4xx_i2c_writel, },
1199    },
1200    .endianness = DEVICE_NATIVE_ENDIAN,
1201};
1202
1203static void ppc4xx_i2c_reset (void *opaque)
1204{
1205    ppc4xx_i2c_t *i2c;
1206
1207    i2c = opaque;
1208    i2c->mdata = 0x00;
1209    i2c->sdata = 0x00;
1210    i2c->cntl = 0x00;
1211    i2c->mdcntl = 0x00;
1212    i2c->sts = 0x00;
1213    i2c->extsts = 0x00;
1214    i2c->clkdiv = 0x00;
1215    i2c->xfrcnt = 0x00;
1216    i2c->directcntl = 0x0F;
1217}
1218
1219static void ppc405_i2c_init(hwaddr base, qemu_irq irq)
1220{
1221    ppc4xx_i2c_t *i2c;
1222
1223    i2c = g_malloc0(sizeof(ppc4xx_i2c_t));
1224    i2c->irq = irq;
1225#ifdef DEBUG_I2C
1226    printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
1227#endif
1228    memory_region_init_io(&i2c->iomem, NULL, &i2c_ops, i2c, "i2c", 0x011);
1229    memory_region_add_subregion(get_system_memory(), base, &i2c->iomem);
1230    qemu_register_reset(ppc4xx_i2c_reset, i2c);
1231}
1232
1233/*****************************************************************************/
1234/* General purpose timers */
1235typedef struct ppc4xx_gpt_t ppc4xx_gpt_t;
1236struct ppc4xx_gpt_t {
1237    MemoryRegion iomem;
1238    int64_t tb_offset;
1239    uint32_t tb_freq;
1240    QEMUTimer *timer;
1241    qemu_irq irqs[5];
1242    uint32_t oe;
1243    uint32_t ol;
1244    uint32_t im;
1245    uint32_t is;
1246    uint32_t ie;
1247    uint32_t comp[5];
1248    uint32_t mask[5];
1249};
1250
1251static uint32_t ppc4xx_gpt_readb (void *opaque, hwaddr addr)
1252{
1253#ifdef DEBUG_GPT
1254    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
1255#endif
1256    /* XXX: generate a bus fault */
1257    return -1;
1258}
1259
1260static void ppc4xx_gpt_writeb (void *opaque,
1261                               hwaddr addr, uint32_t value)
1262{
1263#ifdef DEBUG_I2C
1264    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
1265           value);
1266#endif
1267    /* XXX: generate a bus fault */
1268}
1269
1270static uint32_t ppc4xx_gpt_readw (void *opaque, hwaddr addr)
1271{
1272#ifdef DEBUG_GPT
1273    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
1274#endif
1275    /* XXX: generate a bus fault */
1276    return -1;
1277}
1278
1279static void ppc4xx_gpt_writew (void *opaque,
1280                               hwaddr addr, uint32_t value)
1281{
1282#ifdef DEBUG_I2C
1283    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
1284           value);
1285#endif
1286    /* XXX: generate a bus fault */
1287}
1288
1289static int ppc4xx_gpt_compare (ppc4xx_gpt_t *gpt, int n)
1290{
1291    /* XXX: TODO */
1292    return 0;
1293}
1294
1295static void ppc4xx_gpt_set_output (ppc4xx_gpt_t *gpt, int n, int level)
1296{
1297    /* XXX: TODO */
1298}
1299
1300static void ppc4xx_gpt_set_outputs (ppc4xx_gpt_t *gpt)
1301{
1302    uint32_t mask;
1303    int i;
1304
1305    mask = 0x80000000;
1306    for (i = 0; i < 5; i++) {
1307        if (gpt->oe & mask) {
1308            /* Output is enabled */
1309            if (ppc4xx_gpt_compare(gpt, i)) {
1310                /* Comparison is OK */
1311                ppc4xx_gpt_set_output(gpt, i, gpt->ol & mask);
1312            } else {
1313                /* Comparison is KO */
1314                ppc4xx_gpt_set_output(gpt, i, gpt->ol & mask ? 0 : 1);
1315            }
1316        }
1317        mask = mask >> 1;
1318    }
1319}
1320
1321static void ppc4xx_gpt_set_irqs (ppc4xx_gpt_t *gpt)
1322{
1323    uint32_t mask;
1324    int i;
1325
1326    mask = 0x00008000;
1327    for (i = 0; i < 5; i++) {
1328        if (gpt->is & gpt->im & mask)
1329            qemu_irq_raise(gpt->irqs[i]);
1330        else
1331            qemu_irq_lower(gpt->irqs[i]);
1332        mask = mask >> 1;
1333    }
1334}
1335
1336static void ppc4xx_gpt_compute_timer (ppc4xx_gpt_t *gpt)
1337{
1338    /* XXX: TODO */
1339}
1340
1341static uint32_t ppc4xx_gpt_readl (void *opaque, hwaddr addr)
1342{
1343    ppc4xx_gpt_t *gpt;
1344    uint32_t ret;
1345    int idx;
1346
1347#ifdef DEBUG_GPT
1348    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
1349#endif
1350    gpt = opaque;
1351    switch (addr) {
1352    case 0x00:
1353        /* Time base counter */
1354        ret = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + gpt->tb_offset,
1355                       gpt->tb_freq, get_ticks_per_sec());
1356        break;
1357    case 0x10:
1358        /* Output enable */
1359        ret = gpt->oe;
1360        break;
1361    case 0x14:
1362        /* Output level */
1363        ret = gpt->ol;
1364        break;
1365    case 0x18:
1366        /* Interrupt mask */
1367        ret = gpt->im;
1368        break;
1369    case 0x1C:
1370    case 0x20:
1371        /* Interrupt status */
1372        ret = gpt->is;
1373        break;
1374    case 0x24:
1375        /* Interrupt enable */
1376        ret = gpt->ie;
1377        break;
1378    case 0x80 ... 0x90:
1379        /* Compare timer */
1380        idx = (addr - 0x80) >> 2;
1381        ret = gpt->comp[idx];
1382        break;
1383    case 0xC0 ... 0xD0:
1384        /* Compare mask */
1385        idx = (addr - 0xC0) >> 2;
1386        ret = gpt->mask[idx];
1387        break;
1388    default:
1389        ret = -1;
1390        break;
1391    }
1392
1393    return ret;
1394}
1395
1396static void ppc4xx_gpt_writel (void *opaque,
1397                               hwaddr addr, uint32_t value)
1398{
1399    ppc4xx_gpt_t *gpt;
1400    int idx;
1401
1402#ifdef DEBUG_I2C
1403    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
1404           value);
1405#endif
1406    gpt = opaque;
1407    switch (addr) {
1408    case 0x00:
1409        /* Time base counter */
1410        gpt->tb_offset = muldiv64(value, get_ticks_per_sec(), gpt->tb_freq)
1411            - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
1412        ppc4xx_gpt_compute_timer(gpt);
1413        break;
1414    case 0x10:
1415        /* Output enable */
1416        gpt->oe = value & 0xF8000000;
1417        ppc4xx_gpt_set_outputs(gpt);
1418        break;
1419    case 0x14:
1420        /* Output level */
1421        gpt->ol = value & 0xF8000000;
1422        ppc4xx_gpt_set_outputs(gpt);
1423        break;
1424    case 0x18:
1425        /* Interrupt mask */
1426        gpt->im = value & 0x0000F800;
1427        break;
1428    case 0x1C:
1429        /* Interrupt status set */
1430        gpt->is |= value & 0x0000F800;
1431        ppc4xx_gpt_set_irqs(gpt);
1432        break;
1433    case 0x20:
1434        /* Interrupt status clear */
1435        gpt->is &= ~(value & 0x0000F800);
1436        ppc4xx_gpt_set_irqs(gpt);
1437        break;
1438    case 0x24:
1439        /* Interrupt enable */
1440        gpt->ie = value & 0x0000F800;
1441        ppc4xx_gpt_set_irqs(gpt);
1442        break;
1443    case 0x80 ... 0x90:
1444        /* Compare timer */
1445        idx = (addr - 0x80) >> 2;
1446        gpt->comp[idx] = value & 0xF8000000;
1447        ppc4xx_gpt_compute_timer(gpt);
1448        break;
1449    case 0xC0 ... 0xD0:
1450        /* Compare mask */
1451        idx = (addr - 0xC0) >> 2;
1452        gpt->mask[idx] = value & 0xF8000000;
1453        ppc4xx_gpt_compute_timer(gpt);
1454        break;
1455    }
1456}
1457
1458static const MemoryRegionOps gpt_ops = {
1459    .old_mmio = {
1460        .read = { ppc4xx_gpt_readb, ppc4xx_gpt_readw, ppc4xx_gpt_readl, },
1461        .write = { ppc4xx_gpt_writeb, ppc4xx_gpt_writew, ppc4xx_gpt_writel, },
1462    },
1463    .endianness = DEVICE_NATIVE_ENDIAN,
1464};
1465
1466static void ppc4xx_gpt_cb (void *opaque)
1467{
1468    ppc4xx_gpt_t *gpt;
1469
1470    gpt = opaque;
1471    ppc4xx_gpt_set_irqs(gpt);
1472    ppc4xx_gpt_set_outputs(gpt);
1473    ppc4xx_gpt_compute_timer(gpt);
1474}
1475
1476static void ppc4xx_gpt_reset (void *opaque)
1477{
1478    ppc4xx_gpt_t *gpt;
1479    int i;
1480
1481    gpt = opaque;
1482    timer_del(gpt->timer);
1483    gpt->oe = 0x00000000;
1484    gpt->ol = 0x00000000;
1485    gpt->im = 0x00000000;
1486    gpt->is = 0x00000000;
1487    gpt->ie = 0x00000000;
1488    for (i = 0; i < 5; i++) {
1489        gpt->comp[i] = 0x00000000;
1490        gpt->mask[i] = 0x00000000;
1491    }
1492}
1493
1494static void ppc4xx_gpt_init(hwaddr base, qemu_irq irqs[5])
1495{
1496    ppc4xx_gpt_t *gpt;
1497    int i;
1498
1499    gpt = g_malloc0(sizeof(ppc4xx_gpt_t));
1500    for (i = 0; i < 5; i++) {
1501        gpt->irqs[i] = irqs[i];
1502    }
1503    gpt->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ppc4xx_gpt_cb, gpt);
1504#ifdef DEBUG_GPT
1505    printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
1506#endif
1507    memory_region_init_io(&gpt->iomem, NULL, &gpt_ops, gpt, "gpt", 0x0d4);
1508    memory_region_add_subregion(get_system_memory(), base, &gpt->iomem);
1509    qemu_register_reset(ppc4xx_gpt_reset, gpt);
1510}
1511
1512/*****************************************************************************/
1513/* MAL */
1514enum {
1515    MAL0_CFG      = 0x180,
1516    MAL0_ESR      = 0x181,
1517    MAL0_IER      = 0x182,
1518    MAL0_TXCASR   = 0x184,
1519    MAL0_TXCARR   = 0x185,
1520    MAL0_TXEOBISR = 0x186,
1521    MAL0_TXDEIR   = 0x187,
1522    MAL0_RXCASR   = 0x190,
1523    MAL0_RXCARR   = 0x191,
1524    MAL0_RXEOBISR = 0x192,
1525    MAL0_RXDEIR   = 0x193,
1526    MAL0_TXCTP0R  = 0x1A0,
1527    MAL0_TXCTP1R  = 0x1A1,
1528    MAL0_TXCTP2R  = 0x1A2,
1529    MAL0_TXCTP3R  = 0x1A3,
1530    MAL0_RXCTP0R  = 0x1C0,
1531    MAL0_RXCTP1R  = 0x1C1,
1532    MAL0_RCBS0    = 0x1E0,
1533    MAL0_RCBS1    = 0x1E1,
1534};
1535
1536typedef struct ppc40x_mal_t ppc40x_mal_t;
1537struct ppc40x_mal_t {
1538    qemu_irq irqs[4];
1539    uint32_t cfg;
1540    uint32_t esr;
1541    uint32_t ier;
1542    uint32_t txcasr;
1543    uint32_t txcarr;
1544    uint32_t txeobisr;
1545    uint32_t txdeir;
1546    uint32_t rxcasr;
1547    uint32_t rxcarr;
1548    uint32_t rxeobisr;
1549    uint32_t rxdeir;
1550    uint32_t txctpr[4];
1551    uint32_t rxctpr[2];
1552    uint32_t rcbs[2];
1553};
1554
1555static void ppc40x_mal_reset (void *opaque);
1556
1557static uint32_t dcr_read_mal (void *opaque, int dcrn)
1558{
1559    ppc40x_mal_t *mal;
1560    uint32_t ret;
1561
1562    mal = opaque;
1563    switch (dcrn) {
1564    case MAL0_CFG:
1565        ret = mal->cfg;
1566        break;
1567    case MAL0_ESR:
1568        ret = mal->esr;
1569        break;
1570    case MAL0_IER:
1571        ret = mal->ier;
1572        break;
1573    case MAL0_TXCASR:
1574        ret = mal->txcasr;
1575        break;
1576    case MAL0_TXCARR:
1577        ret = mal->txcarr;
1578        break;
1579    case MAL0_TXEOBISR:
1580        ret = mal->txeobisr;
1581        break;
1582    case MAL0_TXDEIR:
1583        ret = mal->txdeir;
1584        break;
1585    case MAL0_RXCASR:
1586        ret = mal->rxcasr;
1587        break;
1588    case MAL0_RXCARR:
1589        ret = mal->rxcarr;
1590        break;
1591    case MAL0_RXEOBISR:
1592        ret = mal->rxeobisr;
1593        break;
1594    case MAL0_RXDEIR:
1595        ret = mal->rxdeir;
1596        break;
1597    case MAL0_TXCTP0R:
1598        ret = mal->txctpr[0];
1599        break;
1600    case MAL0_TXCTP1R:
1601        ret = mal->txctpr[1];
1602        break;
1603    case MAL0_TXCTP2R:
1604        ret = mal->txctpr[2];
1605        break;
1606    case MAL0_TXCTP3R:
1607        ret = mal->txctpr[3];
1608        break;
1609    case MAL0_RXCTP0R:
1610        ret = mal->rxctpr[0];
1611        break;
1612    case MAL0_RXCTP1R:
1613        ret = mal->rxctpr[1];
1614        break;
1615    case MAL0_RCBS0:
1616        ret = mal->rcbs[0];
1617        break;
1618    case MAL0_RCBS1:
1619        ret = mal->rcbs[1];
1620        break;
1621    default:
1622        ret = 0;
1623        break;
1624    }
1625
1626    return ret;
1627}
1628
1629static void dcr_write_mal (void *opaque, int dcrn, uint32_t val)
1630{
1631    ppc40x_mal_t *mal;
1632    int idx;
1633
1634    mal = opaque;
1635    switch (dcrn) {
1636    case MAL0_CFG:
1637        if (val & 0x80000000)
1638            ppc40x_mal_reset(mal);
1639        mal->cfg = val & 0x00FFC087;
1640        break;
1641    case MAL0_ESR:
1642        /* Read/clear */
1643        mal->esr &= ~val;
1644        break;
1645    case MAL0_IER:
1646        mal->ier = val & 0x0000001F;
1647        break;
1648    case MAL0_TXCASR:
1649        mal->txcasr = val & 0xF0000000;
1650        break;
1651    case MAL0_TXCARR:
1652        mal->txcarr = val & 0xF0000000;
1653        break;
1654    case MAL0_TXEOBISR:
1655        /* Read/clear */
1656        mal->txeobisr &= ~val;
1657        break;
1658    case MAL0_TXDEIR:
1659        /* Read/clear */
1660        mal->txdeir &= ~val;
1661        break;
1662    case MAL0_RXCASR:
1663        mal->rxcasr = val & 0xC0000000;
1664        break;
1665    case MAL0_RXCARR:
1666        mal->rxcarr = val & 0xC0000000;
1667        break;
1668    case MAL0_RXEOBISR:
1669        /* Read/clear */
1670        mal->rxeobisr &= ~val;
1671        break;
1672    case MAL0_RXDEIR:
1673        /* Read/clear */
1674        mal->rxdeir &= ~val;
1675        break;
1676    case MAL0_TXCTP0R:
1677        idx = 0;
1678        goto update_tx_ptr;
1679    case MAL0_TXCTP1R:
1680        idx = 1;
1681        goto update_tx_ptr;
1682    case MAL0_TXCTP2R:
1683        idx = 2;
1684        goto update_tx_ptr;
1685    case MAL0_TXCTP3R:
1686        idx = 3;
1687    update_tx_ptr:
1688        mal->txctpr[idx] = val;
1689        break;
1690    case MAL0_RXCTP0R:
1691        idx = 0;
1692        goto update_rx_ptr;
1693    case MAL0_RXCTP1R:
1694        idx = 1;
1695    update_rx_ptr:
1696        mal->rxctpr[idx] = val;
1697        break;
1698    case MAL0_RCBS0:
1699        idx = 0;
1700        goto update_rx_size;
1701    case MAL0_RCBS1:
1702        idx = 1;
1703    update_rx_size:
1704        mal->rcbs[idx] = val & 0x000000FF;
1705        break;
1706    }
1707}
1708
1709static void ppc40x_mal_reset (void *opaque)
1710{
1711    ppc40x_mal_t *mal;
1712
1713    mal = opaque;
1714    mal->cfg = 0x0007C000;
1715    mal->esr = 0x00000000;
1716    mal->ier = 0x00000000;
1717    mal->rxcasr = 0x00000000;
1718    mal->rxdeir = 0x00000000;
1719    mal->rxeobisr = 0x00000000;
1720    mal->txcasr = 0x00000000;
1721    mal->txdeir = 0x00000000;
1722    mal->txeobisr = 0x00000000;
1723}
1724
1725static void ppc405_mal_init(CPUPPCState *env, qemu_irq irqs[4])
1726{
1727    ppc40x_mal_t *mal;
1728    int i;
1729
1730    mal = g_malloc0(sizeof(ppc40x_mal_t));
1731    for (i = 0; i < 4; i++)
1732        mal->irqs[i] = irqs[i];
1733    qemu_register_reset(&ppc40x_mal_reset, mal);
1734    ppc_dcr_register(env, MAL0_CFG,
1735                     mal, &dcr_read_mal, &dcr_write_mal);
1736    ppc_dcr_register(env, MAL0_ESR,
1737                     mal, &dcr_read_mal, &dcr_write_mal);
1738    ppc_dcr_register(env, MAL0_IER,
1739                     mal, &dcr_read_mal, &dcr_write_mal);
1740    ppc_dcr_register(env, MAL0_TXCASR,
1741                     mal, &dcr_read_mal, &dcr_write_mal);
1742    ppc_dcr_register(env, MAL0_TXCARR,
1743                     mal, &dcr_read_mal, &dcr_write_mal);
1744    ppc_dcr_register(env, MAL0_TXEOBISR,
1745                     mal, &dcr_read_mal, &dcr_write_mal);
1746    ppc_dcr_register(env, MAL0_TXDEIR,
1747                     mal, &dcr_read_mal, &dcr_write_mal);
1748    ppc_dcr_register(env, MAL0_RXCASR,
1749                     mal, &dcr_read_mal, &dcr_write_mal);
1750    ppc_dcr_register(env, MAL0_RXCARR,
1751                     mal, &dcr_read_mal, &dcr_write_mal);
1752    ppc_dcr_register(env, MAL0_RXEOBISR,
1753                     mal, &dcr_read_mal, &dcr_write_mal);
1754    ppc_dcr_register(env, MAL0_RXDEIR,
1755                     mal, &dcr_read_mal, &dcr_write_mal);
1756    ppc_dcr_register(env, MAL0_TXCTP0R,
1757                     mal, &dcr_read_mal, &dcr_write_mal);
1758    ppc_dcr_register(env, MAL0_TXCTP1R,
1759                     mal, &dcr_read_mal, &dcr_write_mal);
1760    ppc_dcr_register(env, MAL0_TXCTP2R,
1761                     mal, &dcr_read_mal, &dcr_write_mal);
1762    ppc_dcr_register(env, MAL0_TXCTP3R,
1763                     mal, &dcr_read_mal, &dcr_write_mal);
1764    ppc_dcr_register(env, MAL0_RXCTP0R,
1765                     mal, &dcr_read_mal, &dcr_write_mal);
1766    ppc_dcr_register(env, MAL0_RXCTP1R,
1767                     mal, &dcr_read_mal, &dcr_write_mal);
1768    ppc_dcr_register(env, MAL0_RCBS0,
1769                     mal, &dcr_read_mal, &dcr_write_mal);
1770    ppc_dcr_register(env, MAL0_RCBS1,
1771                     mal, &dcr_read_mal, &dcr_write_mal);
1772}
1773
1774/*****************************************************************************/
1775/* SPR */
1776void ppc40x_core_reset(PowerPCCPU *cpu)
1777{
1778    CPUPPCState *env = &cpu->env;
1779    target_ulong dbsr;
1780
1781    printf("Reset PowerPC core\n");
1782    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_RESET);
1783    dbsr = env->spr[SPR_40x_DBSR];
1784    dbsr &= ~0x00000300;
1785    dbsr |= 0x00000100;
1786    env->spr[SPR_40x_DBSR] = dbsr;
1787}
1788
1789void ppc40x_chip_reset(PowerPCCPU *cpu)
1790{
1791    CPUPPCState *env = &cpu->env;
1792    target_ulong dbsr;
1793
1794    printf("Reset PowerPC chip\n");
1795    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_RESET);
1796    /* XXX: TODO reset all internal peripherals */
1797    dbsr = env->spr[SPR_40x_DBSR];
1798    dbsr &= ~0x00000300;
1799    dbsr |= 0x00000200;
1800    env->spr[SPR_40x_DBSR] = dbsr;
1801}
1802
1803void ppc40x_system_reset(PowerPCCPU *cpu)
1804{
1805    printf("Reset PowerPC system\n");
1806    qemu_system_reset_request();
1807}
1808
1809void store_40x_dbcr0 (CPUPPCState *env, uint32_t val)
1810{
1811    PowerPCCPU *cpu = ppc_env_get_cpu(env);
1812
1813    switch ((val >> 28) & 0x3) {
1814    case 0x0:
1815        /* No action */
1816        break;
1817    case 0x1:
1818        /* Core reset */
1819        ppc40x_core_reset(cpu);
1820        break;
1821    case 0x2:
1822        /* Chip reset */
1823        ppc40x_chip_reset(cpu);
1824        break;
1825    case 0x3:
1826        /* System reset */
1827        ppc40x_system_reset(cpu);
1828        break;
1829    }
1830}
1831
1832/*****************************************************************************/
1833/* PowerPC 405CR */
1834enum {
1835    PPC405CR_CPC0_PLLMR  = 0x0B0,
1836    PPC405CR_CPC0_CR0    = 0x0B1,
1837    PPC405CR_CPC0_CR1    = 0x0B2,
1838    PPC405CR_CPC0_PSR    = 0x0B4,
1839    PPC405CR_CPC0_JTAGID = 0x0B5,
1840    PPC405CR_CPC0_ER     = 0x0B9,
1841    PPC405CR_CPC0_FR     = 0x0BA,
1842    PPC405CR_CPC0_SR     = 0x0BB,
1843};
1844
1845enum {
1846    PPC405CR_CPU_CLK   = 0,
1847    PPC405CR_TMR_CLK   = 1,
1848    PPC405CR_PLB_CLK   = 2,
1849    PPC405CR_SDRAM_CLK = 3,
1850    PPC405CR_OPB_CLK   = 4,
1851    PPC405CR_EXT_CLK   = 5,
1852    PPC405CR_UART_CLK  = 6,
1853    PPC405CR_CLK_NB    = 7,
1854};
1855
1856typedef struct ppc405cr_cpc_t ppc405cr_cpc_t;
1857struct ppc405cr_cpc_t {
1858    clk_setup_t clk_setup[PPC405CR_CLK_NB];
1859    uint32_t sysclk;
1860    uint32_t psr;
1861    uint32_t cr0;
1862    uint32_t cr1;
1863    uint32_t jtagid;
1864    uint32_t pllmr;
1865    uint32_t er;
1866    uint32_t fr;
1867};
1868
1869static void ppc405cr_clk_setup (ppc405cr_cpc_t *cpc)
1870{
1871    uint64_t VCO_out, PLL_out;
1872    uint32_t CPU_clk, TMR_clk, SDRAM_clk, PLB_clk, OPB_clk, EXT_clk, UART_clk;
1873    int M, D0, D1, D2;
1874
1875    D0 = ((cpc->pllmr >> 26) & 0x3) + 1; /* CBDV */
1876    if (cpc->pllmr & 0x80000000) {
1877        D1 = (((cpc->pllmr >> 20) - 1) & 0xF) + 1; /* FBDV */
1878        D2 = 8 - ((cpc->pllmr >> 16) & 0x7); /* FWDVA */
1879        M = D0 * D1 * D2;
1880        VCO_out = cpc->sysclk * M;
1881        if (VCO_out < 400000000 || VCO_out > 800000000) {
1882            /* PLL cannot lock */
1883            cpc->pllmr &= ~0x80000000;
1884            goto bypass_pll;
1885        }
1886        PLL_out = VCO_out / D2;
1887    } else {
1888        /* Bypass PLL */
1889    bypass_pll:
1890        M = D0;
1891        PLL_out = cpc->sysclk * M;
1892    }
1893    CPU_clk = PLL_out;
1894    if (cpc->cr1 & 0x00800000)
1895        TMR_clk = cpc->sysclk; /* Should have a separate clock */
1896    else
1897        TMR_clk = CPU_clk;
1898    PLB_clk = CPU_clk / D0;
1899    SDRAM_clk = PLB_clk;
1900    D0 = ((cpc->pllmr >> 10) & 0x3) + 1;
1901    OPB_clk = PLB_clk / D0;
1902    D0 = ((cpc->pllmr >> 24) & 0x3) + 2;
1903    EXT_clk = PLB_clk / D0;
1904    D0 = ((cpc->cr0 >> 1) & 0x1F) + 1;
1905    UART_clk = CPU_clk / D0;
1906    /* Setup CPU clocks */
1907    clk_setup(&cpc->clk_setup[PPC405CR_CPU_CLK], CPU_clk);
1908    /* Setup time-base clock */
1909    clk_setup(&cpc->clk_setup[PPC405CR_TMR_CLK], TMR_clk);
1910    /* Setup PLB clock */
1911    clk_setup(&cpc->clk_setup[PPC405CR_PLB_CLK], PLB_clk);
1912    /* Setup SDRAM clock */
1913    clk_setup(&cpc->clk_setup[PPC405CR_SDRAM_CLK], SDRAM_clk);
1914    /* Setup OPB clock */
1915    clk_setup(&cpc->clk_setup[PPC405CR_OPB_CLK], OPB_clk);
1916    /* Setup external clock */
1917    clk_setup(&cpc->clk_setup[PPC405CR_EXT_CLK], EXT_clk);
1918    /* Setup UART clock */
1919    clk_setup(&cpc->clk_setup[PPC405CR_UART_CLK], UART_clk);
1920}
1921
1922static uint32_t dcr_read_crcpc (void *opaque, int dcrn)
1923{
1924    ppc405cr_cpc_t *cpc;
1925    uint32_t ret;
1926
1927    cpc = opaque;
1928    switch (dcrn) {
1929    case PPC405CR_CPC0_PLLMR:
1930        ret = cpc->pllmr;
1931        break;
1932    case PPC405CR_CPC0_CR0:
1933        ret = cpc->cr0;
1934        break;
1935    case PPC405CR_CPC0_CR1:
1936        ret = cpc->cr1;
1937        break;
1938    case PPC405CR_CPC0_PSR:
1939        ret = cpc->psr;
1940        break;
1941    case PPC405CR_CPC0_JTAGID:
1942        ret = cpc->jtagid;
1943        break;
1944    case PPC405CR_CPC0_ER:
1945        ret = cpc->er;
1946        break;
1947    case PPC405CR_CPC0_FR:
1948        ret = cpc->fr;
1949        break;
1950    case PPC405CR_CPC0_SR:
1951        ret = ~(cpc->er | cpc->fr) & 0xFFFF0000;
1952        break;
1953    default:
1954        /* Avoid gcc warning */
1955        ret = 0;
1956        break;
1957    }
1958
1959    return ret;
1960}
1961
1962static void dcr_write_crcpc (void *opaque, int dcrn, uint32_t val)
1963{
1964    ppc405cr_cpc_t *cpc;
1965
1966    cpc = opaque;
1967    switch (dcrn) {
1968    case PPC405CR_CPC0_PLLMR:
1969        cpc->pllmr = val & 0xFFF77C3F;
1970        break;
1971    case PPC405CR_CPC0_CR0:
1972        cpc->cr0 = val & 0x0FFFFFFE;
1973        break;
1974    case PPC405CR_CPC0_CR1:
1975        cpc->cr1 = val & 0x00800000;
1976        break;
1977    case PPC405CR_CPC0_PSR:
1978        /* Read-only */
1979        break;
1980    case PPC405CR_CPC0_JTAGID:
1981        /* Read-only */
1982        break;
1983    case PPC405CR_CPC0_ER:
1984        cpc->er = val & 0xBFFC0000;
1985        break;
1986    case PPC405CR_CPC0_FR:
1987        cpc->fr = val & 0xBFFC0000;
1988        break;
1989    case PPC405CR_CPC0_SR:
1990        /* Read-only */
1991        break;
1992    }
1993}
1994
1995static void ppc405cr_cpc_reset (void *opaque)
1996{
1997    ppc405cr_cpc_t *cpc;
1998    int D;
1999
2000    cpc = opaque;
2001    /* Compute PLLMR value from PSR settings */
2002    cpc->pllmr = 0x80000000;
2003    /* PFWD */
2004    switch ((cpc->psr >> 30) & 3) {
2005    case 0:
2006        /* Bypass */
2007        cpc->pllmr &= ~0x80000000;
2008        break;
2009    case 1:
2010        /* Divide by 3 */
2011        cpc->pllmr |= 5 << 16;
2012        break;
2013    case 2:
2014        /* Divide by 4 */
2015        cpc->pllmr |= 4 << 16;
2016        break;
2017    case 3:
2018        /* Divide by 6 */
2019        cpc->pllmr |= 2 << 16;
2020        break;
2021    }
2022    /* PFBD */
2023    D = (cpc->psr >> 28) & 3;
2024    cpc->pllmr |= (D + 1) << 20;
2025    /* PT   */
2026    D = (cpc->psr >> 25) & 7;
2027    switch (D) {
2028    case 0x2:
2029        cpc->pllmr |= 0x13;
2030        break;
2031    case 0x4:
2032        cpc->pllmr |= 0x15;
2033        break;
2034    case 0x5:
2035        cpc->pllmr |= 0x16;
2036        break;
2037    default:
2038        break;
2039    }
2040    /* PDC  */
2041    D = (cpc->psr >> 23) & 3;
2042    cpc->pllmr |= D << 26;
2043    /* ODP  */
2044    D = (cpc->psr >> 21) & 3;
2045    cpc->pllmr |= D << 10;
2046    /* EBPD */
2047    D = (cpc->psr >> 17) & 3;
2048    cpc->pllmr |= D << 24;
2049    cpc->cr0 = 0x0000003C;
2050    cpc->cr1 = 0x2B0D8800;
2051    cpc->er = 0x00000000;
2052    cpc->fr = 0x00000000;
2053    ppc405cr_clk_setup(cpc);
2054}
2055
2056static void ppc405cr_clk_init (ppc405cr_cpc_t *cpc)
2057{
2058    int D;
2059
2060    /* XXX: this should be read from IO pins */
2061    cpc->psr = 0x00000000; /* 8 bits ROM */
2062    /* PFWD */
2063    D = 0x2; /* Divide by 4 */
2064    cpc->psr |= D << 30;
2065    /* PFBD */
2066    D = 0x1; /* Divide by 2 */
2067    cpc->psr |= D << 28;
2068    /* PDC */
2069    D = 0x1; /* Divide by 2 */
2070    cpc->psr |= D << 23;
2071    /* PT */
2072    D = 0x5; /* M = 16 */
2073    cpc->psr |= D << 25;
2074    /* ODP */
2075    D = 0x1; /* Divide by 2 */
2076    cpc->psr |= D << 21;
2077    /* EBDP */
2078    D = 0x2; /* Divide by 4 */
2079    cpc->psr |= D << 17;
2080}
2081
2082static void ppc405cr_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[7],
2083                               uint32_t sysclk)
2084{
2085    ppc405cr_cpc_t *cpc;
2086
2087    cpc = g_malloc0(sizeof(ppc405cr_cpc_t));
2088    memcpy(cpc->clk_setup, clk_setup,
2089           PPC405CR_CLK_NB * sizeof(clk_setup_t));
2090    cpc->sysclk = sysclk;
2091    cpc->jtagid = 0x42051049;
2092    ppc_dcr_register(env, PPC405CR_CPC0_PSR, cpc,
2093                     &dcr_read_crcpc, &dcr_write_crcpc);
2094    ppc_dcr_register(env, PPC405CR_CPC0_CR0, cpc,
2095                     &dcr_read_crcpc, &dcr_write_crcpc);
2096    ppc_dcr_register(env, PPC405CR_CPC0_CR1, cpc,
2097                     &dcr_read_crcpc, &dcr_write_crcpc);
2098    ppc_dcr_register(env, PPC405CR_CPC0_JTAGID, cpc,
2099                     &dcr_read_crcpc, &dcr_write_crcpc);
2100    ppc_dcr_register(env, PPC405CR_CPC0_PLLMR, cpc,
2101                     &dcr_read_crcpc, &dcr_write_crcpc);
2102    ppc_dcr_register(env, PPC405CR_CPC0_ER, cpc,
2103                     &dcr_read_crcpc, &dcr_write_crcpc);
2104    ppc_dcr_register(env, PPC405CR_CPC0_FR, cpc,
2105                     &dcr_read_crcpc, &dcr_write_crcpc);
2106    ppc_dcr_register(env, PPC405CR_CPC0_SR, cpc,
2107                     &dcr_read_crcpc, &dcr_write_crcpc);
2108    ppc405cr_clk_init(cpc);
2109    qemu_register_reset(ppc405cr_cpc_reset, cpc);
2110}
2111
2112CPUPPCState *ppc405cr_init(MemoryRegion *address_space_mem,
2113                        MemoryRegion ram_memories[4],
2114                        hwaddr ram_bases[4],
2115                        hwaddr ram_sizes[4],
2116                        uint32_t sysclk, qemu_irq **picp,
2117                        int do_init)
2118{
2119    clk_setup_t clk_setup[PPC405CR_CLK_NB];
2120    qemu_irq dma_irqs[4];
2121    PowerPCCPU *cpu;
2122    CPUPPCState *env;
2123    qemu_irq *pic, *irqs;
2124
2125    memset(clk_setup, 0, sizeof(clk_setup));
2126    cpu = ppc4xx_init("405cr", &clk_setup[PPC405CR_CPU_CLK],
2127                      &clk_setup[PPC405CR_TMR_CLK], sysclk);
2128    env = &cpu->env;
2129    /* Memory mapped devices registers */
2130    /* PLB arbitrer */
2131    ppc4xx_plb_init(env);
2132    /* PLB to OPB bridge */
2133    ppc4xx_pob_init(env);
2134    /* OBP arbitrer */
2135    ppc4xx_opba_init(0xef600600);
2136    /* Universal interrupt controller */
2137    irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
2138    irqs[PPCUIC_OUTPUT_INT] =
2139        ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
2140    irqs[PPCUIC_OUTPUT_CINT] =
2141        ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
2142    pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
2143    *picp = pic;
2144    /* SDRAM controller */
2145    ppc4xx_sdram_init(env, pic[14], 1, ram_memories,
2146                      ram_bases, ram_sizes, do_init);
2147    /* External bus controller */
2148    ppc405_ebc_init(env);
2149    /* DMA controller */
2150    dma_irqs[0] = pic[26];
2151    dma_irqs[1] = pic[25];
2152    dma_irqs[2] = pic[24];
2153    dma_irqs[3] = pic[23];
2154    ppc405_dma_init(env, dma_irqs);
2155    /* Serial ports */
2156    if (serial_hds[0] != NULL) {
2157        serial_mm_init(address_space_mem, 0xef600300, 0, pic[0],
2158                       PPC_SERIAL_MM_BAUDBASE, serial_hds[0],
2159                       DEVICE_BIG_ENDIAN);
2160    }
2161    if (serial_hds[1] != NULL) {
2162        serial_mm_init(address_space_mem, 0xef600400, 0, pic[1],
2163                       PPC_SERIAL_MM_BAUDBASE, serial_hds[1],
2164                       DEVICE_BIG_ENDIAN);
2165    }
2166    /* IIC controller */
2167    ppc405_i2c_init(0xef600500, pic[2]);
2168    /* GPIO */
2169    ppc405_gpio_init(0xef600700);
2170    /* CPU control */
2171    ppc405cr_cpc_init(env, clk_setup, sysclk);
2172
2173    return env;
2174}
2175
2176/*****************************************************************************/
2177/* PowerPC 405EP */
2178/* CPU control */
2179enum {
2180    PPC405EP_CPC0_PLLMR0 = 0x0F0,
2181    PPC405EP_CPC0_BOOT   = 0x0F1,
2182    PPC405EP_CPC0_EPCTL  = 0x0F3,
2183    PPC405EP_CPC0_PLLMR1 = 0x0F4,
2184    PPC405EP_CPC0_UCR    = 0x0F5,
2185    PPC405EP_CPC0_SRR    = 0x0F6,
2186    PPC405EP_CPC0_JTAGID = 0x0F7,
2187    PPC405EP_CPC0_PCI    = 0x0F9,
2188#if 0
2189    PPC405EP_CPC0_ER     = xxx,
2190    PPC405EP_CPC0_FR     = xxx,
2191    PPC405EP_CPC0_SR     = xxx,
2192#endif
2193};
2194
2195enum {
2196    PPC405EP_CPU_CLK   = 0,
2197    PPC405EP_PLB_CLK   = 1,
2198    PPC405EP_OPB_CLK   = 2,
2199    PPC405EP_EBC_CLK   = 3,
2200    PPC405EP_MAL_CLK   = 4,
2201    PPC405EP_PCI_CLK   = 5,
2202    PPC405EP_UART0_CLK = 6,
2203    PPC405EP_UART1_CLK = 7,
2204    PPC405EP_CLK_NB    = 8,
2205};
2206
2207typedef struct ppc405ep_cpc_t ppc405ep_cpc_t;
2208struct ppc405ep_cpc_t {
2209    uint32_t sysclk;
2210    clk_setup_t clk_setup[PPC405EP_CLK_NB];
2211    uint32_t boot;
2212    uint32_t epctl;
2213    uint32_t pllmr[2];
2214    uint32_t ucr;
2215    uint32_t srr;
2216    uint32_t jtagid;
2217    uint32_t pci;
2218    /* Clock and power management */
2219    uint32_t er;
2220    uint32_t fr;
2221    uint32_t sr;
2222};
2223
2224static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
2225{
2226    uint32_t CPU_clk, PLB_clk, OPB_clk, EBC_clk, MAL_clk, PCI_clk;
2227    uint32_t UART0_clk, UART1_clk;
2228    uint64_t VCO_out, PLL_out;
2229    int M, D;
2230
2231    VCO_out = 0;
2232    if ((cpc->pllmr[1] & 0x80000000) && !(cpc->pllmr[1] & 0x40000000)) {
2233        M = (((cpc->pllmr[1] >> 20) - 1) & 0xF) + 1; /* FBMUL */
2234#ifdef DEBUG_CLOCKS_LL
2235        printf("FBMUL %01" PRIx32 " %d\n", (cpc->pllmr[1] >> 20) & 0xF, M);
2236#endif
2237        D = 8 - ((cpc->pllmr[1] >> 16) & 0x7); /* FWDA */
2238#ifdef DEBUG_CLOCKS_LL
2239        printf("FWDA %01" PRIx32 " %d\n", (cpc->pllmr[1] >> 16) & 0x7, D);
2240#endif
2241        VCO_out = cpc->sysclk * M * D;
2242        if (VCO_out < 500000000UL || VCO_out > 1000000000UL) {
2243            /* Error - unlock the PLL */
2244            printf("VCO out of range %" PRIu64 "\n", VCO_out);
2245#if 0
2246            cpc->pllmr[1] &= ~0x80000000;
2247            goto pll_bypass;
2248#endif
2249        }
2250        PLL_out = VCO_out / D;
2251        /* Pretend the PLL is locked */
2252        cpc->boot |= 0x00000001;
2253    } else {
2254#if 0
2255    pll_bypass:
2256#endif
2257        PLL_out = cpc->sysclk;
2258        if (cpc->pllmr[1] & 0x40000000) {
2259            /* Pretend the PLL is not locked */
2260            cpc->boot &= ~0x00000001;
2261        }
2262    }
2263    /* Now, compute all other clocks */
2264    D = ((cpc->pllmr[0] >> 20) & 0x3) + 1; /* CCDV */
2265#ifdef DEBUG_CLOCKS_LL
2266    printf("CCDV %01" PRIx32 " %d\n", (cpc->pllmr[0] >> 20) & 0x3, D);
2267#endif
2268    CPU_clk = PLL_out / D;
2269    D = ((cpc->pllmr[0] >> 16) & 0x3) + 1; /* CBDV */
2270#ifdef DEBUG_CLOCKS_LL
2271    printf("CBDV %01" PRIx32 " %d\n", (cpc->pllmr[0] >> 16) & 0x3, D);
2272#endif
2273    PLB_clk = CPU_clk / D;
2274    D = ((cpc->pllmr[0] >> 12) & 0x3) + 1; /* OPDV */
2275#ifdef DEBUG_CLOCKS_LL
2276    printf("OPDV %01" PRIx32 " %d\n", (cpc->pllmr[0] >> 12) & 0x3, D);
2277#endif
2278    OPB_clk = PLB_clk / D;
2279    D = ((cpc->pllmr[0] >> 8) & 0x3) + 2; /* EPDV */
2280#ifdef DEBUG_CLOCKS_LL
2281    printf("EPDV %01" PRIx32 " %d\n", (cpc->pllmr[0] >> 8) & 0x3, D);
2282#endif
2283    EBC_clk = PLB_clk / D;
2284    D = ((cpc->pllmr[0] >> 4) & 0x3) + 1; /* MPDV */
2285#ifdef DEBUG_CLOCKS_LL
2286    printf("MPDV %01" PRIx32 " %d\n", (cpc->pllmr[0] >> 4) & 0x3, D);
2287#endif
2288    MAL_clk = PLB_clk / D;
2289    D = (cpc->pllmr[0] & 0x3) + 1; /* PPDV */
2290#ifdef DEBUG_CLOCKS_LL
2291    printf("PPDV %01" PRIx32 " %d\n", cpc->pllmr[0] & 0x3, D);
2292#endif
2293    PCI_clk = PLB_clk / D;
2294    D = ((cpc->ucr - 1) & 0x7F) + 1; /* U0DIV */
2295#ifdef DEBUG_CLOCKS_LL
2296    printf("U0DIV %01" PRIx32 " %d\n", cpc->ucr & 0x7F, D);
2297#endif
2298    UART0_clk = PLL_out / D;
2299    D = (((cpc->ucr >> 8) - 1) & 0x7F) + 1; /* U1DIV */
2300#ifdef DEBUG_CLOCKS_LL
2301    printf("U1DIV %01" PRIx32 " %d\n", (cpc->ucr >> 8) & 0x7F, D);
2302#endif
2303    UART1_clk = PLL_out / D;
2304#ifdef DEBUG_CLOCKS
2305    printf("Setup PPC405EP clocks - sysclk %" PRIu32 " VCO %" PRIu64
2306           " PLL out %" PRIu64 " Hz\n", cpc->sysclk, VCO_out, PLL_out);
2307    printf("CPU %" PRIu32 " PLB %" PRIu32 " OPB %" PRIu32 " EBC %" PRIu32
2308           " MAL %" PRIu32 " PCI %" PRIu32 " UART0 %" PRIu32
2309           " UART1 %" PRIu32 "\n",
2310           CPU_clk, PLB_clk, OPB_clk, EBC_clk, MAL_clk, PCI_clk,
2311           UART0_clk, UART1_clk);
2312#endif
2313    /* Setup CPU clocks */
2314    clk_setup(&cpc->clk_setup[PPC405EP_CPU_CLK], CPU_clk);
2315    /* Setup PLB clock */
2316    clk_setup(&cpc->clk_setup[PPC405EP_PLB_CLK], PLB_clk);
2317    /* Setup OPB clock */
2318    clk_setup(&cpc->clk_setup[PPC405EP_OPB_CLK], OPB_clk);
2319    /* Setup external clock */
2320    clk_setup(&cpc->clk_setup[PPC405EP_EBC_CLK], EBC_clk);
2321    /* Setup MAL clock */
2322    clk_setup(&cpc->clk_setup[PPC405EP_MAL_CLK], MAL_clk);
2323    /* Setup PCI clock */
2324    clk_setup(&cpc->clk_setup[PPC405EP_PCI_CLK], PCI_clk);
2325    /* Setup UART0 clock */
2326    clk_setup(&cpc->clk_setup[PPC405EP_UART0_CLK], UART0_clk);
2327    /* Setup UART1 clock */
2328    clk_setup(&cpc->clk_setup[PPC405EP_UART1_CLK], UART1_clk);
2329}
2330
2331static uint32_t dcr_read_epcpc (void *opaque, int dcrn)
2332{
2333    ppc405ep_cpc_t *cpc;
2334    uint32_t ret;
2335
2336    cpc = opaque;
2337    switch (dcrn) {
2338    case PPC405EP_CPC0_BOOT:
2339        ret = cpc->boot;
2340        break;
2341    case PPC405EP_CPC0_EPCTL:
2342        ret = cpc->epctl;
2343        break;
2344    case PPC405EP_CPC0_PLLMR0:
2345        ret = cpc->pllmr[0];
2346        break;
2347    case PPC405EP_CPC0_PLLMR1:
2348        ret = cpc->pllmr[1];
2349        break;
2350    case PPC405EP_CPC0_UCR:
2351        ret = cpc->ucr;
2352        break;
2353    case PPC405EP_CPC0_SRR:
2354        ret = cpc->srr;
2355        break;
2356    case PPC405EP_CPC0_JTAGID:
2357        ret = cpc->jtagid;
2358        break;
2359    case PPC405EP_CPC0_PCI:
2360        ret = cpc->pci;
2361        break;
2362    default:
2363        /* Avoid gcc warning */
2364        ret = 0;
2365        break;
2366    }
2367
2368    return ret;
2369}
2370
2371static void dcr_write_epcpc (void *opaque, int dcrn, uint32_t val)
2372{
2373    ppc405ep_cpc_t *cpc;
2374
2375    cpc = opaque;
2376    switch (dcrn) {
2377    case PPC405EP_CPC0_BOOT:
2378        /* Read-only register */
2379        break;
2380    case PPC405EP_CPC0_EPCTL:
2381        /* Don't care for now */
2382        cpc->epctl = val & 0xC00000F3;
2383        break;
2384    case PPC405EP_CPC0_PLLMR0:
2385        cpc->pllmr[0] = val & 0x00633333;
2386        ppc405ep_compute_clocks(cpc);
2387        break;
2388    case PPC405EP_CPC0_PLLMR1:
2389        cpc->pllmr[1] = val & 0xC0F73FFF;
2390        ppc405ep_compute_clocks(cpc);
2391        break;
2392    case PPC405EP_CPC0_UCR:
2393        /* UART control - don't care for now */
2394        cpc->ucr = val & 0x003F7F7F;
2395        break;
2396    case PPC405EP_CPC0_SRR:
2397        cpc->srr = val;
2398        break;
2399    case PPC405EP_CPC0_JTAGID:
2400        /* Read-only */
2401        break;
2402    case PPC405EP_CPC0_PCI:
2403        cpc->pci = val;
2404        break;
2405    }
2406}
2407
2408static void ppc405ep_cpc_reset (void *opaque)
2409{
2410    ppc405ep_cpc_t *cpc = opaque;
2411
2412    cpc->boot = 0x00000010;     /* Boot from PCI - IIC EEPROM disabled */
2413    cpc->epctl = 0x00000000;
2414    cpc->pllmr[0] = 0x00011010;
2415    cpc->pllmr[1] = 0x40000000;
2416    cpc->ucr = 0x00000000;
2417    cpc->srr = 0x00040000;
2418    cpc->pci = 0x00000000;
2419    cpc->er = 0x00000000;
2420    cpc->fr = 0x00000000;
2421    cpc->sr = 0x00000000;
2422    ppc405ep_compute_clocks(cpc);
2423}
2424
2425/* XXX: sysclk should be between 25 and 100 MHz */
2426static void ppc405ep_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[8],
2427                               uint32_t sysclk)
2428{
2429    ppc405ep_cpc_t *cpc;
2430
2431    cpc = g_malloc0(sizeof(ppc405ep_cpc_t));
2432    memcpy(cpc->clk_setup, clk_setup,
2433           PPC405EP_CLK_NB * sizeof(clk_setup_t));
2434    cpc->jtagid = 0x20267049;
2435    cpc->sysclk = sysclk;
2436    qemu_register_reset(&ppc405ep_cpc_reset, cpc);
2437    ppc_dcr_register(env, PPC405EP_CPC0_BOOT, cpc,
2438                     &dcr_read_epcpc, &dcr_write_epcpc);
2439    ppc_dcr_register(env, PPC405EP_CPC0_EPCTL, cpc,
2440                     &dcr_read_epcpc, &dcr_write_epcpc);
2441    ppc_dcr_register(env, PPC405EP_CPC0_PLLMR0, cpc,
2442                     &dcr_read_epcpc, &dcr_write_epcpc);
2443    ppc_dcr_register(env, PPC405EP_CPC0_PLLMR1, cpc,
2444                     &dcr_read_epcpc, &dcr_write_epcpc);
2445    ppc_dcr_register(env, PPC405EP_CPC0_UCR, cpc,
2446                     &dcr_read_epcpc, &dcr_write_epcpc);
2447    ppc_dcr_register(env, PPC405EP_CPC0_SRR, cpc,
2448                     &dcr_read_epcpc, &dcr_write_epcpc);
2449    ppc_dcr_register(env, PPC405EP_CPC0_JTAGID, cpc,
2450                     &dcr_read_epcpc, &dcr_write_epcpc);
2451    ppc_dcr_register(env, PPC405EP_CPC0_PCI, cpc,
2452                     &dcr_read_epcpc, &dcr_write_epcpc);
2453#if 0
2454    ppc_dcr_register(env, PPC405EP_CPC0_ER, cpc,
2455                     &dcr_read_epcpc, &dcr_write_epcpc);
2456    ppc_dcr_register(env, PPC405EP_CPC0_FR, cpc,
2457                     &dcr_read_epcpc, &dcr_write_epcpc);
2458    ppc_dcr_register(env, PPC405EP_CPC0_SR, cpc,
2459                     &dcr_read_epcpc, &dcr_write_epcpc);
2460#endif
2461}
2462
2463CPUPPCState *ppc405ep_init(MemoryRegion *address_space_mem,
2464                        MemoryRegion ram_memories[2],
2465                        hwaddr ram_bases[2],
2466                        hwaddr ram_sizes[2],
2467                        uint32_t sysclk, qemu_irq **picp,
2468                        int do_init)
2469{
2470    clk_setup_t clk_setup[PPC405EP_CLK_NB], tlb_clk_setup;
2471    qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4];
2472    PowerPCCPU *cpu;
2473    CPUPPCState *env;
2474    qemu_irq *pic, *irqs;
2475
2476    memset(clk_setup, 0, sizeof(clk_setup));
2477    /* init CPUs */
2478    cpu = ppc4xx_init("405ep", &clk_setup[PPC405EP_CPU_CLK],
2479                      &tlb_clk_setup, sysclk);
2480    env = &cpu->env;
2481    clk_setup[PPC405EP_CPU_CLK].cb = tlb_clk_setup.cb;
2482    clk_setup[PPC405EP_CPU_CLK].opaque = tlb_clk_setup.opaque;
2483    /* Internal devices init */
2484    /* Memory mapped devices registers */
2485    /* PLB arbitrer */
2486    ppc4xx_plb_init(env);
2487    /* PLB to OPB bridge */
2488    ppc4xx_pob_init(env);
2489    /* OBP arbitrer */
2490    ppc4xx_opba_init(0xef600600);
2491    /* Initialize timers */
2492    ppc_booke_timers_init(cpu, sysclk, 0);
2493    /* Universal interrupt controller */
2494    irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
2495    irqs[PPCUIC_OUTPUT_INT] =
2496        ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
2497    irqs[PPCUIC_OUTPUT_CINT] =
2498        ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
2499    pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
2500    *picp = pic;
2501    /* SDRAM controller */
2502        /* XXX 405EP has no ECC interrupt */
2503    ppc4xx_sdram_init(env, pic[17], 2, ram_memories,
2504                      ram_bases, ram_sizes, do_init);
2505    /* External bus controller */
2506    ppc405_ebc_init(env);
2507    /* DMA controller */
2508    dma_irqs[0] = pic[5];
2509    dma_irqs[1] = pic[6];
2510    dma_irqs[2] = pic[7];
2511    dma_irqs[3] = pic[8];
2512    ppc405_dma_init(env, dma_irqs);
2513    /* IIC controller */
2514    ppc405_i2c_init(0xef600500, pic[2]);
2515    /* GPIO */
2516    ppc405_gpio_init(0xef600700);
2517    /* Serial ports */
2518    if (serial_hds[0] != NULL) {
2519        serial_mm_init(address_space_mem, 0xef600300, 0, pic[0],
2520                       PPC_SERIAL_MM_BAUDBASE, serial_hds[0],
2521                       DEVICE_BIG_ENDIAN);
2522    }
2523    if (serial_hds[1] != NULL) {
2524        serial_mm_init(address_space_mem, 0xef600400, 0, pic[1],
2525                       PPC_SERIAL_MM_BAUDBASE, serial_hds[1],
2526                       DEVICE_BIG_ENDIAN);
2527    }
2528    /* OCM */
2529    ppc405_ocm_init(env);
2530    /* GPT */
2531    gpt_irqs[0] = pic[19];
2532    gpt_irqs[1] = pic[20];
2533    gpt_irqs[2] = pic[21];
2534    gpt_irqs[3] = pic[22];
2535    gpt_irqs[4] = pic[23];
2536    ppc4xx_gpt_init(0xef600000, gpt_irqs);
2537    /* PCI */
2538    /* Uses pic[3], pic[16], pic[18] */
2539    /* MAL */
2540    mal_irqs[0] = pic[11];
2541    mal_irqs[1] = pic[12];
2542    mal_irqs[2] = pic[13];
2543    mal_irqs[3] = pic[14];
2544    ppc405_mal_init(env, mal_irqs);
2545    /* Ethernet */
2546    /* Uses pic[9], pic[15], pic[17] */
2547    /* CPU control */
2548    ppc405ep_cpc_init(env, clk_setup, sysclk);
2549
2550    return env;
2551}
2552