Statistics
| Branch: | Revision:

root / hw / apb_pci.c @ 3812ed0b

History | View | Annotate | Download (13.7 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
typedef struct APBState {
70
    SysBusDevice busdev;
71
    PCIBus      *bus;
72
    MemoryRegion apb_config;
73
    MemoryRegion pci_config;
74
    MemoryRegion pci_ioport;
75
    uint32_t iommu[4];
76
    uint32_t pci_control[16];
77
    uint32_t pci_irq_map[8];
78
    uint32_t obio_irq_map[32];
79
    qemu_irq pci_irqs[32];
80
    uint32_t reset_control;
81
    unsigned int nr_resets;
82
} APBState;
83

    
84
static void apb_config_writel (void *opaque, target_phys_addr_t addr,
85
                               uint64_t val, unsigned size)
86
{
87
    APBState *s = opaque;
88

    
89
    APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %x\n", __func__, addr, val);
90

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

    
132
static uint64_t apb_config_readl (void *opaque,
133
                                  target_phys_addr_t addr, unsigned size)
134
{
135
    APBState *s = opaque;
136
    uint32_t val;
137

    
138
    switch (addr & 0xffff) {
139
    case 0x30 ... 0x4f: /* DMA error registers */
140
        val = 0;
141
        /* XXX: not implemented yet */
142
        break;
143
    case 0x200 ... 0x20b: /* IOMMU */
144
        val = s->iommu[(addr & 0xf) >> 2];
145
        break;
146
    case 0x20c ... 0x3ff: /* IOMMU flush */
147
        val = 0;
148
        break;
149
    case 0xc00 ... 0xc3f: /* PCI interrupt control */
150
        if (addr & 4) {
151
            val = s->pci_irq_map[(addr & 0x3f) >> 3];
152
        } else {
153
            val = 0;
154
        }
155
        break;
156
    case 0x2000 ... 0x202f: /* PCI control */
157
        val = s->pci_control[(addr & 0x3f) >> 2];
158
        break;
159
    case 0xf020 ... 0xf027: /* Reset control */
160
        if (addr & 4) {
161
            val = s->reset_control;
162
        } else {
163
            val = 0;
164
        }
165
        break;
166
    case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
167
    case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
168
    case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
169
    case 0xf000 ... 0xf01f: /* FFB config, memory control */
170
        /* we don't care */
171
    default:
172
        val = 0;
173
        break;
174
    }
175
    APB_DPRINTF("%s: addr " TARGET_FMT_lx " -> %x\n", __func__, addr, val);
176

    
177
    return val;
178
}
179

    
180
static const MemoryRegionOps apb_config_ops = {
181
    .read = apb_config_readl,
182
    .write = apb_config_writel,
183
    .endianness = DEVICE_NATIVE_ENDIAN,
184
};
185

    
186
static void apb_pci_config_write(void *opaque, target_phys_addr_t addr,
187
                                 uint64_t val, unsigned size)
188
{
189
    APBState *s = opaque;
190

    
191
    val = qemu_bswap_len(val, size);
192
    APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %x\n", __func__, addr, val);
193
    pci_data_write(s->bus, addr, val, size);
194
}
195

    
196
static uint64_t apb_pci_config_read(void *opaque, target_phys_addr_t addr,
197
                                    unsigned size)
198
{
199
    uint32_t ret;
200
    APBState *s = opaque;
201

    
202
    ret = pci_data_read(s->bus, addr, size);
203
    ret = qemu_bswap_len(ret, size);
204
    APB_DPRINTF("%s: addr " TARGET_FMT_lx " -> %x\n", __func__, addr, ret);
205
    return ret;
206
}
207

    
208
static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
209
                                  uint32_t val)
210
{
211
    cpu_outb(addr & IOPORTS_MASK, val);
212
}
213

    
214
static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
215
                                  uint32_t val)
216
{
217
    cpu_outw(addr & IOPORTS_MASK, bswap16(val));
218
}
219

    
220
static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
221
                                uint32_t val)
222
{
223
    cpu_outl(addr & IOPORTS_MASK, bswap32(val));
224
}
225

    
226
static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
227
{
228
    uint32_t val;
229

    
230
    val = cpu_inb(addr & IOPORTS_MASK);
231
    return val;
232
}
233

    
234
static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
235
{
236
    uint32_t val;
237

    
238
    val = bswap16(cpu_inw(addr & IOPORTS_MASK));
239
    return val;
240
}
241

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

    
246
    val = bswap32(cpu_inl(addr & IOPORTS_MASK));
247
    return val;
248
}
249

    
250
static const MemoryRegionOps pci_ioport_ops = {
251
    .old_mmio = {
252
        .read = { pci_apb_ioreadb, pci_apb_ioreadw, pci_apb_ioreadl },
253
        .write = { pci_apb_iowriteb, pci_apb_iowritew, pci_apb_iowritel, },
254
    },
255
    .endianness = DEVICE_NATIVE_ENDIAN,
256
};
257

    
258
/* The APB host has an IRQ line for each IRQ line of each slot.  */
259
static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
260
{
261
    return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
262
}
263

    
264
static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
265
{
266
    int bus_offset;
267
    if (pci_dev->devfn & 1)
268
        bus_offset = 16;
269
    else
270
        bus_offset = 0;
271
    return bus_offset + irq_num;
272
}
273

    
274
static void pci_apb_set_irq(void *opaque, int irq_num, int level)
275
{
276
    APBState *s = opaque;
277

    
278
    /* PCI IRQ map onto the first 32 INO.  */
279
    if (irq_num < 32) {
280
        if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
281
            APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
282
            qemu_set_irq(s->pci_irqs[irq_num], level);
283
        } else {
284
            APB_DPRINTF("%s: not enabled: lower irq %d\n", __func__, irq_num);
285
            qemu_irq_lower(s->pci_irqs[irq_num]);
286
        }
287
    }
288
}
289

    
290
static int apb_pci_bridge_initfn(PCIDevice *dev)
291
{
292
    int rc;
293

    
294
    rc = pci_bridge_initfn(dev);
295
    if (rc < 0) {
296
        return rc;
297
    }
298

    
299
    /*
300
     * command register:
301
     * According to PCI bridge spec, after reset
302
     *   bus master bit is off
303
     *   memory space enable bit is off
304
     * According to manual (805-1251.pdf).
305
     *   the reset value should be zero unless the boot pin is tied high
306
     *   (which is true) and thus it should be PCI_COMMAND_MEMORY.
307
     */
308
    pci_set_word(dev->config + PCI_COMMAND,
309
                 PCI_COMMAND_MEMORY);
310
    pci_set_word(dev->config + PCI_STATUS,
311
                 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
312
                 PCI_STATUS_DEVSEL_MEDIUM);
313
    return 0;
314
}
315

    
316
PCIBus *pci_apb_init(target_phys_addr_t special_base,
317
                     target_phys_addr_t mem_base,
318
                     qemu_irq *pic, PCIBus **bus2, PCIBus **bus3)
319
{
320
    DeviceState *dev;
321
    SysBusDevice *s;
322
    APBState *d;
323
    unsigned int i;
324
    PCIDevice *pci_dev;
325
    PCIBridge *br;
326

    
327
    /* Ultrasparc PBM main bus */
328
    dev = qdev_create(NULL, "pbm");
329
    qdev_init_nofail(dev);
330
    s = sysbus_from_qdev(dev);
331
    /* apb_config */
332
    sysbus_mmio_map(s, 0, special_base);
333
    /* PCI configuration space */
334
    sysbus_mmio_map(s, 1, special_base + 0x1000000ULL);
335
    /* pci_ioport */
336
    sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
337
    d = FROM_SYSBUS(APBState, s);
338

    
339
    d->bus = pci_register_bus(&d->busdev.qdev, "pci",
340
                                         pci_apb_set_irq, pci_pbm_map_irq, d,
341
                                         get_system_memory(),
342
                                         get_system_io(),
343
                                         0, 32);
344
    pci_bus_set_mem_base(d->bus, mem_base);
345

    
346
    for (i = 0; i < 32; i++) {
347
        sysbus_connect_irq(s, i, pic[i]);
348
    }
349

    
350
    pci_create_simple(d->bus, 0, "pbm");
351

    
352
    /* APB secondary busses */
353
    pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 0), true,
354
                                   "pbm-bridge");
355
    br = DO_UPCAST(PCIBridge, dev, pci_dev);
356
    pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 1",
357
                       pci_apb_map_irq);
358
    qdev_init_nofail(&pci_dev->qdev);
359
    *bus2 = pci_bridge_get_sec_bus(br);
360

    
361
    pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 1), true,
362
                                   "pbm-bridge");
363
    br = DO_UPCAST(PCIBridge, dev, pci_dev);
364
    pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 2",
365
                       pci_apb_map_irq);
366
    qdev_init_nofail(&pci_dev->qdev);
367
    *bus3 = pci_bridge_get_sec_bus(br);
368

    
369
    return d->bus;
370
}
371

    
372
static void pci_pbm_reset(DeviceState *d)
373
{
374
    unsigned int i;
375
    APBState *s = container_of(d, APBState, busdev.qdev);
376

    
377
    for (i = 0; i < 8; i++) {
378
        s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
379
    }
380

    
381
    if (s->nr_resets++ == 0) {
382
        /* Power on reset */
383
        s->reset_control = POR;
384
    }
385
}
386

    
387
static const MemoryRegionOps pci_config_ops = {
388
    .read = apb_pci_config_read,
389
    .write = apb_pci_config_write,
390
    .endianness = DEVICE_NATIVE_ENDIAN,
391
};
392

    
393
static int pci_pbm_init_device(SysBusDevice *dev)
394
{
395
    APBState *s;
396
    unsigned int i;
397

    
398
    s = FROM_SYSBUS(APBState, dev);
399
    for (i = 0; i < 8; i++) {
400
        s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
401
    }
402
    for (i = 0; i < 32; i++) {
403
        sysbus_init_irq(dev, &s->pci_irqs[i]);
404
    }
405

    
406
    /* apb_config */
407
    memory_region_init_io(&s->apb_config, &apb_config_ops, s, "apb-config",
408
                          0x10000);
409
    /* at region 0 */
410
    sysbus_init_mmio_region(dev, &s->apb_config);
411

    
412
    memory_region_init_io(&s->pci_config, &pci_config_ops, s, "apb-pci-config",
413
                          0x1000000);
414
    /* at region 1 */
415
    sysbus_init_mmio_region(dev, &s->pci_config);
416

    
417
    /* pci_ioport */
418
    memory_region_init_io(&s->pci_ioport, &pci_ioport_ops, s,
419
                          "apb-pci-ioport", 0x10000);
420
    /* at region 2 */
421
    sysbus_init_mmio_region(dev, &s->pci_ioport);
422

    
423
    return 0;
424
}
425

    
426
static int pbm_pci_host_init(PCIDevice *d)
427
{
428
    pci_set_word(d->config + PCI_COMMAND,
429
                 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
430
    pci_set_word(d->config + PCI_STATUS,
431
                 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
432
                 PCI_STATUS_DEVSEL_MEDIUM);
433
    return 0;
434
}
435

    
436
static PCIDeviceInfo pbm_pci_host_info = {
437
    .qdev.name = "pbm",
438
    .qdev.size = sizeof(PCIDevice),
439
    .init      = pbm_pci_host_init,
440
    .vendor_id = PCI_VENDOR_ID_SUN,
441
    .device_id = PCI_DEVICE_ID_SUN_SABRE,
442
    .class_id  = PCI_CLASS_BRIDGE_HOST,
443
    .is_bridge = 1,
444
};
445

    
446
static SysBusDeviceInfo pbm_host_info = {
447
    .qdev.name = "pbm",
448
    .qdev.size = sizeof(APBState),
449
    .qdev.reset = pci_pbm_reset,
450
    .init = pci_pbm_init_device,
451
};
452

    
453
static PCIDeviceInfo pbm_pci_bridge_info = {
454
    .qdev.name = "pbm-bridge",
455
    .qdev.size = sizeof(PCIBridge),
456
    .qdev.vmsd = &vmstate_pci_device,
457
    .qdev.reset = pci_bridge_reset,
458
    .init = apb_pci_bridge_initfn,
459
    .exit = pci_bridge_exitfn,
460
    .vendor_id = PCI_VENDOR_ID_SUN,
461
    .device_id = PCI_DEVICE_ID_SUN_SIMBA,
462
    .revision = 0x11,
463
    .config_write = pci_bridge_write_config,
464
    .is_bridge = 1,
465
};
466

    
467
static void pbm_register_devices(void)
468
{
469
    sysbus_register_withprop(&pbm_host_info);
470
    pci_qdev_register(&pbm_pci_host_info);
471
    pci_qdev_register(&pbm_pci_bridge_info);
472
}
473

    
474
device_init(pbm_register_devices)