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