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