cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

ppc440_uc.c (39367B)


      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}