Statistics
| Branch: | Revision:

root / hw / pci.c @ a8d3431a

History | View | Annotate | Download (41.8 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 30468f78 bellard
    slot_addend = (pci_dev->devfn >> 3);
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 8a8696a3 bellard
    PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read, 
698 8a8696a3 bellard
                                           PPC_PCIIO_write, s);
699 77d4bc34 bellard
    cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
700 77d4bc34 bellard
701 30468f78 bellard
    d = pci_register_device(s, "PREP PCI Bridge", sizeof(PCIDevice), 0,
702 77d4bc34 bellard
                            NULL, NULL);
703 77d4bc34 bellard
704 77d4bc34 bellard
    /* XXX: put correct IDs */
705 77d4bc34 bellard
    d->config[0x00] = 0x11; // vendor_id
706 77d4bc34 bellard
    d->config[0x01] = 0x10;
707 77d4bc34 bellard
    d->config[0x02] = 0x26; // device_id
708 77d4bc34 bellard
    d->config[0x03] = 0x00;
709 77d4bc34 bellard
    d->config[0x08] = 0x02; // revision
710 77d4bc34 bellard
    d->config[0x0a] = 0x04; // class_sub = pci2pci
711 77d4bc34 bellard
    d->config[0x0b] = 0x06; // class_base = PCI_bridge
712 77d4bc34 bellard
    d->config[0x0e] = 0x01; // header_type
713 30468f78 bellard
    return s;
714 77d4bc34 bellard
}
715 77d4bc34 bellard
716 77d4bc34 bellard
717 77d4bc34 bellard
/* pmac pci init */
718 77d4bc34 bellard
719 30468f78 bellard
#if 0
720 f2aa58c6 bellard
/* Grackle PCI host */
721 f2aa58c6 bellard
static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr,
722 f2aa58c6 bellard
                                       uint32_t val)
723 77d4bc34 bellard
{
724 30468f78 bellard
    PCIBus *s = opaque;
725 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
726 77d4bc34 bellard
    val = bswap32(val);
727 77d4bc34 bellard
#endif
728 77d4bc34 bellard
    s->config_reg = val;
729 77d4bc34 bellard
}
730 77d4bc34 bellard
731 f2aa58c6 bellard
static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr)
732 77d4bc34 bellard
{
733 30468f78 bellard
    PCIBus *s = opaque;
734 77d4bc34 bellard
    uint32_t val;
735 77d4bc34 bellard
736 77d4bc34 bellard
    val = s->config_reg;
737 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
738 77d4bc34 bellard
    val = bswap32(val);
739 77d4bc34 bellard
#endif
740 77d4bc34 bellard
    return val;
741 77d4bc34 bellard
}
742 77d4bc34 bellard
743 f2aa58c6 bellard
static CPUWriteMemoryFunc *pci_grackle_config_write[] = {
744 f2aa58c6 bellard
    &pci_grackle_config_writel,
745 f2aa58c6 bellard
    &pci_grackle_config_writel,
746 f2aa58c6 bellard
    &pci_grackle_config_writel,
747 77d4bc34 bellard
};
748 77d4bc34 bellard
749 f2aa58c6 bellard
static CPUReadMemoryFunc *pci_grackle_config_read[] = {
750 f2aa58c6 bellard
    &pci_grackle_config_readl,
751 f2aa58c6 bellard
    &pci_grackle_config_readl,
752 f2aa58c6 bellard
    &pci_grackle_config_readl,
753 77d4bc34 bellard
};
754 77d4bc34 bellard
755 f2aa58c6 bellard
static void pci_grackle_writeb (void *opaque, target_phys_addr_t addr,
756 f2aa58c6 bellard
                                uint32_t val)
757 77d4bc34 bellard
{
758 30468f78 bellard
    PCIBus *s = opaque;
759 77d4bc34 bellard
    pci_data_write(s, addr, val, 1);
760 77d4bc34 bellard
}
761 77d4bc34 bellard
762 f2aa58c6 bellard
static void pci_grackle_writew (void *opaque, target_phys_addr_t addr,
763 f2aa58c6 bellard
                                uint32_t val)
764 77d4bc34 bellard
{
765 30468f78 bellard
    PCIBus *s = opaque;
766 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
767 77d4bc34 bellard
    val = bswap16(val);
768 77d4bc34 bellard
#endif
769 77d4bc34 bellard
    pci_data_write(s, addr, val, 2);
770 77d4bc34 bellard
}
771 77d4bc34 bellard
772 f2aa58c6 bellard
static void pci_grackle_writel (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 = bswap32(val);
778 77d4bc34 bellard
#endif
779 77d4bc34 bellard
    pci_data_write(s, addr, val, 4);
780 77d4bc34 bellard
}
781 77d4bc34 bellard
782 f2aa58c6 bellard
static uint32_t pci_grackle_readb (void *opaque, target_phys_addr_t addr)
783 77d4bc34 bellard
{
784 30468f78 bellard
    PCIBus *s = opaque;
785 77d4bc34 bellard
    uint32_t val;
786 77d4bc34 bellard
    val = pci_data_read(s, addr, 1);
787 77d4bc34 bellard
    return val;
788 77d4bc34 bellard
}
789 77d4bc34 bellard
790 f2aa58c6 bellard
static uint32_t pci_grackle_readw (void *opaque, target_phys_addr_t addr)
791 77d4bc34 bellard
{
792 30468f78 bellard
    PCIBus *s = opaque;
793 77d4bc34 bellard
    uint32_t val;
794 77d4bc34 bellard
    val = pci_data_read(s, addr, 2);
795 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
796 77d4bc34 bellard
    val = bswap16(val);
797 77d4bc34 bellard
#endif
798 77d4bc34 bellard
    return val;
799 77d4bc34 bellard
}
800 77d4bc34 bellard
801 f2aa58c6 bellard
static uint32_t pci_grackle_readl (void *opaque, target_phys_addr_t addr)
802 f2aa58c6 bellard
{
803 30468f78 bellard
    PCIBus *s = opaque;
804 f2aa58c6 bellard
    uint32_t val;
805 f2aa58c6 bellard
806 f2aa58c6 bellard
    val = pci_data_read(s, addr, 4);
807 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
808 f2aa58c6 bellard
    val = bswap32(val);
809 f2aa58c6 bellard
#endif
810 f2aa58c6 bellard
    return val;
811 f2aa58c6 bellard
}
812 f2aa58c6 bellard
813 f2aa58c6 bellard
static CPUWriteMemoryFunc *pci_grackle_write[] = {
814 f2aa58c6 bellard
    &pci_grackle_writeb,
815 f2aa58c6 bellard
    &pci_grackle_writew,
816 f2aa58c6 bellard
    &pci_grackle_writel,
817 f2aa58c6 bellard
};
818 f2aa58c6 bellard
819 f2aa58c6 bellard
static CPUReadMemoryFunc *pci_grackle_read[] = {
820 f2aa58c6 bellard
    &pci_grackle_readb,
821 f2aa58c6 bellard
    &pci_grackle_readw,
822 f2aa58c6 bellard
    &pci_grackle_readl,
823 f2aa58c6 bellard
};
824 30468f78 bellard
#endif
825 f2aa58c6 bellard
826 f2aa58c6 bellard
/* Uninorth PCI host (for all Mac99 and newer machines */
827 f2aa58c6 bellard
static void pci_unin_main_config_writel (void *opaque, target_phys_addr_t addr,
828 f2aa58c6 bellard
                                         uint32_t val)
829 f2aa58c6 bellard
{
830 30468f78 bellard
    PCIBus *s = opaque;
831 f2aa58c6 bellard
    int i;
832 f2aa58c6 bellard
833 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
834 f2aa58c6 bellard
    val = bswap32(val);
835 f2aa58c6 bellard
#endif
836 f2aa58c6 bellard
837 f2aa58c6 bellard
    for (i = 11; i < 32; i++) {
838 f2aa58c6 bellard
        if ((val & (1 << i)) != 0)
839 f2aa58c6 bellard
            break;
840 f2aa58c6 bellard
    }
841 f2aa58c6 bellard
#if 0
842 f2aa58c6 bellard
    s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
843 f2aa58c6 bellard
#else
844 f2aa58c6 bellard
    s->config_reg = 0x80000000 | (0 << 16) | (val & 0x7FC) | (i << 11);
845 f2aa58c6 bellard
#endif
846 f2aa58c6 bellard
}
847 f2aa58c6 bellard
848 f2aa58c6 bellard
static uint32_t pci_unin_main_config_readl (void *opaque,
849 f2aa58c6 bellard
                                            target_phys_addr_t addr)
850 f2aa58c6 bellard
{
851 30468f78 bellard
    PCIBus *s = opaque;
852 f2aa58c6 bellard
    uint32_t val;
853 f2aa58c6 bellard
    int devfn;
854 f2aa58c6 bellard
855 f2aa58c6 bellard
    devfn = (s->config_reg >> 8) & 0xFF;
856 f2aa58c6 bellard
    val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
857 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
858 f2aa58c6 bellard
    val = bswap32(val);
859 f2aa58c6 bellard
#endif
860 f2aa58c6 bellard
861 f2aa58c6 bellard
    return val;
862 f2aa58c6 bellard
}
863 f2aa58c6 bellard
864 f2aa58c6 bellard
static CPUWriteMemoryFunc *pci_unin_main_config_write[] = {
865 f2aa58c6 bellard
    &pci_unin_main_config_writel,
866 f2aa58c6 bellard
    &pci_unin_main_config_writel,
867 f2aa58c6 bellard
    &pci_unin_main_config_writel,
868 f2aa58c6 bellard
};
869 f2aa58c6 bellard
870 f2aa58c6 bellard
static CPUReadMemoryFunc *pci_unin_main_config_read[] = {
871 f2aa58c6 bellard
    &pci_unin_main_config_readl,
872 f2aa58c6 bellard
    &pci_unin_main_config_readl,
873 f2aa58c6 bellard
    &pci_unin_main_config_readl,
874 f2aa58c6 bellard
};
875 f2aa58c6 bellard
876 f2aa58c6 bellard
static void pci_unin_main_writeb (void *opaque, target_phys_addr_t addr,
877 f2aa58c6 bellard
                                  uint32_t val)
878 f2aa58c6 bellard
{
879 30468f78 bellard
    PCIBus *s = opaque;
880 f2aa58c6 bellard
    pci_data_write(s, addr & 7, val, 1);
881 f2aa58c6 bellard
}
882 f2aa58c6 bellard
883 f2aa58c6 bellard
static void pci_unin_main_writew (void *opaque, target_phys_addr_t addr,
884 f2aa58c6 bellard
                                  uint32_t val)
885 f2aa58c6 bellard
{
886 30468f78 bellard
    PCIBus *s = opaque;
887 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
888 f2aa58c6 bellard
    val = bswap16(val);
889 f2aa58c6 bellard
#endif
890 f2aa58c6 bellard
    pci_data_write(s, addr & 7, val, 2);
891 f2aa58c6 bellard
}
892 f2aa58c6 bellard
893 f2aa58c6 bellard
static void pci_unin_main_writel (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 = bswap32(val);
899 f2aa58c6 bellard
#endif
900 f2aa58c6 bellard
    pci_data_write(s, addr & 7, val, 4);
901 f2aa58c6 bellard
}
902 f2aa58c6 bellard
903 f2aa58c6 bellard
static uint32_t pci_unin_main_readb (void *opaque, target_phys_addr_t addr)
904 f2aa58c6 bellard
{
905 30468f78 bellard
    PCIBus *s = opaque;
906 f2aa58c6 bellard
    uint32_t val;
907 f2aa58c6 bellard
908 f2aa58c6 bellard
    val = pci_data_read(s, addr & 7, 1);
909 f2aa58c6 bellard
910 f2aa58c6 bellard
    return val;
911 f2aa58c6 bellard
}
912 f2aa58c6 bellard
913 f2aa58c6 bellard
static uint32_t pci_unin_main_readw (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, 2);
919 f2aa58c6 bellard
#ifdef TARGET_WORDS_BIGENDIAN
920 f2aa58c6 bellard
    val = bswap16(val);
921 f2aa58c6 bellard
#endif
922 f2aa58c6 bellard
923 f2aa58c6 bellard
    return val;
924 f2aa58c6 bellard
}
925 f2aa58c6 bellard
926 f2aa58c6 bellard
static uint32_t pci_unin_main_readl (void *opaque, target_phys_addr_t addr)
927 77d4bc34 bellard
{
928 30468f78 bellard
    PCIBus *s = opaque;
929 77d4bc34 bellard
    uint32_t val;
930 77d4bc34 bellard
931 77d4bc34 bellard
    val = pci_data_read(s, addr, 4);
932 77d4bc34 bellard
#ifdef TARGET_WORDS_BIGENDIAN
933 77d4bc34 bellard
    val = bswap32(val);
934 77d4bc34 bellard
#endif
935 f2aa58c6 bellard
936 f2aa58c6 bellard
    return val;
937 f2aa58c6 bellard
}
938 f2aa58c6 bellard
939 f2aa58c6 bellard
static CPUWriteMemoryFunc *pci_unin_main_write[] = {
940 f2aa58c6 bellard
    &pci_unin_main_writeb,
941 f2aa58c6 bellard
    &pci_unin_main_writew,
942 f2aa58c6 bellard
    &pci_unin_main_writel,
943 f2aa58c6 bellard
};
944 f2aa58c6 bellard
945 f2aa58c6 bellard
static CPUReadMemoryFunc *pci_unin_main_read[] = {
946 f2aa58c6 bellard
    &pci_unin_main_readb,
947 f2aa58c6 bellard
    &pci_unin_main_readw,
948 f2aa58c6 bellard
    &pci_unin_main_readl,
949 f2aa58c6 bellard
};
950 f2aa58c6 bellard
951 30468f78 bellard
#if 0
952 30468f78 bellard

953 f2aa58c6 bellard
static void pci_unin_config_writel (void *opaque, target_phys_addr_t addr,
954 f2aa58c6 bellard
                                    uint32_t val)
955 f2aa58c6 bellard
{
956 30468f78 bellard
    PCIBus *s = opaque;
957 f2aa58c6 bellard

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

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

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

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

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