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