File:  [Qemu by Fabrice Bellard] / qemu / hw / versatile_pci.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:52:35 2018 UTC (2 years, 6 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0105, qemu0104, qemu0103, qemu0102, qemu0101, qemu0100, HEAD
qemu 0.10.0

    1: /*
    2:  * ARM Versatile/PB PCI host controller
    3:  *
    4:  * Copyright (c) 2006 CodeSourcery.
    5:  * Written by Paul Brook
    6:  *
    7:  * This code is licenced under the LGPL.
    8:  */
    9: 
   10: #include "hw.h"
   11: #include "pci.h"
   12: #include "primecell.h"
   13: 
   14: static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr)
   15: {
   16:     return addr & 0xffffff;
   17: }
   18: 
   19: static void pci_vpb_config_writeb (void *opaque, target_phys_addr_t addr,
   20:                                    uint32_t val)
   21: {
   22:     pci_data_write(opaque, vpb_pci_config_addr (addr), val, 1);
   23: }
   24: 
   25: static void pci_vpb_config_writew (void *opaque, target_phys_addr_t addr,
   26:                                    uint32_t val)
   27: {
   28: #ifdef TARGET_WORDS_BIGENDIAN
   29:     val = bswap16(val);
   30: #endif
   31:     pci_data_write(opaque, vpb_pci_config_addr (addr), val, 2);
   32: }
   33: 
   34: static void pci_vpb_config_writel (void *opaque, target_phys_addr_t addr,
   35:                                    uint32_t val)
   36: {
   37: #ifdef TARGET_WORDS_BIGENDIAN
   38:     val = bswap32(val);
   39: #endif
   40:     pci_data_write(opaque, vpb_pci_config_addr (addr), val, 4);
   41: }
   42: 
   43: static uint32_t pci_vpb_config_readb (void *opaque, target_phys_addr_t addr)
   44: {
   45:     uint32_t val;
   46:     val = pci_data_read(opaque, vpb_pci_config_addr (addr), 1);
   47:     return val;
   48: }
   49: 
   50: static uint32_t pci_vpb_config_readw (void *opaque, target_phys_addr_t addr)
   51: {
   52:     uint32_t val;
   53:     val = pci_data_read(opaque, vpb_pci_config_addr (addr), 2);
   54: #ifdef TARGET_WORDS_BIGENDIAN
   55:     val = bswap16(val);
   56: #endif
   57:     return val;
   58: }
   59: 
   60: static uint32_t pci_vpb_config_readl (void *opaque, target_phys_addr_t addr)
   61: {
   62:     uint32_t val;
   63:     val = pci_data_read(opaque, vpb_pci_config_addr (addr), 4);
   64: #ifdef TARGET_WORDS_BIGENDIAN
   65:     val = bswap32(val);
   66: #endif
   67:     return val;
   68: }
   69: 
   70: static CPUWriteMemoryFunc *pci_vpb_config_write[] = {
   71:     &pci_vpb_config_writeb,
   72:     &pci_vpb_config_writew,
   73:     &pci_vpb_config_writel,
   74: };
   75: 
   76: static CPUReadMemoryFunc *pci_vpb_config_read[] = {
   77:     &pci_vpb_config_readb,
   78:     &pci_vpb_config_readw,
   79:     &pci_vpb_config_readl,
   80: };
   81: 
   82: static int pci_vpb_irq;
   83: 
   84: static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
   85: {
   86:     return irq_num;
   87: }
   88: 
   89: static void pci_vpb_set_irq(qemu_irq *pic, int irq_num, int level)
   90: {
   91:     qemu_set_irq(pic[pci_vpb_irq + irq_num], level);
   92: }
   93: 
   94: PCIBus *pci_vpb_init(qemu_irq *pic, int irq, int realview)
   95: {
   96:     PCIBus *s;
   97:     PCIDevice *d;
   98:     int mem_config;
   99:     uint32_t base;
  100:     const char * name;
  101: 
  102:     pci_vpb_irq = irq;
  103:     if (realview) {
  104:         base = 0x60000000;
  105:         name = "RealView EB PCI Controller";
  106:     } else {
  107:         base = 0x40000000;
  108:         name = "Versatile/PB PCI Controller";
  109:     }
  110:     s = pci_register_bus(pci_vpb_set_irq, pci_vpb_map_irq, pic, 11 << 3, 4);
  111:     /* ??? Register memory space.  */
  112: 
  113:     mem_config = cpu_register_io_memory(0, pci_vpb_config_read,
  114:                                         pci_vpb_config_write, s);
  115:     /* Selfconfig area.  */
  116:     cpu_register_physical_memory(base + 0x01000000, 0x1000000, mem_config);
  117:     /* Normal config area.  */
  118:     cpu_register_physical_memory(base + 0x02000000, 0x1000000, mem_config);
  119: 
  120:     d = pci_register_device(s, name, sizeof(PCIDevice), -1, NULL, NULL);
  121: 
  122:     if (realview) {
  123:         /* IO memory area.  */
  124:         isa_mmio_init(base + 0x03000000, 0x00100000);
  125:     }
  126: 
  127:     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_XILINX);
  128:     /* Both boards have the same device ID.  Oh well.  */
  129:     pci_config_set_device_id(d->config, 0x0300); // device_id
  130:     d->config[0x04] = 0x00;
  131:     d->config[0x05] = 0x00;
  132:     d->config[0x06] = 0x20;
  133:     d->config[0x07] = 0x02;
  134:     d->config[0x08] = 0x00; // revision
  135:     d->config[0x09] = 0x00; // programming i/f
  136:     pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_CO);
  137:     d->config[0x0D] = 0x10; // latency_timer
  138: 
  139:     return s;
  140: }

unix.superglobalmegacorp.com