qemu/hw/ppc/ppc440_uc.c
<<
>>
Prefs
   1/*
   2 * QEMU PowerPC 440 embedded processors emulation
   3 *
   4 * Copyright (c) 2012 François Revol
   5 * Copyright (c) 2016-2019 BALATON Zoltan
   6 *
   7 * This work is licensed under the GNU GPL license version 2 or later.
   8 *
   9 */
  10
  11#include "qemu/osdep.h"
  12#include "qemu/units.h"
  13#include "qemu/error-report.h"
  14#include "qapi/error.h"
  15#include "qemu/log.h"
  16#include "qemu/main-loop.h"
  17#include "qemu/module.h"
  18#include "cpu.h"
  19#include "hw/irq.h"
  20#include "exec/address-spaces.h"
  21#include "exec/memory.h"
  22#include "hw/ppc/ppc.h"
  23#include "hw/qdev-properties.h"
  24#include "hw/pci/pci.h"
  25#include "sysemu/block-backend.h"
  26#include "sysemu/reset.h"
  27#include "ppc440.h"
  28
  29/*****************************************************************************/
  30/* L2 Cache as SRAM */
  31/* FIXME:fix names */
  32enum {
  33    DCR_L2CACHE_BASE  = 0x30,
  34    DCR_L2CACHE_CFG   = DCR_L2CACHE_BASE,
  35    DCR_L2CACHE_CMD,
  36    DCR_L2CACHE_ADDR,
  37    DCR_L2CACHE_DATA,
  38    DCR_L2CACHE_STAT,
  39    DCR_L2CACHE_CVER,
  40    DCR_L2CACHE_SNP0,
  41    DCR_L2CACHE_SNP1,
  42    DCR_L2CACHE_END   = DCR_L2CACHE_SNP1,
  43};
  44
  45/* base is 460ex-specific, cf. U-Boot, ppc4xx-isram.h */
  46enum {
  47    DCR_ISRAM0_BASE   = 0x20,
  48    DCR_ISRAM0_SB0CR  = DCR_ISRAM0_BASE,
  49    DCR_ISRAM0_SB1CR,
  50    DCR_ISRAM0_SB2CR,
  51    DCR_ISRAM0_SB3CR,
  52    DCR_ISRAM0_BEAR,
  53    DCR_ISRAM0_BESR0,
  54    DCR_ISRAM0_BESR1,
  55    DCR_ISRAM0_PMEG,
  56    DCR_ISRAM0_CID,
  57    DCR_ISRAM0_REVID,
  58    DCR_ISRAM0_DPC,
  59    DCR_ISRAM0_END    = DCR_ISRAM0_DPC
  60};
  61
  62enum {
  63    DCR_ISRAM1_BASE   = 0xb0,
  64    DCR_ISRAM1_SB0CR  = DCR_ISRAM1_BASE,
  65    /* single bank */
  66    DCR_ISRAM1_BEAR   = DCR_ISRAM1_BASE + 0x04,
  67    DCR_ISRAM1_BESR0,
  68    DCR_ISRAM1_BESR1,
  69    DCR_ISRAM1_PMEG,
  70    DCR_ISRAM1_CID,
  71    DCR_ISRAM1_REVID,
  72    DCR_ISRAM1_DPC,
  73    DCR_ISRAM1_END    = DCR_ISRAM1_DPC
  74};
  75
  76typedef struct ppc4xx_l2sram_t {
  77    MemoryRegion bank[4];
  78    uint32_t l2cache[8];
  79    uint32_t isram0[11];
  80} ppc4xx_l2sram_t;
  81
  82#ifdef MAP_L2SRAM
  83static void l2sram_update_mappings(ppc4xx_l2sram_t *l2sram,
  84                                   uint32_t isarc, uint32_t isacntl,
  85                                   uint32_t dsarc, uint32_t dsacntl)
  86{
  87    if (l2sram->isarc != isarc ||
  88        (l2sram->isacntl & 0x80000000) != (isacntl & 0x80000000)) {
  89        if (l2sram->isacntl & 0x80000000) {
  90            /* Unmap previously assigned memory region */
  91            memory_region_del_subregion(get_system_memory(),
  92                                        &l2sram->isarc_ram);
  93        }
  94        if (isacntl & 0x80000000) {
  95            /* Map new instruction memory region */
  96            memory_region_add_subregion(get_system_memory(), isarc,
  97                                        &l2sram->isarc_ram);
  98        }
  99    }
 100    if (l2sram->dsarc != dsarc ||
 101        (l2sram->dsacntl & 0x80000000) != (dsacntl & 0x80000000)) {
 102        if (l2sram->dsacntl & 0x80000000) {
 103            /* Beware not to unmap the region we just mapped */
 104            if (!(isacntl & 0x80000000) || l2sram->dsarc != isarc) {
 105                /* Unmap previously assigned memory region */
 106                memory_region_del_subregion(get_system_memory(),
 107                                            &l2sram->dsarc_ram);
 108            }
 109        }
 110        if (dsacntl & 0x80000000) {
 111            /* Beware not to remap the region we just mapped */
 112            if (!(isacntl & 0x80000000) || dsarc != isarc) {
 113                /* Map new data memory region */
 114                memory_region_add_subregion(get_system_memory(), dsarc,
 115                                            &l2sram->dsarc_ram);
 116            }
 117        }
 118    }
 119}
 120#endif
 121
 122static uint32_t dcr_read_l2sram(void *opaque, int dcrn)
 123{
 124    ppc4xx_l2sram_t *l2sram = opaque;
 125    uint32_t ret = 0;
 126
 127    switch (dcrn) {
 128    case DCR_L2CACHE_CFG:
 129    case DCR_L2CACHE_CMD:
 130    case DCR_L2CACHE_ADDR:
 131    case DCR_L2CACHE_DATA:
 132    case DCR_L2CACHE_STAT:
 133    case DCR_L2CACHE_CVER:
 134    case DCR_L2CACHE_SNP0:
 135    case DCR_L2CACHE_SNP1:
 136        ret = l2sram->l2cache[dcrn - DCR_L2CACHE_BASE];
 137        break;
 138
 139    case DCR_ISRAM0_SB0CR:
 140    case DCR_ISRAM0_SB1CR:
 141    case DCR_ISRAM0_SB2CR:
 142    case DCR_ISRAM0_SB3CR:
 143    case DCR_ISRAM0_BEAR:
 144    case DCR_ISRAM0_BESR0:
 145    case DCR_ISRAM0_BESR1:
 146    case DCR_ISRAM0_PMEG:
 147    case DCR_ISRAM0_CID:
 148    case DCR_ISRAM0_REVID:
 149    case DCR_ISRAM0_DPC:
 150        ret = l2sram->isram0[dcrn - DCR_ISRAM0_BASE];
 151        break;
 152
 153    default:
 154        break;
 155    }
 156
 157    return ret;
 158}
 159
 160static void dcr_write_l2sram(void *opaque, int dcrn, uint32_t val)
 161{
 162    /*ppc4xx_l2sram_t *l2sram = opaque;*/
 163    /* FIXME: Actually handle L2 cache mapping */
 164
 165    switch (dcrn) {
 166    case DCR_L2CACHE_CFG:
 167    case DCR_L2CACHE_CMD:
 168    case DCR_L2CACHE_ADDR:
 169    case DCR_L2CACHE_DATA:
 170    case DCR_L2CACHE_STAT:
 171    case DCR_L2CACHE_CVER:
 172    case DCR_L2CACHE_SNP0:
 173    case DCR_L2CACHE_SNP1:
 174        /*l2sram->l2cache[dcrn - DCR_L2CACHE_BASE] = val;*/
 175        break;
 176
 177    case DCR_ISRAM0_SB0CR:
 178    case DCR_ISRAM0_SB1CR:
 179    case DCR_ISRAM0_SB2CR:
 180    case DCR_ISRAM0_SB3CR:
 181    case DCR_ISRAM0_BEAR:
 182    case DCR_ISRAM0_BESR0:
 183    case DCR_ISRAM0_BESR1:
 184    case DCR_ISRAM0_PMEG:
 185    case DCR_ISRAM0_CID:
 186    case DCR_ISRAM0_REVID:
 187    case DCR_ISRAM0_DPC:
 188        /*l2sram->isram0[dcrn - DCR_L2CACHE_BASE] = val;*/
 189        break;
 190
 191    case DCR_ISRAM1_SB0CR:
 192    case DCR_ISRAM1_BEAR:
 193    case DCR_ISRAM1_BESR0:
 194    case DCR_ISRAM1_BESR1:
 195    case DCR_ISRAM1_PMEG:
 196    case DCR_ISRAM1_CID:
 197    case DCR_ISRAM1_REVID:
 198    case DCR_ISRAM1_DPC:
 199        /*l2sram->isram1[dcrn - DCR_L2CACHE_BASE] = val;*/
 200        break;
 201    }
 202    /*l2sram_update_mappings(l2sram, isarc, isacntl, dsarc, dsacntl);*/
 203}
 204
 205static void l2sram_reset(void *opaque)
 206{
 207    ppc4xx_l2sram_t *l2sram = opaque;
 208
 209    memset(l2sram->l2cache, 0, sizeof(l2sram->l2cache));
 210    l2sram->l2cache[DCR_L2CACHE_STAT - DCR_L2CACHE_BASE] = 0x80000000;
 211    memset(l2sram->isram0, 0, sizeof(l2sram->isram0));
 212    /*l2sram_update_mappings(l2sram, isarc, isacntl, dsarc, dsacntl);*/
 213}
 214
 215void ppc4xx_l2sram_init(CPUPPCState *env)
 216{
 217    ppc4xx_l2sram_t *l2sram;
 218
 219    l2sram = g_malloc0(sizeof(*l2sram));
 220    /* XXX: Size is 4*64kB for 460ex, cf. U-Boot, ppc4xx-isram.h */
 221    memory_region_init_ram(&l2sram->bank[0], NULL, "ppc4xx.l2sram_bank0",
 222                           64 * KiB, &error_abort);
 223    memory_region_init_ram(&l2sram->bank[1], NULL, "ppc4xx.l2sram_bank1",
 224                           64 * KiB, &error_abort);
 225    memory_region_init_ram(&l2sram->bank[2], NULL, "ppc4xx.l2sram_bank2",
 226                           64 * KiB, &error_abort);
 227    memory_region_init_ram(&l2sram->bank[3], NULL, "ppc4xx.l2sram_bank3",
 228                           64 * KiB, &error_abort);
 229    qemu_register_reset(&l2sram_reset, l2sram);
 230    ppc_dcr_register(env, DCR_L2CACHE_CFG,
 231                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 232    ppc_dcr_register(env, DCR_L2CACHE_CMD,
 233                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 234    ppc_dcr_register(env, DCR_L2CACHE_ADDR,
 235                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 236    ppc_dcr_register(env, DCR_L2CACHE_DATA,
 237                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 238    ppc_dcr_register(env, DCR_L2CACHE_STAT,
 239                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 240    ppc_dcr_register(env, DCR_L2CACHE_CVER,
 241                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 242    ppc_dcr_register(env, DCR_L2CACHE_SNP0,
 243                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 244    ppc_dcr_register(env, DCR_L2CACHE_SNP1,
 245                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 246
 247    ppc_dcr_register(env, DCR_ISRAM0_SB0CR,
 248                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 249    ppc_dcr_register(env, DCR_ISRAM0_SB1CR,
 250                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 251    ppc_dcr_register(env, DCR_ISRAM0_SB2CR,
 252                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 253    ppc_dcr_register(env, DCR_ISRAM0_SB3CR,
 254                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 255    ppc_dcr_register(env, DCR_ISRAM0_PMEG,
 256                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 257    ppc_dcr_register(env, DCR_ISRAM0_DPC,
 258                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 259
 260    ppc_dcr_register(env, DCR_ISRAM1_SB0CR,
 261                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 262    ppc_dcr_register(env, DCR_ISRAM1_PMEG,
 263                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 264    ppc_dcr_register(env, DCR_ISRAM1_DPC,
 265                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 266}
 267
 268/*****************************************************************************/
 269/* Clocking Power on Reset */
 270enum {
 271    CPR0_CFGADDR = 0xC,
 272    CPR0_CFGDATA = 0xD,
 273
 274    CPR0_PLLD = 0x060,
 275    CPR0_PLBED = 0x080,
 276    CPR0_OPBD = 0x0C0,
 277    CPR0_PERD = 0x0E0,
 278    CPR0_AHBD = 0x100,
 279};
 280
 281typedef struct ppc4xx_cpr_t {
 282    uint32_t addr;
 283} ppc4xx_cpr_t;
 284
 285static uint32_t dcr_read_cpr(void *opaque, int dcrn)
 286{
 287    ppc4xx_cpr_t *cpr = opaque;
 288    uint32_t ret = 0;
 289
 290    switch (dcrn) {
 291    case CPR0_CFGADDR:
 292        ret = cpr->addr;
 293        break;
 294    case CPR0_CFGDATA:
 295        switch (cpr->addr) {
 296        case CPR0_PLLD:
 297            ret = (0xb5 << 24) | (1 << 16) | (9 << 8);
 298            break;
 299        case CPR0_PLBED:
 300            ret = (5 << 24);
 301            break;
 302        case CPR0_OPBD:
 303            ret = (2 << 24);
 304            break;
 305        case CPR0_PERD:
 306        case CPR0_AHBD:
 307            ret = (1 << 24);
 308            break;
 309        default:
 310            break;
 311        }
 312        break;
 313    default:
 314        break;
 315    }
 316
 317    return ret;
 318}
 319
 320static void dcr_write_cpr(void *opaque, int dcrn, uint32_t val)
 321{
 322    ppc4xx_cpr_t *cpr = opaque;
 323
 324    switch (dcrn) {
 325    case CPR0_CFGADDR:
 326        cpr->addr = val;
 327        break;
 328    case CPR0_CFGDATA:
 329        break;
 330    default:
 331        break;
 332    }
 333}
 334
 335static void ppc4xx_cpr_reset(void *opaque)
 336{
 337    ppc4xx_cpr_t *cpr = opaque;
 338
 339    cpr->addr = 0;
 340}
 341
 342void ppc4xx_cpr_init(CPUPPCState *env)
 343{
 344    ppc4xx_cpr_t *cpr;
 345
 346    cpr = g_malloc0(sizeof(*cpr));
 347    ppc_dcr_register(env, CPR0_CFGADDR, cpr, &dcr_read_cpr, &dcr_write_cpr);
 348    ppc_dcr_register(env, CPR0_CFGDATA, cpr, &dcr_read_cpr, &dcr_write_cpr);
 349    qemu_register_reset(ppc4xx_cpr_reset, cpr);
 350}
 351
 352/*****************************************************************************/
 353/* System DCRs */
 354typedef struct ppc4xx_sdr_t ppc4xx_sdr_t;
 355struct ppc4xx_sdr_t {
 356    uint32_t addr;
 357};
 358
 359enum {
 360    SDR0_CFGADDR = 0x00e,
 361    SDR0_CFGDATA,
 362    SDR0_STRP0 = 0x020,
 363    SDR0_STRP1,
 364    SDR0_102 = 0x66,
 365    SDR0_103,
 366    SDR0_128 = 0x80,
 367    SDR0_ECID3 = 0x083,
 368    SDR0_DDR0 = 0x0e1,
 369    SDR0_USB0 = 0x320,
 370};
 371
 372enum {
 373    PESDR0_LOOP = 0x303,
 374    PESDR0_RCSSET,
 375    PESDR0_RCSSTS,
 376    PESDR0_RSTSTA = 0x310,
 377    PESDR1_LOOP = 0x343,
 378    PESDR1_RCSSET,
 379    PESDR1_RCSSTS,
 380    PESDR1_RSTSTA = 0x365,
 381};
 382
 383#define SDR0_DDR0_DDRM_ENCODE(n)  ((((unsigned long)(n)) & 0x03) << 29)
 384#define SDR0_DDR0_DDRM_DDR1       0x20000000
 385#define SDR0_DDR0_DDRM_DDR2       0x40000000
 386
 387static uint32_t dcr_read_sdr(void *opaque, int dcrn)
 388{
 389    ppc4xx_sdr_t *sdr = opaque;
 390    uint32_t ret = 0;
 391
 392    switch (dcrn) {
 393    case SDR0_CFGADDR:
 394        ret = sdr->addr;
 395        break;
 396    case SDR0_CFGDATA:
 397        switch (sdr->addr) {
 398        case SDR0_STRP0:
 399            ret = (0xb5 << 8) | (1 << 4) | 9;
 400            break;
 401        case SDR0_STRP1:
 402            ret = (5 << 29) | (2 << 26) | (1 << 24);
 403            break;
 404        case SDR0_ECID3:
 405            ret = 1 << 20; /* No Security/Kasumi support */
 406            break;
 407        case SDR0_DDR0:
 408            ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
 409            break;
 410        case PESDR0_RCSSET:
 411        case PESDR1_RCSSET:
 412            ret = (1 << 24) | (1 << 16);
 413            break;
 414        case PESDR0_RCSSTS:
 415        case PESDR1_RCSSTS:
 416            ret = (1 << 16) | (1 << 12);
 417            break;
 418        case PESDR0_RSTSTA:
 419        case PESDR1_RSTSTA:
 420            ret = 1;
 421            break;
 422        case PESDR0_LOOP:
 423        case PESDR1_LOOP:
 424            ret = 1 << 12;
 425            break;
 426        default:
 427            break;
 428        }
 429        break;
 430    default:
 431        break;
 432    }
 433
 434    return ret;
 435}
 436
 437static void dcr_write_sdr(void *opaque, int dcrn, uint32_t val)
 438{
 439    ppc4xx_sdr_t *sdr = opaque;
 440
 441    switch (dcrn) {
 442    case SDR0_CFGADDR:
 443        sdr->addr = val;
 444        break;
 445    case SDR0_CFGDATA:
 446        switch (sdr->addr) {
 447        case 0x00: /* B0CR */
 448            break;
 449        default:
 450            break;
 451        }
 452        break;
 453    default:
 454        break;
 455    }
 456}
 457
 458static void sdr_reset(void *opaque)
 459{
 460    ppc4xx_sdr_t *sdr = opaque;
 461
 462    sdr->addr = 0;
 463}
 464
 465void ppc4xx_sdr_init(CPUPPCState *env)
 466{
 467    ppc4xx_sdr_t *sdr;
 468
 469    sdr = g_malloc0(sizeof(*sdr));
 470    qemu_register_reset(&sdr_reset, sdr);
 471    ppc_dcr_register(env, SDR0_CFGADDR,
 472                     sdr, &dcr_read_sdr, &dcr_write_sdr);
 473    ppc_dcr_register(env, SDR0_CFGDATA,
 474                     sdr, &dcr_read_sdr, &dcr_write_sdr);
 475    ppc_dcr_register(env, SDR0_102,
 476                     sdr, &dcr_read_sdr, &dcr_write_sdr);
 477    ppc_dcr_register(env, SDR0_103,
 478                     sdr, &dcr_read_sdr, &dcr_write_sdr);
 479    ppc_dcr_register(env, SDR0_128,
 480                     sdr, &dcr_read_sdr, &dcr_write_sdr);
 481    ppc_dcr_register(env, SDR0_USB0,
 482                     sdr, &dcr_read_sdr, &dcr_write_sdr);
 483}
 484
 485/*****************************************************************************/
 486/* SDRAM controller */
 487typedef struct ppc440_sdram_t {
 488    uint32_t addr;
 489    int nbanks;
 490    MemoryRegion containers[4]; /* used for clipping */
 491    MemoryRegion *ram_memories;
 492    hwaddr ram_bases[4];
 493    hwaddr ram_sizes[4];
 494    uint32_t bcr[4];
 495} ppc440_sdram_t;
 496
 497enum {
 498    SDRAM0_CFGADDR = 0x10,
 499    SDRAM0_CFGDATA,
 500    SDRAM_R0BAS = 0x40,
 501    SDRAM_R1BAS,
 502    SDRAM_R2BAS,
 503    SDRAM_R3BAS,
 504    SDRAM_CONF1HB = 0x45,
 505    SDRAM_PLBADDULL = 0x4a,
 506    SDRAM_CONF1LL = 0x4b,
 507    SDRAM_CONFPATHB = 0x4f,
 508    SDRAM_PLBADDUHB = 0x50,
 509};
 510
 511static uint32_t sdram_bcr(hwaddr ram_base, hwaddr ram_size)
 512{
 513    uint32_t bcr;
 514
 515    switch (ram_size) {
 516    case (8 * MiB):
 517        bcr = 0xffc0;
 518        break;
 519    case (16 * MiB):
 520        bcr = 0xff80;
 521        break;
 522    case (32 * MiB):
 523        bcr = 0xff00;
 524        break;
 525    case (64 * MiB):
 526        bcr = 0xfe00;
 527        break;
 528    case (128 * MiB):
 529        bcr = 0xfc00;
 530        break;
 531    case (256 * MiB):
 532        bcr = 0xf800;
 533        break;
 534    case (512 * MiB):
 535        bcr = 0xf000;
 536        break;
 537    case (1 * GiB):
 538        bcr = 0xe000;
 539        break;
 540    case (2 * GiB):
 541        bcr = 0xc000;
 542        break;
 543    case (4 * GiB):
 544        bcr = 0x8000;
 545        break;
 546    default:
 547        error_report("invalid RAM size " TARGET_FMT_plx, ram_size);
 548        return 0;
 549    }
 550    bcr |= ram_base >> 2 & 0xffe00000;
 551    bcr |= 1;
 552
 553    return bcr;
 554}
 555
 556static inline hwaddr sdram_base(uint32_t bcr)
 557{
 558    return (bcr & 0xffe00000) << 2;
 559}
 560
 561static uint64_t sdram_size(uint32_t bcr)
 562{
 563    uint64_t size;
 564    int sh;
 565
 566    sh = 1024 - ((bcr >> 6) & 0x3ff);
 567    size = 8 * MiB * sh;
 568
 569    return size;
 570}
 571
 572static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
 573                          uint32_t bcr, int enabled)
 574{
 575    if (sdram->bcr[i] & 1) {
 576        /* First unmap RAM if enabled */
 577        memory_region_del_subregion(get_system_memory(),
 578                                    &sdram->containers[i]);
 579        memory_region_del_subregion(&sdram->containers[i],
 580                                    &sdram->ram_memories[i]);
 581        object_unparent(OBJECT(&sdram->containers[i]));
 582    }
 583    sdram->bcr[i] = bcr & 0xffe0ffc1;
 584    if (enabled && (bcr & 1)) {
 585        memory_region_init(&sdram->containers[i], NULL, "sdram-containers",
 586                           sdram_size(bcr));
 587        memory_region_add_subregion(&sdram->containers[i], 0,
 588                                    &sdram->ram_memories[i]);
 589        memory_region_add_subregion(get_system_memory(),
 590                                    sdram_base(bcr),
 591                                    &sdram->containers[i]);
 592    }
 593}
 594
 595static void sdram_map_bcr(ppc440_sdram_t *sdram)
 596{
 597    int i;
 598
 599    for (i = 0; i < sdram->nbanks; i++) {
 600        if (sdram->ram_sizes[i] != 0) {
 601            sdram_set_bcr(sdram, i, sdram_bcr(sdram->ram_bases[i],
 602                                              sdram->ram_sizes[i]), 1);
 603        } else {
 604            sdram_set_bcr(sdram, i, 0, 0);
 605        }
 606    }
 607}
 608
 609static uint32_t dcr_read_sdram(void *opaque, int dcrn)
 610{
 611    ppc440_sdram_t *sdram = opaque;
 612    uint32_t ret = 0;
 613
 614    switch (dcrn) {
 615    case SDRAM_R0BAS:
 616    case SDRAM_R1BAS:
 617    case SDRAM_R2BAS:
 618    case SDRAM_R3BAS:
 619        if (sdram->ram_sizes[dcrn - SDRAM_R0BAS]) {
 620            ret = sdram_bcr(sdram->ram_bases[dcrn - SDRAM_R0BAS],
 621                            sdram->ram_sizes[dcrn - SDRAM_R0BAS]);
 622        }
 623        break;
 624    case SDRAM_CONF1HB:
 625    case SDRAM_CONF1LL:
 626    case SDRAM_CONFPATHB:
 627    case SDRAM_PLBADDULL:
 628    case SDRAM_PLBADDUHB:
 629        break;
 630    case SDRAM0_CFGADDR:
 631        ret = sdram->addr;
 632        break;
 633    case SDRAM0_CFGDATA:
 634        switch (sdram->addr) {
 635        case 0x14: /* SDRAM_MCSTAT (405EX) */
 636        case 0x1F:
 637            ret = 0x80000000;
 638            break;
 639        case 0x21: /* SDRAM_MCOPT2 */
 640            ret = 0x08000000;
 641            break;
 642        case 0x40: /* SDRAM_MB0CF */
 643            ret = 0x00008001;
 644            break;
 645        case 0x7A: /* SDRAM_DLCR */
 646            ret = 0x02000000;
 647            break;
 648        case 0xE1: /* SDR0_DDR0 */
 649            ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
 650            break;
 651        default:
 652            break;
 653        }
 654        break;
 655    default:
 656        break;
 657    }
 658
 659    return ret;
 660}
 661
 662static void dcr_write_sdram(void *opaque, int dcrn, uint32_t val)
 663{
 664    ppc440_sdram_t *sdram = opaque;
 665
 666    switch (dcrn) {
 667    case SDRAM_R0BAS:
 668    case SDRAM_R1BAS:
 669    case SDRAM_R2BAS:
 670    case SDRAM_R3BAS:
 671    case SDRAM_CONF1HB:
 672    case SDRAM_CONF1LL:
 673    case SDRAM_CONFPATHB:
 674    case SDRAM_PLBADDULL:
 675    case SDRAM_PLBADDUHB:
 676        break;
 677    case SDRAM0_CFGADDR:
 678        sdram->addr = val;
 679        break;
 680    case SDRAM0_CFGDATA:
 681        switch (sdram->addr) {
 682        case 0x00: /* B0CR */
 683            break;
 684        default:
 685            break;
 686        }
 687        break;
 688    default:
 689        break;
 690    }
 691}
 692
 693static void sdram_reset(void *opaque)
 694{
 695    ppc440_sdram_t *sdram = opaque;
 696
 697    sdram->addr = 0;
 698}
 699
 700void ppc440_sdram_init(CPUPPCState *env, int nbanks,
 701                       MemoryRegion *ram_memories,
 702                       hwaddr *ram_bases, hwaddr *ram_sizes,
 703                       int do_init)
 704{
 705    ppc440_sdram_t *sdram;
 706
 707    sdram = g_malloc0(sizeof(*sdram));
 708    sdram->nbanks = nbanks;
 709    sdram->ram_memories = ram_memories;
 710    memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(hwaddr));
 711    memcpy(sdram->ram_sizes, ram_sizes, nbanks * sizeof(hwaddr));
 712    qemu_register_reset(&sdram_reset, sdram);
 713    ppc_dcr_register(env, SDRAM0_CFGADDR,
 714                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 715    ppc_dcr_register(env, SDRAM0_CFGDATA,
 716                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 717    if (do_init) {
 718        sdram_map_bcr(sdram);
 719    }
 720
 721    ppc_dcr_register(env, SDRAM_R0BAS,
 722                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 723    ppc_dcr_register(env, SDRAM_R1BAS,
 724                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 725    ppc_dcr_register(env, SDRAM_R2BAS,
 726                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 727    ppc_dcr_register(env, SDRAM_R3BAS,
 728                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 729    ppc_dcr_register(env, SDRAM_CONF1HB,
 730                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 731    ppc_dcr_register(env, SDRAM_PLBADDULL,
 732                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 733    ppc_dcr_register(env, SDRAM_CONF1LL,
 734                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 735    ppc_dcr_register(env, SDRAM_CONFPATHB,
 736                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 737    ppc_dcr_register(env, SDRAM_PLBADDUHB,
 738                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 739}
 740
 741/*****************************************************************************/
 742/* PLB to AHB bridge */
 743enum {
 744    AHB_TOP    = 0xA4,
 745    AHB_BOT    = 0xA5,
 746};
 747
 748typedef struct ppc4xx_ahb_t {
 749    uint32_t top;
 750    uint32_t bot;
 751} ppc4xx_ahb_t;
 752
 753static uint32_t dcr_read_ahb(void *opaque, int dcrn)
 754{
 755    ppc4xx_ahb_t *ahb = opaque;
 756    uint32_t ret = 0;
 757
 758    switch (dcrn) {
 759    case AHB_TOP:
 760        ret = ahb->top;
 761        break;
 762    case AHB_BOT:
 763        ret = ahb->bot;
 764        break;
 765    default:
 766        break;
 767    }
 768
 769    return ret;
 770}
 771
 772static void dcr_write_ahb(void *opaque, int dcrn, uint32_t val)
 773{
 774    ppc4xx_ahb_t *ahb = opaque;
 775
 776    switch (dcrn) {
 777    case AHB_TOP:
 778        ahb->top = val;
 779        break;
 780    case AHB_BOT:
 781        ahb->bot = val;
 782        break;
 783    }
 784}
 785
 786static void ppc4xx_ahb_reset(void *opaque)
 787{
 788    ppc4xx_ahb_t *ahb = opaque;
 789
 790    /* No error */
 791    ahb->top = 0;
 792    ahb->bot = 0;
 793}
 794
 795void ppc4xx_ahb_init(CPUPPCState *env)
 796{
 797    ppc4xx_ahb_t *ahb;
 798
 799    ahb = g_malloc0(sizeof(*ahb));
 800    ppc_dcr_register(env, AHB_TOP, ahb, &dcr_read_ahb, &dcr_write_ahb);
 801    ppc_dcr_register(env, AHB_BOT, ahb, &dcr_read_ahb, &dcr_write_ahb);
 802    qemu_register_reset(ppc4xx_ahb_reset, ahb);
 803}
 804
 805/*****************************************************************************/
 806/* DMA controller */
 807
 808#define DMA0_CR_CE  (1 << 31)
 809#define DMA0_CR_PW  (1 << 26 | 1 << 25)
 810#define DMA0_CR_DAI (1 << 24)
 811#define DMA0_CR_SAI (1 << 23)
 812#define DMA0_CR_DEC (1 << 2)
 813
 814enum {
 815    DMA0_CR  = 0x00,
 816    DMA0_CT,
 817    DMA0_SAH,
 818    DMA0_SAL,
 819    DMA0_DAH,
 820    DMA0_DAL,
 821    DMA0_SGH,
 822    DMA0_SGL,
 823
 824    DMA0_SR  = 0x20,
 825    DMA0_SGC = 0x23,
 826    DMA0_SLP = 0x25,
 827    DMA0_POL = 0x26,
 828};
 829
 830typedef struct {
 831    uint32_t cr;
 832    uint32_t ct;
 833    uint64_t sa;
 834    uint64_t da;
 835    uint64_t sg;
 836} PPC4xxDmaChnl;
 837
 838typedef struct {
 839    int base;
 840    PPC4xxDmaChnl ch[4];
 841    uint32_t sr;
 842} PPC4xxDmaState;
 843
 844static uint32_t dcr_read_dma(void *opaque, int dcrn)
 845{
 846    PPC4xxDmaState *dma = opaque;
 847    uint32_t val = 0;
 848    int addr = dcrn - dma->base;
 849    int chnl = addr / 8;
 850
 851    switch (addr) {
 852    case 0x00 ... 0x1f:
 853        switch (addr % 8) {
 854        case DMA0_CR:
 855            val = dma->ch[chnl].cr;
 856            break;
 857        case DMA0_CT:
 858            val = dma->ch[chnl].ct;
 859            break;
 860        case DMA0_SAH:
 861            val = dma->ch[chnl].sa >> 32;
 862            break;
 863        case DMA0_SAL:
 864            val = dma->ch[chnl].sa;
 865            break;
 866        case DMA0_DAH:
 867            val = dma->ch[chnl].da >> 32;
 868            break;
 869        case DMA0_DAL:
 870            val = dma->ch[chnl].da;
 871            break;
 872        case DMA0_SGH:
 873            val = dma->ch[chnl].sg >> 32;
 874            break;
 875        case DMA0_SGL:
 876            val = dma->ch[chnl].sg;
 877            break;
 878        }
 879        break;
 880    case DMA0_SR:
 881        val = dma->sr;
 882        break;
 883    default:
 884        qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
 885                      __func__, dcrn, chnl, addr);
 886    }
 887
 888    return val;
 889}
 890
 891static void dcr_write_dma(void *opaque, int dcrn, uint32_t val)
 892{
 893    PPC4xxDmaState *dma = opaque;
 894    int addr = dcrn - dma->base;
 895    int chnl = addr / 8;
 896
 897    switch (addr) {
 898    case 0x00 ... 0x1f:
 899        switch (addr % 8) {
 900        case DMA0_CR:
 901            dma->ch[chnl].cr = val;
 902            if (val & DMA0_CR_CE) {
 903                int count = dma->ch[chnl].ct & 0xffff;
 904
 905                if (count) {
 906                    int width, i, sidx, didx;
 907                    uint8_t *rptr, *wptr;
 908                    hwaddr rlen, wlen;
 909
 910                    sidx = didx = 0;
 911                    width = 1 << ((val & DMA0_CR_PW) >> 25);
 912                    rptr = cpu_physical_memory_map(dma->ch[chnl].sa, &rlen, 0);
 913                    wptr = cpu_physical_memory_map(dma->ch[chnl].da, &wlen, 1);
 914                    if (rptr && wptr) {
 915                        if (!(val & DMA0_CR_DEC) &&
 916                            val & DMA0_CR_SAI && val & DMA0_CR_DAI) {
 917                            /* optimise common case */
 918                            memmove(wptr, rptr, count * width);
 919                            sidx = didx = count * width;
 920                        } else {
 921                            /* do it the slow way */
 922                            for (sidx = didx = i = 0; i < count; i++) {
 923                                uint64_t v = ldn_le_p(rptr + sidx, width);
 924                                stn_le_p(wptr + didx, width, v);
 925                                if (val & DMA0_CR_SAI) {
 926                                    sidx += width;
 927                                }
 928                                if (val & DMA0_CR_DAI) {
 929                                    didx += width;
 930                                }
 931                            }
 932                        }
 933                    }
 934                    if (wptr) {
 935                        cpu_physical_memory_unmap(wptr, wlen, 1, didx);
 936                    }
 937                    if (rptr) {
 938                        cpu_physical_memory_unmap(rptr, rlen, 0, sidx);
 939                    }
 940                }
 941            }
 942            break;
 943        case DMA0_CT:
 944            dma->ch[chnl].ct = val;
 945            break;
 946        case DMA0_SAH:
 947            dma->ch[chnl].sa &= 0xffffffffULL;
 948            dma->ch[chnl].sa |= (uint64_t)val << 32;
 949            break;
 950        case DMA0_SAL:
 951            dma->ch[chnl].sa &= 0xffffffff00000000ULL;
 952            dma->ch[chnl].sa |= val;
 953            break;
 954        case DMA0_DAH:
 955            dma->ch[chnl].da &= 0xffffffffULL;
 956            dma->ch[chnl].da |= (uint64_t)val << 32;
 957            break;
 958        case DMA0_DAL:
 959            dma->ch[chnl].da &= 0xffffffff00000000ULL;
 960            dma->ch[chnl].da |= val;
 961            break;
 962        case DMA0_SGH:
 963            dma->ch[chnl].sg &= 0xffffffffULL;
 964            dma->ch[chnl].sg |= (uint64_t)val << 32;
 965            break;
 966        case DMA0_SGL:
 967            dma->ch[chnl].sg &= 0xffffffff00000000ULL;
 968            dma->ch[chnl].sg |= val;
 969            break;
 970        }
 971        break;
 972    case DMA0_SR:
 973        dma->sr &= ~val;
 974        break;
 975    default:
 976        qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
 977                      __func__, dcrn, chnl, addr);
 978    }
 979}
 980
 981static void ppc4xx_dma_reset(void *opaque)
 982{
 983    PPC4xxDmaState *dma = opaque;
 984    int dma_base = dma->base;
 985
 986    memset(dma, 0, sizeof(*dma));
 987    dma->base = dma_base;
 988}
 989
 990void ppc4xx_dma_init(CPUPPCState *env, int dcr_base)
 991{
 992    PPC4xxDmaState *dma;
 993    int i;
 994
 995    dma = g_malloc0(sizeof(*dma));
 996    dma->base = dcr_base;
 997    qemu_register_reset(&ppc4xx_dma_reset, dma);
 998    for (i = 0; i < 4; i++) {
 999        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CR,
1000                         dma, &dcr_read_dma, &dcr_write_dma);
1001        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CT,
1002                         dma, &dcr_read_dma, &dcr_write_dma);
1003        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAH,
1004                         dma, &dcr_read_dma, &dcr_write_dma);
1005        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAL,
1006                         dma, &dcr_read_dma, &dcr_write_dma);
1007        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAH,
1008                         dma, &dcr_read_dma, &dcr_write_dma);
1009        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAL,
1010                         dma, &dcr_read_dma, &dcr_write_dma);
1011        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGH,
1012                         dma, &dcr_read_dma, &dcr_write_dma);
1013        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGL,
1014                         dma, &dcr_read_dma, &dcr_write_dma);
1015    }
1016    ppc_dcr_register(env, dcr_base + DMA0_SR,
1017                     dma, &dcr_read_dma, &dcr_write_dma);
1018    ppc_dcr_register(env, dcr_base + DMA0_SGC,
1019                     dma, &dcr_read_dma, &dcr_write_dma);
1020    ppc_dcr_register(env, dcr_base + DMA0_SLP,
1021                     dma, &dcr_read_dma, &dcr_write_dma);
1022    ppc_dcr_register(env, dcr_base + DMA0_POL,
1023                     dma, &dcr_read_dma, &dcr_write_dma);
1024}
1025
1026/*****************************************************************************/
1027/* PCI Express controller */
1028/* FIXME: This is not complete and does not work, only implemented partially
1029 * to allow firmware and guests to find an empty bus. Cards should use PCI.
1030 */
1031#include "hw/pci/pcie_host.h"
1032
1033#define TYPE_PPC460EX_PCIE_HOST "ppc460ex-pcie-host"
1034#define PPC460EX_PCIE_HOST(obj) \
1035    OBJECT_CHECK(PPC460EXPCIEState, (obj), TYPE_PPC460EX_PCIE_HOST)
1036
1037typedef struct PPC460EXPCIEState {
1038    PCIExpressHost host;
1039
1040    MemoryRegion iomem;
1041    qemu_irq irq[4];
1042    int32_t dcrn_base;
1043
1044    uint64_t cfg_base;
1045    uint32_t cfg_mask;
1046    uint64_t msg_base;
1047    uint32_t msg_mask;
1048    uint64_t omr1_base;
1049    uint64_t omr1_mask;
1050    uint64_t omr2_base;
1051    uint64_t omr2_mask;
1052    uint64_t omr3_base;
1053    uint64_t omr3_mask;
1054    uint64_t reg_base;
1055    uint32_t reg_mask;
1056    uint32_t special;
1057    uint32_t cfg;
1058} PPC460EXPCIEState;
1059
1060#define DCRN_PCIE0_BASE 0x100
1061#define DCRN_PCIE1_BASE 0x120
1062
1063enum {
1064    PEGPL_CFGBAH = 0x0,
1065    PEGPL_CFGBAL,
1066    PEGPL_CFGMSK,
1067    PEGPL_MSGBAH,
1068    PEGPL_MSGBAL,
1069    PEGPL_MSGMSK,
1070    PEGPL_OMR1BAH,
1071    PEGPL_OMR1BAL,
1072    PEGPL_OMR1MSKH,
1073    PEGPL_OMR1MSKL,
1074    PEGPL_OMR2BAH,
1075    PEGPL_OMR2BAL,
1076    PEGPL_OMR2MSKH,
1077    PEGPL_OMR2MSKL,
1078    PEGPL_OMR3BAH,
1079    PEGPL_OMR3BAL,
1080    PEGPL_OMR3MSKH,
1081    PEGPL_OMR3MSKL,
1082    PEGPL_REGBAH,
1083    PEGPL_REGBAL,
1084    PEGPL_REGMSK,
1085    PEGPL_SPECIAL,
1086    PEGPL_CFG,
1087};
1088
1089static uint32_t dcr_read_pcie(void *opaque, int dcrn)
1090{
1091    PPC460EXPCIEState *state = opaque;
1092    uint32_t ret = 0;
1093
1094    switch (dcrn - state->dcrn_base) {
1095    case PEGPL_CFGBAH:
1096        ret = state->cfg_base >> 32;
1097        break;
1098    case PEGPL_CFGBAL:
1099        ret = state->cfg_base;
1100        break;
1101    case PEGPL_CFGMSK:
1102        ret = state->cfg_mask;
1103        break;
1104    case PEGPL_MSGBAH:
1105        ret = state->msg_base >> 32;
1106        break;
1107    case PEGPL_MSGBAL:
1108        ret = state->msg_base;
1109        break;
1110    case PEGPL_MSGMSK:
1111        ret = state->msg_mask;
1112        break;
1113    case PEGPL_OMR1BAH:
1114        ret = state->omr1_base >> 32;
1115        break;
1116    case PEGPL_OMR1BAL:
1117        ret = state->omr1_base;
1118        break;
1119    case PEGPL_OMR1MSKH:
1120        ret = state->omr1_mask >> 32;
1121        break;
1122    case PEGPL_OMR1MSKL:
1123        ret = state->omr1_mask;
1124        break;
1125    case PEGPL_OMR2BAH:
1126        ret = state->omr2_base >> 32;
1127        break;
1128    case PEGPL_OMR2BAL:
1129        ret = state->omr2_base;
1130        break;
1131    case PEGPL_OMR2MSKH:
1132        ret = state->omr2_mask >> 32;
1133        break;
1134    case PEGPL_OMR2MSKL:
1135        ret = state->omr3_mask;
1136        break;
1137    case PEGPL_OMR3BAH:
1138        ret = state->omr3_base >> 32;
1139        break;
1140    case PEGPL_OMR3BAL:
1141        ret = state->omr3_base;
1142        break;
1143    case PEGPL_OMR3MSKH:
1144        ret = state->omr3_mask >> 32;
1145        break;
1146    case PEGPL_OMR3MSKL:
1147        ret = state->omr3_mask;
1148        break;
1149    case PEGPL_REGBAH:
1150        ret = state->reg_base >> 32;
1151        break;
1152    case PEGPL_REGBAL:
1153        ret = state->reg_base;
1154        break;
1155    case PEGPL_REGMSK:
1156        ret = state->reg_mask;
1157        break;
1158    case PEGPL_SPECIAL:
1159        ret = state->special;
1160        break;
1161    case PEGPL_CFG:
1162        ret = state->cfg;
1163        break;
1164    }
1165
1166    return ret;
1167}
1168
1169static void dcr_write_pcie(void *opaque, int dcrn, uint32_t val)
1170{
1171    PPC460EXPCIEState *s = opaque;
1172    uint64_t size;
1173
1174    switch (dcrn - s->dcrn_base) {
1175    case PEGPL_CFGBAH:
1176        s->cfg_base = ((uint64_t)val << 32) | (s->cfg_base & 0xffffffff);
1177        break;
1178    case PEGPL_CFGBAL:
1179        s->cfg_base = (s->cfg_base & 0xffffffff00000000ULL) | val;
1180        break;
1181    case PEGPL_CFGMSK:
1182        s->cfg_mask = val;
1183        size = ~(val & 0xfffffffe) + 1;
1184        qemu_mutex_lock_iothread();
1185        pcie_host_mmcfg_update(PCIE_HOST_BRIDGE(s), val & 1, s->cfg_base, size);
1186        qemu_mutex_unlock_iothread();
1187        break;
1188    case PEGPL_MSGBAH:
1189        s->msg_base = ((uint64_t)val << 32) | (s->msg_base & 0xffffffff);
1190        break;
1191    case PEGPL_MSGBAL:
1192        s->msg_base = (s->msg_base & 0xffffffff00000000ULL) | val;
1193        break;
1194    case PEGPL_MSGMSK:
1195        s->msg_mask = val;
1196        break;
1197    case PEGPL_OMR1BAH:
1198        s->omr1_base = ((uint64_t)val << 32) | (s->omr1_base & 0xffffffff);
1199        break;
1200    case PEGPL_OMR1BAL:
1201        s->omr1_base = (s->omr1_base & 0xffffffff00000000ULL) | val;
1202        break;
1203    case PEGPL_OMR1MSKH:
1204        s->omr1_mask = ((uint64_t)val << 32) | (s->omr1_mask & 0xffffffff);
1205        break;
1206    case PEGPL_OMR1MSKL:
1207        s->omr1_mask = (s->omr1_mask & 0xffffffff00000000ULL) | val;
1208        break;
1209    case PEGPL_OMR2BAH:
1210        s->omr2_base = ((uint64_t)val << 32) | (s->omr2_base & 0xffffffff);
1211        break;
1212    case PEGPL_OMR2BAL:
1213        s->omr2_base = (s->omr2_base & 0xffffffff00000000ULL) | val;
1214        break;
1215    case PEGPL_OMR2MSKH:
1216        s->omr2_mask = ((uint64_t)val << 32) | (s->omr2_mask & 0xffffffff);
1217        break;
1218    case PEGPL_OMR2MSKL:
1219        s->omr2_mask = (s->omr2_mask & 0xffffffff00000000ULL) | val;
1220        break;
1221    case PEGPL_OMR3BAH:
1222        s->omr3_base = ((uint64_t)val << 32) | (s->omr3_base & 0xffffffff);
1223        break;
1224    case PEGPL_OMR3BAL:
1225        s->omr3_base = (s->omr3_base & 0xffffffff00000000ULL) | val;
1226        break;
1227    case PEGPL_OMR3MSKH:
1228        s->omr3_mask = ((uint64_t)val << 32) | (s->omr3_mask & 0xffffffff);
1229        break;
1230    case PEGPL_OMR3MSKL:
1231        s->omr3_mask = (s->omr3_mask & 0xffffffff00000000ULL) | val;
1232        break;
1233    case PEGPL_REGBAH:
1234        s->reg_base = ((uint64_t)val << 32) | (s->reg_base & 0xffffffff);
1235        break;
1236    case PEGPL_REGBAL:
1237        s->reg_base = (s->reg_base & 0xffffffff00000000ULL) | val;
1238        break;
1239    case PEGPL_REGMSK:
1240        s->reg_mask = val;
1241        /* FIXME: how is size encoded? */
1242        size = (val == 0x7001 ? 4096 : ~(val & 0xfffffffe) + 1);
1243        break;
1244    case PEGPL_SPECIAL:
1245        s->special = val;
1246        break;
1247    case PEGPL_CFG:
1248        s->cfg = val;
1249        break;
1250    }
1251}
1252
1253static void ppc460ex_set_irq(void *opaque, int irq_num, int level)
1254{
1255       PPC460EXPCIEState *s = opaque;
1256       qemu_set_irq(s->irq[irq_num], level);
1257}
1258
1259static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp)
1260{
1261    PPC460EXPCIEState *s = PPC460EX_PCIE_HOST(dev);
1262    PCIHostState *pci = PCI_HOST_BRIDGE(dev);
1263    int i, id;
1264    char buf[16];
1265
1266    switch (s->dcrn_base) {
1267    case DCRN_PCIE0_BASE:
1268        id = 0;
1269        break;
1270    case DCRN_PCIE1_BASE:
1271        id = 1;
1272        break;
1273    default:
1274        error_setg(errp, "invalid PCIe DCRN base");
1275        return;
1276    }
1277    snprintf(buf, sizeof(buf), "pcie%d-io", id);
1278    memory_region_init(&s->iomem, OBJECT(s), buf, UINT64_MAX);
1279    for (i = 0; i < 4; i++) {
1280        sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
1281    }
1282    snprintf(buf, sizeof(buf), "pcie.%d", id);
1283    pci->bus = pci_register_root_bus(DEVICE(s), buf, ppc460ex_set_irq,
1284                                pci_swizzle_map_irq_fn, s, &s->iomem,
1285                                get_system_io(), 0, 4, TYPE_PCIE_BUS);
1286}
1287
1288static Property ppc460ex_pcie_props[] = {
1289    DEFINE_PROP_INT32("dcrn-base", PPC460EXPCIEState, dcrn_base, -1),
1290    DEFINE_PROP_END_OF_LIST(),
1291};
1292
1293static void ppc460ex_pcie_class_init(ObjectClass *klass, void *data)
1294{
1295    DeviceClass *dc = DEVICE_CLASS(klass);
1296
1297    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
1298    dc->realize = ppc460ex_pcie_realize;
1299    dc->props = ppc460ex_pcie_props;
1300    dc->hotpluggable = false;
1301}
1302
1303static const TypeInfo ppc460ex_pcie_host_info = {
1304    .name = TYPE_PPC460EX_PCIE_HOST,
1305    .parent = TYPE_PCIE_HOST_BRIDGE,
1306    .instance_size = sizeof(PPC460EXPCIEState),
1307    .class_init = ppc460ex_pcie_class_init,
1308};
1309
1310static void ppc460ex_pcie_register(void)
1311{
1312    type_register_static(&ppc460ex_pcie_host_info);
1313}
1314
1315type_init(ppc460ex_pcie_register)
1316
1317static void ppc460ex_pcie_register_dcrs(PPC460EXPCIEState *s, CPUPPCState *env)
1318{
1319    ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAH, s,
1320                     &dcr_read_pcie, &dcr_write_pcie);
1321    ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAL, s,
1322                     &dcr_read_pcie, &dcr_write_pcie);
1323    ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGMSK, s,
1324                     &dcr_read_pcie, &dcr_write_pcie);
1325    ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAH, s,
1326                     &dcr_read_pcie, &dcr_write_pcie);
1327    ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAL, s,
1328                     &dcr_read_pcie, &dcr_write_pcie);
1329    ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGMSK, s,
1330                     &dcr_read_pcie, &dcr_write_pcie);
1331    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAH, s,
1332                     &dcr_read_pcie, &dcr_write_pcie);
1333    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAL, s,
1334                     &dcr_read_pcie, &dcr_write_pcie);
1335    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKH, s,
1336                     &dcr_read_pcie, &dcr_write_pcie);
1337    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKL, s,
1338                     &dcr_read_pcie, &dcr_write_pcie);
1339    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAH, s,
1340                     &dcr_read_pcie, &dcr_write_pcie);
1341    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAL, s,
1342                     &dcr_read_pcie, &dcr_write_pcie);
1343    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKH, s,
1344                     &dcr_read_pcie, &dcr_write_pcie);
1345    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKL, s,
1346                     &dcr_read_pcie, &dcr_write_pcie);
1347    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAH, s,
1348                     &dcr_read_pcie, &dcr_write_pcie);
1349    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAL, s,
1350                     &dcr_read_pcie, &dcr_write_pcie);
1351    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKH, s,
1352                     &dcr_read_pcie, &dcr_write_pcie);
1353    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKL, s,
1354                     &dcr_read_pcie, &dcr_write_pcie);
1355    ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAH, s,
1356                     &dcr_read_pcie, &dcr_write_pcie);
1357    ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAL, s,
1358                     &dcr_read_pcie, &dcr_write_pcie);
1359    ppc_dcr_register(env, s->dcrn_base + PEGPL_REGMSK, s,
1360                     &dcr_read_pcie, &dcr_write_pcie);
1361    ppc_dcr_register(env, s->dcrn_base + PEGPL_SPECIAL, s,
1362                     &dcr_read_pcie, &dcr_write_pcie);
1363    ppc_dcr_register(env, s->dcrn_base + PEGPL_CFG, s,
1364                     &dcr_read_pcie, &dcr_write_pcie);
1365}
1366
1367void ppc460ex_pcie_init(CPUPPCState *env)
1368{
1369    DeviceState *dev;
1370
1371    dev = qdev_create(NULL, TYPE_PPC460EX_PCIE_HOST);
1372    qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE0_BASE);
1373    qdev_init_nofail(dev);
1374    object_property_set_bool(OBJECT(dev), true, "realized", NULL);
1375    ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env);
1376
1377    dev = qdev_create(NULL, TYPE_PPC460EX_PCIE_HOST);
1378    qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE1_BASE);
1379    qdev_init_nofail(dev);
1380    object_property_set_bool(OBJECT(dev), true, "realized", NULL);
1381    ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env);
1382}
1383