Commit 74c62ba88902575be9ac3badf95d773470884b1c

Authored by aurel32
1 parent dfebf62b

kvm/powerpc: Add freescale pci controller's support

This patch add the emulation of freescale's pci controller for MPC85xx platform.

Signed-off-by: Liu Yu <yu.liu@freescale.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6661 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -602,6 +602,8 @@ OBJS+= unin_pci.o ppc_newworld.o
602 602 # PowerPC 4xx boards
603 603 OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
604 604 OBJS+= ppc440.o ppc440_bamboo.o
  605 +# PowerPC E500 boards
  606 +OBJS+= ppce500_pci.o
605 607 ifdef FDT_LIBS
606 608 OBJS+= device_tree.o
607 609 LIBS+= $(FDT_LIBS)
... ...
hw/pci.h
... ... @@ -40,6 +40,7 @@ extern target_phys_addr_t pci_mem_base;
40 40 #define PCI_CLASS_BRIDGE_OTHER 0x0680
41 41  
42 42 #define PCI_CLASS_PROCESSOR_CO 0x0b40
  43 +#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20
43 44  
44 45 #define PCI_CLASS_OTHERS 0xff
45 46  
... ... @@ -112,6 +113,9 @@ extern target_phys_addr_t pci_mem_base;
112 113 #define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
113 114 #define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
114 115  
  116 +#define PCI_VENDOR_ID_FSL 0x1957
  117 +#define PCI_DEVICE_ID_FSL_E500 0x0030
  118 +
115 119 /* Red Hat / Qumranet (for QEMU) -- see pci-ids.txt */
116 120 #define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4
117 121 #define PCI_SUBVENDOR_ID_REDHAT_QUMRANET 0x1af4
... ...
hw/ppce500_pci.c 0 → 100644
  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 "ppc.h"
  19 +#include "ppce500.h"
  20 +typedef target_phys_addr_t pci_addr_t;
  21 +#include "pci.h"
  22 +#include "pci_host.h"
  23 +#include "bswap.h"
  24 +#include "qemu-log.h"
  25 +
  26 +#ifdef DEBUG_PCI
  27 +#define pci_debug(fmt, arg...) fprintf(stderr, fmt, ##arg)
  28 +#else
  29 +#define pci_debug(fmt, arg...)
  30 +#endif
  31 +
  32 +#define PCIE500_CFGADDR 0x0
  33 +#define PCIE500_CFGDATA 0x4
  34 +#define PCIE500_REG_BASE 0xC00
  35 +#define PCIE500_REG_SIZE (0x1000 - PCIE500_REG_BASE)
  36 +
  37 +#define PPCE500_PCI_CONFIG_ADDR 0x0
  38 +#define PPCE500_PCI_CONFIG_DATA 0x4
  39 +#define PPCE500_PCI_INTACK 0x8
  40 +
  41 +#define PPCE500_PCI_OW1 (0xC20 - PCIE500_REG_BASE)
  42 +#define PPCE500_PCI_OW2 (0xC40 - PCIE500_REG_BASE)
  43 +#define PPCE500_PCI_OW3 (0xC60 - PCIE500_REG_BASE)
  44 +#define PPCE500_PCI_OW4 (0xC80 - PCIE500_REG_BASE)
  45 +#define PPCE500_PCI_IW3 (0xDA0 - PCIE500_REG_BASE)
  46 +#define PPCE500_PCI_IW2 (0xDC0 - PCIE500_REG_BASE)
  47 +#define PPCE500_PCI_IW1 (0xDE0 - PCIE500_REG_BASE)
  48 +
  49 +#define PPCE500_PCI_GASKET_TIMR (0xE20 - PCIE500_REG_BASE)
  50 +
  51 +#define PCI_POTAR 0x0
  52 +#define PCI_POTEAR 0x4
  53 +#define PCI_POWBAR 0x8
  54 +#define PCI_POWAR 0x10
  55 +
  56 +#define PCI_PITAR 0x0
  57 +#define PCI_PIWBAR 0x8
  58 +#define PCI_PIWBEAR 0xC
  59 +#define PCI_PIWAR 0x10
  60 +
  61 +#define PPCE500_PCI_NR_POBS 5
  62 +#define PPCE500_PCI_NR_PIBS 3
  63 +
  64 +struct pci_outbound {
  65 + uint32_t potar;
  66 + uint32_t potear;
  67 + uint32_t powbar;
  68 + uint32_t powar;
  69 +};
  70 +
  71 +struct pci_inbound {
  72 + uint32_t pitar;
  73 + uint32_t piwbar;
  74 + uint32_t piwbear;
  75 + uint32_t piwar;
  76 +};
  77 +
  78 +struct PPCE500PCIState {
  79 + struct pci_outbound pob[PPCE500_PCI_NR_POBS];
  80 + struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
  81 + uint32_t gasket_time;
  82 + PCIHostState pci_state;
  83 + PCIDevice *pci_dev;
  84 +};
  85 +
  86 +typedef struct PPCE500PCIState PPCE500PCIState;
  87 +
  88 +static uint32_t pcie500_cfgaddr_readl(void *opaque, target_phys_addr_t addr)
  89 +{
  90 + PPCE500PCIState *pci = opaque;
  91 +
  92 + pci_debug("%s: (addr:%Lx) -> value:%x\n", __func__, addr,
  93 + pci->pci_state.config_reg);
  94 + return pci->pci_state.config_reg;
  95 +}
  96 +
  97 +static CPUReadMemoryFunc *pcie500_cfgaddr_read[] = {
  98 + &pcie500_cfgaddr_readl,
  99 + &pcie500_cfgaddr_readl,
  100 + &pcie500_cfgaddr_readl,
  101 +};
  102 +
  103 +static void pcie500_cfgaddr_writel(void *opaque, target_phys_addr_t addr,
  104 + uint32_t value)
  105 +{
  106 + PPCE500PCIState *controller = opaque;
  107 +
  108 + pci_debug("%s: value:%x -> (addr%Lx)\n", __func__, value, addr);
  109 + controller->pci_state.config_reg = value & ~0x3;
  110 +}
  111 +
  112 +static CPUWriteMemoryFunc *pcie500_cfgaddr_write[] = {
  113 + &pcie500_cfgaddr_writel,
  114 + &pcie500_cfgaddr_writel,
  115 + &pcie500_cfgaddr_writel,
  116 +};
  117 +
  118 +static CPUReadMemoryFunc *pcie500_cfgdata_read[] = {
  119 + &pci_host_data_readb,
  120 + &pci_host_data_readw,
  121 + &pci_host_data_readl,
  122 +};
  123 +
  124 +static CPUWriteMemoryFunc *pcie500_cfgdata_write[] = {
  125 + &pci_host_data_writeb,
  126 + &pci_host_data_writew,
  127 + &pci_host_data_writel,
  128 +};
  129 +
  130 +static uint32_t pci_reg_read4(void *opaque, target_phys_addr_t addr)
  131 +{
  132 + PPCE500PCIState *pci = opaque;
  133 + unsigned long win;
  134 + uint32_t value = 0;
  135 +
  136 + win = addr & 0xfe0;
  137 +
  138 + switch (win) {
  139 + case PPCE500_PCI_OW1:
  140 + case PPCE500_PCI_OW2:
  141 + case PPCE500_PCI_OW3:
  142 + case PPCE500_PCI_OW4:
  143 + switch (addr & 0xC) {
  144 + case PCI_POTAR: value = pci->pob[(addr >> 5) & 0x7].potar; break;
  145 + case PCI_POTEAR: value = pci->pob[(addr >> 5) & 0x7].potear; break;
  146 + case PCI_POWBAR: value = pci->pob[(addr >> 5) & 0x7].powbar; break;
  147 + case PCI_POWAR: value = pci->pob[(addr >> 5) & 0x7].powar; break;
  148 + default: break;
  149 + }
  150 + break;
  151 +
  152 + case PPCE500_PCI_IW3:
  153 + case PPCE500_PCI_IW2:
  154 + case PPCE500_PCI_IW1:
  155 + switch (addr & 0xC) {
  156 + case PCI_PITAR: value = pci->pib[(addr >> 5) & 0x3].pitar; break;
  157 + case PCI_PIWBAR: value = pci->pib[(addr >> 5) & 0x3].piwbar; break;
  158 + case PCI_PIWBEAR: value = pci->pib[(addr >> 5) & 0x3].piwbear; break;
  159 + case PCI_PIWAR: value = pci->pib[(addr >> 5) & 0x3].piwar; break;
  160 + default: break;
  161 + };
  162 + break;
  163 +
  164 + case PPCE500_PCI_GASKET_TIMR:
  165 + value = pci->gasket_time;
  166 + break;
  167 +
  168 + default:
  169 + break;
  170 + }
  171 +
  172 + pci_debug("%s: win:%lx(addr:%Lx) -> value:%x\n",__func__,win,addr,value);
  173 + return value;
  174 +}
  175 +
  176 +static CPUReadMemoryFunc *e500_pci_reg_read[] = {
  177 + &pci_reg_read4,
  178 + &pci_reg_read4,
  179 + &pci_reg_read4,
  180 +};
  181 +
  182 +static void pci_reg_write4(void *opaque, target_phys_addr_t addr,
  183 + uint32_t value)
  184 +{
  185 + PPCE500PCIState *pci = opaque;
  186 + unsigned long win;
  187 +
  188 + win = addr & 0xfe0;
  189 +
  190 + pci_debug("%s: value:%x -> win:%lx(addr:%Lx)\n",__func__,value,win,addr);
  191 +
  192 + switch (win) {
  193 + case PPCE500_PCI_OW1:
  194 + case PPCE500_PCI_OW2:
  195 + case PPCE500_PCI_OW3:
  196 + case PPCE500_PCI_OW4:
  197 + switch (addr & 0xC) {
  198 + case PCI_POTAR: pci->pob[(addr >> 5) & 0x7].potar = value; break;
  199 + case PCI_POTEAR: pci->pob[(addr >> 5) & 0x7].potear = value; break;
  200 + case PCI_POWBAR: pci->pob[(addr >> 5) & 0x7].powbar = value; break;
  201 + case PCI_POWAR: pci->pob[(addr >> 5) & 0x7].powar = value; break;
  202 + default: break;
  203 + };
  204 + break;
  205 +
  206 + case PPCE500_PCI_IW3:
  207 + case PPCE500_PCI_IW2:
  208 + case PPCE500_PCI_IW1:
  209 + switch (addr & 0xC) {
  210 + case PCI_PITAR: pci->pib[(addr >> 5) & 0x3].pitar = value; break;
  211 + case PCI_PIWBAR: pci->pib[(addr >> 5) & 0x3].piwbar = value; break;
  212 + case PCI_PIWBEAR: pci->pib[(addr >> 5) & 0x3].piwbear = value; break;
  213 + case PCI_PIWAR: pci->pib[(addr >> 5) & 0x3].piwar = value; break;
  214 + default: break;
  215 + };
  216 + break;
  217 +
  218 + case PPCE500_PCI_GASKET_TIMR:
  219 + pci->gasket_time = value;
  220 + break;
  221 +
  222 + default:
  223 + break;
  224 + };
  225 +}
  226 +
  227 +static CPUWriteMemoryFunc *e500_pci_reg_write[] = {
  228 + &pci_reg_write4,
  229 + &pci_reg_write4,
  230 + &pci_reg_write4,
  231 +};
  232 +
  233 +static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
  234 +{
  235 + int devno = pci_dev->devfn >> 3, ret = 0;
  236 +
  237 + switch (devno) {
  238 + /* Two PCI slot */
  239 + case 0x11:
  240 + case 0x12:
  241 + ret = (irq_num + devno - 0x10) % 4;
  242 + break;
  243 + default:
  244 + printf("Error:%s:unknow dev number\n", __func__);
  245 + }
  246 +
  247 + pci_debug("%s: devfn %x irq %d -> %d devno:%x\n", __func__,
  248 + pci_dev->devfn, irq_num, ret, devno);
  249 +
  250 + return ret;
  251 +}
  252 +
  253 +static void mpc85xx_pci_set_irq(qemu_irq *pic, int irq_num, int level)
  254 +{
  255 + pci_debug("%s: PCI irq %d, level:%d\n", __func__, irq_num, level);
  256 +
  257 + qemu_set_irq(pic[irq_num], level);
  258 +}
  259 +
  260 +static void ppce500_pci_save(QEMUFile *f, void *opaque)
  261 +{
  262 + PPCE500PCIState *controller = opaque;
  263 + int i;
  264 +
  265 + pci_device_save(controller->pci_dev, f);
  266 +
  267 + for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
  268 + qemu_put_be32s(f, &controller->pob[i].potar);
  269 + qemu_put_be32s(f, &controller->pob[i].potear);
  270 + qemu_put_be32s(f, &controller->pob[i].powbar);
  271 + qemu_put_be32s(f, &controller->pob[i].powar);
  272 + }
  273 +
  274 + for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
  275 + qemu_put_be32s(f, &controller->pib[i].pitar);
  276 + qemu_put_be32s(f, &controller->pib[i].piwbar);
  277 + qemu_put_be32s(f, &controller->pib[i].piwbear);
  278 + qemu_put_be32s(f, &controller->pib[i].piwar);
  279 + }
  280 + qemu_put_be32s(f, &controller->gasket_time);
  281 +}
  282 +
  283 +static int ppce500_pci_load(QEMUFile *f, void *opaque, int version_id)
  284 +{
  285 + PPCE500PCIState *controller = opaque;
  286 + int i;
  287 +
  288 + if (version_id != 1)
  289 + return -EINVAL;
  290 +
  291 + pci_device_load(controller->pci_dev, f);
  292 +
  293 + for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
  294 + qemu_get_be32s(f, &controller->pob[i].potar);
  295 + qemu_get_be32s(f, &controller->pob[i].potear);
  296 + qemu_get_be32s(f, &controller->pob[i].powbar);
  297 + qemu_get_be32s(f, &controller->pob[i].powar);
  298 + }
  299 +
  300 + for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
  301 + qemu_get_be32s(f, &controller->pib[i].pitar);
  302 + qemu_get_be32s(f, &controller->pib[i].piwbar);
  303 + qemu_get_be32s(f, &controller->pib[i].piwbear);
  304 + qemu_get_be32s(f, &controller->pib[i].piwar);
  305 + }
  306 + qemu_get_be32s(f, &controller->gasket_time);
  307 +
  308 + return 0;
  309 +}
  310 +
  311 +PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
  312 +{
  313 + PPCE500PCIState *controller;
  314 + PCIDevice *d;
  315 + int index;
  316 + static int ppce500_pci_id;
  317 +
  318 + controller = qemu_mallocz(sizeof(PPCE500PCIState));
  319 +
  320 + controller->pci_state.bus = pci_register_bus(mpc85xx_pci_set_irq,
  321 + mpc85xx_pci_map_irq,
  322 + pci_irqs, 0x88, 4);
  323 + d = pci_register_device(controller->pci_state.bus,
  324 + "host bridge", sizeof(PCIDevice),
  325 + 0, NULL, NULL);
  326 +
  327 + pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_FSL);
  328 + pci_config_set_device_id(d->config, PCI_DEVICE_ID_FSL_E500);
  329 + pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_POWERPC);
  330 +
  331 + controller->pci_dev = d;
  332 +
  333 + /* CFGADDR */
  334 + index = cpu_register_io_memory(0, pcie500_cfgaddr_read,
  335 + pcie500_cfgaddr_write, controller);
  336 + if (index < 0)
  337 + goto free;
  338 + cpu_register_physical_memory(registers + PCIE500_CFGADDR, 4, index);
  339 +
  340 + /* CFGDATA */
  341 + index = cpu_register_io_memory(0, pcie500_cfgdata_read,
  342 + pcie500_cfgdata_write,
  343 + &controller->pci_state);
  344 + if (index < 0)
  345 + goto free;
  346 + cpu_register_physical_memory(registers + PCIE500_CFGDATA, 4, index);
  347 +
  348 + index = cpu_register_io_memory(0, e500_pci_reg_read,
  349 + e500_pci_reg_write, controller);
  350 + if (index < 0)
  351 + goto free;
  352 + cpu_register_physical_memory(registers + PCIE500_REG_BASE,
  353 + PCIE500_REG_SIZE, index);
  354 +
  355 + /* XXX load/save code not tested. */
  356 + register_savevm("ppce500_pci", ppce500_pci_id++, 1,
  357 + ppce500_pci_save, ppce500_pci_load, controller);
  358 +
  359 + return controller->pci_state.bus;
  360 +
  361 +free:
  362 + printf("%s error\n", __func__);
  363 + qemu_free(controller);
  364 + return NULL;
  365 +}
... ...