Commit 1e5459a3fa01824c18272fb840f43e3c138dee76

Authored by balrog
1 parent d47ede60

SH: On-chip PCI controller support (Takashi YOSHII).

This patch adds SuperH on-chip PCI controller(PCIC) support.

Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>
Signed-off-by: Andrzej Zaborowski <andrew.zaborowski@intel.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5927 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -710,7 +710,7 @@ CPPFLAGS += -DHAS_AUDIO
710 710 endif
711 711 ifeq ($(TARGET_BASE_ARCH), sh4)
712 712 OBJS+= shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
713   -OBJS+= sh_timer.o ptimer.o sh_serial.o sh_intc.o sm501.o serial.o
  713 +OBJS+= sh_timer.o ptimer.o sh_serial.o sh_intc.o sh_pci.o sm501.o serial.o
714 714 OBJS+= ide.o
715 715 endif
716 716 ifeq ($(TARGET_BASE_ARCH), m68k)
... ...
hw/sh_pci.c 0 → 100644
  1 +/*
  2 + * SuperH on-chip PCIC emulation.
  3 + *
  4 + * Copyright (c) 2008 Takashi YOSHII
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "hw.h"
  25 +#include "sh.h"
  26 +#include "pci.h"
  27 +#include "bswap.h"
  28 +
  29 +typedef struct {
  30 + PCIBus *bus;
  31 + PCIDevice *dev;
  32 + uint32_t regbase;
  33 + uint32_t iopbase;
  34 + uint32_t membase;
  35 + uint32_t par;
  36 + uint32_t mbr;
  37 + uint32_t iobr;
  38 +} SHPCIC;
  39 +
  40 +static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val)
  41 +{
  42 + SHPCIC *pcic = p;
  43 + addr -= pcic->regbase;
  44 + switch(addr) {
  45 + case 0 ... 0xfc:
  46 + cpu_to_le32w((uint32_t*)(pcic->dev->config + addr), val);
  47 + break;
  48 + case 0x1c0:
  49 + pcic->par = val;
  50 + break;
  51 + case 0x1c4:
  52 + pcic->mbr = val;
  53 + break;
  54 + case 0x1c8:
  55 + pcic->iobr = val;
  56 + break;
  57 + case 0x220:
  58 + pci_data_write(pcic->bus, pcic->par, val, 4);
  59 + break;
  60 + }
  61 +}
  62 +
  63 +static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr)
  64 +{
  65 + SHPCIC *pcic = p;
  66 + addr -= pcic->regbase;
  67 + switch(addr) {
  68 + case 0 ... 0xfc:
  69 + return le32_to_cpup((uint32_t*)(pcic->dev->config + addr));
  70 + case 0x1c0:
  71 + return pcic->par;
  72 + case 0x220:
  73 + return pci_data_read(pcic->bus, pcic->par, 4);
  74 + }
  75 + return 0;
  76 +}
  77 +
  78 +static void sh_pci_data_write (SHPCIC *pcic, target_phys_addr_t addr,
  79 + uint32_t val, int size)
  80 +{
  81 + pci_data_write(pcic->bus, addr - pcic->membase + pcic->mbr, val, size);
  82 +}
  83 +
  84 +static uint32_t sh_pci_mem_read (SHPCIC *pcic, target_phys_addr_t addr,
  85 + int size)
  86 +{
  87 + return pci_data_read(pcic->bus, addr - pcic->membase + pcic->mbr, size);
  88 +}
  89 +
  90 +static void sh_pci_writeb (void *p, target_phys_addr_t addr, uint32_t val)
  91 +{
  92 + sh_pci_data_write(p, addr, val, 1);
  93 +}
  94 +
  95 +static void sh_pci_writew (void *p, target_phys_addr_t addr, uint32_t val)
  96 +{
  97 + sh_pci_data_write(p, addr, val, 2);
  98 +}
  99 +
  100 +static void sh_pci_writel (void *p, target_phys_addr_t addr, uint32_t val)
  101 +{
  102 + sh_pci_data_write(p, addr, val, 4);
  103 +}
  104 +
  105 +static uint32_t sh_pci_readb (void *p, target_phys_addr_t addr)
  106 +{
  107 + return sh_pci_mem_read(p, addr, 1);
  108 +}
  109 +
  110 +static uint32_t sh_pci_readw (void *p, target_phys_addr_t addr)
  111 +{
  112 + return sh_pci_mem_read(p, addr, 2);
  113 +}
  114 +
  115 +static uint32_t sh_pci_readl (void *p, target_phys_addr_t addr)
  116 +{
  117 + return sh_pci_mem_read(p, addr, 4);
  118 +}
  119 +
  120 +static int sh_pci_addr2port(SHPCIC *pcic, target_phys_addr_t addr)
  121 +{
  122 + return addr - pcic->iopbase + pcic->iobr;
  123 +}
  124 +
  125 +static void sh_pci_outb (void *p, target_phys_addr_t addr, uint32_t val)
  126 +{
  127 + cpu_outb(NULL, sh_pci_addr2port(p, addr), val);
  128 +}
  129 +
  130 +static void sh_pci_outw (void *p, target_phys_addr_t addr, uint32_t val)
  131 +{
  132 + cpu_outw(NULL, sh_pci_addr2port(p, addr), val);
  133 +}
  134 +
  135 +static void sh_pci_outl (void *p, target_phys_addr_t addr, uint32_t val)
  136 +{
  137 + cpu_outl(NULL, sh_pci_addr2port(p, addr), val);
  138 +}
  139 +
  140 +static uint32_t sh_pci_inb (void *p, target_phys_addr_t addr)
  141 +{
  142 + return cpu_inb(NULL, sh_pci_addr2port(p, addr));
  143 +}
  144 +
  145 +static uint32_t sh_pci_inw (void *p, target_phys_addr_t addr)
  146 +{
  147 + return cpu_inw(NULL, sh_pci_addr2port(p, addr));
  148 +}
  149 +
  150 +static uint32_t sh_pci_inl (void *p, target_phys_addr_t addr)
  151 +{
  152 + return cpu_inl(NULL, sh_pci_addr2port(p, addr));
  153 +}
  154 +
  155 +typedef struct {
  156 + CPUReadMemoryFunc *r[3];
  157 + CPUWriteMemoryFunc *w[3];
  158 +} MemOp;
  159 +
  160 +static MemOp sh_pci_reg = {
  161 + { NULL, NULL, sh_pci_reg_read },
  162 + { NULL, NULL, sh_pci_reg_write },
  163 +};
  164 +
  165 +static MemOp sh_pci_mem = {
  166 + { sh_pci_readb, sh_pci_readw, sh_pci_readl },
  167 + { sh_pci_writeb, sh_pci_writew, sh_pci_writel },
  168 +};
  169 +
  170 +static MemOp sh_pci_iop = {
  171 + { sh_pci_inb, sh_pci_inw, sh_pci_inl },
  172 + { sh_pci_outb, sh_pci_outw, sh_pci_outl },
  173 +};
  174 +
  175 +PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
  176 + qemu_irq *pic, int devfn_min, int nirq)
  177 +{
  178 + SHPCIC *p;
  179 + int mem, reg, iop;
  180 +
  181 + p = qemu_mallocz(sizeof(SHPCIC));
  182 + p->bus = pci_register_bus(set_irq, map_irq, pic, devfn_min, nirq);
  183 +
  184 + p->dev = pci_register_device(p->bus, "SH PCIC", sizeof(PCIDevice),
  185 + -1, NULL, NULL);
  186 + p->regbase = 0x1e200000;
  187 + p->iopbase = 0x1e240000;
  188 + p->membase = 0xfd000000;
  189 + reg = cpu_register_io_memory(0, sh_pci_reg.r, sh_pci_reg.w, p);
  190 + mem = cpu_register_io_memory(0, sh_pci_mem.r, sh_pci_mem.w, p);
  191 + iop = cpu_register_io_memory(0, sh_pci_iop.r, sh_pci_iop.w, p);
  192 + cpu_register_physical_memory(p->regbase, 0x224, reg);
  193 + cpu_register_physical_memory(p->iopbase, 0x40000, iop);
  194 + cpu_register_physical_memory(p->membase, 0x1000000, mem);
  195 +
  196 + p->dev->config[0x00] = 0x54; // HITACHI
  197 + p->dev->config[0x01] = 0x10; //
  198 + p->dev->config[0x02] = 0x0e; // SH7751R
  199 + p->dev->config[0x03] = 0x35; //
  200 + p->dev->config[0x04] = 0x80;
  201 + p->dev->config[0x05] = 0x00;
  202 + p->dev->config[0x06] = 0x90;
  203 + p->dev->config[0x07] = 0x02;
  204 +
  205 + return p->bus;
  206 +}
  207 +
... ...
target-sh4/helper.c
... ... @@ -439,6 +439,9 @@ int get_physical_address(CPUState * env, target_ulong * physical,
439 439 if (address >= 0x80000000 && address < 0xc0000000) {
440 440 /* Mask upper 3 bits for P1 and P2 areas */
441 441 *physical = address & 0x1fffffff;
  442 + } else if (address >= 0xfd000000 && address < 0xfe000000) {
  443 + /* PCI memory space */
  444 + *physical = address;
442 445 } else if (address >= 0xfc000000) {
443 446 /*
444 447 * Mask upper 3 bits for control registers in P4 area,
... ...