Statistics
| Branch: | Revision:

root / hw / apb_pci.c @ 9fe52c7f

History | View | Annotate | Download (14.6 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 "apb_pci.h"
33

    
34
/* debug APB */
35
//#define DEBUG_APB
36

    
37
#ifdef DEBUG_APB
38
#define APB_DPRINTF(fmt, ...) \
39
do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
40
#else
41
#define APB_DPRINTF(fmt, ...)
42
#endif
43

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

    
53
#define PBM_PCI_IMR_MASK    0x7fffffff
54
#define PBM_PCI_IMR_ENABLED 0x80000000
55

    
56
#define POR          (1 << 31)
57
#define SOFT_POR     (1 << 30)
58
#define SOFT_XIR     (1 << 29)
59
#define BTN_POR      (1 << 28)
60
#define BTN_XIR      (1 << 27)
61
#define RESET_MASK   0xf8000000
62
#define RESET_WCMASK 0x98000000
63
#define RESET_WMASK  0x60000000
64

    
65
typedef struct APBState {
66
    SysBusDevice busdev;
67
    PCIHostState host_state;
68
    uint32_t iommu[4];
69
    uint32_t pci_control[16];
70
    uint32_t pci_irq_map[8];
71
    uint32_t obio_irq_map[32];
72
    qemu_irq pci_irqs[32];
73
    uint32_t reset_control;
74
} APBState;
75

    
76
static unsigned int nr_resets;
77

    
78
static void apb_config_writel (void *opaque, target_phys_addr_t addr,
79
                               uint32_t val)
80
{
81
    APBState *s = opaque;
82

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

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

    
126
static uint32_t apb_config_readl (void *opaque,
127
                                  target_phys_addr_t addr)
128
{
129
    APBState *s = opaque;
130
    uint32_t val;
131

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

    
171
    return val;
172
}
173

    
174
static CPUWriteMemoryFunc * const apb_config_write[] = {
175
    &apb_config_writel,
176
    &apb_config_writel,
177
    &apb_config_writel,
178
};
179

    
180
static CPUReadMemoryFunc * const apb_config_read[] = {
181
    &apb_config_readl,
182
    &apb_config_readl,
183
    &apb_config_readl,
184
};
185

    
186
static void apb_pci_config_write(APBState *s, target_phys_addr_t addr,
187
                                 uint32_t val, int size)
188
{
189
    APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %x\n", __func__, addr, val);
190
    pci_data_write(s->host_state.bus, (addr & 0x00ffffff) | (1u << 31), val,
191
                   size);
192
}
193

    
194
static uint32_t apb_pci_config_read(APBState *s, target_phys_addr_t addr,
195
                                    int size)
196
{
197
    uint32_t ret;
198

    
199
    ret = pci_data_read(s->host_state.bus, (addr & 0x00ffffff) | (1u << 31),
200
                        size);
201
    APB_DPRINTF("%s: addr " TARGET_FMT_lx " -> %x\n", __func__, addr, ret);
202
    return ret;
203
}
204

    
205
static void apb_pci_config_writel(void *opaque, target_phys_addr_t addr,
206
                                  uint32_t val)
207
{
208
    APBState *s = opaque;
209

    
210
    apb_pci_config_write(s, addr, bswap32(val), 4);
211
}
212

    
213
static void apb_pci_config_writew(void *opaque, target_phys_addr_t addr,
214
                                  uint32_t val)
215
{
216
    APBState *s = opaque;
217

    
218
    apb_pci_config_write(s, addr, bswap16(val), 2);
219
}
220

    
221
static void apb_pci_config_writeb(void *opaque, target_phys_addr_t addr,
222
                                  uint32_t val)
223
{
224
    APBState *s = opaque;
225

    
226
    apb_pci_config_write(s, addr, val, 1);
227
}
228

    
229
static uint32_t apb_pci_config_readl(void *opaque, target_phys_addr_t addr)
230
{
231
    APBState *s = opaque;
232

    
233
    return bswap32(apb_pci_config_read(s, addr, 4));
234
}
235

    
236
static uint32_t apb_pci_config_readw(void *opaque, target_phys_addr_t addr)
237
{
238
    APBState *s = opaque;
239

    
240
    return bswap16(apb_pci_config_read(s, addr, 2));
241
}
242

    
243
static uint32_t apb_pci_config_readb(void *opaque, target_phys_addr_t addr)
244
{
245
    APBState *s = opaque;
246

    
247
    return apb_pci_config_read(s, addr, 1);
248
}
249

    
250
static CPUWriteMemoryFunc * const apb_pci_config_writes[] = {
251
    &apb_pci_config_writeb,
252
    &apb_pci_config_writew,
253
    &apb_pci_config_writel,
254
};
255

    
256
static CPUReadMemoryFunc * const apb_pci_config_reads[] = {
257
    &apb_pci_config_readb,
258
    &apb_pci_config_readw,
259
    &apb_pci_config_readl,
260
};
261

    
262
static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
263
                                  uint32_t val)
264
{
265
    cpu_outb(addr & IOPORTS_MASK, val);
266
}
267

    
268
static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
269
                                  uint32_t val)
270
{
271
    cpu_outw(addr & IOPORTS_MASK, bswap16(val));
272
}
273

    
274
static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
275
                                uint32_t val)
276
{
277
    cpu_outl(addr & IOPORTS_MASK, bswap32(val));
278
}
279

    
280
static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
281
{
282
    uint32_t val;
283

    
284
    val = cpu_inb(addr & IOPORTS_MASK);
285
    return val;
286
}
287

    
288
static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
289
{
290
    uint32_t val;
291

    
292
    val = bswap16(cpu_inw(addr & IOPORTS_MASK));
293
    return val;
294
}
295

    
296
static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
297
{
298
    uint32_t val;
299

    
300
    val = bswap32(cpu_inl(addr & IOPORTS_MASK));
301
    return val;
302
}
303

    
304
static CPUWriteMemoryFunc * const pci_apb_iowrite[] = {
305
    &pci_apb_iowriteb,
306
    &pci_apb_iowritew,
307
    &pci_apb_iowritel,
308
};
309

    
310
static CPUReadMemoryFunc * const pci_apb_ioread[] = {
311
    &pci_apb_ioreadb,
312
    &pci_apb_ioreadw,
313
    &pci_apb_ioreadl,
314
};
315

    
316
/* The APB host has an IRQ line for each IRQ line of each slot.  */
317
static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
318
{
319
    return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
320
}
321

    
322
static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
323
{
324
    int bus_offset;
325
    if (pci_dev->devfn & 1)
326
        bus_offset = 16;
327
    else
328
        bus_offset = 0;
329
    return bus_offset + irq_num;
330
}
331

    
332
static void pci_apb_set_irq(void *opaque, int irq_num, int level)
333
{
334
    APBState *s = opaque;
335

    
336
    /* PCI IRQ map onto the first 32 INO.  */
337
    if (irq_num < 32) {
338
        if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
339
            APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
340
            qemu_set_irq(s->pci_irqs[irq_num], level);
341
        } else {
342
            APB_DPRINTF("%s: not enabled: lower irq %d\n", __func__, irq_num);
343
            qemu_irq_lower(s->pci_irqs[irq_num]);
344
        }
345
    }
346
}
347

    
348
static void apb_pci_bridge_init(PCIBus *b)
349
{
350
    PCIDevice *dev = pci_bridge_get_device(b);
351

    
352
    /*
353
     * command register:
354
     * According to PCI bridge spec, after reset
355
     *   bus master bit is off
356
     *   memory space enable bit is off
357
     * According to manual (805-1251.pdf).
358
     *   the reset value should be zero unless the boot pin is tied high
359
     *   (which is true) and thus it should be PCI_COMMAND_MEMORY.
360
     */
361
    pci_set_word(dev->config + PCI_COMMAND,
362
                 PCI_COMMAND_MEMORY);
363
    pci_set_word(dev->config + PCI_STATUS,
364
                 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
365
                 PCI_STATUS_DEVSEL_MEDIUM);
366
    pci_set_byte(dev->config + PCI_REVISION_ID, 0x11);
367
    pci_set_byte(dev->config + PCI_HEADER_TYPE,
368
                 pci_get_byte(dev->config + PCI_HEADER_TYPE) |
369
                 PCI_HEADER_TYPE_MULTI_FUNCTION);
370
}
371

    
372
PCIBus *pci_apb_init(target_phys_addr_t special_base,
373
                     target_phys_addr_t mem_base,
374
                     qemu_irq *pic, PCIBus **bus2, PCIBus **bus3)
375
{
376
    DeviceState *dev;
377
    SysBusDevice *s;
378
    APBState *d;
379
    unsigned int i;
380

    
381
    /* Ultrasparc PBM main bus */
382
    dev = qdev_create(NULL, "pbm");
383
    qdev_init_nofail(dev);
384
    s = sysbus_from_qdev(dev);
385
    /* apb_config */
386
    sysbus_mmio_map(s, 0, special_base);
387
    /* pci_ioport */
388
    sysbus_mmio_map(s, 1, special_base + 0x2000000ULL);
389
    /* pci_config */
390
    sysbus_mmio_map(s, 2, special_base + 0x1000000ULL);
391
    /* mem_data */
392
    sysbus_mmio_map(s, 3, mem_base);
393
    d = FROM_SYSBUS(APBState, s);
394
    d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
395
                                         pci_apb_set_irq, pci_pbm_map_irq, d,
396
                                         0, 32);
397
    pci_bus_set_mem_base(d->host_state.bus, mem_base);
398

    
399
    for (i = 0; i < 32; i++) {
400
        sysbus_connect_irq(s, i, pic[i]);
401
    }
402

    
403
    pci_create_simple(d->host_state.bus, 0, "pbm");
404
    /* APB secondary busses */
405
    *bus2 = pci_bridge_init(d->host_state.bus, PCI_DEVFN(1, 0),
406
                            PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SIMBA,
407
                            pci_apb_map_irq,
408
                            "Advanced PCI Bus secondary bridge 1");
409
    apb_pci_bridge_init(*bus2);
410

    
411
    *bus3 = pci_bridge_init(d->host_state.bus, PCI_DEVFN(1, 1),
412
                            PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SIMBA,
413
                            pci_apb_map_irq,
414
                            "Advanced PCI Bus secondary bridge 2");
415
    apb_pci_bridge_init(*bus3);
416

    
417
    return d->host_state.bus;
418
}
419

    
420
static void pci_pbm_reset(DeviceState *d)
421
{
422
    unsigned int i;
423
    APBState *s = container_of(d, APBState, busdev.qdev);
424

    
425
    for (i = 0; i < 8; i++) {
426
        s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
427
    }
428

    
429
    if (nr_resets++ == 0) {
430
        /* Power on reset */
431
        s->reset_control = POR;
432
    }
433
}
434

    
435
static int pci_pbm_init_device(SysBusDevice *dev)
436
{
437
    APBState *s;
438
    int pci_mem_data, apb_config, pci_ioport, pci_config;
439
    unsigned int i;
440

    
441
    s = FROM_SYSBUS(APBState, dev);
442
    for (i = 0; i < 8; i++) {
443
        s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
444
    }
445
    for (i = 0; i < 32; i++) {
446
        sysbus_init_irq(dev, &s->pci_irqs[i]);
447
    }
448

    
449
    /* apb_config */
450
    apb_config = cpu_register_io_memory(apb_config_read,
451
                                        apb_config_write, s);
452
    sysbus_init_mmio(dev, 0x10000ULL, apb_config);
453
    /* pci_ioport */
454
    pci_ioport = cpu_register_io_memory(pci_apb_ioread,
455
                                          pci_apb_iowrite, s);
456
    sysbus_init_mmio(dev, 0x10000ULL, pci_ioport);
457
    /* pci_config */
458
    pci_config = cpu_register_io_memory(apb_pci_config_reads,
459
                                        apb_pci_config_writes, s);
460
    sysbus_init_mmio(dev, 0x1000000ULL, pci_config);
461
    /* mem_data */
462
    pci_mem_data = pci_host_data_register_mmio(&s->host_state);
463
    sysbus_init_mmio(dev, 0x10000000ULL, pci_mem_data);
464
    return 0;
465
}
466

    
467
static int pbm_pci_host_init(PCIDevice *d)
468
{
469
    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN);
470
    pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE);
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
    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
477
    pci_set_byte(d->config + PCI_HEADER_TYPE,
478
                 PCI_HEADER_TYPE_NORMAL);
479
    return 0;
480
}
481

    
482
static PCIDeviceInfo pbm_pci_host_info = {
483
    .qdev.name = "pbm",
484
    .qdev.size = sizeof(PCIDevice),
485
    .init      = pbm_pci_host_init,
486
    .header_type  = PCI_HEADER_TYPE_BRIDGE,
487
};
488

    
489
static SysBusDeviceInfo pbm_host_info = {
490
    .qdev.name = "pbm",
491
    .qdev.size = sizeof(APBState),
492
    .qdev.reset = pci_pbm_reset,
493
    .init = pci_pbm_init_device,
494
};
495
static void pbm_register_devices(void)
496
{
497
    sysbus_register_withprop(&pbm_host_info);
498
    pci_qdev_register(&pbm_pci_host_info);
499
}
500

    
501
device_init(pbm_register_devices)