Statistics
| Branch: | Revision:

root / hw / apb_pci.c @ 847c25d0

History | View | Annotate | Download (15.3 kB)

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

    
25
/* XXX This file and most of its contents are somewhat misnamed.  The
26
   Ultrasparc PCI host is called the PCI Bus Module (PBM).  The APB is
27
   the secondary PCI bridge.  */
28

    
29
#include "sysbus.h"
30
#include "pci.h"
31
#include "pci_host.h"
32
#include "pci_bridge.h"
33
#include "pci_internals.h"
34
#include "apb_pci.h"
35
#include "sysemu.h"
36
#include "exec-memory.h"
37

    
38
/* debug APB */
39
//#define DEBUG_APB
40

    
41
#ifdef DEBUG_APB
42
#define APB_DPRINTF(fmt, ...) \
43
do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
44
#else
45
#define APB_DPRINTF(fmt, ...)
46
#endif
47

    
48
/*
49
 * Chipset docs:
50
 * PBM: "UltraSPARC IIi User's Manual",
51
 * http://www.sun.com/processors/manuals/805-0087.pdf
52
 *
53
 * APB: "Advanced PCI Bridge (APB) User's Manual",
54
 * http://www.sun.com/processors/manuals/805-1251.pdf
55
 */
56

    
57
#define PBM_PCI_IMR_MASK    0x7fffffff
58
#define PBM_PCI_IMR_ENABLED 0x80000000
59

    
60
#define POR          (1 << 31)
61
#define SOFT_POR     (1 << 30)
62
#define SOFT_XIR     (1 << 29)
63
#define BTN_POR      (1 << 28)
64
#define BTN_XIR      (1 << 27)
65
#define RESET_MASK   0xf8000000
66
#define RESET_WCMASK 0x98000000
67
#define RESET_WMASK  0x60000000
68

    
69
#define MAX_IVEC 0x30
70

    
71
typedef struct APBState {
72
    SysBusDevice busdev;
73
    PCIBus      *bus;
74
    MemoryRegion apb_config;
75
    MemoryRegion pci_config;
76
    MemoryRegion pci_mmio;
77
    MemoryRegion pci_ioport;
78
    uint32_t iommu[4];
79
    uint32_t pci_control[16];
80
    uint32_t pci_irq_map[8];
81
    uint32_t obio_irq_map[32];
82
    qemu_irq *pbm_irqs;
83
    qemu_irq *ivec_irqs;
84
    uint32_t reset_control;
85
    unsigned int nr_resets;
86
} APBState;
87

    
88
static void apb_config_writel (void *opaque, target_phys_addr_t addr,
89
                               uint64_t val, unsigned size)
90
{
91
    APBState *s = opaque;
92

    
93
    APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %" PRIx64 "\n", __func__, addr, val);
94

    
95
    switch (addr & 0xffff) {
96
    case 0x30 ... 0x4f: /* DMA error registers */
97
        /* XXX: not implemented yet */
98
        break;
99
    case 0x200 ... 0x20b: /* IOMMU */
100
        s->iommu[(addr & 0xf) >> 2] = val;
101
        break;
102
    case 0x20c ... 0x3ff: /* IOMMU flush */
103
        break;
104
    case 0xc00 ... 0xc3f: /* PCI interrupt control */
105
        if (addr & 4) {
106
            s->pci_irq_map[(addr & 0x3f) >> 3] &= PBM_PCI_IMR_MASK;
107
            s->pci_irq_map[(addr & 0x3f) >> 3] |= val & ~PBM_PCI_IMR_MASK;
108
        }
109
        break;
110
    case 0x1000 ... 0x1080: /* OBIO interrupt control */
111
        if (addr & 4) {
112
            s->obio_irq_map[(addr & 0xff) >> 3] &= PBM_PCI_IMR_MASK;
113
            s->obio_irq_map[(addr & 0xff) >> 3] |= val & ~PBM_PCI_IMR_MASK;
114
        }
115
        break;
116
    case 0x2000 ... 0x202f: /* PCI control */
117
        s->pci_control[(addr & 0x3f) >> 2] = val;
118
        break;
119
    case 0xf020 ... 0xf027: /* Reset control */
120
        if (addr & 4) {
121
            val &= RESET_MASK;
122
            s->reset_control &= ~(val & RESET_WCMASK);
123
            s->reset_control |= val & RESET_WMASK;
124
            if (val & SOFT_POR) {
125
                s->nr_resets = 0;
126
                qemu_system_reset_request();
127
            } else if (val & SOFT_XIR) {
128
                qemu_system_reset_request();
129
            }
130
        }
131
        break;
132
    case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
133
    case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
134
    case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
135
    case 0xf000 ... 0xf01f: /* FFB config, memory control */
136
        /* we don't care */
137
    default:
138
        break;
139
    }
140
}
141

    
142
static uint64_t apb_config_readl (void *opaque,
143
                                  target_phys_addr_t addr, unsigned size)
144
{
145
    APBState *s = opaque;
146
    uint32_t val;
147

    
148
    switch (addr & 0xffff) {
149
    case 0x30 ... 0x4f: /* DMA error registers */
150
        val = 0;
151
        /* XXX: not implemented yet */
152
        break;
153
    case 0x200 ... 0x20b: /* IOMMU */
154
        val = s->iommu[(addr & 0xf) >> 2];
155
        break;
156
    case 0x20c ... 0x3ff: /* IOMMU flush */
157
        val = 0;
158
        break;
159
    case 0xc00 ... 0xc3f: /* PCI interrupt control */
160
        if (addr & 4) {
161
            val = s->pci_irq_map[(addr & 0x3f) >> 3];
162
        } else {
163
            val = 0;
164
        }
165
        break;
166
    case 0x1000 ... 0x1080: /* OBIO interrupt control */
167
        if (addr & 4) {
168
            val = s->obio_irq_map[(addr & 0xff) >> 3];
169
        } else {
170
            val = 0;
171
        }
172
        break;
173
    case 0x2000 ... 0x202f: /* PCI control */
174
        val = s->pci_control[(addr & 0x3f) >> 2];
175
        break;
176
    case 0xf020 ... 0xf027: /* Reset control */
177
        if (addr & 4) {
178
            val = s->reset_control;
179
        } else {
180
            val = 0;
181
        }
182
        break;
183
    case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
184
    case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
185
    case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
186
    case 0xf000 ... 0xf01f: /* FFB config, memory control */
187
        /* we don't care */
188
    default:
189
        val = 0;
190
        break;
191
    }
192
    APB_DPRINTF("%s: addr " TARGET_FMT_lx " -> %x\n", __func__, addr, val);
193

    
194
    return val;
195
}
196

    
197
static const MemoryRegionOps apb_config_ops = {
198
    .read = apb_config_readl,
199
    .write = apb_config_writel,
200
    .endianness = DEVICE_NATIVE_ENDIAN,
201
};
202

    
203
static void apb_pci_config_write(void *opaque, target_phys_addr_t addr,
204
                                 uint64_t val, unsigned size)
205
{
206
    APBState *s = opaque;
207

    
208
    val = qemu_bswap_len(val, size);
209
    APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %" PRIx64 "\n", __func__, addr, val);
210
    pci_data_write(s->bus, addr, val, size);
211
}
212

    
213
static uint64_t apb_pci_config_read(void *opaque, target_phys_addr_t addr,
214
                                    unsigned size)
215
{
216
    uint32_t ret;
217
    APBState *s = opaque;
218

    
219
    ret = pci_data_read(s->bus, addr, size);
220
    ret = qemu_bswap_len(ret, size);
221
    APB_DPRINTF("%s: addr " TARGET_FMT_lx " -> %x\n", __func__, addr, ret);
222
    return ret;
223
}
224

    
225
static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
226
                                  uint32_t val)
227
{
228
    cpu_outb(addr & IOPORTS_MASK, val);
229
}
230

    
231
static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
232
                                  uint32_t val)
233
{
234
    cpu_outw(addr & IOPORTS_MASK, bswap16(val));
235
}
236

    
237
static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
238
                                uint32_t val)
239
{
240
    cpu_outl(addr & IOPORTS_MASK, bswap32(val));
241
}
242

    
243
static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
244
{
245
    uint32_t val;
246

    
247
    val = cpu_inb(addr & IOPORTS_MASK);
248
    return val;
249
}
250

    
251
static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
252
{
253
    uint32_t val;
254

    
255
    val = bswap16(cpu_inw(addr & IOPORTS_MASK));
256
    return val;
257
}
258

    
259
static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
260
{
261
    uint32_t val;
262

    
263
    val = bswap32(cpu_inl(addr & IOPORTS_MASK));
264
    return val;
265
}
266

    
267
static const MemoryRegionOps pci_ioport_ops = {
268
    .old_mmio = {
269
        .read = { pci_apb_ioreadb, pci_apb_ioreadw, pci_apb_ioreadl },
270
        .write = { pci_apb_iowriteb, pci_apb_iowritew, pci_apb_iowritel, },
271
    },
272
    .endianness = DEVICE_NATIVE_ENDIAN,
273
};
274

    
275
/* The APB host has an IRQ line for each IRQ line of each slot.  */
276
static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
277
{
278
    return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
279
}
280

    
281
static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
282
{
283
    int bus_offset;
284
    if (pci_dev->devfn & 1)
285
        bus_offset = 16;
286
    else
287
        bus_offset = 0;
288
    return bus_offset + irq_num;
289
}
290

    
291
static void pci_apb_set_irq(void *opaque, int irq_num, int level)
292
{
293
    APBState *s = opaque;
294

    
295
    /* PCI IRQ map onto the first 32 INO.  */
296
    if (irq_num < 32) {
297
        if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
298
            APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
299
            qemu_set_irq(s->ivec_irqs[irq_num], level);
300
        } else {
301
            APB_DPRINTF("%s: not enabled: lower irq %d\n", __func__, irq_num);
302
            qemu_irq_lower(s->ivec_irqs[irq_num]);
303
        }
304
    } else {
305
        /* OBIO IRQ map onto the next 16 INO.  */
306
        if (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED) {
307
            APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
308
            qemu_set_irq(s->ivec_irqs[irq_num], level);
309
        } else {
310
            APB_DPRINTF("%s: not enabled: lower irq %d\n", __func__, irq_num);
311
            qemu_irq_lower(s->ivec_irqs[irq_num]);
312
        }
313
    }
314
}
315

    
316
static int apb_pci_bridge_initfn(PCIDevice *dev)
317
{
318
    int rc;
319

    
320
    rc = pci_bridge_initfn(dev);
321
    if (rc < 0) {
322
        return rc;
323
    }
324

    
325
    /*
326
     * command register:
327
     * According to PCI bridge spec, after reset
328
     *   bus master bit is off
329
     *   memory space enable bit is off
330
     * According to manual (805-1251.pdf).
331
     *   the reset value should be zero unless the boot pin is tied high
332
     *   (which is true) and thus it should be PCI_COMMAND_MEMORY.
333
     */
334
    pci_set_word(dev->config + PCI_COMMAND,
335
                 PCI_COMMAND_MEMORY);
336
    pci_set_word(dev->config + PCI_STATUS,
337
                 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
338
                 PCI_STATUS_DEVSEL_MEDIUM);
339
    return 0;
340
}
341

    
342
PCIBus *pci_apb_init(target_phys_addr_t special_base,
343
                     target_phys_addr_t mem_base,
344
                     qemu_irq *ivec_irqs, PCIBus **bus2, PCIBus **bus3,
345
                     qemu_irq **pbm_irqs)
346
{
347
    DeviceState *dev;
348
    SysBusDevice *s;
349
    APBState *d;
350
    PCIDevice *pci_dev;
351
    PCIBridge *br;
352

    
353
    /* Ultrasparc PBM main bus */
354
    dev = qdev_create(NULL, "pbm");
355
    qdev_init_nofail(dev);
356
    s = sysbus_from_qdev(dev);
357
    /* apb_config */
358
    sysbus_mmio_map(s, 0, special_base);
359
    /* PCI configuration space */
360
    sysbus_mmio_map(s, 1, special_base + 0x1000000ULL);
361
    /* pci_ioport */
362
    sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
363
    d = FROM_SYSBUS(APBState, s);
364

    
365
    memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
366
    memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
367

    
368
    d->bus = pci_register_bus(&d->busdev.qdev, "pci",
369
                              pci_apb_set_irq, pci_pbm_map_irq, d,
370
                              &d->pci_mmio,
371
                              get_system_io(),
372
                              0, 32);
373

    
374
    *pbm_irqs = d->pbm_irqs;
375
    d->ivec_irqs = ivec_irqs;
376

    
377
    pci_create_simple(d->bus, 0, "pbm-pci");
378

    
379
    /* APB secondary busses */
380
    pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 0), true,
381
                                   "pbm-bridge");
382
    br = DO_UPCAST(PCIBridge, dev, pci_dev);
383
    pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 1",
384
                       pci_apb_map_irq);
385
    qdev_init_nofail(&pci_dev->qdev);
386
    *bus2 = pci_bridge_get_sec_bus(br);
387

    
388
    pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 1), true,
389
                                   "pbm-bridge");
390
    br = DO_UPCAST(PCIBridge, dev, pci_dev);
391
    pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 2",
392
                       pci_apb_map_irq);
393
    qdev_init_nofail(&pci_dev->qdev);
394
    *bus3 = pci_bridge_get_sec_bus(br);
395

    
396
    return d->bus;
397
}
398

    
399
static void pci_pbm_reset(DeviceState *d)
400
{
401
    unsigned int i;
402
    APBState *s = container_of(d, APBState, busdev.qdev);
403

    
404
    for (i = 0; i < 8; i++) {
405
        s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
406
    }
407

    
408
    if (s->nr_resets++ == 0) {
409
        /* Power on reset */
410
        s->reset_control = POR;
411
    }
412
}
413

    
414
static const MemoryRegionOps pci_config_ops = {
415
    .read = apb_pci_config_read,
416
    .write = apb_pci_config_write,
417
    .endianness = DEVICE_NATIVE_ENDIAN,
418
};
419

    
420
static int pci_pbm_init_device(SysBusDevice *dev)
421
{
422
    APBState *s;
423
    unsigned int i;
424

    
425
    s = FROM_SYSBUS(APBState, dev);
426
    for (i = 0; i < 8; i++) {
427
        s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
428
    }
429
    s->pbm_irqs = qemu_allocate_irqs(pci_apb_set_irq, s, MAX_IVEC);
430

    
431
    /* apb_config */
432
    memory_region_init_io(&s->apb_config, &apb_config_ops, s, "apb-config",
433
                          0x10000);
434
    /* at region 0 */
435
    sysbus_init_mmio(dev, &s->apb_config);
436

    
437
    memory_region_init_io(&s->pci_config, &pci_config_ops, s, "apb-pci-config",
438
                          0x1000000);
439
    /* at region 1 */
440
    sysbus_init_mmio(dev, &s->pci_config);
441

    
442
    /* pci_ioport */
443
    memory_region_init_io(&s->pci_ioport, &pci_ioport_ops, s,
444
                          "apb-pci-ioport", 0x10000);
445
    /* at region 2 */
446
    sysbus_init_mmio(dev, &s->pci_ioport);
447

    
448
    return 0;
449
}
450

    
451
static int pbm_pci_host_init(PCIDevice *d)
452
{
453
    pci_set_word(d->config + PCI_COMMAND,
454
                 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
455
    pci_set_word(d->config + PCI_STATUS,
456
                 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
457
                 PCI_STATUS_DEVSEL_MEDIUM);
458
    return 0;
459
}
460

    
461
static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
462
{
463
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
464

    
465
    k->init = pbm_pci_host_init;
466
    k->vendor_id = PCI_VENDOR_ID_SUN;
467
    k->device_id = PCI_DEVICE_ID_SUN_SABRE;
468
    k->class_id = PCI_CLASS_BRIDGE_HOST;
469
}
470

    
471
static TypeInfo pbm_pci_host_info = {
472
    .name          = "pbm-pci",
473
    .parent        = TYPE_PCI_DEVICE,
474
    .instance_size = sizeof(PCIDevice),
475
    .class_init    = pbm_pci_host_class_init,
476
};
477

    
478
static void pbm_host_class_init(ObjectClass *klass, void *data)
479
{
480
    DeviceClass *dc = DEVICE_CLASS(klass);
481
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
482

    
483
    k->init = pci_pbm_init_device;
484
    dc->reset = pci_pbm_reset;
485
}
486

    
487
static TypeInfo pbm_host_info = {
488
    .name          = "pbm",
489
    .parent        = TYPE_SYS_BUS_DEVICE,
490
    .instance_size = sizeof(APBState),
491
    .class_init    = pbm_host_class_init,
492
};
493

    
494
static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
495
{
496
    DeviceClass *dc = DEVICE_CLASS(klass);
497
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
498

    
499
    k->init = apb_pci_bridge_initfn;
500
    k->exit = pci_bridge_exitfn;
501
    k->vendor_id = PCI_VENDOR_ID_SUN;
502
    k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
503
    k->revision = 0x11;
504
    k->config_write = pci_bridge_write_config;
505
    k->is_bridge = 1;
506
    dc->reset = pci_bridge_reset;
507
    dc->vmsd = &vmstate_pci_device;
508
}
509

    
510
static TypeInfo pbm_pci_bridge_info = {
511
    .name          = "pbm-bridge",
512
    .parent        = TYPE_PCI_DEVICE,
513
    .instance_size = sizeof(PCIBridge),
514
    .class_init    = pbm_pci_bridge_class_init,
515
};
516

    
517
static void pbm_register_types(void)
518
{
519
    type_register_static(&pbm_host_info);
520
    type_register_static(&pbm_pci_host_info);
521
    type_register_static(&pbm_pci_bridge_info);
522
}
523

    
524
type_init(pbm_register_types)