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/module.h"
  17#include "cpu.h"
  18#include "hw/irq.h"
  19#include "exec/address-spaces.h"
  20#include "exec/memory.h"
  21#include "hw/ppc/ppc.h"
  22#include "hw/qdev-properties.h"
  23#include "hw/pci/pci.h"
  24#include "sysemu/block-backend.h"
  25#include "sysemu/reset.h"
  26#include "ppc440.h"
  27#include "qom/object.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,
 913                                                   false);
 914                    wptr = cpu_physical_memory_map(dma->ch[chnl].da, &wlen,
 915                                                   true);
 916                    if (rptr && wptr) {
 917                        if (!(val & DMA0_CR_DEC) &&
 918                            val & DMA0_CR_SAI && val & DMA0_CR_DAI) {
 919                            /* optimise common case */
 920                            memmove(wptr, rptr, count * width);
 921                            sidx = didx = count * width;
 922                        } else {
 923                            /* do it the slow way */
 924                            for (sidx = didx = i = 0; i < count; i++) {
 925                                uint64_t v = ldn_le_p(rptr + sidx, width);
 926                                stn_le_p(wptr + didx, width, v);
 927                                if (val & DMA0_CR_SAI) {
 928                                    sidx += width;
 929                                }
 930                                if (val & DMA0_CR_DAI) {
 931                                    didx += width;
 932                                }
 933                            }
 934                        }
 935                    }
 936                    if (wptr) {
 937                        cpu_physical_memory_unmap(wptr, wlen, 1, didx);
 938                    }
 939                    if (rptr) {
 940                        cpu_physical_memory_unmap(rptr, rlen, 0, sidx);
 941                    }
 942                }
 943            }
 944            break;
 945        case DMA0_CT:
 946            dma->ch[chnl].ct = val;
 947            break;
 948        case DMA0_SAH:
 949            dma->ch[chnl].sa &= 0xffffffffULL;
 950            dma->ch[chnl].sa |= (uint64_t)val << 32;
 951            break;
 952        case DMA0_SAL:
 953            dma->ch[chnl].sa &= 0xffffffff00000000ULL;
 954            dma->ch[chnl].sa |= val;
 955            break;
 956        case DMA0_DAH:
 957            dma->ch[chnl].da &= 0xffffffffULL;
 958            dma->ch[chnl].da |= (uint64_t)val << 32;
 959            break;
 960        case DMA0_DAL:
 961            dma->ch[chnl].da &= 0xffffffff00000000ULL;
 962            dma->ch[chnl].da |= val;
 963            break;
 964        case DMA0_SGH:
 965            dma->ch[chnl].sg &= 0xffffffffULL;
 966            dma->ch[chnl].sg |= (uint64_t)val << 32;
 967            break;
 968        case DMA0_SGL:
 969            dma->ch[chnl].sg &= 0xffffffff00000000ULL;
 970            dma->ch[chnl].sg |= val;
 971            break;
 972        }
 973        break;
 974    case DMA0_SR:
 975        dma->sr &= ~val;
 976        break;
 977    default:
 978        qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
 979                      __func__, dcrn, chnl, addr);
 980    }
 981}
 982
 983static void ppc4xx_dma_reset(void *opaque)
 984{
 985    PPC4xxDmaState *dma = opaque;
 986    int dma_base = dma->base;
 987
 988    memset(dma, 0, sizeof(*dma));
 989    dma->base = dma_base;
 990}
 991
 992void ppc4xx_dma_init(CPUPPCState *env, int dcr_base)
 993{
 994    PPC4xxDmaState *dma;
 995    int i;
 996
 997    dma = g_malloc0(sizeof(*dma));
 998    dma->base = dcr_base;
 999    qemu_register_reset(&ppc4xx_dma_reset, dma);
1000    for (i = 0; i < 4; i++) {
1001        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CR,
1002                         dma, &dcr_read_dma, &dcr_write_dma);
1003        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CT,
1004                         dma, &dcr_read_dma, &dcr_write_dma);
1005        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAH,
1006                         dma, &dcr_read_dma, &dcr_write_dma);
1007        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAL,
1008                         dma, &dcr_read_dma, &dcr_write_dma);
1009        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAH,
1010                         dma, &dcr_read_dma, &dcr_write_dma);
1011        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAL,
1012                         dma, &dcr_read_dma, &dcr_write_dma);
1013        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGH,
1014                         dma, &dcr_read_dma, &dcr_write_dma);
1015        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGL,
1016                         dma, &dcr_read_dma, &dcr_write_dma);
1017    }
1018    ppc_dcr_register(env, dcr_base + DMA0_SR,
1019                     dma, &dcr_read_dma, &dcr_write_dma);
1020    ppc_dcr_register(env, dcr_base + DMA0_SGC,
1021                     dma, &dcr_read_dma, &dcr_write_dma);
1022    ppc_dcr_register(env, dcr_base + DMA0_SLP,
1023                     dma, &dcr_read_dma, &dcr_write_dma);
1024    ppc_dcr_register(env, dcr_base + DMA0_POL,
1025                     dma, &dcr_read_dma, &dcr_write_dma);
1026}
1027
1028/*****************************************************************************/
1029/* PCI Express controller */
1030/* FIXME: This is not complete and does not work, only implemented partially
1031 * to allow firmware and guests to find an empty bus. Cards should use PCI.
1032 */
1033#include "hw/pci/pcie_host.h"
1034
1035#define TYPE_PPC460EX_PCIE_HOST "ppc460ex-pcie-host"
1036OBJECT_DECLARE_SIMPLE_TYPE(PPC460EXPCIEState, PPC460EX_PCIE_HOST)
1037
1038struct PPC460EXPCIEState {
1039    PCIExpressHost host;
1040
1041    MemoryRegion iomem;
1042    qemu_irq irq[4];
1043    int32_t dcrn_base;
1044
1045    uint64_t cfg_base;
1046    uint32_t cfg_mask;
1047    uint64_t msg_base;
1048    uint32_t msg_mask;
1049    uint64_t omr1_base;
1050    uint64_t omr1_mask;
1051    uint64_t omr2_base;
1052    uint64_t omr2_mask;
1053    uint64_t omr3_base;
1054    uint64_t omr3_mask;
1055    uint64_t reg_base;
1056    uint32_t reg_mask;
1057    uint32_t special;
1058    uint32_t cfg;
1059};
1060
1061#define DCRN_PCIE0_BASE 0x100
1062#define DCRN_PCIE1_BASE 0x120
1063
1064enum {
1065    PEGPL_CFGBAH = 0x0,
1066    PEGPL_CFGBAL,
1067    PEGPL_CFGMSK,
1068    PEGPL_MSGBAH,
1069    PEGPL_MSGBAL,
1070    PEGPL_MSGMSK,
1071    PEGPL_OMR1BAH,
1072    PEGPL_OMR1BAL,
1073    PEGPL_OMR1MSKH,
1074    PEGPL_OMR1MSKL,
1075    PEGPL_OMR2BAH,
1076    PEGPL_OMR2BAL,
1077    PEGPL_OMR2MSKH,
1078    PEGPL_OMR2MSKL,
1079    PEGPL_OMR3BAH,
1080    PEGPL_OMR3BAL,
1081    PEGPL_OMR3MSKH,
1082    PEGPL_OMR3MSKL,
1083    PEGPL_REGBAH,
1084    PEGPL_REGBAL,
1085    PEGPL_REGMSK,
1086    PEGPL_SPECIAL,
1087    PEGPL_CFG,
1088};
1089
1090static uint32_t dcr_read_pcie(void *opaque, int dcrn)
1091{
1092    PPC460EXPCIEState *state = opaque;
1093    uint32_t ret = 0;
1094
1095    switch (dcrn - state->dcrn_base) {
1096    case PEGPL_CFGBAH:
1097        ret = state->cfg_base >> 32;
1098        break;
1099    case PEGPL_CFGBAL:
1100        ret = state->cfg_base;
1101        break;
1102    case PEGPL_CFGMSK:
1103        ret = state->cfg_mask;
1104        break;
1105    case PEGPL_MSGBAH:
1106        ret = state->msg_base >> 32;
1107        break;
1108    case PEGPL_MSGBAL:
1109        ret = state->msg_base;
1110        break;
1111    case PEGPL_MSGMSK:
1112        ret = state->msg_mask;
1113        break;
1114    case PEGPL_OMR1BAH:
1115        ret = state->omr1_base >> 32;
1116        break;
1117    case PEGPL_OMR1BAL:
1118        ret = state->omr1_base;
1119        break;
1120    case PEGPL_OMR1MSKH:
1121        ret = state->omr1_mask >> 32;
1122        break;
1123    case PEGPL_OMR1MSKL:
1124        ret = state->omr1_mask;
1125        break;
1126    case PEGPL_OMR2BAH:
1127        ret = state->omr2_base >> 32;
1128        break;
1129    case PEGPL_OMR2BAL:
1130        ret = state->omr2_base;
1131        break;
1132    case PEGPL_OMR2MSKH:
1133        ret = state->omr2_mask >> 32;
1134        break;
1135    case PEGPL_OMR2MSKL:
1136        ret = state->omr3_mask;
1137        break;
1138    case PEGPL_OMR3BAH:
1139        ret = state->omr3_base >> 32;
1140        break;
1141    case PEGPL_OMR3BAL:
1142        ret = state->omr3_base;
1143        break;
1144    case PEGPL_OMR3MSKH:
1145        ret = state->omr3_mask >> 32;
1146        break;
1147    case PEGPL_OMR3MSKL:
1148        ret = state->omr3_mask;
1149        break;
1150    case PEGPL_REGBAH:
1151        ret = state->reg_base >> 32;
1152        break;
1153    case PEGPL_REGBAL:
1154        ret = state->reg_base;
1155        break;
1156    case PEGPL_REGMSK:
1157        ret = state->reg_mask;
1158        break;
1159    case PEGPL_SPECIAL:
1160        ret = state->special;
1161        break;
1162    case PEGPL_CFG:
1163        ret = state->cfg;
1164        break;
1165    }
1166
1167    return ret;
1168}
1169
1170static void dcr_write_pcie(void *opaque, int dcrn, uint32_t val)
1171{
1172    PPC460EXPCIEState *s = opaque;
1173    uint64_t size;
1174
1175    switch (dcrn - s->dcrn_base) {
1176    case PEGPL_CFGBAH:
1177        s->cfg_base = ((uint64_t)val << 32) | (s->cfg_base & 0xffffffff);
1178        break;
1179    case PEGPL_CFGBAL:
1180        s->cfg_base = (s->cfg_base & 0xffffffff00000000ULL) | val;
1181        break;
1182    case PEGPL_CFGMSK:
1183        s->cfg_mask = val;
1184        size = ~(val & 0xfffffffe) + 1;
1185        pcie_host_mmcfg_update(PCIE_HOST_BRIDGE(s), val & 1, s->cfg_base, size);
1186        break;
1187    case PEGPL_MSGBAH:
1188        s->msg_base = ((uint64_t)val << 32) | (s->msg_base & 0xffffffff);
1189        break;
1190    case PEGPL_MSGBAL:
1191        s->msg_base = (s->msg_base & 0xffffffff00000000ULL) | val;
1192        break;
1193    case PEGPL_MSGMSK:
1194        s->msg_mask = val;
1195        break;
1196    case PEGPL_OMR1BAH:
1197        s->omr1_base = ((uint64_t)val << 32) | (s->omr1_base & 0xffffffff);
1198        break;
1199    case PEGPL_OMR1BAL:
1200        s->omr1_base = (s->omr1_base & 0xffffffff00000000ULL) | val;
1201        break;
1202    case PEGPL_OMR1MSKH:
1203        s->omr1_mask = ((uint64_t)val << 32) | (s->omr1_mask & 0xffffffff);
1204        break;
1205    case PEGPL_OMR1MSKL:
1206        s->omr1_mask = (s->omr1_mask & 0xffffffff00000000ULL) | val;
1207        break;
1208    case PEGPL_OMR2BAH:
1209        s->omr2_base = ((uint64_t)val << 32) | (s->omr2_base & 0xffffffff);
1210        break;
1211    case PEGPL_OMR2BAL:
1212        s->omr2_base = (s->omr2_base & 0xffffffff00000000ULL) | val;
1213        break;
1214    case PEGPL_OMR2MSKH:
1215        s->omr2_mask = ((uint64_t)val << 32) | (s->omr2_mask & 0xffffffff);
1216        break;
1217    case PEGPL_OMR2MSKL:
1218        s->omr2_mask = (s->omr2_mask & 0xffffffff00000000ULL) | val;
1219        break;
1220    case PEGPL_OMR3BAH:
1221        s->omr3_base = ((uint64_t)val << 32) | (s->omr3_base & 0xffffffff);
1222        break;
1223    case PEGPL_OMR3BAL:
1224        s->omr3_base = (s->omr3_base & 0xffffffff00000000ULL) | val;
1225        break;
1226    case PEGPL_OMR3MSKH:
1227        s->omr3_mask = ((uint64_t)val << 32) | (s->omr3_mask & 0xffffffff);
1228        break;
1229    case PEGPL_OMR3MSKL:
1230        s->omr3_mask = (s->omr3_mask & 0xffffffff00000000ULL) | val;
1231        break;
1232    case PEGPL_REGBAH:
1233        s->reg_base = ((uint64_t)val << 32) | (s->reg_base & 0xffffffff);
1234        break;
1235    case PEGPL_REGBAL:
1236        s->reg_base = (s->reg_base & 0xffffffff00000000ULL) | val;
1237        break;
1238    case PEGPL_REGMSK:
1239        s->reg_mask = val;
1240        /* FIXME: how is size encoded? */
1241        size = (val == 0x7001 ? 4096 : ~(val & 0xfffffffe) + 1);
1242        break;
1243    case PEGPL_SPECIAL:
1244        s->special = val;
1245        break;
1246    case PEGPL_CFG:
1247        s->cfg = val;
1248        break;
1249    }
1250}
1251
1252static void ppc460ex_set_irq(void *opaque, int irq_num, int level)
1253{
1254       PPC460EXPCIEState *s = opaque;
1255       qemu_set_irq(s->irq[irq_num], level);
1256}
1257
1258static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp)
1259{
1260    PPC460EXPCIEState *s = PPC460EX_PCIE_HOST(dev);
1261    PCIHostState *pci = PCI_HOST_BRIDGE(dev);
1262    int i, id;
1263    char buf[16];
1264
1265    switch (s->dcrn_base) {
1266    case DCRN_PCIE0_BASE:
1267        id = 0;
1268        break;
1269    case DCRN_PCIE1_BASE:
1270        id = 1;
1271        break;
1272    default:
1273        error_setg(errp, "invalid PCIe DCRN base");
1274        return;
1275    }
1276    snprintf(buf, sizeof(buf), "pcie%d-io", id);
1277    memory_region_init(&s->iomem, OBJECT(s), buf, UINT64_MAX);
1278    for (i = 0; i < 4; i++) {
1279        sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
1280    }
1281    snprintf(buf, sizeof(buf), "pcie.%d", id);
1282    pci->bus = pci_register_root_bus(DEVICE(s), buf, ppc460ex_set_irq,
1283                                pci_swizzle_map_irq_fn, s, &s->iomem,
1284                                get_system_io(), 0, 4, TYPE_PCIE_BUS);
1285}
1286
1287static Property ppc460ex_pcie_props[] = {
1288    DEFINE_PROP_INT32("dcrn-base", PPC460EXPCIEState, dcrn_base, -1),
1289    DEFINE_PROP_END_OF_LIST(),
1290};
1291
1292static void ppc460ex_pcie_class_init(ObjectClass *klass, void *data)
1293{
1294    DeviceClass *dc = DEVICE_CLASS(klass);
1295
1296    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
1297    dc->realize = ppc460ex_pcie_realize;
1298    device_class_set_props(dc, ppc460ex_pcie_props);
1299    dc->hotpluggable = false;
1300}
1301
1302static const TypeInfo ppc460ex_pcie_host_info = {
1303    .name = TYPE_PPC460EX_PCIE_HOST,
1304    .parent = TYPE_PCIE_HOST_BRIDGE,
1305    .instance_size = sizeof(PPC460EXPCIEState),
1306    .class_init = ppc460ex_pcie_class_init,
1307};
1308
1309static void ppc460ex_pcie_register(void)
1310{
1311    type_register_static(&ppc460ex_pcie_host_info);
1312}
1313
1314type_init(ppc460ex_pcie_register)
1315
1316static void ppc460ex_pcie_register_dcrs(PPC460EXPCIEState *s, CPUPPCState *env)
1317{
1318    ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAH, s,
1319                     &dcr_read_pcie, &dcr_write_pcie);
1320    ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAL, s,
1321                     &dcr_read_pcie, &dcr_write_pcie);
1322    ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGMSK, s,
1323                     &dcr_read_pcie, &dcr_write_pcie);
1324    ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAH, s,
1325                     &dcr_read_pcie, &dcr_write_pcie);
1326    ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAL, s,
1327                     &dcr_read_pcie, &dcr_write_pcie);
1328    ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGMSK, s,
1329                     &dcr_read_pcie, &dcr_write_pcie);
1330    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAH, s,
1331                     &dcr_read_pcie, &dcr_write_pcie);
1332    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAL, s,
1333                     &dcr_read_pcie, &dcr_write_pcie);
1334    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKH, s,
1335                     &dcr_read_pcie, &dcr_write_pcie);
1336    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKL, s,
1337                     &dcr_read_pcie, &dcr_write_pcie);
1338    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAH, s,
1339                     &dcr_read_pcie, &dcr_write_pcie);
1340    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAL, s,
1341                     &dcr_read_pcie, &dcr_write_pcie);
1342    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKH, s,
1343                     &dcr_read_pcie, &dcr_write_pcie);
1344    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKL, s,
1345                     &dcr_read_pcie, &dcr_write_pcie);
1346    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAH, s,
1347                     &dcr_read_pcie, &dcr_write_pcie);
1348    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAL, s,
1349                     &dcr_read_pcie, &dcr_write_pcie);
1350    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKH, s,
1351                     &dcr_read_pcie, &dcr_write_pcie);
1352    ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKL, s,
1353                     &dcr_read_pcie, &dcr_write_pcie);
1354    ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAH, s,
1355                     &dcr_read_pcie, &dcr_write_pcie);
1356    ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAL, s,
1357                     &dcr_read_pcie, &dcr_write_pcie);
1358    ppc_dcr_register(env, s->dcrn_base + PEGPL_REGMSK, s,
1359                     &dcr_read_pcie, &dcr_write_pcie);
1360    ppc_dcr_register(env, s->dcrn_base + PEGPL_SPECIAL, s,
1361                     &dcr_read_pcie, &dcr_write_pcie);
1362    ppc_dcr_register(env, s->dcrn_base + PEGPL_CFG, s,
1363                     &dcr_read_pcie, &dcr_write_pcie);
1364}
1365
1366void ppc460ex_pcie_init(CPUPPCState *env)
1367{
1368    DeviceState *dev;
1369
1370    dev = qdev_new(TYPE_PPC460EX_PCIE_HOST);
1371    qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE0_BASE);
1372    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1373    ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env);
1374
1375    dev = qdev_new(TYPE_PPC460EX_PCIE_HOST);
1376    qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE1_BASE);
1377    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1378    ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env);
1379}
1380