qemu/hw/ppce500_pci.c
<<
>>
Prefs
   1/*
   2 * QEMU PowerPC E500 embedded processors pci controller emulation
   3 *
   4 * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
   5 *
   6 * Author: Yu Liu,     <yu.liu@freescale.com>
   7 *
   8 * This file is derived from hw/ppc4xx_pci.c,
   9 * the copyright for that material belongs to the original owners.
  10 *
  11 * This is free software; you can redistribute it and/or modify
  12 * it under the terms of  the GNU General  Public License as published by
  13 * the Free Software Foundation;  either version 2 of the  License, or
  14 * (at your option) any later version.
  15 */
  16
  17#include "hw.h"
  18#include "ppce500.h"
  19#include "pci.h"
  20#include "pci_host.h"
  21#include "bswap.h"
  22
  23#ifdef DEBUG_PCI
  24#define pci_debug(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
  25#else
  26#define pci_debug(fmt, ...)
  27#endif
  28
  29#define PCIE500_CFGADDR       0x0
  30#define PCIE500_CFGDATA       0x4
  31#define PCIE500_REG_BASE      0xC00
  32#define PCIE500_REG_SIZE      (0x1000 - PCIE500_REG_BASE)
  33
  34#define PPCE500_PCI_CONFIG_ADDR         0x0
  35#define PPCE500_PCI_CONFIG_DATA         0x4
  36#define PPCE500_PCI_INTACK              0x8
  37
  38#define PPCE500_PCI_OW1                 (0xC20 - PCIE500_REG_BASE)
  39#define PPCE500_PCI_OW2                 (0xC40 - PCIE500_REG_BASE)
  40#define PPCE500_PCI_OW3                 (0xC60 - PCIE500_REG_BASE)
  41#define PPCE500_PCI_OW4                 (0xC80 - PCIE500_REG_BASE)
  42#define PPCE500_PCI_IW3                 (0xDA0 - PCIE500_REG_BASE)
  43#define PPCE500_PCI_IW2                 (0xDC0 - PCIE500_REG_BASE)
  44#define PPCE500_PCI_IW1                 (0xDE0 - PCIE500_REG_BASE)
  45
  46#define PPCE500_PCI_GASKET_TIMR         (0xE20 - PCIE500_REG_BASE)
  47
  48#define PCI_POTAR               0x0
  49#define PCI_POTEAR              0x4
  50#define PCI_POWBAR              0x8
  51#define PCI_POWAR               0x10
  52
  53#define PCI_PITAR               0x0
  54#define PCI_PIWBAR              0x8
  55#define PCI_PIWBEAR             0xC
  56#define PCI_PIWAR               0x10
  57
  58#define PPCE500_PCI_NR_POBS     5
  59#define PPCE500_PCI_NR_PIBS     3
  60
  61struct  pci_outbound {
  62    uint32_t potar;
  63    uint32_t potear;
  64    uint32_t powbar;
  65    uint32_t powar;
  66};
  67
  68struct pci_inbound {
  69    uint32_t pitar;
  70    uint32_t piwbar;
  71    uint32_t piwbear;
  72    uint32_t piwar;
  73};
  74
  75struct PPCE500PCIState {
  76    struct pci_outbound pob[PPCE500_PCI_NR_POBS];
  77    struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
  78    uint32_t gasket_time;
  79    PCIHostState pci_state;
  80    PCIDevice *pci_dev;
  81};
  82
  83typedef struct PPCE500PCIState PPCE500PCIState;
  84
  85static uint32_t pci_reg_read4(void *opaque, target_phys_addr_t addr)
  86{
  87    PPCE500PCIState *pci = opaque;
  88    unsigned long win;
  89    uint32_t value = 0;
  90
  91    win = addr & 0xfe0;
  92
  93    switch (win) {
  94    case PPCE500_PCI_OW1:
  95    case PPCE500_PCI_OW2:
  96    case PPCE500_PCI_OW3:
  97    case PPCE500_PCI_OW4:
  98        switch (addr & 0xC) {
  99        case PCI_POTAR: value = pci->pob[(addr >> 5) & 0x7].potar; break;
 100        case PCI_POTEAR: value = pci->pob[(addr >> 5) & 0x7].potear; break;
 101        case PCI_POWBAR: value = pci->pob[(addr >> 5) & 0x7].powbar; break;
 102        case PCI_POWAR: value = pci->pob[(addr >> 5) & 0x7].powar; break;
 103        default: break;
 104        }
 105        break;
 106
 107    case PPCE500_PCI_IW3:
 108    case PPCE500_PCI_IW2:
 109    case PPCE500_PCI_IW1:
 110        switch (addr & 0xC) {
 111        case PCI_PITAR: value = pci->pib[(addr >> 5) & 0x3].pitar; break;
 112        case PCI_PIWBAR: value = pci->pib[(addr >> 5) & 0x3].piwbar; break;
 113        case PCI_PIWBEAR: value = pci->pib[(addr >> 5) & 0x3].piwbear; break;
 114        case PCI_PIWAR: value = pci->pib[(addr >> 5) & 0x3].piwar; break;
 115        default: break;
 116        };
 117        break;
 118
 119    case PPCE500_PCI_GASKET_TIMR:
 120        value = pci->gasket_time;
 121        break;
 122
 123    default:
 124        break;
 125    }
 126
 127    pci_debug("%s: win:%lx(addr:" TARGET_FMT_plx ") -> value:%x\n", __func__,
 128              win, addr, value);
 129    return value;
 130}
 131
 132static CPUReadMemoryFunc * const e500_pci_reg_read[] = {
 133    &pci_reg_read4,
 134    &pci_reg_read4,
 135    &pci_reg_read4,
 136};
 137
 138static void pci_reg_write4(void *opaque, target_phys_addr_t addr,
 139                               uint32_t value)
 140{
 141    PPCE500PCIState *pci = opaque;
 142    unsigned long win;
 143
 144    win = addr & 0xfe0;
 145
 146    pci_debug("%s: value:%x -> win:%lx(addr:" TARGET_FMT_plx ")\n",
 147              __func__, value, win, addr);
 148
 149    switch (win) {
 150    case PPCE500_PCI_OW1:
 151    case PPCE500_PCI_OW2:
 152    case PPCE500_PCI_OW3:
 153    case PPCE500_PCI_OW4:
 154        switch (addr & 0xC) {
 155        case PCI_POTAR: pci->pob[(addr >> 5) & 0x7].potar = value; break;
 156        case PCI_POTEAR: pci->pob[(addr >> 5) & 0x7].potear = value; break;
 157        case PCI_POWBAR: pci->pob[(addr >> 5) & 0x7].powbar = value; break;
 158        case PCI_POWAR: pci->pob[(addr >> 5) & 0x7].powar = value; break;
 159        default: break;
 160        };
 161        break;
 162
 163    case PPCE500_PCI_IW3:
 164    case PPCE500_PCI_IW2:
 165    case PPCE500_PCI_IW1:
 166        switch (addr & 0xC) {
 167        case PCI_PITAR: pci->pib[(addr >> 5) & 0x3].pitar = value; break;
 168        case PCI_PIWBAR: pci->pib[(addr >> 5) & 0x3].piwbar = value; break;
 169        case PCI_PIWBEAR: pci->pib[(addr >> 5) & 0x3].piwbear = value; break;
 170        case PCI_PIWAR: pci->pib[(addr >> 5) & 0x3].piwar = value; break;
 171        default: break;
 172        };
 173        break;
 174
 175    case PPCE500_PCI_GASKET_TIMR:
 176        pci->gasket_time = value;
 177        break;
 178
 179    default:
 180        break;
 181    };
 182}
 183
 184static CPUWriteMemoryFunc * const e500_pci_reg_write[] = {
 185    &pci_reg_write4,
 186    &pci_reg_write4,
 187    &pci_reg_write4,
 188};
 189
 190static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
 191{
 192    int devno = pci_dev->devfn >> 3, ret = 0;
 193
 194    switch (devno) {
 195        /* Two PCI slot */
 196        case 0x11:
 197        case 0x12:
 198            ret = (irq_num + devno - 0x10) % 4;
 199            break;
 200        default:
 201            printf("Error:%s:unknow dev number\n", __func__);
 202    }
 203
 204    pci_debug("%s: devfn %x irq %d -> %d  devno:%x\n", __func__,
 205           pci_dev->devfn, irq_num, ret, devno);
 206
 207    return ret;
 208}
 209
 210static void mpc85xx_pci_set_irq(void *opaque, int irq_num, int level)
 211{
 212    qemu_irq *pic = opaque;
 213
 214    pci_debug("%s: PCI irq %d, level:%d\n", __func__, irq_num, level);
 215
 216    qemu_set_irq(pic[irq_num], level);
 217}
 218
 219static void ppce500_pci_save(QEMUFile *f, void *opaque)
 220{
 221    PPCE500PCIState *controller = opaque;
 222    int i;
 223
 224    pci_device_save(controller->pci_dev, f);
 225
 226    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
 227        qemu_put_be32s(f, &controller->pob[i].potar);
 228        qemu_put_be32s(f, &controller->pob[i].potear);
 229        qemu_put_be32s(f, &controller->pob[i].powbar);
 230        qemu_put_be32s(f, &controller->pob[i].powar);
 231    }
 232
 233    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
 234        qemu_put_be32s(f, &controller->pib[i].pitar);
 235        qemu_put_be32s(f, &controller->pib[i].piwbar);
 236        qemu_put_be32s(f, &controller->pib[i].piwbear);
 237        qemu_put_be32s(f, &controller->pib[i].piwar);
 238    }
 239    qemu_put_be32s(f, &controller->gasket_time);
 240}
 241
 242static int ppce500_pci_load(QEMUFile *f, void *opaque, int version_id)
 243{
 244    PPCE500PCIState *controller = opaque;
 245    int i;
 246
 247    if (version_id != 1)
 248        return -EINVAL;
 249
 250    pci_device_load(controller->pci_dev, f);
 251
 252    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
 253        qemu_get_be32s(f, &controller->pob[i].potar);
 254        qemu_get_be32s(f, &controller->pob[i].potear);
 255        qemu_get_be32s(f, &controller->pob[i].powbar);
 256        qemu_get_be32s(f, &controller->pob[i].powar);
 257    }
 258
 259    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
 260        qemu_get_be32s(f, &controller->pib[i].pitar);
 261        qemu_get_be32s(f, &controller->pib[i].piwbar);
 262        qemu_get_be32s(f, &controller->pib[i].piwbear);
 263        qemu_get_be32s(f, &controller->pib[i].piwar);
 264    }
 265    qemu_get_be32s(f, &controller->gasket_time);
 266
 267    return 0;
 268}
 269
 270PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
 271{
 272    PPCE500PCIState *controller;
 273    PCIDevice *d;
 274    int index;
 275    static int ppce500_pci_id;
 276
 277    controller = qemu_mallocz(sizeof(PPCE500PCIState));
 278
 279    controller->pci_state.bus = pci_register_bus(NULL, "pci",
 280                                                 mpc85xx_pci_set_irq,
 281                                                 mpc85xx_pci_map_irq,
 282                                                 pci_irqs, PCI_DEVFN(0x11, 0),
 283                                                 4);
 284    d = pci_register_device(controller->pci_state.bus,
 285                            "host bridge", sizeof(PCIDevice),
 286                            0, NULL, NULL);
 287
 288    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_FREESCALE);
 289    pci_config_set_device_id(d->config, PCI_DEVICE_ID_MPC8533E);
 290    pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_POWERPC);
 291
 292    controller->pci_dev = d;
 293
 294    /* CFGADDR */
 295    index = pci_host_conf_register_mmio(&controller->pci_state,
 296                                        DEVICE_BIG_ENDIAN);
 297    if (index < 0)
 298        goto free;
 299    cpu_register_physical_memory(registers + PCIE500_CFGADDR, 4, index);
 300
 301    /* CFGDATA */
 302    index = pci_host_data_register_mmio(&controller->pci_state,
 303                                        DEVICE_BIG_ENDIAN);
 304    if (index < 0)
 305        goto free;
 306    cpu_register_physical_memory(registers + PCIE500_CFGDATA, 4, index);
 307
 308    index = cpu_register_io_memory(e500_pci_reg_read,
 309                                   e500_pci_reg_write, controller,
 310                                   DEVICE_NATIVE_ENDIAN);
 311    if (index < 0)
 312        goto free;
 313    cpu_register_physical_memory(registers + PCIE500_REG_BASE,
 314                                   PCIE500_REG_SIZE, index);
 315
 316    /* XXX load/save code not tested. */
 317    register_savevm(&d->qdev, "ppce500_pci", ppce500_pci_id++,
 318                    1, ppce500_pci_save, ppce500_pci_load, controller);
 319
 320    return controller->pci_state.bus;
 321
 322free:
 323    printf("%s error\n", __func__);
 324    qemu_free(controller);
 325    return NULL;
 326}
 327