Statistics
| Branch: | Revision:

root / hw / pci.c @ 89344d5a

History | View | Annotate | Download (42.3 kB)

1 69b91039 bellard
/*
2 69b91039 bellard
 * QEMU PCI bus manager
3 69b91039 bellard
 *
4 69b91039 bellard
 * Copyright (c) 2004 Fabrice Bellard
5 69b91039 bellard
 * 
6 69b91039 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 69b91039 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 69b91039 bellard
 * in the Software without restriction, including without limitation the rights
9 69b91039 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 69b91039 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 69b91039 bellard
 * furnished to do so, subject to the following conditions:
12 69b91039 bellard
 *
13 69b91039 bellard
 * The above copyright notice and this permission notice shall be included in
14 69b91039 bellard
 * all copies or substantial portions of the Software.
15 69b91039 bellard
 *
16 69b91039 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 69b91039 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 69b91039 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 69b91039 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 69b91039 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 69b91039 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 69b91039 bellard
 * THE SOFTWARE.
23 69b91039 bellard
 */
24 69b91039 bellard
#include "vl.h"
25 69b91039 bellard
26 69b91039 bellard
//#define DEBUG_PCI
27 69b91039 bellard
28 0ac32c83 bellard
#define PCI_VENDOR_ID                0x00        /* 16 bits */
29 0ac32c83 bellard
#define PCI_DEVICE_ID                0x02        /* 16 bits */
30 0ac32c83 bellard
#define PCI_COMMAND                0x04        /* 16 bits */
31 0ac32c83 bellard
#define  PCI_COMMAND_IO                0x1        /* Enable response in I/O space */
32 0ac32c83 bellard
#define  PCI_COMMAND_MEMORY        0x2        /* Enable response in Memory space */
33 0ac32c83 bellard
#define PCI_CLASS_DEVICE        0x0a    /* Device class */
34 0ac32c83 bellard
#define PCI_INTERRUPT_LINE        0x3c        /* 8 bits */
35 0ac32c83 bellard
#define PCI_INTERRUPT_PIN        0x3d        /* 8 bits */
36 0ac32c83 bellard
#define PCI_MIN_GNT                0x3e        /* 8 bits */
37 0ac32c83 bellard
#define PCI_MAX_LAT                0x3f        /* 8 bits */
38 0ac32c83 bellard
39 0ac32c83 bellard
/* just used for simpler irq handling. */
40 0ac32c83 bellard
#define PCI_DEVICES_MAX 64
41 0ac32c83 bellard
#define PCI_IRQ_WORDS   ((PCI_DEVICES_MAX + 31) / 32)
42 0ac32c83 bellard
43 30468f78 bellard
struct PCIBus {
44 30468f78 bellard
    int bus_num;
45 30468f78 bellard
    int devfn_min;
46 30468f78 bellard
    void (*set_irq)(PCIDevice *pci_dev, int irq_num, int level);
47 30468f78 bellard
    uint32_t config_reg; /* XXX: suppress */
48 30468f78 bellard
    openpic_t *openpic; /* XXX: suppress */
49 30468f78 bellard
    PCIDevice *devices[256];
50 30468f78 bellard
};
51 69b91039 bellard
52 69b91039 bellard
target_phys_addr_t pci_mem_base;
53 0ac32c83 bellard
static int pci_irq_index;
54 0ac32c83 bellard
static uint32_t pci_irq_levels[4][PCI_IRQ_WORDS];
55 30468f78 bellard
static PCIBus *first_bus;
56 30468f78 bellard
57 30468f78 bellard
static PCIBus *pci_register_bus(void)
58 30468f78 bellard
{
59 30468f78 bellard
    PCIBus *bus;
60 30468f78 bellard
    bus = qemu_mallocz(sizeof(PCIBus));
61 30468f78 bellard
    first_bus = bus;
62 30468f78 bellard
    return bus;
63 30468f78 bellard
}
64 69b91039 bellard
65 30ca2aab bellard
void generic_pci_save(QEMUFile* f, void *opaque)
66 30ca2aab bellard
{
67 30ca2aab bellard
    PCIDevice* s=(PCIDevice*)opaque;
68 30ca2aab bellard
69 30ca2aab bellard
    qemu_put_buffer(f, s->config, 256);
70 30ca2aab bellard
}
71 30ca2aab bellard
72 30ca2aab bellard
int generic_pci_load(QEMUFile* f, void *opaque, int version_id)
73 30ca2aab bellard
{
74 30ca2aab bellard
    PCIDevice* s=(PCIDevice*)opaque;
75 30ca2aab bellard
76 30ca2aab bellard
    if (version_id != 1)
77 30ca2aab bellard
        return -EINVAL;
78 30ca2aab bellard
79 30ca2aab bellard
    qemu_get_buffer(f, s->config, 256);
80 30ca2aab bellard
    return 0;
81 30ca2aab bellard
}
82 30ca2aab bellard
83 69b91039 bellard
/* -1 for devfn means auto assign */
84 30468f78 bellard
PCIDevice *pci_register_device(PCIBus *bus, const char *name, 
85 30468f78 bellard
                               int instance_size, int devfn,
86 69b91039 bellard
                               PCIConfigReadFunc *config_read, 
87 69b91039 bellard
                               PCIConfigWriteFunc *config_write)
88 69b91039 bellard
{
89 30468f78 bellard
    PCIDevice *pci_dev;
90 69b91039 bellard
91 0ac32c83 bellard
    if (pci_irq_index >= PCI_DEVICES_MAX)
92 0ac32c83 bellard
        return NULL;
93 0ac32c83 bellard
    
94 69b91039 bellard
    if (devfn < 0) {
95 30468f78 bellard
        for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
96 30468f78 bellard
            if (!bus->devices[devfn])
97 69b91039 bellard
                goto found;
98 69b91039 bellard
        }
99 69b91039 bellard
        return NULL;
100 69b91039 bellard
    found: ;
101 69b91039 bellard
    }
102 69b91039 bellard
    pci_dev = qemu_mallocz(instance_size);
103 69b91039 bellard
    if (!pci_dev)
104 69b91039 bellard
        return NULL;
105 30468f78 bellard
    pci_dev->bus = bus;
106 69b91039 bellard
    pci_dev->devfn = devfn;
107 69b91039 bellard
    pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
108 0ac32c83 bellard
109 0ac32c83 bellard
    if (!config_read)
110 0ac32c83 bellard
        config_read = pci_default_read_config;
111 0ac32c83 bellard
    if (!config_write)
112 0ac32c83 bellard
        config_write = pci_default_write_config;
113 69b91039 bellard
    pci_dev->config_read = config_read;
114 69b91039 bellard
    pci_dev->config_write = config_write;
115 0ac32c83 bellard
    pci_dev->irq_index = pci_irq_index++;
116 30468f78 bellard
    bus->devices[devfn] = pci_dev;
117 69b91039 bellard
    return pci_dev;
118 69b91039 bellard
}
119 69b91039 bellard
120 69b91039 bellard
void pci_register_io_region(PCIDevice *pci_dev, int region_num, 
121 69b91039 bellard
                            uint32_t size, int type, 
122 69b91039 bellard
                            PCIMapIORegionFunc *map_func)
123 69b91039 bellard
{
124 69b91039 bellard
    PCIIORegion *r;
125 69b91039 bellard
126 8a8696a3 bellard
    if ((unsigned int)region_num >= PCI_NUM_REGIONS)
127 69b91039 bellard
        return;
128 69b91039 bellard
    r = &pci_dev->io_regions[region_num];
129 69b91039 bellard
    r->addr = -1;
130 69b91039 bellard
    r->size = size;
131 69b91039 bellard
    r->type = type;
132 69b91039 bellard
    r->map_func = map_func;
133 69b91039 bellard
}
134 69b91039 bellard
135 0ac32c83 bellard
static void pci_addr_writel(void* opaque, uint32_t addr, uint32_t val)
136 69b91039 bellard
{
137 30468f78 bellard
    PCIBus *s = opaque;
138 69b91039 bellard
    s->config_reg = val;
139 69b91039 bellard
}
140 69b91039 bellard
141 0ac32c83 bellard
static uint32_t pci_addr_readl(void* opaque, uint32_t addr)
142 69b91039 bellard
{
143 30468f78 bellard
    PCIBus *s = opaque;
144 69b91039 bellard
    return s->config_reg;
145 69b91039 bellard
}
146 69b91039 bellard
147 0ac32c83 bellard
static void pci_update_mappings(PCIDevice *d)
148 0ac32c83 bellard
{
149 0ac32c83 bellard
    PCIIORegion *r;
150 0ac32c83 bellard
    int cmd, i;
151 8a8696a3 bellard
    uint32_t last_addr, new_addr, config_ofs;
152 0ac32c83 bellard
    
153 0ac32c83 bellard
    cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
154 8a8696a3 bellard
    for(i = 0; i < PCI_NUM_REGIONS; i++) {
155 0ac32c83 bellard
        r = &d->io_regions[i];
156 8a8696a3 bellard
        if (i == PCI_ROM_SLOT) {
157 8a8696a3 bellard
            config_ofs = 0x30;
158 8a8696a3 bellard
        } else {
159 8a8696a3 bellard
            config_ofs = 0x10 + i * 4;
160 8a8696a3 bellard
        }
161 0ac32c83 bellard
        if (r->size != 0) {
162 0ac32c83 bellard
            if (r->type & PCI_ADDRESS_SPACE_IO) {
163 0ac32c83 bellard
                if (cmd & PCI_COMMAND_IO) {
164 0ac32c83 bellard
                    new_addr = le32_to_cpu(*(uint32_t *)(d->config + 
165 8a8696a3 bellard
                                                         config_ofs));
166 0ac32c83 bellard
                    new_addr = new_addr & ~(r->size - 1);
167 0ac32c83 bellard
                    last_addr = new_addr + r->size - 1;
168 0ac32c83 bellard
                    /* NOTE: we have only 64K ioports on PC */
169 0ac32c83 bellard
                    if (last_addr <= new_addr || new_addr == 0 ||
170 0ac32c83 bellard
                        last_addr >= 0x10000) {
171 0ac32c83 bellard
                        new_addr = -1;
172 0ac32c83 bellard
                    }
173 0ac32c83 bellard
                } else {
174 0ac32c83 bellard
                    new_addr = -1;
175 0ac32c83 bellard
                }
176 0ac32c83 bellard
            } else {
177 0ac32c83 bellard
                if (cmd & PCI_COMMAND_MEMORY) {
178 0ac32c83 bellard
                    new_addr = le32_to_cpu(*(uint32_t *)(d->config + 
179 8a8696a3 bellard
                                                         config_ofs));
180 8a8696a3 bellard
                    /* the ROM slot has a specific enable bit */
181 8a8696a3 bellard
                    if (i == PCI_ROM_SLOT && !(new_addr & 1))
182 8a8696a3 bellard
                        goto no_mem_map;
183 0ac32c83 bellard
                    new_addr = new_addr & ~(r->size - 1);
184 0ac32c83 bellard
                    last_addr = new_addr + r->size - 1;
185 0ac32c83 bellard
                    /* NOTE: we do not support wrapping */
186 0ac32c83 bellard
                    /* XXX: as we cannot support really dynamic
187 0ac32c83 bellard
                       mappings, we handle specific values as invalid
188 0ac32c83 bellard
                       mappings. */
189 0ac32c83 bellard
                    if (last_addr <= new_addr || new_addr == 0 ||
190 0ac32c83 bellard
                        last_addr == -1) {
191 0ac32c83 bellard
                        new_addr = -1;
192 0ac32c83 bellard
                    }
193 0ac32c83 bellard
                } else {
194 8a8696a3 bellard
                no_mem_map:
195 0ac32c83 bellard
                    new_addr = -1;
196 0ac32c83 bellard
                }
197 0ac32c83 bellard
            }
198 0ac32c83 bellard
            /* now do the real mapping */
199 0ac32c83 bellard
            if (new_addr != r->addr) {
200 0ac32c83 bellard
                if (r->addr != -1) {
201 0ac32c83 bellard
                    if (r->type & PCI_ADDRESS_SPACE_IO) {
202 0ac32c83 bellard
                        int class;
203 0ac32c83 bellard
                        /* NOTE: specific hack for IDE in PC case:
204 0ac32c83 bellard
                           only one byte must be mapped. */
205 0ac32c83 bellard
                        class = d->config[0x0a] | (d->config[0x0b] << 8);
206 0ac32c83 bellard
                        if (class == 0x0101 && r->size == 4) {
207 0ac32c83 bellard
                            isa_unassign_ioport(r->addr + 2, 1);
208 0ac32c83 bellard
                        } else {
209 0ac32c83 bellard
                            isa_unassign_ioport(r->addr, r->size);
210 0ac32c83 bellard
                        }
211 0ac32c83 bellard
                    } else {
212 0ac32c83 bellard
                        cpu_register_physical_memory(r->addr + pci_mem_base, 
213 0ac32c83 bellard
                                                     r->size, 
214 0ac32c83 bellard
                                                     IO_MEM_UNASSIGNED);
215 0ac32c83 bellard
                    }
216 0ac32c83 bellard
                }
217 0ac32c83 bellard
                r->addr = new_addr;
218 0ac32c83 bellard
                if (r->addr != -1) {
219 0ac32c83 bellard
                    r->map_func(d, i, r->addr, r->size, r->type);
220 0ac32c83 bellard
                }
221 0ac32c83 bellard
            }
222 0ac32c83 bellard
        }
223 0ac32c83 bellard
    }
224 0ac32c83 bellard
}
225 0ac32c83 bellard
226 0ac32c83 bellard
uint32_t pci_default_read_config(PCIDevice *d, 
227 0ac32c83 bellard
                                 uint32_t address, int len)
228 69b91039 bellard
{
229 0ac32c83 bellard
    uint32_t val;
230 0ac32c83 bellard
    switch(len) {
231 0ac32c83 bellard
    case 1:
232 0ac32c83 bellard
        val = d->config[address];
233 0ac32c83 bellard
        break;
234 0ac32c83 bellard
    case 2:
235 0ac32c83 bellard
        val = le16_to_cpu(*(uint16_t *)(d->config + address));
236 0ac32c83 bellard
        break;
237 0ac32c83 bellard
    default:
238 0ac32c83 bellard
    case 4:
239 0ac32c83 bellard
        val = le32_to_cpu(*(uint32_t *)(d->config + address));
240 0ac32c83 bellard
        break;
241 0ac32c83 bellard
    }
242 0ac32c83 bellard
    return val;
243 0ac32c83 bellard
}
244 0ac32c83 bellard
245 0ac32c83 bellard
void pci_default_write_config(PCIDevice *d, 
246 0ac32c83 bellard
                              uint32_t address, uint32_t val, int len)
247 0ac32c83 bellard
{
248 0ac32c83 bellard
    int can_write, i;
249 7bf5be70 bellard
    uint32_t end, addr;
250 0ac32c83 bellard
251 8a8696a3 bellard
    if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) || 
252 8a8696a3 bellard
                     (address >= 0x30 && address < 0x34))) {
253 0ac32c83 bellard
        PCIIORegion *r;
254 0ac32c83 bellard
        int reg;
255 0ac32c83 bellard
256 8a8696a3 bellard
        if ( address >= 0x30 ) {
257 8a8696a3 bellard
            reg = PCI_ROM_SLOT;
258 8a8696a3 bellard
        }else{
259 8a8696a3 bellard
            reg = (address - 0x10) >> 2;
260 8a8696a3 bellard
        }
261 0ac32c83 bellard
        r = &d->io_regions[reg];
262 0ac32c83 bellard
        if (r->size == 0)
263 0ac32c83 bellard
            goto default_config;
264 0ac32c83 bellard
        /* compute the stored value */
265 8a8696a3 bellard
        if (reg == PCI_ROM_SLOT) {
266 8a8696a3 bellard
            /* keep ROM enable bit */
267 8a8696a3 bellard
            val &= (~(r->size - 1)) | 1;
268 8a8696a3 bellard
        } else {
269 8a8696a3 bellard
            val &= ~(r->size - 1);
270 8a8696a3 bellard
            val |= r->type;
271 8a8696a3 bellard
        }
272 8a8696a3 bellard
        *(uint32_t *)(d->config + address) = cpu_to_le32(val);
273 0ac32c83 bellard
        pci_update_mappings(d);
274 69b91039 bellard
        return;
275 0ac32c83 bellard
    }
276 0ac32c83 bellard
 default_config:
277 0ac32c83 bellard
    /* not efficient, but simple */
278 7bf5be70 bellard
    addr = address;
279 0ac32c83 bellard
    for(i = 0; i < len; i++) {
280 0ac32c83 bellard
        /* default read/write accesses */
281 1f62d938 bellard
        switch(d->config[0x0e]) {
282 0ac32c83 bellard
        case 0x00:
283 1f62d938 bellard
        case 0x80:
284 1f62d938 bellard
            switch(addr) {
285 1f62d938 bellard
            case 0x00:
286 1f62d938 bellard
            case 0x01:
287 1f62d938 bellard
            case 0x02:
288 1f62d938 bellard
            case 0x03:
289 1f62d938 bellard
            case 0x08:
290 1f62d938 bellard
            case 0x09:
291 1f62d938 bellard
            case 0x0a:
292 1f62d938 bellard
            case 0x0b:
293 1f62d938 bellard
            case 0x0e:
294 1f62d938 bellard
            case 0x10 ... 0x27: /* base */
295 1f62d938 bellard
            case 0x30 ... 0x33: /* rom */
296 1f62d938 bellard
            case 0x3d:
297 1f62d938 bellard
                can_write = 0;
298 1f62d938 bellard
                break;
299 1f62d938 bellard
            default:
300 1f62d938 bellard
                can_write = 1;
301 1f62d938 bellard
                break;
302 1f62d938 bellard
            }
303 0ac32c83 bellard
            break;
304 0ac32c83 bellard
        default:
305 1f62d938 bellard
        case 0x01:
306 1f62d938 bellard
            switch(addr) {
307 1f62d938 bellard
            case 0x00:
308 1f62d938 bellard
            case 0x01:
309 1f62d938 bellard
            case 0x02:
310 1f62d938 bellard
            case 0x03:
311 1f62d938 bellard
            case 0x08:
312 1f62d938 bellard
            case 0x09:
313 1f62d938 bellard
            case 0x0a:
314 1f62d938 bellard
            case 0x0b:
315 1f62d938 bellard
            case 0x0e:
316 1f62d938 bellard
            case 0x38 ... 0x3b: /* rom */
317 1f62d938 bellard
            case 0x3d:
318 1f62d938 bellard
                can_write = 0;
319 1f62d938 bellard
                break;
320 1f62d938 bellard
            default:
321 1f62d938 bellard
                can_write = 1;
322 1f62d938 bellard
                break;
323 1f62d938 bellard
            }
324 0ac32c83 bellard
            break;
325 0ac32c83 bellard
        }
326 0ac32c83 bellard
        if (can_write) {
327 7bf5be70 bellard
            d->config[addr] = val;
328 0ac32c83 bellard
        }
329 7bf5be70 bellard
        addr++;
330 0ac32c83 bellard
        val >>= 8;
331 0ac32c83 bellard
    }
332 0ac32c83 bellard
333 0ac32c83 bellard
    end = address + len;
334 0ac32c83 bellard
    if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
335 0ac32c83 bellard
        /* if the command register is modified, we must modify the mappings */
336 0ac32c83 bellard
        pci_update_mappings(d);
337 69b91039 bellard
    }
338 69b91039 bellard
}
339 69b91039 bellard
340 69b91039 bellard
static void pci_data_write(void *opaque, uint32_t addr, 
341 69b91039 bellard
                           uint32_t val, int len)
342 69b91039 bellard
{
343 30468f78 bellard
    PCIBus *s = opaque;
344 30468f78 bellard
    PCIDevice *pci_dev;
345 30468f78 bellard
    int config_addr, bus_num;
346 69b91039 bellard
    
347 69b91039 bellard
#if defined(DEBUG_PCI) && 0
348 69b91039 bellard
    printf("pci_data_write: addr=%08x val=%08x len=%d\n",
349 69b91039 bellard
           s->config_reg, val, len);
350 69b91039 bellard
#endif
351 69b91039 bellard
    if (!(s->config_reg & (1 << 31))) {
352 69b91039 bellard
        return;
353 69b91039 bellard
    }
354 69b91039 bellard
    if ((s->config_reg & 0x3) != 0) {
355 69b91039 bellard
        return;
356 69b91039 bellard
    }
357 30468f78 bellard
    bus_num = (s->config_reg >> 16) & 0xff;
358 30468f78 bellard
    if (bus_num != 0)
359 69b91039 bellard
        return;
360 30468f78 bellard
    pci_dev = s->devices[(s->config_reg >> 8) & 0xff];
361 69b91039 bellard
    if (!pci_dev)
362 69b91039 bellard
        return;
363 69b91039 bellard
    config_addr = (s->config_reg & 0xfc) | (addr & 3);
364 69b91039 bellard
#if defined(DEBUG_PCI)
365 69b91039 bellard
    printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
366 69b91039 bellard
           pci_dev->name, config_addr, val, len);
367 69b91039 bellard
#endif
368 0ac32c83 bellard
    pci_dev->config_write(pci_dev, config_addr, val, len);
369 69b91039 bellard
}
370 69b91039 bellard
371 69b91039 bellard
static uint32_t pci_data_read(void *opaque, uint32_t addr, 
372 69b91039 bellard
                              int len)
373 69b91039 bellard
{
374 30468f78 bellard
    PCIBus *s = opaque;
375 30468f78 bellard
    PCIDevice *pci_dev;
376 30468f78 bellard
    int config_addr, bus_num;
377 69b91039 bellard
    uint32_t val;
378 69b91039 bellard
379 69b91039 bellard
    if (!(s->config_reg & (1 << 31)))
380 69b91039 bellard
        goto fail;
381 69b91039 bellard
    if ((s->config_reg & 0x3) != 0)
382 69b91039 bellard
        goto fail;
383 30468f78 bellard
    bus_num = (s->config_reg >> 16) & 0xff;
384 30468f78 bellard
    if (bus_num != 0)
385 69b91039 bellard
        goto fail;
386 30468f78 bellard
    pci_dev = s->devices[(s->config_reg >> 8) & 0xff];
387 69b91039 bellard
    if (!pci_dev) {
388 69b91039 bellard
    fail:
389 63ce9e0a bellard
        switch(len) {
390 63ce9e0a bellard
        case 1:
391 63ce9e0a bellard
            val = 0xff;
392 63ce9e0a bellard
            break;
393 63ce9e0a bellard
        case 2:
394 63ce9e0a bellard
            val = 0xffff;
395 63ce9e0a bellard
            break;
396 63ce9e0a bellard
        default:
397 63ce9e0a bellard
        case 4:
398 63ce9e0a bellard
            val = 0xffffffff;
399 63ce9e0a bellard
            break;
400 63ce9e0a bellard
        }
401 69b91039 bellard
        goto the_end;
402 69b91039 bellard
    }
403 69b91039 bellard
    config_addr = (s->config_reg & 0xfc) | (addr & 3);
404 69b91039 bellard
    val = pci_dev->config_read(pci_dev, config_addr, len);
405 69b91039 bellard
#if defined(DEBUG_PCI)
406 69b91039 bellard
    printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
407 69b91039 bellard
           pci_dev->name, config_addr, val, len);
408 69b91039 bellard
#endif
409 69b91039 bellard
 the_end:
410 69b91039 bellard
#if defined(DEBUG_PCI) && 0
411 69b91039 bellard
    printf("pci_data_read: addr=%08x val=%08x len=%d\n",
412 69b91039 bellard
           s->config_reg, val, len);
413 69b91039 bellard
#endif
414 69b91039 bellard
    return val;
415 69b91039 bellard
}
416 69b91039 bellard
417 69b91039 bellard
static void pci_data_writeb(void* opaque, uint32_t addr, uint32_t val)
418 69b91039 bellard
{
419 69b91039 bellard
    pci_data_write(opaque, addr, val, 1);
420 69b91039 bellard
}
421 69b91039 bellard
422 69b91039 bellard
static void pci_data_writew(void* opaque, uint32_t addr, uint32_t val)
423 69b91039 bellard
{
424 69b91039 bellard
    pci_data_write(opaque, addr, val, 2);
425 69b91039 bellard
}
426 69b91039 bellard
427 69b91039 bellard
static void pci_data_writel(void* opaque, uint32_t addr, uint32_t val)
428 69b91039 bellard
{
429 69b91039 bellard
    pci_data_write(opaque, addr, val, 4);
430 69b91039 bellard
}
431 69b91039 bellard
432 69b91039 bellard
static uint32_t pci_data_readb(void* opaque, uint32_t addr)
433 69b91039 bellard
{
434 69b91039 bellard
    return pci_data_read(opaque, addr, 1);
435 69b91039 bellard
}
436 69b91039 bellard
437 69b91039 bellard
static uint32_t pci_data_readw(void* opaque, uint32_t addr)
438 69b91039 bellard
{
439 69b91039 bellard
    return pci_data_read(opaque, addr, 2);
440 69b91039 bellard
}
441 69b91039 bellard
442 69b91039 bellard
static uint32_t pci_data_readl(void* opaque, uint32_t addr)
443 69b91039 bellard
{
444 69b91039 bellard
    return pci_data_read(opaque, addr, 4);
445 69b91039 bellard
}
446 69b91039 bellard
447 69b91039 bellard
/* i440FX PCI bridge */
448 69b91039 bellard
449 30468f78 bellard
static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level);
450 30468f78 bellard
451 30468f78 bellard
PCIBus *i440fx_init(void)
452 69b91039 bellard
{
453 30468f78 bellard
    PCIBus *s;
454 69b91039 bellard
    PCIDevice *d;
455 69b91039 bellard
456 30468f78 bellard
    s = pci_register_bus();
457 30468f78 bellard
    s->set_irq = piix3_set_irq;
458 30468f78 bellard
459 0ac32c83 bellard
    register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);
460 0ac32c83 bellard
    register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s);
461 69b91039 bellard
462 69b91039 bellard
    register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);
463 69b91039 bellard
    register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);
464 69b91039 bellard
    register_ioport_write(0xcfc, 4, 4, pci_data_writel, s);
465 69b91039 bellard
    register_ioport_read(0xcfc, 4, 1, pci_data_readb, s);
466 69b91039 bellard
    register_ioport_read(0xcfc, 4, 2, pci_data_readw, s);
467 69b91039 bellard
    register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);
468 69b91039 bellard
469 30468f78 bellard
    d = pci_register_device(s, "i440FX", sizeof(PCIDevice), 0, 
470 0ac32c83 bellard
                            NULL, NULL);
471 69b91039 bellard
472 69b91039 bellard
    d->config[0x00] = 0x86; // vendor_id
473 69b91039 bellard
    d->config[0x01] = 0x80;
474 69b91039 bellard
    d->config[0x02] = 0x37; // device_id
475 69b91039 bellard
    d->config[0x03] = 0x12;
476 69b91039 bellard
    d->config[0x08] = 0x02; // revision
477 358c6407 bellard
    d->config[0x0a] = 0x00; // class_sub = host2pci
478 69b91039 bellard
    d->config[0x0b] = 0x06; // class_base = PCI_bridge
479 358c6407 bellard
    d->config[0x0e] = 0x00; // header_type
480 30468f78 bellard
    return s;
481 69b91039 bellard
}
482 69b91039 bellard
483 0ac32c83 bellard
/* PIIX3 PCI to ISA bridge */
484 0ac32c83 bellard
485 0ac32c83 bellard
typedef struct PIIX3State {
486 0ac32c83 bellard
    PCIDevice dev;
487 0ac32c83 bellard
} PIIX3State;
488 0ac32c83 bellard
489 0ac32c83 bellard
PIIX3State *piix3_state;
490 0ac32c83 bellard
491 30468f78 bellard
/* return the global irq number corresponding to a given device irq
492 30468f78 bellard
   pin. We could also use the bus number to have a more precise
493 30468f78 bellard
   mapping. */
494 30468f78 bellard
static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
495 30468f78 bellard
{
496 30468f78 bellard
    int slot_addend;
497 39d22439 bellard
    slot_addend = (pci_dev->devfn >> 3) - 1;
498 30468f78 bellard
    return (irq_num + slot_addend) & 3;
499 30468f78 bellard
}
500 30468f78 bellard
501 30468f78 bellard
static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level)
502 30468f78 bellard
{
503 30468f78 bellard
    int irq_index, shift, pic_irq, pic_level;
504 30468f78 bellard
    uint32_t *p;
505 30468f78 bellard
506 30468f78 bellard
    irq_num = pci_slot_get_pirq(pci_dev, irq_num);
507 30468f78 bellard
    irq_index = pci_dev->irq_index;
508 30468f78 bellard
    p = &pci_irq_levels[irq_num][irq_index >> 5];
509 30468f78 bellard
    shift = (irq_index & 0x1f);
510 30468f78 bellard
    *p = (*p & ~(1 << shift)) | (level << shift);
511 30468f78 bellard
512 30468f78 bellard
    /* now we change the pic irq level according to the piix irq mappings */
513 30468f78 bellard
    pic_irq = piix3_state->dev.config[0x60 + irq_num];
514 30468f78 bellard
    if (pic_irq < 16) {
515 30468f78 bellard
        /* the pic level is the logical OR of all the PCI irqs mapped
516 30468f78 bellard
           to it */
517 30468f78 bellard
        pic_level = 0;
518 30468f78 bellard
#if (PCI_IRQ_WORDS == 2)
519 30468f78 bellard
        pic_level = ((pci_irq_levels[irq_num][0] | 
520 30468f78 bellard
                      pci_irq_levels[irq_num][1]) != 0);
521 30468f78 bellard
#else
522 30468f78 bellard
        {
523 30468f78 bellard
            int i;
524 30468f78 bellard
            pic_level = 0;
525 30468f78 bellard
            for(i = 0; i < PCI_IRQ_WORDS; i++) {
526 30468f78 bellard
                if (pci_irq_levels[irq_num][i]) {
527 30468f78 bellard
                    pic_level = 1;
528 30468f78 bellard
                    break;
529 30468f78 bellard
                }
530 30468f78 bellard
            }
531 30468f78 bellard
        }
532 30468f78 bellard
#endif
533 30468f78 bellard
        pic_set_irq(pic_irq, pic_level);
534 30468f78 bellard
    }
535 30468f78 bellard
}
536 30468f78 bellard
537 0ac32c83 bellard
static void piix3_reset(PIIX3State *d)
538 0ac32c83 bellard
{
539 0ac32c83 bellard
    uint8_t *pci_conf = d->dev.config;
540 0ac32c83 bellard
541 0ac32c83 bellard
    pci_conf[0x04] = 0x07; // master, memory and I/O
542 0ac32c83 bellard
    pci_conf[0x05] = 0x00;
543 0ac32c83 bellard
    pci_conf[0x06] = 0x00;
544 0ac32c83 bellard
    pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
545 0ac32c83 bellard
    pci_conf[0x4c] = 0x4d;
546 0ac32c83 bellard
    pci_conf[0x4e] = 0x03;
547 0ac32c83 bellard
    pci_conf[0x4f] = 0x00;
548 0ac32c83 bellard
    pci_conf[0x60] = 0x80;
549 0ac32c83 bellard
    pci_conf[0x69] = 0x02;
550 0ac32c83 bellard
    pci_conf[0x70] = 0x80;
551 0ac32c83 bellard
    pci_conf[0x76] = 0x0c;
552 0ac32c83 bellard
    pci_conf[0x77] = 0x0c;
553 0ac32c83 bellard
    pci_conf[0x78] = 0x02;
554 0ac32c83 bellard
    pci_conf[0x79] = 0x00;
555 0ac32c83 bellard
    pci_conf[0x80] = 0x00;
556 0ac32c83 bellard
    pci_conf[0x82] = 0x00;
557 0ac32c83 bellard
    pci_conf[0xa0] = 0x08;
558 0ac32c83 bellard
    pci_conf[0xa0] = 0x08;
559 0ac32c83 bellard
    pci_conf[0xa2] = 0x00;
560 0ac32c83 bellard
    pci_conf[0xa3] = 0x00;
561 0ac32c83 bellard
    pci_conf[0xa4] = 0x00;
562 0ac32c83 bellard
    pci_conf[0xa5] = 0x00;
563 0ac32c83 bellard
    pci_conf[0xa6] = 0x00;
564 0ac32c83 bellard
    pci_conf[0xa7] = 0x00;
565 0ac32c83 bellard
    pci_conf[0xa8] = 0x0f;
566 0ac32c83 bellard
    pci_conf[0xaa] = 0x00;
567 0ac32c83 bellard
    pci_conf[0xab] = 0x00;
568 0ac32c83 bellard
    pci_conf[0xac] = 0x00;
569 0ac32c83 bellard
    pci_conf[0xae] = 0x00;
570 0ac32c83 bellard
}
571 0ac32c83 bellard
572 30468f78 bellard
void piix3_init(PCIBus *bus)
573 0ac32c83 bellard
{
574 0ac32c83 bellard
    PIIX3State *d;
575 0ac32c83 bellard
    uint8_t *pci_conf;
576 0ac32c83 bellard
577 30468f78 bellard
    d = (PIIX3State *)pci_register_device(bus, "PIIX3", sizeof(PIIX3State),
578 30468f78 bellard
                                          -1, NULL, NULL);
579 30ca2aab bellard
    register_savevm("PIIX3", 0, 1, generic_pci_save, generic_pci_load, d);
580 30ca2aab bellard
581 0ac32c83 bellard
    piix3_state = d;
582 0ac32c83 bellard
    pci_conf = d->dev.config;
583 0ac32c83 bellard
584 0ac32c83 bellard
    pci_conf[0x00] = 0x86; // Intel
585 0ac32c83 bellard
    pci_conf[0x01] = 0x80;
586 0ac32c83 bellard
    pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
587 0ac32c83 bellard
    pci_conf[0x03] = 0x70;
588 0ac32c83 bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
589 0ac32c83 bellard
    pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
590 0ac32c83 bellard
    pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
591 0ac32c83 bellard
592 0ac32c83 bellard
    piix3_reset(d);
593 0ac32c83 bellard
}
594 0ac32c83 bellard
595 77d4bc34 bellard
/* PREP pci init */
596 77d4bc34 bellard
597 30468f78 bellard
static inline void set_config(PCIBus *s, target_phys_addr_t addr)
598 77d4bc34 bellard
{
599 77d4bc34 bellard
    int devfn, i;
600 77d4bc34 bellard
601 77d4bc34 bellard
    for(i = 0; i < 11; i++) {
602 77d4bc34 bellard
        if ((addr & (1 << (11 + i))) != 0)
603 77d4bc34 bellard
            break;
604 77d4bc34 bellard
    }
605 77d4bc34 bellard
    devfn = ((addr >> 8) & 7) | (i << 3);
606 77d4bc34 bellard
    s->config_reg = 0x80000000 | (addr & 0xfc) | (devfn << 8);
607 77d4bc34 bellard
}
608 77d4bc34 bellard
609 8a8696a3 bellard
static void PPC_PCIIO_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
610 77d4bc34 bellard
{
611 30468f78 bellard
    PCIBus *s = opaque;
612 77d4bc34 bellard
    set_config(s, addr);
613 77d4bc34 bellard
    pci_data_write(s, addr, val, 1);
614 77d4bc34 bellard
}
615 77d4bc34 bellard
616 8a8696a3 bellard
static void PPC_PCIIO_writew (void *opaque, target_phys_addr_t addr, uint32_t val)
617 77d4bc34 bellard
{
618 30468f78 bellard
    PCIBus *s = opaque;
619 77d4bc34 bellard
    set_config(s, addr);
620 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
621 77d4bc34 bellard
    val = bswap16(val);
622 77d4bc34 bellard
#endif
623 77d4bc34 bellard
    pci_data_write(s, addr, val, 2);
624 77d4bc34 bellard
}
625 77d4bc34 bellard
626 8a8696a3 bellard
static void PPC_PCIIO_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
627 77d4bc34 bellard
{
628 30468f78 bellard
    PCIBus *s = opaque;
629 77d4bc34 bellard
    set_config(s, addr);
630 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
631 77d4bc34 bellard
    val = bswap32(val);
632 77d4bc34 bellard
#endif
633 77d4bc34 bellard
    pci_data_write(s, addr, val, 4);
634 77d4bc34 bellard
}
635 77d4bc34 bellard
636 8a8696a3 bellard
static uint32_t PPC_PCIIO_readb (void *opaque, target_phys_addr_t addr)
637 77d4bc34 bellard
{
638 30468f78 bellard
    PCIBus *s = opaque;
639 77d4bc34 bellard
    uint32_t val;
640 77d4bc34 bellard
    set_config(s, addr);
641 77d4bc34 bellard
    val = pci_data_read(s, addr, 1);
642 77d4bc34 bellard
    return val;
643 77d4bc34 bellard
}
644 77d4bc34 bellard
645 8a8696a3 bellard
static uint32_t PPC_PCIIO_readw (void *opaque, target_phys_addr_t addr)
646 77d4bc34 bellard
{
647 30468f78 bellard
    PCIBus *s = opaque;
648 77d4bc34 bellard
    uint32_t val;
649 77d4bc34 bellard
    set_config(s, addr);
650 77d4bc34 bellard
    val = pci_data_read(s, addr, 2);
651 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
652 77d4bc34 bellard
    val = bswap16(val);
653 77d4bc34 bellard
#endif
654 77d4bc34 bellard
    return val;
655 77d4bc34 bellard
}
656 77d4bc34 bellard
657 8a8696a3 bellard
static uint32_t PPC_PCIIO_readl (void *opaque, target_phys_addr_t addr)
658 77d4bc34 bellard
{
659 30468f78 bellard
    PCIBus *s = opaque;
660 77d4bc34 bellard
    uint32_t val;
661 77d4bc34 bellard
    set_config(s, addr);
662 77d4bc34 bellard
    val = pci_data_read(s, addr, 4);
663 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
664 77d4bc34 bellard
    val = bswap32(val);
665 77d4bc34 bellard
#endif
666 77d4bc34 bellard
    return val;
667 77d4bc34 bellard
}
668 77d4bc34 bellard
669 77d4bc34 bellard
static CPUWriteMemoryFunc *PPC_PCIIO_write[] = {
670 77d4bc34 bellard
    &PPC_PCIIO_writeb,
671 77d4bc34 bellard
    &PPC_PCIIO_writew,
672 77d4bc34 bellard
    &PPC_PCIIO_writel,
673 77d4bc34 bellard
};
674 77d4bc34 bellard
675 77d4bc34 bellard
static CPUReadMemoryFunc *PPC_PCIIO_read[] = {
676 77d4bc34 bellard
    &PPC_PCIIO_readb,
677 77d4bc34 bellard
    &PPC_PCIIO_readw,
678 77d4bc34 bellard
    &PPC_PCIIO_readl,
679 77d4bc34 bellard
};
680 77d4bc34 bellard
681 30468f78 bellard
static void prep_set_irq(PCIDevice *d, int irq_num, int level)
682 30468f78 bellard
{
683 30468f78 bellard
    /* XXX: we do not simulate the hardware - we rely on the BIOS to
684 30468f78 bellard
       set correctly for irq line field */
685 30468f78 bellard
    pic_set_irq(d->config[PCI_INTERRUPT_LINE], level);
686 30468f78 bellard
}
687 30468f78 bellard
688 30468f78 bellard
PCIBus *pci_prep_init(void)
689 77d4bc34 bellard
{
690 30468f78 bellard
    PCIBus *s;
691 77d4bc34 bellard
    PCIDevice *d;
692 77d4bc34 bellard
    int PPC_io_memory;
693 77d4bc34 bellard
694 30468f78 bellard
    s = pci_register_bus();
695 30468f78 bellard
    s->set_irq = prep_set_irq;
696 30468f78 bellard
697 da9b266b bellard
    register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);
698 da9b266b bellard
    register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s);
699 da9b266b bellard
700 da9b266b bellard
    register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);
701 da9b266b bellard
    register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);
702 da9b266b bellard
    register_ioport_write(0xcfc, 4, 4, pci_data_writel, s);
703 da9b266b bellard
    register_ioport_read(0xcfc, 4, 1, pci_data_readb, s);
704 da9b266b bellard
    register_ioport_read(0xcfc, 4, 2, pci_data_readw, s);
705 da9b266b bellard
    register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);
706 da9b266b bellard
707 8a8696a3 bellard
    PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read, 
708 8a8696a3 bellard
                                           PPC_PCIIO_write, s);
709 77d4bc34 bellard
    cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
710 77d4bc34 bellard
711 30468f78 bellard
    d = pci_register_device(s, "PREP PCI Bridge", sizeof(PCIDevice), 0,
712 77d4bc34 bellard
                            NULL, NULL);
713 77d4bc34 bellard
714 77d4bc34 bellard
    /* XXX: put correct IDs */
715 77d4bc34 bellard
    d->config[0x00] = 0x11; // vendor_id
716 77d4bc34 bellard
    d->config[0x01] = 0x10;
717 77d4bc34 bellard
    d->config[0x02] = 0x26; // device_id
718 77d4bc34 bellard
    d->config[0x03] = 0x00;
719 77d4bc34 bellard
    d->config[0x08] = 0x02; // revision
720 77d4bc34 bellard
    d->config[0x0a] = 0x04; // class_sub = pci2pci
721 77d4bc34 bellard
    d->config[0x0b] = 0x06; // class_base = PCI_bridge
722 77d4bc34 bellard
    d->config[0x0e] = 0x01; // header_type
723 30468f78 bellard
    return s;
724 77d4bc34 bellard
}
725 77d4bc34 bellard
726 77d4bc34 bellard
727 77d4bc34 bellard
/* pmac pci init */
728 77d4bc34 bellard
729 30468f78 bellard
#if 0
730 f2aa58c6 bellard
/* Grackle PCI host */
731 f2aa58c6 bellard
static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr,
732 f2aa58c6 bellard
                                       uint32_t val)
733 77d4bc34 bellard
{
734 30468f78 bellard
    PCIBus *s = opaque;
735 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
736 77d4bc34 bellard
    val = bswap32(val);
737 77d4bc34 bellard
#endif
738 77d4bc34 bellard
    s->config_reg = val;
739 77d4bc34 bellard
}
740 77d4bc34 bellard
741 f2aa58c6 bellard
static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr)
742 77d4bc34 bellard
{
743 30468f78 bellard
    PCIBus *s = opaque;
744 77d4bc34 bellard
    uint32_t val;
745 77d4bc34 bellard
746 77d4bc34 bellard
    val = s->config_reg;
747 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
748 77d4bc34 bellard
    val = bswap32(val);
749 77d4bc34 bellard
#endif
750 77d4bc34 bellard
    return val;
751 77d4bc34 bellard
}
752 77d4bc34 bellard
753 f2aa58c6 bellard
static CPUWriteMemoryFunc *pci_grackle_config_write[] = {
754 f2aa58c6 bellard
    &pci_grackle_config_writel,
755 f2aa58c6 bellard
    &pci_grackle_config_writel,
756 f2aa58c6 bellard
    &pci_grackle_config_writel,
757 77d4bc34 bellard
};
758 77d4bc34 bellard
759 f2aa58c6 bellard
static CPUReadMemoryFunc *pci_grackle_config_read[] = {
760 f2aa58c6 bellard
    &pci_grackle_config_readl,
761 f2aa58c6 bellard
    &pci_grackle_config_readl,
762 f2aa58c6 bellard
    &pci_grackle_config_readl,
763 77d4bc34 bellard
};
764 77d4bc34 bellard
765 f2aa58c6 bellard
static void pci_grackle_writeb (void *opaque, target_phys_addr_t addr,
766 f2aa58c6 bellard
                                uint32_t val)
767 77d4bc34 bellard
{
768 30468f78 bellard
    PCIBus *s = opaque;
769 77d4bc34 bellard
    pci_data_write(s, addr, val, 1);
770 77d4bc34 bellard
}
771 77d4bc34 bellard
772 f2aa58c6 bellard
static void pci_grackle_writew (void *opaque, target_phys_addr_t addr,
773 f2aa58c6 bellard
                                uint32_t val)
774 77d4bc34 bellard
{
775 30468f78 bellard
    PCIBus *s = opaque;
776 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
777 77d4bc34 bellard
    val = bswap16(val);
778 77d4bc34 bellard
#endif
779 77d4bc34 bellard
    pci_data_write(s, addr, val, 2);
780 77d4bc34 bellard
}
781 77d4bc34 bellard
782 f2aa58c6 bellard
static void pci_grackle_writel (void *opaque, target_phys_addr_t addr,
783 f2aa58c6 bellard
                                uint32_t val)
784 77d4bc34 bellard
{
785 30468f78 bellard
    PCIBus *s = opaque;
786 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
787 77d4bc34 bellard
    val = bswap32(val);
788 77d4bc34 bellard
#endif
789 77d4bc34 bellard
    pci_data_write(s, addr, val, 4);
790 77d4bc34 bellard
}
791 77d4bc34 bellard
792 f2aa58c6 bellard
static uint32_t pci_grackle_readb (void *opaque, target_phys_addr_t addr)
793 77d4bc34 bellard
{
794 30468f78 bellard
    PCIBus *s = opaque;
795 77d4bc34 bellard
    uint32_t val;
796 77d4bc34 bellard
    val = pci_data_read(s, addr, 1);
797 77d4bc34 bellard
    return val;
798 77d4bc34 bellard
}
799 77d4bc34 bellard
800 f2aa58c6 bellard
static uint32_t pci_grackle_readw (void *opaque, target_phys_addr_t addr)
801 77d4bc34 bellard
{
802 30468f78 bellard
    PCIBus *s = opaque;
803 77d4bc34 bellard
    uint32_t val;
804 77d4bc34 bellard
    val = pci_data_read(s, addr, 2);
805 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
806 77d4bc34 bellard
    val = bswap16(val);
807 77d4bc34 bellard
#endif
808 77d4bc34 bellard
    return val;
809 77d4bc34 bellard
}
810 77d4bc34 bellard
811 f2aa58c6 bellard
static uint32_t pci_grackle_readl (void *opaque, target_phys_addr_t addr)
812 f2aa58c6 bellard
{
813 30468f78 bellard
    PCIBus *s = opaque;
814 f2aa58c6 bellard
    uint32_t val;
815 f2aa58c6 bellard
816 f2aa58c6 bellard
    val = pci_data_read(s, addr, 4);
817 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
818 f2aa58c6 bellard
    val = bswap32(val);
819 f2aa58c6 bellard
#endif
820 f2aa58c6 bellard
    return val;
821 f2aa58c6 bellard
}
822 f2aa58c6 bellard
823 f2aa58c6 bellard
static CPUWriteMemoryFunc *pci_grackle_write[] = {
824 f2aa58c6 bellard
    &pci_grackle_writeb,
825 f2aa58c6 bellard
    &pci_grackle_writew,
826 f2aa58c6 bellard
    &pci_grackle_writel,
827 f2aa58c6 bellard
};
828 f2aa58c6 bellard
829 f2aa58c6 bellard
static CPUReadMemoryFunc *pci_grackle_read[] = {
830 f2aa58c6 bellard
    &pci_grackle_readb,
831 f2aa58c6 bellard
    &pci_grackle_readw,
832 f2aa58c6 bellard
    &pci_grackle_readl,
833 f2aa58c6 bellard
};
834 30468f78 bellard
#endif
835 f2aa58c6 bellard
836 f2aa58c6 bellard
/* Uninorth PCI host (for all Mac99 and newer machines */
837 f2aa58c6 bellard
static void pci_unin_main_config_writel (void *opaque, target_phys_addr_t addr,
838 f2aa58c6 bellard
                                         uint32_t val)
839 f2aa58c6 bellard
{
840 30468f78 bellard
    PCIBus *s = opaque;
841 f2aa58c6 bellard
    int i;
842 f2aa58c6 bellard
843 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
844 f2aa58c6 bellard
    val = bswap32(val);
845 f2aa58c6 bellard
#endif
846 f2aa58c6 bellard
847 f2aa58c6 bellard
    for (i = 11; i < 32; i++) {
848 f2aa58c6 bellard
        if ((val & (1 << i)) != 0)
849 f2aa58c6 bellard
            break;
850 f2aa58c6 bellard
    }
851 f2aa58c6 bellard
#if 0
852 f2aa58c6 bellard
    s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
853 f2aa58c6 bellard
#else
854 f2aa58c6 bellard
    s->config_reg = 0x80000000 | (0 << 16) | (val & 0x7FC) | (i << 11);
855 f2aa58c6 bellard
#endif
856 f2aa58c6 bellard
}
857 f2aa58c6 bellard
858 f2aa58c6 bellard
static uint32_t pci_unin_main_config_readl (void *opaque,
859 f2aa58c6 bellard
                                            target_phys_addr_t addr)
860 f2aa58c6 bellard
{
861 30468f78 bellard
    PCIBus *s = opaque;
862 f2aa58c6 bellard
    uint32_t val;
863 f2aa58c6 bellard
    int devfn;
864 f2aa58c6 bellard
865 f2aa58c6 bellard
    devfn = (s->config_reg >> 8) & 0xFF;
866 f2aa58c6 bellard
    val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
867 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
868 f2aa58c6 bellard
    val = bswap32(val);
869 f2aa58c6 bellard
#endif
870 f2aa58c6 bellard
871 f2aa58c6 bellard
    return val;
872 f2aa58c6 bellard
}
873 f2aa58c6 bellard
874 f2aa58c6 bellard
static CPUWriteMemoryFunc *pci_unin_main_config_write[] = {
875 f2aa58c6 bellard
    &pci_unin_main_config_writel,
876 f2aa58c6 bellard
    &pci_unin_main_config_writel,
877 f2aa58c6 bellard
    &pci_unin_main_config_writel,
878 f2aa58c6 bellard
};
879 f2aa58c6 bellard
880 f2aa58c6 bellard
static CPUReadMemoryFunc *pci_unin_main_config_read[] = {
881 f2aa58c6 bellard
    &pci_unin_main_config_readl,
882 f2aa58c6 bellard
    &pci_unin_main_config_readl,
883 f2aa58c6 bellard
    &pci_unin_main_config_readl,
884 f2aa58c6 bellard
};
885 f2aa58c6 bellard
886 f2aa58c6 bellard
static void pci_unin_main_writeb (void *opaque, target_phys_addr_t addr,
887 f2aa58c6 bellard
                                  uint32_t val)
888 f2aa58c6 bellard
{
889 30468f78 bellard
    PCIBus *s = opaque;
890 f2aa58c6 bellard
    pci_data_write(s, addr & 7, val, 1);
891 f2aa58c6 bellard
}
892 f2aa58c6 bellard
893 f2aa58c6 bellard
static void pci_unin_main_writew (void *opaque, target_phys_addr_t addr,
894 f2aa58c6 bellard
                                  uint32_t val)
895 f2aa58c6 bellard
{
896 30468f78 bellard
    PCIBus *s = opaque;
897 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
898 f2aa58c6 bellard
    val = bswap16(val);
899 f2aa58c6 bellard
#endif
900 f2aa58c6 bellard
    pci_data_write(s, addr & 7, val, 2);
901 f2aa58c6 bellard
}
902 f2aa58c6 bellard
903 f2aa58c6 bellard
static void pci_unin_main_writel (void *opaque, target_phys_addr_t addr,
904 f2aa58c6 bellard
                                uint32_t val)
905 f2aa58c6 bellard
{
906 30468f78 bellard
    PCIBus *s = opaque;
907 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
908 f2aa58c6 bellard
    val = bswap32(val);
909 f2aa58c6 bellard
#endif
910 f2aa58c6 bellard
    pci_data_write(s, addr & 7, val, 4);
911 f2aa58c6 bellard
}
912 f2aa58c6 bellard
913 f2aa58c6 bellard
static uint32_t pci_unin_main_readb (void *opaque, target_phys_addr_t addr)
914 f2aa58c6 bellard
{
915 30468f78 bellard
    PCIBus *s = opaque;
916 f2aa58c6 bellard
    uint32_t val;
917 f2aa58c6 bellard
918 f2aa58c6 bellard
    val = pci_data_read(s, addr & 7, 1);
919 f2aa58c6 bellard
920 f2aa58c6 bellard
    return val;
921 f2aa58c6 bellard
}
922 f2aa58c6 bellard
923 f2aa58c6 bellard
static uint32_t pci_unin_main_readw (void *opaque, target_phys_addr_t addr)
924 f2aa58c6 bellard
{
925 30468f78 bellard
    PCIBus *s = opaque;
926 f2aa58c6 bellard
    uint32_t val;
927 f2aa58c6 bellard
928 f2aa58c6 bellard
    val = pci_data_read(s, addr & 7, 2);
929 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
930 f2aa58c6 bellard
    val = bswap16(val);
931 f2aa58c6 bellard
#endif
932 f2aa58c6 bellard
933 f2aa58c6 bellard
    return val;
934 f2aa58c6 bellard
}
935 f2aa58c6 bellard
936 f2aa58c6 bellard
static uint32_t pci_unin_main_readl (void *opaque, target_phys_addr_t addr)
937 77d4bc34 bellard
{
938 30468f78 bellard
    PCIBus *s = opaque;
939 77d4bc34 bellard
    uint32_t val;
940 77d4bc34 bellard
941 77d4bc34 bellard
    val = pci_data_read(s, addr, 4);
942 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
943 77d4bc34 bellard
    val = bswap32(val);
944 77d4bc34 bellard
#endif
945 f2aa58c6 bellard
946 f2aa58c6 bellard
    return val;
947 f2aa58c6 bellard
}
948 f2aa58c6 bellard
949 f2aa58c6 bellard
static CPUWriteMemoryFunc *pci_unin_main_write[] = {
950 f2aa58c6 bellard
    &pci_unin_main_writeb,
951 f2aa58c6 bellard
    &pci_unin_main_writew,
952 f2aa58c6 bellard
    &pci_unin_main_writel,
953 f2aa58c6 bellard
};
954 f2aa58c6 bellard
955 f2aa58c6 bellard
static CPUReadMemoryFunc *pci_unin_main_read[] = {
956 f2aa58c6 bellard
    &pci_unin_main_readb,
957 f2aa58c6 bellard
    &pci_unin_main_readw,
958 f2aa58c6 bellard
    &pci_unin_main_readl,
959 f2aa58c6 bellard
};
960 f2aa58c6 bellard
961 30468f78 bellard
#if 0
962 30468f78 bellard

963 f2aa58c6 bellard
static void pci_unin_config_writel (void *opaque, target_phys_addr_t addr,
964 f2aa58c6 bellard
                                    uint32_t val)
965 f2aa58c6 bellard
{
966 30468f78 bellard
    PCIBus *s = opaque;
967 f2aa58c6 bellard

968 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
969 f2aa58c6 bellard
    val = bswap32(val);
970 f2aa58c6 bellard
#endif
971 f2aa58c6 bellard
    s->config_reg = 0x80000000 | (val & ~0x00000001);
972 f2aa58c6 bellard
}
973 f2aa58c6 bellard
974 f2aa58c6 bellard
static uint32_t pci_unin_config_readl (void *opaque,
975 f2aa58c6 bellard
                                       target_phys_addr_t addr)
976 f2aa58c6 bellard
{
977 30468f78 bellard
    PCIBus *s = opaque;
978 f2aa58c6 bellard
    uint32_t val;
979 f2aa58c6 bellard
980 f2aa58c6 bellard
    val = (s->config_reg | 0x00000001) & ~0x80000000;
981 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
982 f2aa58c6 bellard
    val = bswap32(val);
983 f2aa58c6 bellard
#endif
984 f2aa58c6 bellard
985 f2aa58c6 bellard
    return val;
986 f2aa58c6 bellard
}
987 f2aa58c6 bellard
988 f2aa58c6 bellard
static CPUWriteMemoryFunc *pci_unin_config_write[] = {
989 f2aa58c6 bellard
    &pci_unin_config_writel,
990 f2aa58c6 bellard
    &pci_unin_config_writel,
991 f2aa58c6 bellard
    &pci_unin_config_writel,
992 f2aa58c6 bellard
};
993 f2aa58c6 bellard
994 f2aa58c6 bellard
static CPUReadMemoryFunc *pci_unin_config_read[] = {
995 f2aa58c6 bellard
    &pci_unin_config_readl,
996 f2aa58c6 bellard
    &pci_unin_config_readl,
997 f2aa58c6 bellard
    &pci_unin_config_readl,
998 f2aa58c6 bellard
};
999 f2aa58c6 bellard
1000 f2aa58c6 bellard
static void pci_unin_writeb (void *opaque, target_phys_addr_t addr,
1001 f2aa58c6 bellard
                             uint32_t val)
1002 f2aa58c6 bellard
{
1003 30468f78 bellard
    PCIBus *s = opaque;
1004 f2aa58c6 bellard
    pci_data_write(s, addr & 3, val, 1);
1005 f2aa58c6 bellard
}
1006 f2aa58c6 bellard
1007 f2aa58c6 bellard
static void pci_unin_writew (void *opaque, target_phys_addr_t addr,
1008 f2aa58c6 bellard
                             uint32_t val)
1009 f2aa58c6 bellard
{
1010 30468f78 bellard
    PCIBus *s = opaque;
1011 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
1012 f2aa58c6 bellard
    val = bswap16(val);
1013 f2aa58c6 bellard
#endif
1014 f2aa58c6 bellard
    pci_data_write(s, addr & 3, val, 2);
1015 f2aa58c6 bellard
}
1016 f2aa58c6 bellard
1017 f2aa58c6 bellard
static void pci_unin_writel (void *opaque, target_phys_addr_t addr,
1018 f2aa58c6 bellard
                             uint32_t val)
1019 f2aa58c6 bellard
{
1020 30468f78 bellard
    PCIBus *s = opaque;
1021 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
1022 f2aa58c6 bellard
    val = bswap32(val);
1023 f2aa58c6 bellard
#endif
1024 f2aa58c6 bellard
    pci_data_write(s, addr & 3, val, 4);
1025 f2aa58c6 bellard
}
1026 f2aa58c6 bellard
1027 f2aa58c6 bellard
static uint32_t pci_unin_readb (void *opaque, target_phys_addr_t addr)
1028 f2aa58c6 bellard
{
1029 30468f78 bellard
    PCIBus *s = opaque;
1030 f2aa58c6 bellard
    uint32_t val;
1031 f2aa58c6 bellard
1032 f2aa58c6 bellard
    val = pci_data_read(s, addr & 3, 1);
1033 f2aa58c6 bellard
1034 f2aa58c6 bellard
    return val;
1035 f2aa58c6 bellard
}
1036 f2aa58c6 bellard
1037 f2aa58c6 bellard
static uint32_t pci_unin_readw (void *opaque, target_phys_addr_t addr)
1038 f2aa58c6 bellard
{
1039 30468f78 bellard
    PCIBus *s = opaque;
1040 f2aa58c6 bellard
    uint32_t val;
1041 f2aa58c6 bellard
1042 f2aa58c6 bellard
    val = pci_data_read(s, addr & 3, 2);
1043 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
1044 f2aa58c6 bellard
    val = bswap16(val);
1045 f2aa58c6 bellard
#endif
1046 f2aa58c6 bellard
1047 f2aa58c6 bellard
    return val;
1048 f2aa58c6 bellard
}
1049 f2aa58c6 bellard
1050 f2aa58c6 bellard
static uint32_t pci_unin_readl (void *opaque, target_phys_addr_t addr)
1051 f2aa58c6 bellard
{
1052 30468f78 bellard
    PCIBus *s = opaque;
1053 f2aa58c6 bellard
    uint32_t val;
1054 f2aa58c6 bellard
1055 f2aa58c6 bellard
    val = pci_data_read(s, addr & 3, 4);
1056 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
1057 f2aa58c6 bellard
    val = bswap32(val);
1058 f2aa58c6 bellard
#endif
1059 f2aa58c6 bellard
1060 77d4bc34 bellard
    return val;
1061 77d4bc34 bellard
}
1062 77d4bc34 bellard
1063 f2aa58c6 bellard
static CPUWriteMemoryFunc *pci_unin_write[] = {
1064 f2aa58c6 bellard
    &pci_unin_writeb,
1065 f2aa58c6 bellard
    &pci_unin_writew,
1066 f2aa58c6 bellard
    &pci_unin_writel,
1067 77d4bc34 bellard
};
1068 77d4bc34 bellard
1069 f2aa58c6 bellard
static CPUReadMemoryFunc *pci_unin_read[] = {
1070 f2aa58c6 bellard
    &pci_unin_readb,
1071 f2aa58c6 bellard
    &pci_unin_readw,
1072 f2aa58c6 bellard
    &pci_unin_readl,
1073 77d4bc34 bellard
};
1074 30468f78 bellard
#endif
1075 30468f78 bellard
1076 30468f78 bellard
static void pmac_set_irq(PCIDevice *d, int irq_num, int level)
1077 30468f78 bellard
{
1078 30468f78 bellard
    openpic_t *openpic;
1079 30468f78 bellard
    /* XXX: we do not simulate the hardware - we rely on the BIOS to
1080 30468f78 bellard
       set correctly for irq line field */
1081 30468f78 bellard
    openpic = d->bus->openpic;
1082 30468f78 bellard
#ifdef TARGET_PPC
1083 30468f78 bellard
    if (openpic)
1084 30468f78 bellard
        openpic_set_irq(openpic, d->config[PCI_INTERRUPT_LINE], level);
1085 30468f78 bellard
#endif
1086 30468f78 bellard
}
1087 30468f78 bellard
1088 30468f78 bellard
void pci_pmac_set_openpic(PCIBus *bus, openpic_t *openpic)
1089 30468f78 bellard
{
1090 30468f78 bellard
    bus->openpic = openpic;
1091 30468f78 bellard
}
1092 77d4bc34 bellard
1093 30468f78 bellard
PCIBus *pci_pmac_init(void)
1094 77d4bc34 bellard
{
1095 30468f78 bellard
    PCIBus *s;
1096 77d4bc34 bellard
    PCIDevice *d;
1097 77d4bc34 bellard
    int pci_mem_config, pci_mem_data;
1098 77d4bc34 bellard
1099 f2aa58c6 bellard
    /* Use values found on a real PowerMac */
1100 f2aa58c6 bellard
    /* Uninorth main bus */
1101 30468f78 bellard
    s = pci_register_bus();
1102 30468f78 bellard
    s->set_irq = pmac_set_irq;
1103 30468f78 bellard
1104 f2aa58c6 bellard
    pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read, 
1105 f2aa58c6 bellard
                                            pci_unin_main_config_write, s);
1106 f2aa58c6 bellard
    pci_mem_data = cpu_register_io_memory(0, pci_unin_main_read,
1107 f2aa58c6 bellard
                                          pci_unin_main_write, s);
1108 f2aa58c6 bellard
    cpu_register_physical_memory(0xf2800000, 0x1000, pci_mem_config);
1109 f2aa58c6 bellard
    cpu_register_physical_memory(0xf2c00000, 0x1000, pci_mem_data);
1110 30468f78 bellard
    s->devfn_min = 11 << 3;
1111 30468f78 bellard
    d = pci_register_device(s, "Uni-north main", sizeof(PCIDevice), 
1112 30468f78 bellard
                            11 << 3, NULL, NULL);
1113 f2aa58c6 bellard
    d->config[0x00] = 0x6b; // vendor_id : Apple
1114 f2aa58c6 bellard
    d->config[0x01] = 0x10;
1115 f2aa58c6 bellard
    d->config[0x02] = 0x1F; // device_id
1116 f2aa58c6 bellard
    d->config[0x03] = 0x00;
1117 f2aa58c6 bellard
    d->config[0x08] = 0x00; // revision
1118 f2aa58c6 bellard
    d->config[0x0A] = 0x00; // class_sub = pci host
1119 f2aa58c6 bellard
    d->config[0x0B] = 0x06; // class_base = PCI_bridge
1120 f2aa58c6 bellard
    d->config[0x0C] = 0x08; // cache_line_size
1121 f2aa58c6 bellard
    d->config[0x0D] = 0x10; // latency_timer
1122 f2aa58c6 bellard
    d->config[0x0E] = 0x00; // header_type
1123 f2aa58c6 bellard
    d->config[0x34] = 0x00; // capabilities_pointer
1124 f2aa58c6 bellard
1125 f2aa58c6 bellard
#if 0 // XXX: not activated as PPC BIOS doesn't handle mutiple buses properly
1126 f2aa58c6 bellard
    /* pci-to-pci bridge */
1127 f2aa58c6 bellard
    d = pci_register_device("Uni-north bridge", sizeof(PCIDevice), 0, 13 << 3,
1128 f2aa58c6 bellard
                            NULL, NULL);
1129 f2aa58c6 bellard
    d->config[0x00] = 0x11; // vendor_id : TI
1130 f2aa58c6 bellard
    d->config[0x01] = 0x10;
1131 f2aa58c6 bellard
    d->config[0x02] = 0x26; // device_id
1132 f2aa58c6 bellard
    d->config[0x03] = 0x00;
1133 f2aa58c6 bellard
    d->config[0x08] = 0x05; // revision
1134 f2aa58c6 bellard
    d->config[0x0A] = 0x04; // class_sub = pci2pci
1135 f2aa58c6 bellard
    d->config[0x0B] = 0x06; // class_base = PCI_bridge
1136 f2aa58c6 bellard
    d->config[0x0C] = 0x08; // cache_line_size
1137 f2aa58c6 bellard
    d->config[0x0D] = 0x20; // latency_timer
1138 f2aa58c6 bellard
    d->config[0x0E] = 0x01; // header_type
1139 f2aa58c6 bellard

1140 f2aa58c6 bellard
    d->config[0x18] = 0x01; // primary_bus
1141 f2aa58c6 bellard
    d->config[0x19] = 0x02; // secondary_bus
1142 f2aa58c6 bellard
    d->config[0x1A] = 0x02; // subordinate_bus
1143 f2aa58c6 bellard
    d->config[0x1B] = 0x20; // secondary_latency_timer
1144 f2aa58c6 bellard
    d->config[0x1C] = 0x11; // io_base
1145 f2aa58c6 bellard
    d->config[0x1D] = 0x01; // io_limit
1146 f2aa58c6 bellard
    d->config[0x20] = 0x00; // memory_base
1147 f2aa58c6 bellard
    d->config[0x21] = 0x80;
1148 f2aa58c6 bellard
    d->config[0x22] = 0x00; // memory_limit
1149 f2aa58c6 bellard
    d->config[0x23] = 0x80;
1150 f2aa58c6 bellard
    d->config[0x24] = 0x01; // prefetchable_memory_base
1151 f2aa58c6 bellard
    d->config[0x25] = 0x80;
1152 f2aa58c6 bellard
    d->config[0x26] = 0xF1; // prefectchable_memory_limit
1153 f2aa58c6 bellard
    d->config[0x27] = 0x7F;
1154 f2aa58c6 bellard
    // d->config[0x34] = 0xdc // capabilities_pointer
1155 f2aa58c6 bellard
#endif
1156 f2aa58c6 bellard
#if 0 // XXX: not needed for now
1157 f2aa58c6 bellard
    /* Uninorth AGP bus */
1158 f2aa58c6 bellard
    s = &pci_bridge[1];
1159 f2aa58c6 bellard
    pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read, 
1160 f2aa58c6 bellard
                                            pci_unin_config_write, s);
1161 f2aa58c6 bellard
    pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
1162 f2aa58c6 bellard
                                          pci_unin_write, s);
1163 f2aa58c6 bellard
    cpu_register_physical_memory(0xf0800000, 0x1000, pci_mem_config);
1164 f2aa58c6 bellard
    cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data);
1165 f2aa58c6 bellard

1166 f2aa58c6 bellard
    d = pci_register_device("Uni-north AGP", sizeof(PCIDevice), 0, 11 << 3,
1167 f2aa58c6 bellard
                            NULL, NULL);
1168 f2aa58c6 bellard
    d->config[0x00] = 0x6b; // vendor_id : Apple
1169 f2aa58c6 bellard
    d->config[0x01] = 0x10;
1170 f2aa58c6 bellard
    d->config[0x02] = 0x20; // device_id
1171 f2aa58c6 bellard
    d->config[0x03] = 0x00;
1172 f2aa58c6 bellard
    d->config[0x08] = 0x00; // revision
1173 f2aa58c6 bellard
    d->config[0x0A] = 0x00; // class_sub = pci host
1174 f2aa58c6 bellard
    d->config[0x0B] = 0x06; // class_base = PCI_bridge
1175 f2aa58c6 bellard
    d->config[0x0C] = 0x08; // cache_line_size
1176 f2aa58c6 bellard
    d->config[0x0D] = 0x10; // latency_timer
1177 f2aa58c6 bellard
    d->config[0x0E] = 0x00; // header_type
1178 f2aa58c6 bellard
    //    d->config[0x34] = 0x80; // capabilities_pointer
1179 f2aa58c6 bellard
#endif
1180 77d4bc34 bellard
1181 f2aa58c6 bellard
#if 0 // XXX: not needed for now
1182 f2aa58c6 bellard
    /* Uninorth internal bus */
1183 f2aa58c6 bellard
    s = &pci_bridge[2];
1184 f2aa58c6 bellard
    pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read, 
1185 f2aa58c6 bellard
                                            pci_unin_config_write, s);
1186 f2aa58c6 bellard
    pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
1187 f2aa58c6 bellard
                                          pci_unin_write, s);
1188 f2aa58c6 bellard
    cpu_register_physical_memory(0xf4800000, 0x1000, pci_mem_config);
1189 f2aa58c6 bellard
    cpu_register_physical_memory(0xf4c00000, 0x1000, pci_mem_data);
1190 f2aa58c6 bellard

1191 f2aa58c6 bellard
    d = pci_register_device("Uni-north internal", sizeof(PCIDevice),
1192 f2aa58c6 bellard
                            3, 11 << 3, NULL, NULL);
1193 f2aa58c6 bellard
    d->config[0x00] = 0x6b; // vendor_id : Apple
1194 f2aa58c6 bellard
    d->config[0x01] = 0x10;
1195 f2aa58c6 bellard
    d->config[0x02] = 0x1E; // device_id
1196 f2aa58c6 bellard
    d->config[0x03] = 0x00;
1197 f2aa58c6 bellard
    d->config[0x08] = 0x00; // revision
1198 f2aa58c6 bellard
    d->config[0x0A] = 0x00; // class_sub = pci host
1199 f2aa58c6 bellard
    d->config[0x0B] = 0x06; // class_base = PCI_bridge
1200 f2aa58c6 bellard
    d->config[0x0C] = 0x08; // cache_line_size
1201 f2aa58c6 bellard
    d->config[0x0D] = 0x10; // latency_timer
1202 f2aa58c6 bellard
    d->config[0x0E] = 0x00; // header_type
1203 f2aa58c6 bellard
    d->config[0x34] = 0x00; // capabilities_pointer
1204 f2aa58c6 bellard
#endif
1205 f2aa58c6 bellard
1206 f2aa58c6 bellard
#if 0 // Grackle ?
1207 77d4bc34 bellard
    /* same values as PearPC - check this */
1208 77d4bc34 bellard
    d->config[0x00] = 0x11; // vendor_id
1209 77d4bc34 bellard
    d->config[0x01] = 0x10;
1210 77d4bc34 bellard
    d->config[0x02] = 0x26; // device_id
1211 77d4bc34 bellard
    d->config[0x03] = 0x00;
1212 77d4bc34 bellard
    d->config[0x08] = 0x02; // revision
1213 77d4bc34 bellard
    d->config[0x0a] = 0x04; // class_sub = pci2pci
1214 77d4bc34 bellard
    d->config[0x0b] = 0x06; // class_base = PCI_bridge
1215 77d4bc34 bellard
    d->config[0x0e] = 0x01; // header_type
1216 77d4bc34 bellard

1217 77d4bc34 bellard
    d->config[0x18] = 0x0;  // primary_bus
1218 77d4bc34 bellard
    d->config[0x19] = 0x1;  // secondary_bus
1219 77d4bc34 bellard
    d->config[0x1a] = 0x1;  // subordinate_bus
1220 77d4bc34 bellard
    d->config[0x1c] = 0x10; // io_base
1221 77d4bc34 bellard
    d->config[0x1d] = 0x20; // io_limit
1222 77d4bc34 bellard
    
1223 77d4bc34 bellard
    d->config[0x20] = 0x80; // memory_base
1224 77d4bc34 bellard
    d->config[0x21] = 0x80;
1225 77d4bc34 bellard
    d->config[0x22] = 0x90; // memory_limit
1226 77d4bc34 bellard
    d->config[0x23] = 0x80;
1227 77d4bc34 bellard
    
1228 77d4bc34 bellard
    d->config[0x24] = 0x00; // prefetchable_memory_base
1229 77d4bc34 bellard
    d->config[0x25] = 0x84;
1230 77d4bc34 bellard
    d->config[0x26] = 0x00; // prefetchable_memory_limit
1231 77d4bc34 bellard
    d->config[0x27] = 0x85;
1232 f2aa58c6 bellard
#endif
1233 30468f78 bellard
    return s;
1234 77d4bc34 bellard
}
1235 77d4bc34 bellard
1236 0ac32c83 bellard
/***********************************************************/
1237 0ac32c83 bellard
/* generic PCI irq support */
1238 0ac32c83 bellard
1239 0ac32c83 bellard
/* 0 <= irq_num <= 3. level must be 0 or 1 */
1240 77d4bc34 bellard
void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
1241 77d4bc34 bellard
{
1242 30468f78 bellard
    PCIBus *bus = pci_dev->bus;
1243 30468f78 bellard
    bus->set_irq(pci_dev, irq_num, level);
1244 77d4bc34 bellard
}
1245 0ac32c83 bellard
1246 0ac32c83 bellard
/***********************************************************/
1247 0ac32c83 bellard
/* monitor info on PCI */
1248 0ac32c83 bellard
1249 0ac32c83 bellard
static void pci_info_device(PCIDevice *d)
1250 0ac32c83 bellard
{
1251 0ac32c83 bellard
    int i, class;
1252 0ac32c83 bellard
    PCIIORegion *r;
1253 0ac32c83 bellard
1254 8e3a9fd2 bellard
    term_printf("  Bus %2d, device %3d, function %d:\n",
1255 30468f78 bellard
           d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
1256 0ac32c83 bellard
    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
1257 8e3a9fd2 bellard
    term_printf("    ");
1258 0ac32c83 bellard
    switch(class) {
1259 0ac32c83 bellard
    case 0x0101:
1260 8e3a9fd2 bellard
        term_printf("IDE controller");
1261 0ac32c83 bellard
        break;
1262 0ac32c83 bellard
    case 0x0200:
1263 8e3a9fd2 bellard
        term_printf("Ethernet controller");
1264 0ac32c83 bellard
        break;
1265 0ac32c83 bellard
    case 0x0300:
1266 8e3a9fd2 bellard
        term_printf("VGA controller");
1267 0ac32c83 bellard
        break;
1268 0ac32c83 bellard
    default:
1269 8e3a9fd2 bellard
        term_printf("Class %04x", class);
1270 0ac32c83 bellard
        break;
1271 0ac32c83 bellard
    }
1272 8e3a9fd2 bellard
    term_printf(": PCI device %04x:%04x\n",
1273 0ac32c83 bellard
           le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
1274 0ac32c83 bellard
           le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
1275 0ac32c83 bellard
1276 0ac32c83 bellard
    if (d->config[PCI_INTERRUPT_PIN] != 0) {
1277 8e3a9fd2 bellard
        term_printf("      IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
1278 0ac32c83 bellard
    }
1279 8a8696a3 bellard
    for(i = 0;i < PCI_NUM_REGIONS; i++) {
1280 0ac32c83 bellard
        r = &d->io_regions[i];
1281 0ac32c83 bellard
        if (r->size != 0) {
1282 8e3a9fd2 bellard
            term_printf("      BAR%d: ", i);
1283 0ac32c83 bellard
            if (r->type & PCI_ADDRESS_SPACE_IO) {
1284 8e3a9fd2 bellard
                term_printf("I/O at 0x%04x [0x%04x].\n", 
1285 0ac32c83 bellard
                       r->addr, r->addr + r->size - 1);
1286 0ac32c83 bellard
            } else {
1287 8e3a9fd2 bellard
                term_printf("32 bit memory at 0x%08x [0x%08x].\n", 
1288 0ac32c83 bellard
                       r->addr, r->addr + r->size - 1);
1289 0ac32c83 bellard
            }
1290 0ac32c83 bellard
        }
1291 0ac32c83 bellard
    }
1292 0ac32c83 bellard
}
1293 0ac32c83 bellard
1294 0ac32c83 bellard
void pci_info(void)
1295 0ac32c83 bellard
{
1296 30468f78 bellard
    PCIBus *bus = first_bus;
1297 30468f78 bellard
    PCIDevice *d;
1298 30468f78 bellard
    int devfn;
1299 0ac32c83 bellard
    
1300 30468f78 bellard
    if (bus) {
1301 30468f78 bellard
        for(devfn = 0; devfn < 256; devfn++) {
1302 30468f78 bellard
            d = bus->devices[devfn];
1303 30468f78 bellard
            if (d)
1304 30468f78 bellard
                pci_info_device(d);
1305 0ac32c83 bellard
        }
1306 0ac32c83 bellard
    }
1307 0ac32c83 bellard
}
1308 0ac32c83 bellard
1309 0ac32c83 bellard
/***********************************************************/
1310 0ac32c83 bellard
/* XXX: the following should be moved to the PC BIOS */
1311 0ac32c83 bellard
1312 30468f78 bellard
static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
1313 0ac32c83 bellard
{
1314 0ac32c83 bellard
    return cpu_inb(cpu_single_env, addr);
1315 0ac32c83 bellard
}
1316 0ac32c83 bellard
1317 0ac32c83 bellard
static void isa_outb(uint32_t val, uint32_t addr)
1318 0ac32c83 bellard
{
1319 0ac32c83 bellard
    cpu_outb(cpu_single_env, addr, val);
1320 0ac32c83 bellard
}
1321 0ac32c83 bellard
1322 30468f78 bellard
static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
1323 0ac32c83 bellard
{
1324 0ac32c83 bellard
    return cpu_inw(cpu_single_env, addr);
1325 0ac32c83 bellard
}
1326 0ac32c83 bellard
1327 30468f78 bellard
static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
1328 0ac32c83 bellard
{
1329 0ac32c83 bellard
    cpu_outw(cpu_single_env, addr, val);
1330 0ac32c83 bellard
}
1331 0ac32c83 bellard
1332 30468f78 bellard
static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
1333 0ac32c83 bellard
{
1334 0ac32c83 bellard
    return cpu_inl(cpu_single_env, addr);
1335 0ac32c83 bellard
}
1336 0ac32c83 bellard
1337 30468f78 bellard
static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
1338 0ac32c83 bellard
{
1339 0ac32c83 bellard
    cpu_outl(cpu_single_env, addr, val);
1340 0ac32c83 bellard
}
1341 0ac32c83 bellard
1342 0ac32c83 bellard
static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
1343 0ac32c83 bellard
{
1344 30468f78 bellard
    PCIBus *s = d->bus;
1345 30468f78 bellard
    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
1346 0ac32c83 bellard
        (d->devfn << 8) | addr;
1347 0ac32c83 bellard
    pci_data_write(s, 0, val, 4);
1348 0ac32c83 bellard
}
1349 0ac32c83 bellard
1350 0ac32c83 bellard
static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
1351 0ac32c83 bellard
{
1352 30468f78 bellard
    PCIBus *s = d->bus;
1353 30468f78 bellard
    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
1354 0ac32c83 bellard
        (d->devfn << 8) | (addr & ~3);
1355 0ac32c83 bellard
    pci_data_write(s, addr & 3, val, 2);
1356 0ac32c83 bellard
}
1357 0ac32c83 bellard
1358 0ac32c83 bellard
static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
1359 0ac32c83 bellard
{
1360 30468f78 bellard
    PCIBus *s = d->bus;
1361 30468f78 bellard
    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
1362 0ac32c83 bellard
        (d->devfn << 8) | (addr & ~3);
1363 0ac32c83 bellard
    pci_data_write(s, addr & 3, val, 1);
1364 0ac32c83 bellard
}
1365 0ac32c83 bellard
1366 30468f78 bellard
static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
1367 0ac32c83 bellard
{
1368 30468f78 bellard
    PCIBus *s = d->bus;
1369 30468f78 bellard
    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
1370 0ac32c83 bellard
        (d->devfn << 8) | addr;
1371 0ac32c83 bellard
    return pci_data_read(s, 0, 4);
1372 0ac32c83 bellard
}
1373 0ac32c83 bellard
1374 0ac32c83 bellard
static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
1375 0ac32c83 bellard
{
1376 30468f78 bellard
    PCIBus *s = d->bus;
1377 30468f78 bellard
    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
1378 0ac32c83 bellard
        (d->devfn << 8) | (addr & ~3);
1379 0ac32c83 bellard
    return pci_data_read(s, addr & 3, 2);
1380 0ac32c83 bellard
}
1381 0ac32c83 bellard
1382 0ac32c83 bellard
static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
1383 0ac32c83 bellard
{
1384 30468f78 bellard
    PCIBus *s = d->bus;
1385 30468f78 bellard
    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
1386 0ac32c83 bellard
        (d->devfn << 8) | (addr & ~3);
1387 0ac32c83 bellard
    return pci_data_read(s, addr & 3, 1);
1388 0ac32c83 bellard
}
1389 69b91039 bellard
1390 69b91039 bellard
static uint32_t pci_bios_io_addr;
1391 69b91039 bellard
static uint32_t pci_bios_mem_addr;
1392 0ac32c83 bellard
/* host irqs corresponding to PCI irqs A-D */
1393 0ac32c83 bellard
static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
1394 69b91039 bellard
1395 69b91039 bellard
static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
1396 69b91039 bellard
{
1397 69b91039 bellard
    PCIIORegion *r;
1398 0ac32c83 bellard
    uint16_t cmd;
1399 8a8696a3 bellard
    uint32_t ofs;
1400 8a8696a3 bellard
1401 8a8696a3 bellard
    if ( region_num == PCI_ROM_SLOT ) {
1402 8a8696a3 bellard
        ofs = 0x30;
1403 8a8696a3 bellard
    }else{
1404 8a8696a3 bellard
        ofs = 0x10 + region_num * 4;
1405 8a8696a3 bellard
    }
1406 69b91039 bellard
1407 8a8696a3 bellard
    pci_config_writel(d, ofs, addr);
1408 69b91039 bellard
    r = &d->io_regions[region_num];
1409 69b91039 bellard
1410 69b91039 bellard
    /* enable memory mappings */
1411 0ac32c83 bellard
    cmd = pci_config_readw(d, PCI_COMMAND);
1412 8a8696a3 bellard
    if ( region_num == PCI_ROM_SLOT )
1413 8a8696a3 bellard
        cmd |= 2;
1414 8a8696a3 bellard
    else if (r->type & PCI_ADDRESS_SPACE_IO)
1415 0ac32c83 bellard
        cmd |= 1;
1416 69b91039 bellard
    else
1417 0ac32c83 bellard
        cmd |= 2;
1418 0ac32c83 bellard
    pci_config_writew(d, PCI_COMMAND, cmd);
1419 69b91039 bellard
}
1420 69b91039 bellard
1421 69b91039 bellard
static void pci_bios_init_device(PCIDevice *d)
1422 69b91039 bellard
{
1423 69b91039 bellard
    int class;
1424 69b91039 bellard
    PCIIORegion *r;
1425 69b91039 bellard
    uint32_t *paddr;
1426 63ce9e0a bellard
    int i, pin, pic_irq, vendor_id, device_id;
1427 69b91039 bellard
1428 63ce9e0a bellard
    class = pci_config_readw(d, PCI_CLASS_DEVICE);
1429 1f62d938 bellard
    vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
1430 1f62d938 bellard
    device_id = pci_config_readw(d, PCI_DEVICE_ID);
1431 69b91039 bellard
    switch(class) {
1432 69b91039 bellard
    case 0x0101:
1433 63ce9e0a bellard
        if (vendor_id == 0x8086 && device_id == 0x7010) {
1434 63ce9e0a bellard
            /* PIIX3 IDE */
1435 63ce9e0a bellard
            pci_config_writew(d, 0x40, 0x8000); // enable IDE0
1436 7f647cf6 bellard
            pci_config_writew(d, 0x42, 0x8000); // enable IDE1
1437 d187d4b2 bellard
            goto default_map;
1438 63ce9e0a bellard
        } else {
1439 63ce9e0a bellard
            /* IDE: we map it as in ISA mode */
1440 63ce9e0a bellard
            pci_set_io_region_addr(d, 0, 0x1f0);
1441 63ce9e0a bellard
            pci_set_io_region_addr(d, 1, 0x3f4);
1442 63ce9e0a bellard
            pci_set_io_region_addr(d, 2, 0x170);
1443 63ce9e0a bellard
            pci_set_io_region_addr(d, 3, 0x374);
1444 63ce9e0a bellard
        }
1445 69b91039 bellard
        break;
1446 0ac32c83 bellard
    case 0x0300:
1447 4c7634bc bellard
        if (vendor_id != 0x1234)
1448 4c7634bc bellard
            goto default_map;
1449 0ac32c83 bellard
        /* VGA: map frame buffer to default Bochs VBE address */
1450 0ac32c83 bellard
        pci_set_io_region_addr(d, 0, 0xE0000000);
1451 0ac32c83 bellard
        break;
1452 f2aa58c6 bellard
    case 0x0800:
1453 f2aa58c6 bellard
        /* PIC */
1454 f2aa58c6 bellard
        vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
1455 f2aa58c6 bellard
        device_id = pci_config_readw(d, PCI_DEVICE_ID);
1456 f2aa58c6 bellard
        if (vendor_id == 0x1014) {
1457 f2aa58c6 bellard
            /* IBM */
1458 f2aa58c6 bellard
            if (device_id == 0x0046 || device_id == 0xFFFF) {
1459 f2aa58c6 bellard
                /* MPIC & MPIC2 */
1460 f2aa58c6 bellard
                pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
1461 f2aa58c6 bellard
            }
1462 f2aa58c6 bellard
        }
1463 f2aa58c6 bellard
        break;
1464 1f62d938 bellard
    case 0xff00:
1465 f2aa58c6 bellard
        if (vendor_id == 0x0106b &&
1466 f2aa58c6 bellard
            (device_id == 0x0017 || device_id == 0x0022)) {
1467 1f62d938 bellard
            /* macio bridge */
1468 1f62d938 bellard
            pci_set_io_region_addr(d, 0, 0x80800000);
1469 1f62d938 bellard
        }
1470 1f62d938 bellard
        break;
1471 69b91039 bellard
    default:
1472 4c7634bc bellard
    default_map:
1473 69b91039 bellard
        /* default memory mappings */
1474 8a8696a3 bellard
        for(i = 0; i < PCI_NUM_REGIONS; i++) {
1475 69b91039 bellard
            r = &d->io_regions[i];
1476 69b91039 bellard
            if (r->size) {
1477 69b91039 bellard
                if (r->type & PCI_ADDRESS_SPACE_IO)
1478 69b91039 bellard
                    paddr = &pci_bios_io_addr;
1479 69b91039 bellard
                else
1480 69b91039 bellard
                    paddr = &pci_bios_mem_addr;
1481 69b91039 bellard
                *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
1482 69b91039 bellard
                pci_set_io_region_addr(d, i, *paddr);
1483 69b91039 bellard
                *paddr += r->size;
1484 69b91039 bellard
            }
1485 69b91039 bellard
        }
1486 69b91039 bellard
        break;
1487 69b91039 bellard
    }
1488 0ac32c83 bellard
1489 0ac32c83 bellard
    /* map the interrupt */
1490 0ac32c83 bellard
    pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
1491 0ac32c83 bellard
    if (pin != 0) {
1492 0ac32c83 bellard
        pin = pci_slot_get_pirq(d, pin - 1);
1493 0ac32c83 bellard
        pic_irq = pci_irqs[pin];
1494 0ac32c83 bellard
        pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
1495 0ac32c83 bellard
    }
1496 69b91039 bellard
}
1497 69b91039 bellard
1498 69b91039 bellard
/*
1499 69b91039 bellard
 * This function initializes the PCI devices as a normal PCI BIOS
1500 69b91039 bellard
 * would do. It is provided just in case the BIOS has no support for
1501 69b91039 bellard
 * PCI.
1502 69b91039 bellard
 */
1503 69b91039 bellard
void pci_bios_init(void)
1504 69b91039 bellard
{
1505 30468f78 bellard
    PCIBus *bus;
1506 30468f78 bellard
    PCIDevice *d;
1507 30468f78 bellard
    int devfn, i, irq;
1508 0ac32c83 bellard
    uint8_t elcr[2];
1509 69b91039 bellard
1510 69b91039 bellard
    pci_bios_io_addr = 0xc000;
1511 69b91039 bellard
    pci_bios_mem_addr = 0xf0000000;
1512 69b91039 bellard
1513 0ac32c83 bellard
    /* activate IRQ mappings */
1514 0ac32c83 bellard
    elcr[0] = 0x00;
1515 0ac32c83 bellard
    elcr[1] = 0x00;
1516 0ac32c83 bellard
    for(i = 0; i < 4; i++) {
1517 0ac32c83 bellard
        irq = pci_irqs[i];
1518 0ac32c83 bellard
        /* set to trigger level */
1519 0ac32c83 bellard
        elcr[irq >> 3] |= (1 << (irq & 7));
1520 0ac32c83 bellard
        /* activate irq remapping in PIIX */
1521 0ac32c83 bellard
        pci_config_writeb((PCIDevice *)piix3_state, 0x60 + i, irq);
1522 0ac32c83 bellard
    }
1523 0ac32c83 bellard
    isa_outb(elcr[0], 0x4d0);
1524 0ac32c83 bellard
    isa_outb(elcr[1], 0x4d1);
1525 0ac32c83 bellard
1526 30468f78 bellard
    bus = first_bus;
1527 30468f78 bellard
    if (bus) {
1528 30468f78 bellard
        for(devfn = 0; devfn < 256; devfn++) {
1529 30468f78 bellard
            d = bus->devices[devfn];
1530 30468f78 bellard
            if (d)
1531 30468f78 bellard
                pci_bios_init_device(d);
1532 77d4bc34 bellard
        }
1533 77d4bc34 bellard
    }
1534 77d4bc34 bellard
}