Statistics
| Branch: | Revision:

root / hw / apb_pci.c @ 9c17d615

History | View | Annotate | Download (15.8 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/pci.h"
31
#include "pci/pci_host.h"
32
#include "pci/pci_bridge.h"
33
#include "pci/pci_bus.h"
34
#include "apb_pci.h"
35
#include "sysemu/sysemu.h"
36
#include "exec/address-spaces.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 pci_apb_set_irq(void *opaque, int irq_num, int level);
89

    
90
static void apb_config_writel (void *opaque, hwaddr addr,
91
                               uint64_t val, unsigned size)
92
{
93
    APBState *s = opaque;
94

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

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

    
154
static uint64_t apb_config_readl (void *opaque,
155
                                  hwaddr addr, unsigned size)
156
{
157
    APBState *s = opaque;
158
    uint32_t val;
159

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

    
206
    return val;
207
}
208

    
209
static const MemoryRegionOps apb_config_ops = {
210
    .read = apb_config_readl,
211
    .write = apb_config_writel,
212
    .endianness = DEVICE_NATIVE_ENDIAN,
213
};
214

    
215
static void apb_pci_config_write(void *opaque, hwaddr addr,
216
                                 uint64_t val, unsigned size)
217
{
218
    APBState *s = opaque;
219

    
220
    val = qemu_bswap_len(val, size);
221
    APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %" PRIx64 "\n", __func__, addr, val);
222
    pci_data_write(s->bus, addr, val, size);
223
}
224

    
225
static uint64_t apb_pci_config_read(void *opaque, hwaddr addr,
226
                                    unsigned size)
227
{
228
    uint32_t ret;
229
    APBState *s = opaque;
230

    
231
    ret = pci_data_read(s->bus, addr, size);
232
    ret = qemu_bswap_len(ret, size);
233
    APB_DPRINTF("%s: addr " TARGET_FMT_lx " -> %x\n", __func__, addr, ret);
234
    return ret;
235
}
236

    
237
static void pci_apb_iowriteb (void *opaque, hwaddr addr,
238
                                  uint32_t val)
239
{
240
    cpu_outb(addr & IOPORTS_MASK, val);
241
}
242

    
243
static void pci_apb_iowritew (void *opaque, hwaddr addr,
244
                                  uint32_t val)
245
{
246
    cpu_outw(addr & IOPORTS_MASK, bswap16(val));
247
}
248

    
249
static void pci_apb_iowritel (void *opaque, hwaddr addr,
250
                                uint32_t val)
251
{
252
    cpu_outl(addr & IOPORTS_MASK, bswap32(val));
253
}
254

    
255
static uint32_t pci_apb_ioreadb (void *opaque, hwaddr addr)
256
{
257
    uint32_t val;
258

    
259
    val = cpu_inb(addr & IOPORTS_MASK);
260
    return val;
261
}
262

    
263
static uint32_t pci_apb_ioreadw (void *opaque, hwaddr addr)
264
{
265
    uint32_t val;
266

    
267
    val = bswap16(cpu_inw(addr & IOPORTS_MASK));
268
    return val;
269
}
270

    
271
static uint32_t pci_apb_ioreadl (void *opaque, hwaddr addr)
272
{
273
    uint32_t val;
274

    
275
    val = bswap32(cpu_inl(addr & IOPORTS_MASK));
276
    return val;
277
}
278

    
279
static const MemoryRegionOps pci_ioport_ops = {
280
    .old_mmio = {
281
        .read = { pci_apb_ioreadb, pci_apb_ioreadw, pci_apb_ioreadl },
282
        .write = { pci_apb_iowriteb, pci_apb_iowritew, pci_apb_iowritel, },
283
    },
284
    .endianness = DEVICE_NATIVE_ENDIAN,
285
};
286

    
287
/* The APB host has an IRQ line for each IRQ line of each slot.  */
288
static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
289
{
290
    return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
291
}
292

    
293
static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
294
{
295
    int bus_offset;
296
    if (pci_dev->devfn & 1)
297
        bus_offset = 16;
298
    else
299
        bus_offset = 0;
300
    return bus_offset + irq_num;
301
}
302

    
303
static void pci_apb_set_irq(void *opaque, int irq_num, int level)
304
{
305
    APBState *s = opaque;
306

    
307
    /* PCI IRQ map onto the first 32 INO.  */
308
    if (irq_num < 32) {
309
        if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
310
            APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
311
            qemu_set_irq(s->ivec_irqs[irq_num], level);
312
        } else {
313
            APB_DPRINTF("%s: not enabled: lower irq %d\n", __func__, irq_num);
314
            qemu_irq_lower(s->ivec_irqs[irq_num]);
315
        }
316
    } else {
317
        /* OBIO IRQ map onto the next 16 INO.  */
318
        if (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED) {
319
            APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
320
            qemu_set_irq(s->ivec_irqs[irq_num], level);
321
        } else {
322
            APB_DPRINTF("%s: not enabled: lower irq %d\n", __func__, irq_num);
323
            qemu_irq_lower(s->ivec_irqs[irq_num]);
324
        }
325
    }
326
}
327

    
328
static int apb_pci_bridge_initfn(PCIDevice *dev)
329
{
330
    int rc;
331

    
332
    rc = pci_bridge_initfn(dev);
333
    if (rc < 0) {
334
        return rc;
335
    }
336

    
337
    /*
338
     * command register:
339
     * According to PCI bridge spec, after reset
340
     *   bus master bit is off
341
     *   memory space enable bit is off
342
     * According to manual (805-1251.pdf).
343
     *   the reset value should be zero unless the boot pin is tied high
344
     *   (which is true) and thus it should be PCI_COMMAND_MEMORY.
345
     */
346
    pci_set_word(dev->config + PCI_COMMAND,
347
                 PCI_COMMAND_MEMORY);
348
    pci_set_word(dev->config + PCI_STATUS,
349
                 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
350
                 PCI_STATUS_DEVSEL_MEDIUM);
351
    return 0;
352
}
353

    
354
PCIBus *pci_apb_init(hwaddr special_base,
355
                     hwaddr mem_base,
356
                     qemu_irq *ivec_irqs, PCIBus **bus2, PCIBus **bus3,
357
                     qemu_irq **pbm_irqs)
358
{
359
    DeviceState *dev;
360
    SysBusDevice *s;
361
    APBState *d;
362
    PCIDevice *pci_dev;
363
    PCIBridge *br;
364

    
365
    /* Ultrasparc PBM main bus */
366
    dev = qdev_create(NULL, "pbm");
367
    qdev_init_nofail(dev);
368
    s = sysbus_from_qdev(dev);
369
    /* apb_config */
370
    sysbus_mmio_map(s, 0, special_base);
371
    /* PCI configuration space */
372
    sysbus_mmio_map(s, 1, special_base + 0x1000000ULL);
373
    /* pci_ioport */
374
    sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
375
    d = FROM_SYSBUS(APBState, s);
376

    
377
    memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
378
    memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
379

    
380
    d->bus = pci_register_bus(&d->busdev.qdev, "pci",
381
                              pci_apb_set_irq, pci_pbm_map_irq, d,
382
                              &d->pci_mmio,
383
                              get_system_io(),
384
                              0, 32);
385

    
386
    *pbm_irqs = d->pbm_irqs;
387
    d->ivec_irqs = ivec_irqs;
388

    
389
    pci_create_simple(d->bus, 0, "pbm-pci");
390

    
391
    /* APB secondary busses */
392
    pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 0), true,
393
                                   "pbm-bridge");
394
    br = DO_UPCAST(PCIBridge, dev, pci_dev);
395
    pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 1",
396
                       pci_apb_map_irq);
397
    qdev_init_nofail(&pci_dev->qdev);
398
    *bus2 = pci_bridge_get_sec_bus(br);
399

    
400
    pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 1), true,
401
                                   "pbm-bridge");
402
    br = DO_UPCAST(PCIBridge, dev, pci_dev);
403
    pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 2",
404
                       pci_apb_map_irq);
405
    qdev_init_nofail(&pci_dev->qdev);
406
    *bus3 = pci_bridge_get_sec_bus(br);
407

    
408
    return d->bus;
409
}
410

    
411
static void pci_pbm_reset(DeviceState *d)
412
{
413
    unsigned int i;
414
    APBState *s = container_of(d, APBState, busdev.qdev);
415

    
416
    for (i = 0; i < 8; i++) {
417
        s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
418
    }
419
    for (i = 0; i < 32; i++) {
420
        s->obio_irq_map[i] &= PBM_PCI_IMR_MASK;
421
    }
422

    
423
    if (s->nr_resets++ == 0) {
424
        /* Power on reset */
425
        s->reset_control = POR;
426
    }
427
}
428

    
429
static const MemoryRegionOps pci_config_ops = {
430
    .read = apb_pci_config_read,
431
    .write = apb_pci_config_write,
432
    .endianness = DEVICE_NATIVE_ENDIAN,
433
};
434

    
435
static int pci_pbm_init_device(SysBusDevice *dev)
436
{
437
    APBState *s;
438
    unsigned int i;
439

    
440
    s = FROM_SYSBUS(APBState, dev);
441
    for (i = 0; i < 8; i++) {
442
        s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
443
    }
444
    for (i = 0; i < 32; i++) {
445
        s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
446
    }
447
    s->pbm_irqs = qemu_allocate_irqs(pci_apb_set_irq, s, MAX_IVEC);
448

    
449
    /* apb_config */
450
    memory_region_init_io(&s->apb_config, &apb_config_ops, s, "apb-config",
451
                          0x10000);
452
    /* at region 0 */
453
    sysbus_init_mmio(dev, &s->apb_config);
454

    
455
    memory_region_init_io(&s->pci_config, &pci_config_ops, s, "apb-pci-config",
456
                          0x1000000);
457
    /* at region 1 */
458
    sysbus_init_mmio(dev, &s->pci_config);
459

    
460
    /* pci_ioport */
461
    memory_region_init_io(&s->pci_ioport, &pci_ioport_ops, s,
462
                          "apb-pci-ioport", 0x10000);
463
    /* at region 2 */
464
    sysbus_init_mmio(dev, &s->pci_ioport);
465

    
466
    return 0;
467
}
468

    
469
static int pbm_pci_host_init(PCIDevice *d)
470
{
471
    pci_set_word(d->config + PCI_COMMAND,
472
                 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
473
    pci_set_word(d->config + PCI_STATUS,
474
                 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
475
                 PCI_STATUS_DEVSEL_MEDIUM);
476
    return 0;
477
}
478

    
479
static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
480
{
481
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
482

    
483
    k->init = pbm_pci_host_init;
484
    k->vendor_id = PCI_VENDOR_ID_SUN;
485
    k->device_id = PCI_DEVICE_ID_SUN_SABRE;
486
    k->class_id = PCI_CLASS_BRIDGE_HOST;
487
}
488

    
489
static TypeInfo pbm_pci_host_info = {
490
    .name          = "pbm-pci",
491
    .parent        = TYPE_PCI_DEVICE,
492
    .instance_size = sizeof(PCIDevice),
493
    .class_init    = pbm_pci_host_class_init,
494
};
495

    
496
static void pbm_host_class_init(ObjectClass *klass, void *data)
497
{
498
    DeviceClass *dc = DEVICE_CLASS(klass);
499
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
500

    
501
    k->init = pci_pbm_init_device;
502
    dc->reset = pci_pbm_reset;
503
}
504

    
505
static TypeInfo pbm_host_info = {
506
    .name          = "pbm",
507
    .parent        = TYPE_SYS_BUS_DEVICE,
508
    .instance_size = sizeof(APBState),
509
    .class_init    = pbm_host_class_init,
510
};
511

    
512
static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
513
{
514
    DeviceClass *dc = DEVICE_CLASS(klass);
515
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
516

    
517
    k->init = apb_pci_bridge_initfn;
518
    k->exit = pci_bridge_exitfn;
519
    k->vendor_id = PCI_VENDOR_ID_SUN;
520
    k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
521
    k->revision = 0x11;
522
    k->config_write = pci_bridge_write_config;
523
    k->is_bridge = 1;
524
    dc->reset = pci_bridge_reset;
525
    dc->vmsd = &vmstate_pci_device;
526
}
527

    
528
static TypeInfo pbm_pci_bridge_info = {
529
    .name          = "pbm-bridge",
530
    .parent        = TYPE_PCI_DEVICE,
531
    .instance_size = sizeof(PCIBridge),
532
    .class_init    = pbm_pci_bridge_class_init,
533
};
534

    
535
static void pbm_register_types(void)
536
{
537
    type_register_static(&pbm_host_info);
538
    type_register_static(&pbm_pci_host_info);
539
    type_register_static(&pbm_pci_bridge_info);
540
}
541

    
542
type_init(pbm_register_types)