prep_pci.c 5.1 KB
Newer Older
P
pbrook 已提交
1 2 3 4
/*
 * QEMU PREP PCI host
 *
 * Copyright (c) 2006 Fabrice Bellard
5
 *
P
pbrook 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

P
pbrook 已提交
25 26 27
#include "hw.h"
#include "pci.h"

M
malc 已提交
28
typedef uint32_t a_pci_addr;
P
pbrook 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
#include "pci_host.h"

typedef PCIHostState PREPPCIState;

static void pci_prep_addr_writel(void* opaque, uint32_t addr, uint32_t val)
{
    PREPPCIState *s = opaque;
    s->config_reg = val;
}

static uint32_t pci_prep_addr_readl(void* opaque, uint32_t addr)
{
    PREPPCIState *s = opaque;
    return s->config_reg;
}

M
malc 已提交
45
static inline uint32_t PPC_PCIIO_config(a_target_phys_addr addr)
P
pbrook 已提交
46 47 48 49 50 51 52 53 54 55
{
    int i;

    for(i = 0; i < 11; i++) {
        if ((addr & (1 << (11 + i))) != 0)
            break;
    }
    return (addr & 0x7ff) |  (i << 11);
}

M
malc 已提交
56
static void PPC_PCIIO_writeb (void *opaque, a_target_phys_addr addr, uint32_t val)
P
pbrook 已提交
57 58 59 60 61
{
    PREPPCIState *s = opaque;
    pci_data_write(s->bus, PPC_PCIIO_config(addr), val, 1);
}

M
malc 已提交
62
static void PPC_PCIIO_writew (void *opaque, a_target_phys_addr addr, uint32_t val)
P
pbrook 已提交
63 64 65 66 67 68 69 70
{
    PREPPCIState *s = opaque;
#ifdef TARGET_WORDS_BIGENDIAN
    val = bswap16(val);
#endif
    pci_data_write(s->bus, PPC_PCIIO_config(addr), val, 2);
}

M
malc 已提交
71
static void PPC_PCIIO_writel (void *opaque, a_target_phys_addr addr, uint32_t val)
P
pbrook 已提交
72 73 74 75 76 77 78 79
{
    PREPPCIState *s = opaque;
#ifdef TARGET_WORDS_BIGENDIAN
    val = bswap32(val);
#endif
    pci_data_write(s->bus, PPC_PCIIO_config(addr), val, 4);
}

M
malc 已提交
80
static uint32_t PPC_PCIIO_readb (void *opaque, a_target_phys_addr addr)
P
pbrook 已提交
81 82 83 84 85 86 87
{
    PREPPCIState *s = opaque;
    uint32_t val;
    val = pci_data_read(s->bus, PPC_PCIIO_config(addr), 1);
    return val;
}

M
malc 已提交
88
static uint32_t PPC_PCIIO_readw (void *opaque, a_target_phys_addr addr)
P
pbrook 已提交
89 90 91 92 93 94 95 96 97 98
{
    PREPPCIState *s = opaque;
    uint32_t val;
    val = pci_data_read(s->bus, PPC_PCIIO_config(addr), 2);
#ifdef TARGET_WORDS_BIGENDIAN
    val = bswap16(val);
#endif
    return val;
}

M
malc 已提交
99
static uint32_t PPC_PCIIO_readl (void *opaque, a_target_phys_addr addr)
P
pbrook 已提交
100 101 102 103 104 105 106 107 108 109
{
    PREPPCIState *s = opaque;
    uint32_t val;
    val = pci_data_read(s->bus, PPC_PCIIO_config(addr), 4);
#ifdef TARGET_WORDS_BIGENDIAN
    val = bswap32(val);
#endif
    return val;
}

110
static CPUWriteMemoryFunc * const PPC_PCIIO_write[] = {
P
pbrook 已提交
111 112 113 114 115
    &PPC_PCIIO_writeb,
    &PPC_PCIIO_writew,
    &PPC_PCIIO_writel,
};

116
static CPUReadMemoryFunc * const PPC_PCIIO_read[] = {
P
pbrook 已提交
117 118 119 120 121
    &PPC_PCIIO_readb,
    &PPC_PCIIO_readw,
    &PPC_PCIIO_readl,
};

122
static int prep_map_irq(PCIDevice *pci_dev, int irq_num)
P
pbrook 已提交
123
{
P
pbrook 已提交
124
    return (irq_num + (pci_dev->devfn >> 3)) & 1;
125 126
}

127
static void prep_set_irq(void *opaque, int irq_num, int level)
128
{
129 130
    qemu_irq *pic = opaque;

J
j_mayer 已提交
131
    qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level);
P
pbrook 已提交
132 133
}

P
pbrook 已提交
134
PCIBus *pci_prep_init(qemu_irq *pic)
P
pbrook 已提交
135 136 137 138 139 140
{
    PREPPCIState *s;
    PCIDevice *d;
    int PPC_io_memory;

    s = qemu_mallocz(sizeof(PREPPCIState));
P
Paul Brook 已提交
141 142
    s->bus = pci_register_bus(NULL, "pci",
                              prep_set_irq, prep_map_irq, pic, 0, 4);
P
pbrook 已提交
143 144 145 146 147 148 149 150 151 152 153

    register_ioport_write(0xcf8, 4, 4, pci_prep_addr_writel, s);
    register_ioport_read(0xcf8, 4, 4, pci_prep_addr_readl, s);

    register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);
    register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s);
    register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s);
    register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);
    register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
    register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);

154
    PPC_io_memory = cpu_register_io_memory(PPC_PCIIO_read,
P
pbrook 已提交
155 156 157
                                           PPC_PCIIO_write, s);
    cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);

158 159
    /* PCI host bridge */
    d = pci_register_device(s->bus, "PREP Host Bridge - Motorola Raven",
P
pbrook 已提交
160
                            sizeof(PCIDevice), 0, NULL, NULL);
161 162
    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_MOTOROLA);
    pci_config_set_device_id(d->config, PCI_DEVICE_ID_MOTOROLA_RAVEN);
P
pbrook 已提交
163
    d->config[0x08] = 0x00; // revision
164
    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
P
pbrook 已提交
165 166
    d->config[0x0C] = 0x08; // cache_line_size
    d->config[0x0D] = 0x10; // latency_timer
I
Isaku Yamahata 已提交
167
    d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
P
pbrook 已提交
168 169 170 171
    d->config[0x34] = 0x00; // capabilities_pointer

    return s->bus;
}