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
  28/*****************************************************************************/
  29/* L2 Cache as SRAM */
  30/* FIXME:fix names */
  31enum {
  32    DCR_L2CACHE_BASE  = 0x30,
  33    DCR_L2CACHE_CFG   = DCR_L2CACHE_BASE,
  34    DCR_L2CACHE_CMD,
  35    DCR_L2CACHE_ADDR,
  36    DCR_L2CACHE_DATA,
  37    DCR_L2CACHE_STAT,
  38    DCR_L2CACHE_CVER,
  39    DCR_L2CACHE_SNP0,
  40    DCR_L2CACHE_SNP1,
  41    DCR_L2CACHE_END   = DCR_L2CACHE_SNP1,
  42};
  43
  44/* base is 460ex-specific, cf. U-Boot, ppc4xx-isram.h */
  45enum {
  46    DCR_ISRAM0_BASE   = 0x20,
  47    DCR_ISRAM0_SB0CR  = DCR_ISRAM0_BASE,
  48    DCR_ISRAM0_SB1CR,
  49    DCR_ISRAM0_SB2CR,
  50    DCR_ISRAM0_SB3CR,
  51    DCR_ISRAM0_BEAR,
  52    DCR_ISRAM0_BESR0,
  53    DCR_ISRAM0_BESR1,
  54    DCR_ISRAM0_PMEG,
  55    DCR_ISRAM0_CID,
  56    DCR_ISRAM0_REVID,
  57    DCR_ISRAM0_DPC,
  58    DCR_ISRAM0_END    = DCR_ISRAM0_DPC
  59};
  60
  61enum {
  62    DCR_ISRAM1_BASE   = 0xb0,
  63    DCR_ISRAM1_SB0CR  = DCR_ISRAM1_BASE,
  64    /* single bank */
  65    DCR_ISRAM1_BEAR   = DCR_ISRAM1_BASE + 0x04,
  66    DCR_ISRAM1_BESR0,
  67    DCR_ISRAM1_BESR1,
  68    DCR_ISRAM1_PMEG,
  69    DCR_ISRAM1_CID,
  70    DCR_ISRAM1_REVID,
  71    DCR_ISRAM1_DPC,
  72    DCR_ISRAM1_END    = DCR_ISRAM1_DPC
  73};
  74
  75typedef struct ppc4xx_l2sram_t {
  76    MemoryRegion bank[4];
  77    uint32_t l2cache[8];
  78    uint32_t isram0[11];
  79} ppc4xx_l2sram_t;
  80
  81#ifdef MAP_L2SRAM
  82static void l2sram_update_mappings(ppc4xx_l2sram_t *l2sram,
  83                                   uint32_t isarc, uint32_t isacntl,
  84                                   uint32_t dsarc, uint32_t dsacntl)
  85{
  86    if (l2sram->isarc != isarc ||
  87        (l2sram->isacntl & 0x80000000) != (isacntl & 0x80000000)) {
  88        if (l2sram->isacntl & 0x80000000) {
  89            /* Unmap previously assigned memory region */
  90            memory_region_del_subregion(get_system_memory(),
  91                                        &l2sram->isarc_ram);
  92        }
  93        if (isacntl & 0x80000000) {
  94            /* Map new instruction memory region */
  95            memory_region_add_subregion(get_system_memory(), isarc,
  96                                        &l2sram->isarc_ram);
  97        }
  98    }
  99    if (l2sram->dsarc != dsarc ||
 100        (l2sram->dsacntl & 0x80000000) != (dsacntl & 0x80000000)) {
 101        if (l2sram->dsacntl & 0x80000000) {
 102            /* Beware not to unmap the region we just mapped */
 103            if (!(isacntl & 0x80000000) || l2sram->dsarc != isarc) {
 104                /* Unmap previously assigned memory region */
 105                memory_region_del_subregion(get_system_memory(),
 106                                            &l2sram->dsarc_ram);
 107            }
 108        }
 109        if (dsacntl & 0x80000000) {
 110            /* Beware not to remap the region we just mapped */
 111            if (!(isacntl & 0x80000000) || dsarc != isarc) {
 112                /* Map new data memory region */
 113                memory_region_add_subregion(get_system_memory(), dsarc,
 114                                            &l2sram->dsarc_ram);
 115            }
 116        }
 117    }
 118}
 119#endif
 120
 121static uint32_t dcr_read_l2sram(void *opaque, int dcrn)
 122{
 123    ppc4xx_l2sram_t *l2sram = opaque;
 124    uint32_t ret = 0;
 125
 126    switch (dcrn) {
 127    case DCR_L2CACHE_CFG:
 128    case DCR_L2CACHE_CMD:
 129    case DCR_L2CACHE_ADDR:
 130    case DCR_L2CACHE_DATA:
 131    case DCR_L2CACHE_STAT:
 132    case DCR_L2CACHE_CVER:
 133    case DCR_L2CACHE_SNP0:
 134    case DCR_L2CACHE_SNP1:
 135        ret = l2sram->l2cache[dcrn - DCR_L2CACHE_BASE];
 136        break;
 137
 138    case DCR_ISRAM0_SB0CR:
 139    case DCR_ISRAM0_SB1CR:
 140    case DCR_ISRAM0_SB2CR:
 141    case DCR_ISRAM0_SB3CR:
 142    case DCR_ISRAM0_BEAR:
 143    case DCR_ISRAM0_BESR0:
 144    case DCR_ISRAM0_BESR1:
 145    case DCR_ISRAM0_PMEG:
 146    case DCR_ISRAM0_CID:
 147    case DCR_ISRAM0_REVID:
 148    case DCR_ISRAM0_DPC:
 149        ret = l2sram->isram0[dcrn - DCR_ISRAM0_BASE];
 150        break;
 151
 152    default:
 153        break;
 154    }
 155
 156    return ret;
 157}
 158
 159static void dcr_write_l2sram(void *opaque, int dcrn, uint32_t val)
 160{
 161    /*ppc4xx_l2sram_t *l2sram = opaque;*/
 162    /* FIXME: Actually handle L2 cache mapping */
 163
 164    switch (dcrn) {
 165    case DCR_L2CACHE_CFG:
 166    case DCR_L2CACHE_CMD:
 167    case DCR_L2CACHE_ADDR:
 168    case DCR_L2CACHE_DATA:
 169    case DCR_L2CACHE_STAT:
 170    case DCR_L2CACHE_CVER:
 171    case DCR_L2CACHE_SNP0:
 172    case DCR_L2CACHE_SNP1:
 173        /*l2sram->l2cache[dcrn - DCR_L2CACHE_BASE] = val;*/
 174        break;
 175
 176    case DCR_ISRAM0_SB0CR:
 177    case DCR_ISRAM0_SB1CR:
 178    case DCR_ISRAM0_SB2CR:
 179    case DCR_ISRAM0_SB3CR:
 180    case DCR_ISRAM0_BEAR:
 181    case DCR_ISRAM0_BESR0:
 182    case DCR_ISRAM0_BESR1:
 183    case DCR_ISRAM0_PMEG:
 184    case DCR_ISRAM0_CID:
 185    case DCR_ISRAM0_REVID:
 186    case DCR_ISRAM0_DPC:
 187        /*l2sram->isram0[dcrn - DCR_L2CACHE_BASE] = val;*/
 188        break;
 189
 190    case DCR_ISRAM1_SB0CR:
 191    case DCR_ISRAM1_BEAR:
 192    case DCR_ISRAM1_BESR0:
 193    case DCR_ISRAM1_BESR1:
 194    case DCR_ISRAM1_PMEG:
 195    case DCR_ISRAM1_CID:
 196    case DCR_ISRAM1_REVID:
 197    case DCR_ISRAM1_DPC:
 198        /*l2sram->isram1[dcrn - DCR_L2CACHE_BASE] = val;*/
 199        break;
 200    }
 201    /*l2sram_update_mappings(l2sram, isarc, isacntl, dsarc, dsacntl);*/
 202}
 203
 204static void l2sram_reset(void *opaque)
 205{
 206    ppc4xx_l2sram_t *l2sram = opaque;
 207
 208    memset(l2sram->l2cache, 0, sizeof(l2sram->l2cache));
 209    l2sram->l2cache[DCR_L2CACHE_STAT - DCR_L2CACHE_BASE] = 0x80000000;
 210    memset(l2sram->isram0, 0, sizeof(l2sram->isram0));
 211    /*l2sram_update_mappings(l2sram, isarc, isacntl, dsarc, dsacntl);*/
 212}
 213
 214void ppc4xx_l2sram_init(CPUPPCState *env)
 215{
 216    ppc4xx_l2sram_t *l2sram;
 217
 218    l2sram = g_malloc0(sizeof(*l2sram));
 219    /* XXX: Size is 4*64kB for 460ex, cf. U-Boot, ppc4xx-isram.h */
 220    memory_region_init_ram(&l2sram->bank[0], NULL, "ppc4xx.l2sram_bank0",
 221                           64 * KiB, &error_abort);
 222    memory_region_init_ram(&l2sram->bank[1], NULL, "ppc4xx.l2sram_bank1",
 223                           64 * KiB, &error_abort);
 224    memory_region_init_ram(&l2sram->bank[2], NULL, "ppc4xx.l2sram_bank2",
 225                           64 * KiB, &error_abort);
 226    memory_region_init_ram(&l2sram->bank[3], NULL, "ppc4xx.l2sram_bank3",
 227                           64 * KiB, &error_abort);
 228    qemu_register_reset(&l2sram_reset, l2sram);
 229    ppc_dcr_register(env, DCR_L2CACHE_CFG,
 230                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 231    ppc_dcr_register(env, DCR_L2CACHE_CMD,
 232                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 233    ppc_dcr_register(env, DCR_L2CACHE_ADDR,
 234                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 235    ppc_dcr_register(env, DCR_L2CACHE_DATA,
 236                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 237    ppc_dcr_register(env, DCR_L2CACHE_STAT,
 238                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 239    ppc_dcr_register(env, DCR_L2CACHE_CVER,
 240                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 241    ppc_dcr_register(env, DCR_L2CACHE_SNP0,
 242                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 243    ppc_dcr_register(env, DCR_L2CACHE_SNP1,
 244                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 245
 246    ppc_dcr_register(env, DCR_ISRAM0_SB0CR,
 247                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 248    ppc_dcr_register(env, DCR_ISRAM0_SB1CR,
 249                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 250    ppc_dcr_register(env, DCR_ISRAM0_SB2CR,
 251                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 252    ppc_dcr_register(env, DCR_ISRAM0_SB3CR,
 253                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 254    ppc_dcr_register(env, DCR_ISRAM0_PMEG,
 255                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 256    ppc_dcr_register(env, DCR_ISRAM0_DPC,
 257                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 258
 259    ppc_dcr_register(env, DCR_ISRAM1_SB0CR,
 260                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 261    ppc_dcr_register(env, DCR_ISRAM1_PMEG,
 262                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 263    ppc_dcr_register(env, DCR_ISRAM1_DPC,
 264                     l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
 265}
 266
 267/*****************************************************************************/
 268/* Clocking Power on Reset */
 269enum {
 270    CPR0_CFGADDR = 0xC,
 271    CPR0_CFGDATA = 0xD,
 272
 273    CPR0_PLLD = 0x060,
 274    CPR0_PLBED = 0x080,
 275    CPR0_OPBD = 0x0C0,
 276    CPR0_PERD = 0x0E0,
 277    CPR0_AHBD = 0x100,
 278};
 279
 280typedef struct ppc4xx_cpr_t {
 281    uint32_t addr;
 282} ppc4xx_cpr_t;
 283
 284static uint32_t dcr_read_cpr(void *opaque, int dcrn)
 285{
 286    ppc4xx_cpr_t *cpr = opaque;
 287    uint32_t ret = 0;
 288
 289    switch (dcrn) {
 290    case CPR0_CFGADDR:
 291        ret = cpr->addr;
 292        break;
 293    case CPR0_CFGDATA:
 294        switch (cpr->addr) {
 295        case CPR0_PLLD:
 296            ret = (0xb5 << 24) | (1 << 16) | (9 << 8);
 297            break;
 298        case CPR0_PLBED:
 299            ret = (5 << 24);
 300            break;
 301        case CPR0_OPBD:
 302            ret = (2 << 24);
 303            break;
 304        case CPR0_PERD:
 305        case CPR0_AHBD:
 306            ret = (1 << 24);
 307            break;
 308        default:
 309            break;
 310        }
 311        break;
 312    default:
 313        break;
 314    }
 315
 316    return ret;
 317}
 318
 319static void dcr_write_cpr(void *opaque, int dcrn, uint32_t val)
 320{
 321    ppc4xx_cpr_t *cpr = opaque;
 322
 323    switch (dcrn) {
 324    case CPR0_CFGADDR:
 325        cpr->addr = val;
 326        break;
 327    case CPR0_CFGDATA:
 328        break;
 329    default:
 330        break;
 331    }
 332}
 333
 334static void ppc4xx_cpr_reset(void *opaque)
 335{
 336    ppc4xx_cpr_t *cpr = opaque;
 337
 338    cpr->addr = 0;
 339}
 340
 341void ppc4xx_cpr_init(CPUPPCState *env)
 342{
 343    ppc4xx_cpr_t *cpr;
 344
 345    cpr = g_malloc0(sizeof(*cpr));
 346    ppc_dcr_register(env, CPR0_CFGADDR, cpr, &dcr_read_cpr, &dcr_write_cpr);
 347    ppc_dcr_register(env, CPR0_CFGDATA, cpr, &dcr_read_cpr, &dcr_write_cpr);
 348    qemu_register_reset(ppc4xx_cpr_reset, cpr);
 349}
 350
 351/*****************************************************************************/
 352/* System DCRs */
 353typedef struct ppc4xx_sdr_t ppc4xx_sdr_t;
 354struct ppc4xx_sdr_t {
 355    uint32_t addr;
 356};
 357
 358enum {
 359    SDR0_CFGADDR = 0x00e,
 360    SDR0_CFGDATA,
 361    SDR0_STRP0 = 0x020,
 362    SDR0_STRP1,
 363    SDR0_102 = 0x66,
 364    SDR0_103,
 365    SDR0_128 = 0x80,
 366    SDR0_ECID3 = 0x083,
 367    SDR0_DDR0 = 0x0e1,
 368    SDR0_USB0 = 0x320,
 369};
 370
 371enum {
 372    PESDR0_LOOP = 0x303,
 373    PESDR0_RCSSET,
 374    PESDR0_RCSSTS,
 375    PESDR0_RSTSTA = 0x310,
 376    PESDR1_LOOP = 0x343,
 377    PESDR1_RCSSET,
 378    PESDR1_RCSSTS,
 379    PESDR1_RSTSTA = 0x365,
 380};
 381
 382#define SDR0_DDR0_DDRM_ENCODE(n)  ((((unsigned long)(n)) & 0x03) << 29)
 383#define SDR0_DDR0_DDRM_DDR1       0x20000000
 384#define SDR0_DDR0_DDRM_DDR2       0x40000000
 385
 386static uint32_t dcr_read_sdr(void *opaque, int dcrn)
 387{
 388    ppc4xx_sdr_t *sdr = opaque;
 389    uint32_t ret = 0;
 390
 391    switch (dcrn) {
 392    case SDR0_CFGADDR:
 393        ret = sdr->addr;
 394        break;
 395    case SDR0_CFGDATA:
 396        switch (sdr->addr) {
 397        case SDR0_STRP0:
 398            ret = (0xb5 << 8) | (1 << 4) | 9;
 399            break;
 400        case SDR0_STRP1:
 401            ret = (5 << 29) | (2 << 26) | (1 << 24);
 402            break;
 403        case SDR0_ECID3:
 404            ret = 1 << 20; /* No Security/Kasumi support */
 405            break;
 406        case SDR0_DDR0:
 407            ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
 408            break;
 409        case PESDR0_RCSSET:
 410        case PESDR1_RCSSET:
 411            ret = (1 << 24) | (1 << 16);
 412            break;
 413        case PESDR0_RCSSTS:
 414        case PESDR1_RCSSTS:
 415            ret = (1 << 16) | (1 << 12);
 416            break;
 417        case PESDR0_RSTSTA:
 418        case PESDR1_RSTSTA:
 419            ret = 1;
 420            break;
 421        case PESDR0_LOOP:
 422        case PESDR1_LOOP:
 423            ret = 1 << 12;
 424            break;
 425        default:
 426            break;
 427        }
 428        break;
 429    default:
 430        break;
 431    }
 432
 433    return ret;
 434}
 435
 436static void dcr_write_sdr(void *opaque, int dcrn, uint32_t val)
 437{
 438    ppc4xx_sdr_t *sdr = opaque;
 439
 440    switch (dcrn) {
 441    case SDR0_CFGADDR:
 442        sdr->addr = val;
 443        break;
 444    case SDR0_CFGDATA:
 445        switch (sdr->addr) {
 446        case 0x00: /* B0CR */
 447            break;
 448        default:
 449            break;
 450        }
 451        break;
 452    default:
 453        break;
 454    }
 455}
 456
 457static void sdr_reset(void *opaque)
 458{
 459    ppc4xx_sdr_t *sdr = opaque;
 460
 461    sdr->addr = 0;
 462}
 463
 464void ppc4xx_sdr_init(CPUPPCState *env)
 465{
 466    ppc4xx_sdr_t *sdr;
 467
 468    sdr = g_malloc0(sizeof(*sdr));
 469    qemu_register_reset(&sdr_reset, sdr);
 470    ppc_dcr_register(env, SDR0_CFGADDR,
 471                     sdr, &dcr_read_sdr, &dcr_write_sdr);
 472    ppc_dcr_register(env, SDR0_CFGDATA,
 473                     sdr, &dcr_read_sdr, &dcr_write_sdr);
 474    ppc_dcr_register(env, SDR0_102,
 475                     sdr, &dcr_read_sdr, &dcr_write_sdr);
 476    ppc_dcr_register(env, SDR0_103,
 477                     sdr, &dcr_read_sdr, &dcr_write_sdr);
 478    ppc_dcr_register(env, SDR0_128,
 479                     sdr, &dcr_read_sdr, &dcr_write_sdr);
 480    ppc_dcr_register(env, SDR0_USB0,
 481                     sdr, &dcr_read_sdr, &dcr_write_sdr);
 482}
 483
 484/*****************************************************************************/
 485/* SDRAM controller */
 486typedef struct ppc440_sdram_t {
 487    uint32_t addr;
 488    int nbanks;
 489    MemoryRegion containers[4]; /* used for clipping */
 490    MemoryRegion *ram_memories;
 491    hwaddr ram_bases[4];
 492    hwaddr ram_sizes[4];
 493    uint32_t bcr[4];
 494} ppc440_sdram_t;
 495
 496enum {
 497    SDRAM0_CFGADDR = 0x10,
 498    SDRAM0_CFGDATA,
 499    SDRAM_R0BAS = 0x40,
 500    SDRAM_R1BAS,
 501    SDRAM_R2BAS,
 502    SDRAM_R3BAS,
 503    SDRAM_CONF1HB = 0x45,
 504    SDRAM_PLBADDULL = 0x4a,
 505    SDRAM_CONF1LL = 0x4b,
 506    SDRAM_CONFPATHB = 0x4f,
 507    SDRAM_PLBADDUHB = 0x50,
 508};
 509
 510static uint32_t sdram_bcr(hwaddr ram_base, hwaddr ram_size)
 511{
 512    uint32_t bcr;
 513
 514    switch (ram_size) {
 515    case (8 * MiB):
 516        bcr = 0xffc0;
 517        break;
 518    case (16 * MiB):
 519        bcr = 0xff80;
 520        break;
 521    case (32 * MiB):
 522        bcr = 0xff00;
 523        break;
 524    case (64 * MiB):
 525        bcr = 0xfe00;
 526        break;
 527    case (128 * MiB):
 528        bcr = 0xfc00;
 529        break;
 530    case (256 * MiB):
 531        bcr = 0xf800;
 532        break;
 533    case (512 * MiB):
 534        bcr = 0xf000;
 535        break;
 536    case (1 * GiB):
 537        bcr = 0xe000;
 538        break;
 539    case (2 * GiB):
 540        bcr = 0xc000;
 541        break;
 542    case (4 * GiB):
 543        bcr = 0x8000;
 544        break;
 545    default:
 546        error_report("invalid RAM size " TARGET_FMT_plx, ram_size);
 547        return 0;
 548    }
 549    bcr |= ram_base >> 2 & 0xffe00000;
 550    bcr |= 1;
 551
 552    return bcr;
 553}
 554
 555static inline hwaddr sdram_base(uint32_t bcr)
 556{
 557    return (bcr & 0xffe00000) << 2;
 558}
 559
 560static uint64_t sdram_size(uint32_t bcr)
 561{
 562    uint64_t size;
 563    int sh;
 564
 565    sh = 1024 - ((bcr >> 6) & 0x3ff);
 566    size = 8 * MiB * sh;
 567
 568    return size;
 569}
 570
 571static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
 572                          uint32_t bcr, int enabled)
 573{
 574    if (sdram->bcr[i] & 1) {
 575        /* First unmap RAM if enabled */
 576        memory_region_del_subregion(get_system_memory(),
 577                                    &sdram->containers[i]);
 578        memory_region_del_subregion(&sdram->containers[i],
 579                                    &sdram->ram_memories[i]);
 580        object_unparent(OBJECT(&sdram->containers[i]));
 581    }
 582    sdram->bcr[i] = bcr & 0xffe0ffc1;
 583    if (enabled && (bcr & 1)) {
 584        memory_region_init(&sdram->containers[i], NULL, "sdram-containers",
 585                           sdram_size(bcr));
 586        memory_region_add_subregion(&sdram->containers[i], 0,
 587                                    &sdram->ram_memories[i]);
 588        memory_region_add_subregion(get_system_memory(),
 589                                    sdram_base(bcr),
 590                                    &sdram->containers[i]);
 591    }
 592}
 593
 594static void sdram_map_bcr(ppc440_sdram_t *sdram)
 595{
 596    int i;
 597
 598    for (i = 0; i < sdram->nbanks; i++) {
 599        if (sdram->ram_sizes[i] != 0) {
 600            sdram_set_bcr(sdram, i, sdram_bcr(sdram->ram_bases[i],
 601                                              sdram->ram_sizes[i]), 1);
 602        } else {
 603            sdram_set_bcr(sdram, i, 0, 0);
 604        }
 605    }
 606}
 607
 608static uint32_t dcr_read_sdram(void *opaque, int dcrn)
 609{
 610    ppc440_sdram_t *sdram = opaque;
 611    uint32_t ret = 0;
 612
 613    switch (dcrn) {
 614    case SDRAM_R0BAS:
 615    case SDRAM_R1BAS:
 616    case SDRAM_R2BAS:
 617    case SDRAM_R3BAS:
 618        if (sdram->ram_sizes[dcrn - SDRAM_R0BAS]) {
 619            ret = sdram_bcr(sdram->ram_bases[dcrn - SDRAM_R0BAS],
 620                            sdram->ram_sizes[dcrn - SDRAM_R0BAS]);
 621        }
 622        break;
 623    case SDRAM_CONF1HB:
 624    case SDRAM_CONF1LL:
 625    case SDRAM_CONFPATHB:
 626    case SDRAM_PLBADDULL:
 627    case SDRAM_PLBADDUHB:
 628        break;
 629    case SDRAM0_CFGADDR:
 630        ret = sdram->addr;
 631        break;
 632    case SDRAM0_CFGDATA:
 633        switch (sdram->addr) {
 634        case 0x14: /* SDRAM_MCSTAT (405EX) */
 635        case 0x1F:
 636            ret = 0x80000000;
 637            break;
 638        case 0x21: /* SDRAM_MCOPT2 */
 639            ret = 0x08000000;
 640            break;
 641        case 0x40: /* SDRAM_MB0CF */
 642            ret = 0x00008001;
 643            break;
 644        case 0x7A: /* SDRAM_DLCR */
 645            ret = 0x02000000;
 646            break;
 647        case 0xE1: /* SDR0_DDR0 */
 648            ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
 649            break;
 650        default:
 651            break;
 652        }
 653        break;
 654    default:
 655        break;
 656    }
 657
 658    return ret;
 659}
 660
 661static void dcr_write_sdram(void *opaque, int dcrn, uint32_t val)
 662{
 663    ppc440_sdram_t *sdram = opaque;
 664
 665    switch (dcrn) {
 666    case SDRAM_R0BAS:
 667    case SDRAM_R1BAS:
 668    case SDRAM_R2BAS:
 669    case SDRAM_R3BAS:
 670    case SDRAM_CONF1HB:
 671    case SDRAM_CONF1LL:
 672    case SDRAM_CONFPATHB:
 673    case SDRAM_PLBADDULL:
 674    case SDRAM_PLBADDUHB:
 675        break;
 676    case SDRAM0_CFGADDR:
 677        sdram->addr = val;
 678        break;
 679    case SDRAM0_CFGDATA:
 680        switch (sdram->addr) {
 681        case 0x00: /* B0CR */
 682            break;
 683        default:
 684            break;
 685        }
 686        break;
 687    default:
 688        break;
 689    }
 690}
 691
 692static void sdram_reset(void *opaque)
 693{
 694    ppc440_sdram_t *sdram = opaque;
 695
 696    sdram->addr = 0;
 697}
 698
 699void ppc440_sdram_init(CPUPPCState *env, int nbanks,
 700                       MemoryRegion *ram_memories,
 701                       hwaddr *ram_bases, hwaddr *ram_sizes,
 702                       int do_init)
 703{
 704    ppc440_sdram_t *sdram;
 705
 706    sdram = g_malloc0(sizeof(*sdram));
 707    sdram->nbanks = nbanks;
 708    sdram->ram_memories = ram_memories;
 709    memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(hwaddr));
 710    memcpy(sdram->ram_sizes, ram_sizes, nbanks * sizeof(hwaddr));
 711    qemu_register_reset(&sdram_reset, sdram);
 712    ppc_dcr_register(env, SDRAM0_CFGADDR,
 713                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 714    ppc_dcr_register(env, SDRAM0_CFGDATA,
 715                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 716    if (do_init) {
 717        sdram_map_bcr(sdram);
 718    }
 719
 720    ppc_dcr_register(env, SDRAM_R0BAS,
 721                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 722    ppc_dcr_register(env, SDRAM_R1BAS,
 723                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 724    ppc_dcr_register(env, SDRAM_R2BAS,
 725                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 726    ppc_dcr_register(env, SDRAM_R3BAS,
 727                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 728    ppc_dcr_register(env, SDRAM_CONF1HB,
 729                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 730    ppc_dcr_register(env, SDRAM_PLBADDULL,
 731                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 732    ppc_dcr_register(env, SDRAM_CONF1LL,
 733                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 734    ppc_dcr_register(env, SDRAM_CONFPATHB,
 735                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 736    ppc_dcr_register(env, SDRAM_PLBADDUHB,
 737                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 738}
 739
 740/*****************************************************************************/
 741/* PLB to AHB bridge */
 742enum {
 743    AHB_TOP    = 0xA4,
 744    AHB_BOT    = 0xA5,
 745};
 746
 747typedef struct ppc4xx_ahb_t {
 748    uint32_t top;
 749    uint32_t bot;
 750} ppc4xx_ahb_t;
 751
 752static uint32_t dcr_read_ahb(void *opaque, int dcrn)
 753{
 754    ppc4xx_ahb_t *ahb = opaque;
 755    uint32_t ret = 0;
 756
 757    switch (dcrn) {
 758    case AHB_TOP:
 759        ret = ahb->top;
 760        break;
 761    case AHB_BOT:
 762        ret = ahb->bot;
 763        break;
 764    default:
 765        break;
 766    }
 767
 768    return ret;
 769}
 770
 771static void dcr_write_ahb(void *opaque, int dcrn, uint32_t val)
 772{
 773    ppc4xx_ahb_t *ahb = opaque;
 774
 775    switch (dcrn) {
 776    case AHB_TOP:
 777        ahb->top = val;
 778        break;
 779    case AHB_BOT:
 780        ahb->bot = val;
 781        break;
 782    }
 783}
 784
 785static void ppc4xx_ahb_reset(void *opaque)
 786{
 787    ppc4xx_ahb_t *ahb = opaque;
 788
 789    /* No error */
 790    ahb->top = 0;
 791    ahb->bot = 0;
 792}
 793
 794void ppc4xx_ahb_init(CPUPPCState *env)
 795{
 796    ppc4xx_ahb_t *ahb;
 797
 798    ahb = g_malloc0(sizeof(*ahb));
 799    ppc_dcr_register(env, AHB_TOP, ahb, &dcr_read_ahb, &dcr_write_ahb);
 800    ppc_dcr_register(env, AHB_BOT, ahb, &dcr_read_ahb, &dcr_write_ahb);
 801    qemu_register_reset(ppc4xx_ahb_reset, ahb);
 802}
 803
 804/*****************************************************************************/
 805/* DMA controller */
 806
 807#define DMA0_CR_CE  (1 << 31)
 808#define DMA0_CR_PW  (1 << 26 | 1 << 25)
 809#define DMA0_CR_DAI (1 << 24)
 810#define DMA0_CR_SAI (1 << 23)
 811#define DMA0_CR_DEC (1 << 2)
 812
 813enum {
 814    DMA0_CR  = 0x00,
 815    DMA0_CT,
 816    DMA0_SAH,
 817    DMA0_SAL,
 818    DMA0_DAH,
 819    DMA0_DAL,
 820    DMA0_SGH,
 821    DMA0_SGL,
 822
 823    DMA0_SR  = 0x20,
 824    DMA0_SGC = 0x23,
 825    DMA0_SLP = 0x25,
 826    DMA0_POL = 0x26,
 827};
 828
 829typedef struct {
 830    uint32_t cr;
 831    uint32_t ct;
 832    uint64_t sa;
 833    uint64_t da;
 834    uint64_t sg;
 835} PPC4xxDmaChnl;
 836
 837typedef struct {
 838    int base;
 839    PPC4xxDmaChnl ch[4];
 840    uint32_t sr;
 841} PPC4xxDmaState;
 842
 843static uint32_t dcr_read_dma(void *opaque, int dcrn)
 844{
 845    PPC4xxDmaState *dma = opaque;
 846    uint32_t val = 0;
 847    int addr = dcrn - dma->base;
 848    int chnl = addr / 8;
 849
 850    switch (addr) {
 851    case 0x00 ... 0x1f:
 852        switch (addr % 8) {
 853        case DMA0_CR:
 854            val = dma->ch[chnl].cr;
 855            break;
 856        case DMA0_CT:
 857            val = dma->ch[chnl].ct;
 858            break;
 859        case DMA0_SAH:
 860            val = dma->ch[chnl].sa >> 32;
 861            break;
 862        case DMA0_SAL:
 863            val = dma->ch[chnl].sa;
 864            break;
 865        case DMA0_DAH:
 866            val = dma->ch[chnl].da >> 32;
 867            break;
 868        case DMA0_DAL:
 869            val = dma->ch[chnl].da;
 870            break;
 871        case DMA0_SGH:
 872            val = dma->ch[chnl].sg >> 32;
 873            break;
 874        case DMA0_SGL:
 875            val = dma->ch[chnl].sg;
 876            break;
 877        }
 878        break;
 879    case DMA0_SR:
 880        val = dma->sr;
 881        break;
 882    default:
 883        qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
 884                      __func__, dcrn, chnl, addr);
 885    }
 886
 887    return val;
 888}
 889
 890static void dcr_write_dma(void *opaque, int dcrn, uint32_t val)
 891{
 892    PPC4xxDmaState *dma = opaque;
 893    int addr = dcrn - dma->base;
 894    int chnl = addr / 8;
 895
 896    switch (addr) {
 897    case 0x00 ... 0x1f:
 898        switch (addr % 8) {
 899        case DMA0_CR:
 900            dma->ch[chnl].cr = val;
 901            if (val & DMA0_CR_CE) {
 902                int count = dma->ch[chnl].ct & 0xffff;
 903
 904                if (count) {
 905                    int width, i, sidx, didx;
 906                    uint8_t *rptr, *wptr;
 907                    hwaddr rlen, wlen;
 908
 909                    sidx = didx = 0;
 910                    width = 1 << ((val & DMA0_CR_PW) >> 25);
 911                    rptr = cpu_physical_memory_map(dma->ch[chnl].sa, &rlen,
 912                                                   false);
 913                    wptr = cpu_physical_memory_map(dma->ch[chnl].da, &wlen,
 914                                                   true);
 915                    if (rptr && wptr) {
 916                        if (!(val & DMA0_CR_DEC) &&
 917                            val & DMA0_CR_SAI && val & DMA0_CR_DAI) {
 918                            /* optimise common case */
 919                            memmove(wptr, rptr, count * width);
 920                            sidx = didx = count * width;
 921                        } else {
 922                            /* do it the slow way */
 923                            for (sidx = didx = i = 0; i < count; i++) {
 924                                uint64_t v = ldn_le_p(rptr + sidx, width);
 925                                stn_le_p(wptr + didx, width, v);
 926                                if (val & DMA0_CR_SAI) {
 927                                    sidx += width;
 928                                }
 929                                if (val & DMA0_CR_DAI) {
 930                                    didx += width;
 931                                }
 932                            }
 933                        }
 934                    }
 935                    if (wptr) {
 936                        cpu_physical_memory_unmap(wptr, wlen, 1, didx);
 937                    }
 938                    if (rptr) {
 939                        cpu_physical_memory_unmap(rptr, rlen, 0, sidx);
 940                    }
 941                }
 942            }
 943            break;
 944        case DMA0_CT:
 945            dma->ch[chnl].ct = val;
 946            break;
 947        case DMA0_SAH:
 948            dma->ch[chnl].sa &= 0xffffffffULL;
 949            dma->ch[chnl].sa |= (uint64_t)val << 32;
 950            break;
 951        case DMA0_SAL:
 952            dma->ch[chnl].sa &= 0xffffffff00000000ULL;
 953            dma->ch[chnl].sa |= val;
 954            break;
 955        case DMA0_DAH:
 956            dma->ch[chnl].da &= 0xffffffffULL;
 957            dma->ch[chnl].da |= (uint64_t)val << 32;
 958            break;
 959        case DMA0_DAL:
 960            dma->ch[chnl].da &= 0xffffffff00000000ULL;
 961            dma->ch[chnl].da |= val;
 962            break;
 963        case DMA0_SGH:
 964            dma->ch[chnl].sg &= 0xffffffffULL;
 965            dma->ch[chnl].sg |= (uint64_t)val << 32;
 966            break;
 967        case DMA0_SGL:
 968            dma->ch[chnl].sg &= 0xffffffff00000000ULL;
 969            dma->ch[chnl].sg |= val;
 970            break;
 971        }
 972        break;
 973    case DMA0_SR:
 974        dma->sr &= ~val;
 975        break;
 976    default:
 977        qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
 978                      __func__, dcrn, chnl, addr);
 979    }
 980}
 981
 982static void ppc4xx_dma_reset(void *opaque)
 983{
 984    PPC4xxDmaState *dma = opaque;
 985    int dma_base = dma->base;
 986
 987    memset(dma, 0, sizeof(*dma));
 988    dma->base = dma_base;
 989}
 990
 991void ppc4xx_dma_init(CPUPPCState *env, int dcr_base)
 992{
 993    PPC4xxDmaState *dma;
 994    int i;
 995
 996    dma = g_malloc0(sizeof(*dma));
 997    dma->base = dcr_base;
 998    qemu_register_reset(&ppc4xx_dma_reset, dma);
 999    for (i = 0; i < 4; i++) {
1000        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CR,
1001                         dma, &dcr_read_dma, &dcr_write_dma);
1002        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CT,
1003                         dma, &dcr_read_dma, &dcr_write_dma);
1004        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAH,
1005                         dma, &dcr_read_dma, &dcr_write_dma);
1006        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAL,
1007                         dma, &dcr_read_dma, &dcr_write_dma);
1008        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAH,
1009                         dma, &dcr_read_dma, &dcr_write_dma);
1010        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAL,
1011                         dma, &dcr_read_dma, &dcr_write_dma);
1012        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGH,
1013                         dma, &dcr_read_dma, &dcr_write_dma);
1014        ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGL,
1015                         dma, &dcr_read_dma, &dcr_write_dma);
1016    }
1017    ppc_dcr_register(env, dcr_base + DMA0_SR,
1018                     dma, &dcr_read_dma, &dcr_write_dma);
1019    ppc_dcr_register(env, dcr_base + DMA0_SGC,
1020                     dma, &dcr_read_dma, &dcr_write_dma);
1021    ppc_dcr_register(env, dcr_base + DMA0_SLP,
1022                     dma, &dcr_read_dma, &dcr_write_dma);
1023    ppc_dcr_register(env, dcr_base + DMA0_POL,
1024                     dma, &dcr_read_dma, &dcr_write_dma);
1025}
1026
1027/*****************************************************************************/
1028/* PCI Express controller */
1029/* FIXME: This is not complete and does not work, only implemented partially
1030 * to allow firmware and guests to find an empty bus. Cards should use PCI.
1031 */
1032#include "hw/pci/pcie_host.h"
1033
1034#define TYPE_PPC460EX_PCIE_HOST "ppc460ex-pcie-host"
1035#define PPC460EX_PCIE_HOST(obj) \
1036    OBJECT_CHECK(PPC460EXPCIEState, (obj), TYPE_PPC460EX_PCIE_HOST)
1037
1038typedef struct 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} PPC460EXPCIEState;
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_create(NULL, TYPE_PPC460EX_PCIE_HOST);
1371    qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE0_BASE);
1372    qdev_init_nofail(dev);
1373    object_property_set_bool(OBJECT(dev), true, "realized", NULL);
1374    ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env);
1375
1376    dev = qdev_create(NULL, TYPE_PPC460EX_PCIE_HOST);
1377    qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE1_BASE);
1378    qdev_init_nofail(dev);
1379    object_property_set_bool(OBJECT(dev), true, "realized", NULL);
1380    ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env);
1381}
1382