Revision a9f49946

b/Makefile.target
154 154
# System emulator target
155 155
ifdef CONFIG_SOFTMMU
156 156

  
157
obj-y = vl.o async.o monitor.o pci.o pci_host.o machine.o gdbstub.o
157
obj-y = vl.o async.o monitor.o pci.o pci_host.o pcie_host.o machine.o gdbstub.o
158 158
# virtio has to be here due to weird dependency between PCI and virtio-net.
159 159
# need to fix this properly
160 160
obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o virtio-pci.o
b/hw/hw.h
512 512
    .offset     = vmstate_offset_value(_state, _field, PCIDevice),   \
513 513
}
514 514

  
515
extern const VMStateDescription vmstate_pcie_device;
516

  
517
#define VMSTATE_PCIE_DEVICE(_field, _state) {                        \
518
    .name       = (stringify(_field)),                               \
519
    .version_id = 2,                                                 \
520
    .size       = sizeof(PCIDevice),                                 \
521
    .vmsd       = &vmstate_pcie_device,                              \
522
    .flags      = VMS_STRUCT,                                        \
523
    .offset     = vmstate_offset_value(_state, _field, PCIDevice),   \
524
}
525

  
515 526
extern const VMStateDescription vmstate_i2c_slave;
516 527

  
517 528
#define VMSTATE_I2C_SLAVE(_field, _state) {                          \
b/hw/pci.c
23 23
 */
24 24
#include "hw.h"
25 25
#include "pci.h"
26
#include "pci_host.h"
26 27
#include "monitor.h"
27 28
#include "net.h"
28 29
#include "sysemu.h"
......
248 249
static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
249 250
{
250 251
    PCIDevice *s = container_of(pv, PCIDevice, config);
251
    uint8_t config[PCI_CONFIG_SPACE_SIZE];
252
    uint8_t *config;
252 253
    int i;
253 254

  
254
    assert(size == sizeof config);
255
    qemu_get_buffer(f, config, sizeof config);
256
    for (i = 0; i < sizeof config; ++i)
257
        if ((config[i] ^ s->config[i]) & s->cmask[i] & ~s->wmask[i])
255
    assert(size == pci_config_size(s));
256
    config = qemu_malloc(size);
257

  
258
    qemu_get_buffer(f, config, size);
259
    for (i = 0; i < size; ++i) {
260
        if ((config[i] ^ s->config[i]) & s->cmask[i] & ~s->wmask[i]) {
261
            qemu_free(config);
258 262
            return -EINVAL;
259
    memcpy(s->config, config, sizeof config);
263
        }
264
    }
265
    memcpy(s->config, config, size);
260 266

  
261 267
    pci_update_mappings(s);
262 268

  
269
    qemu_free(config);
263 270
    return 0;
264 271
}
265 272

  
......
267 274
static void put_pci_config_device(QEMUFile *f, void *pv, size_t size)
268 275
{
269 276
    const uint8_t *v = pv;
277
    assert(size == pci_config_size(container_of(pv, PCIDevice, config)));
270 278
    qemu_put_buffer(f, v, size);
271 279
}
272 280

  
......
283 291
    .minimum_version_id_old = 1,
284 292
    .fields      = (VMStateField []) {
285 293
        VMSTATE_INT32_LE(version_id, PCIDevice),
286
        VMSTATE_SINGLE(config, PCIDevice, 0, vmstate_info_pci_config,
287
                       typeof_field(PCIDevice,config)),
294
        VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
295
                                   vmstate_info_pci_config,
296
                                   PCI_CONFIG_SPACE_SIZE),
297
        VMSTATE_INT32_ARRAY_V(irq_state, PCIDevice, PCI_NUM_PINS, 2),
298
        VMSTATE_END_OF_LIST()
299
    }
300
};
301

  
302
const VMStateDescription vmstate_pcie_device = {
303
    .name = "PCIDevice",
304
    .version_id = 2,
305
    .minimum_version_id = 1,
306
    .minimum_version_id_old = 1,
307
    .fields      = (VMStateField []) {
308
        VMSTATE_INT32_LE(version_id, PCIDevice),
309
        VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
310
                                   vmstate_info_pci_config,
311
                                   PCIE_CONFIG_SPACE_SIZE),
288 312
        VMSTATE_INT32_ARRAY_V(irq_state, PCIDevice, PCI_NUM_PINS, 2),
289 313
        VMSTATE_END_OF_LIST()
290 314
    }
291 315
};
292 316

  
317
static inline const VMStateDescription *pci_get_vmstate(PCIDevice *s)
318
{
319
    return pci_is_express(s) ? &vmstate_pcie_device : &vmstate_pci_device;
320
}
321

  
293 322
void pci_device_save(PCIDevice *s, QEMUFile *f)
294 323
{
295
    vmstate_save_state(f, &vmstate_pci_device, s);
324
    vmstate_save_state(f, pci_get_vmstate(s), s);
296 325
}
297 326

  
298 327
int pci_device_load(PCIDevice *s, QEMUFile *f)
299 328
{
300
    return vmstate_load_state(f, &vmstate_pci_device, s, s->version_id);
329
    return vmstate_load_state(f, pci_get_vmstate(s), s, s->version_id);
301 330
}
302 331

  
303 332
static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
......
406 435
static void pci_init_wmask(PCIDevice *dev)
407 436
{
408 437
    int i;
438
    int config_size = pci_config_size(dev);
439

  
409 440
    dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff;
410 441
    dev->wmask[PCI_INTERRUPT_LINE] = 0xff;
411 442
    pci_set_word(dev->wmask + PCI_COMMAND,
412 443
                 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
413
    for (i = PCI_CONFIG_HEADER_SIZE; i < PCI_CONFIG_SPACE_SIZE; ++i)
444
    for (i = PCI_CONFIG_HEADER_SIZE; i < config_size; ++i)
414 445
        dev->wmask[i] = 0xff;
415 446
}
416 447

  
448
static void pci_config_alloc(PCIDevice *pci_dev)
449
{
450
    int config_size = pci_config_size(pci_dev);
451

  
452
    pci_dev->config = qemu_mallocz(config_size);
453
    pci_dev->cmask = qemu_mallocz(config_size);
454
    pci_dev->wmask = qemu_mallocz(config_size);
455
    pci_dev->used = qemu_mallocz(config_size);
456
}
457

  
458
static void pci_config_free(PCIDevice *pci_dev)
459
{
460
    qemu_free(pci_dev->config);
461
    qemu_free(pci_dev->cmask);
462
    qemu_free(pci_dev->wmask);
463
    qemu_free(pci_dev->used);
464
}
465

  
417 466
/* -1 for devfn means auto assign */
418 467
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
419 468
                                         const char *name, int devfn,
......
434 483
    pci_dev->devfn = devfn;
435 484
    pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
436 485
    memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
486
    pci_config_alloc(pci_dev);
437 487
    pci_set_default_subsystem_id(pci_dev);
438 488
    pci_init_cmask(pci_dev);
439 489
    pci_init_wmask(pci_dev);
......
501 551

  
502 552
    qemu_free_irqs(pci_dev->irq);
503 553
    pci_dev->bus->devices[pci_dev->devfn] = NULL;
554
    pci_config_free(pci_dev);
504 555
    return 0;
505 556
}
506 557

  
......
641 692
{
642 693
    uint32_t val = 0;
643 694
    assert(len == 1 || len == 2 || len == 4);
644
    len = MIN(len, PCI_CONFIG_SPACE_SIZE - address);
695
    len = MIN(len, pci_config_size(d) - address);
645 696
    memcpy(&val, d->config + address, len);
646 697
    return le32_to_cpu(val);
647 698
}
......
650 701
{
651 702
    uint8_t orig[PCI_CONFIG_SPACE_SIZE];
652 703
    int i;
704
    uint32_t config_size = pci_config_size(d);
653 705

  
654 706
    /* not efficient, but simple */
655 707
    memcpy(orig, d->config, PCI_CONFIG_SPACE_SIZE);
656
    for(i = 0; i < l && addr < PCI_CONFIG_SPACE_SIZE; val >>= 8, ++i, ++addr) {
708
    for(i = 0; i < l && addr < config_size; val >>= 8, ++i, ++addr) {
657 709
        uint8_t wmask = d->wmask[addr];
658 710
        d->config[addr] = (d->config[addr] & ~wmask) | (val & wmask);
659 711
    }
......
1001 1053
    PCIBus *bus;
1002 1054
    int devfn, rc;
1003 1055

  
1056
    /* initialize cap_present for pci_is_express() and pci_config_size() */
1057
    if (info->is_express) {
1058
        pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
1059
    }
1060

  
1004 1061
    bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
1005 1062
    devfn = pci_dev->devfn;
1006 1063
    pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
......
1057 1114

  
1058 1115
static int pci_find_space(PCIDevice *pdev, uint8_t size)
1059 1116
{
1117
    int config_size = pci_config_size(pdev);
1060 1118
    int offset = PCI_CONFIG_HEADER_SIZE;
1061 1119
    int i;
1062
    for (i = PCI_CONFIG_HEADER_SIZE; i < PCI_CONFIG_SPACE_SIZE; ++i)
1120
    for (i = PCI_CONFIG_HEADER_SIZE; i < config_size; ++i)
1063 1121
        if (pdev->used[i])
1064 1122
            offset = i + 1;
1065 1123
        else if (i - offset + 1 == size)
b/hw/pci.h
163 163
#define PCI_CONFIG_HEADER_SIZE 0x40
164 164
/* Size of the standard PCI config space */
165 165
#define PCI_CONFIG_SPACE_SIZE 0x100
166
/* Size of the standart PCIe config space: 4KB */
167
#define PCIE_CONFIG_SPACE_SIZE  0x1000
166 168

  
167 169
#define PCI_NUM_PINS 4 /* A-D */
168 170

  
169 171
/* Bits in cap_present field. */
170 172
enum {
171 173
    QEMU_PCI_CAP_MSIX = 0x1,
174
    QEMU_PCI_CAP_EXPRESS = 0x2,
172 175
};
173 176

  
174 177
struct PCIDevice {
175 178
    DeviceState qdev;
176 179
    /* PCI config space */
177
    uint8_t config[PCI_CONFIG_SPACE_SIZE];
180
    uint8_t *config;
178 181

  
179 182
    /* Used to enable config checks on load. Note that writeable bits are
180 183
     * never checked even if set in cmask. */
181
    uint8_t cmask[PCI_CONFIG_SPACE_SIZE];
184
    uint8_t *cmask;
182 185

  
183 186
    /* Used to implement R/W bytes */
184
    uint8_t wmask[PCI_CONFIG_SPACE_SIZE];
187
    uint8_t *wmask;
185 188

  
186 189
    /* Used to allocate config space for capabilities. */
187
    uint8_t used[PCI_CONFIG_SPACE_SIZE];
190
    uint8_t *used;
188 191

  
189 192
    /* the following fields are read only */
190 193
    PCIBus *bus;
......
354 357
    PCIUnregisterFunc *exit;
355 358
    PCIConfigReadFunc *config_read;
356 359
    PCIConfigWriteFunc *config_write;
360

  
361
    /* pcie stuff */
362
    int is_express;   /* is this device pci express?
363
                       * initialization code needs to know this before
364
                       * each specific device initialization.
365
                       */
357 366
} PCIDeviceInfo;
358 367

  
359 368
void pci_qdev_register(PCIDeviceInfo *info);
......
362 371
PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name);
363 372
PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name);
364 373

  
374
static inline int pci_is_express(PCIDevice *d)
375
{
376
    return d->cap_present & QEMU_PCI_CAP_EXPRESS;
377
}
378

  
379
static inline uint32_t pci_config_size(PCIDevice *d)
380
{
381
    return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE;
382
}
383

  
365 384
/* lsi53c895a.c */
366 385
#define LSI_MAX_DEVS 7
367 386

  
b/hw/pcie_host.c
1
/*
2
 * pcie_host.c
3
 * utility functions for pci express host bridge.
4
 *
5
 * Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
6
 *                    VA Linux Systems Japan K.K.
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12

  
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17

  
18
 * You should have received a copy of the GNU General Public License along
19
 * with this program; if not, write to the Free Software Foundation, Inc.,
20
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
 */
22

  
23
#include "hw.h"
24
#include "pci.h"
25
#include "pcie_host.h"
26

  
27
/*
28
 * PCI express mmcfig address
29
 * bit 20 - 28: bus number
30
 * bit 15 - 19: device number
31
 * bit 12 - 14: function number
32
 * bit  0 - 11: offset in configuration space of a given device
33
 */
34
#define PCIE_MMCFG_SIZE_MAX             (1ULL << 28)
35
#define PCIE_MMCFG_SIZE_MIN             (1ULL << 20)
36
#define PCIE_MMCFG_BUS_BIT              20
37
#define PCIE_MMCFG_BUS_MASK             0x1ff
38
#define PCIE_MMCFG_DEVFN_BIT            12
39
#define PCIE_MMCFG_DEVFN_MASK           0xff
40
#define PCIE_MMCFG_CONFOFFSET_MASK      0xfff
41
#define PCIE_MMCFG_BUS(addr)            (((addr) >> PCIE_MMCFG_BUS_BIT) & \
42
                                         PCIE_MMCFG_BUS_MASK)
43
#define PCIE_MMCFG_DEVFN(addr)          (((addr) >> PCIE_MMCFG_DEVFN_BIT) & \
44
                                         PCIE_MMCFG_DEVFN_MASK)
45
#define PCIE_MMCFG_CONFOFFSET(addr)     ((addr) & PCIE_MMCFG_CONFOFFSET_MASK)
46

  
47

  
48
/* a helper function to get a PCIDevice for a given mmconfig address */
49
static inline PCIDevice *pcie_mmcfg_addr_to_dev(PCIBus *s, uint32_t mmcfg_addr)
50
{
51
    return pci_find_device(s, PCIE_MMCFG_BUS(mmcfg_addr),
52
                           PCI_SLOT(PCIE_MMCFG_DEVFN(mmcfg_addr)),
53
                           PCI_FUNC(PCIE_MMCFG_DEVFN(mmcfg_addr)));
54
}
55

  
56
static void pcie_mmcfg_data_write(PCIBus *s,
57
                                  uint32_t mmcfg_addr, uint32_t val, int len)
58
{
59
    PCIDevice *pci_dev = pcie_mmcfg_addr_to_dev(s, mmcfg_addr);
60

  
61
    if (!pci_dev)
62
        return;
63

  
64
    pci_dev->config_write(pci_dev,
65
                          PCIE_MMCFG_CONFOFFSET(mmcfg_addr), val, len);
66
}
67

  
68
static uint32_t pcie_mmcfg_data_read(PCIBus *s,
69
                                     uint32_t mmcfg_addr, int len)
70
{
71
    PCIDevice *pci_dev = pcie_mmcfg_addr_to_dev(s, mmcfg_addr);
72
    uint32_t val;
73

  
74
    if (!pci_dev) {
75
        switch(len) {
76
        case 1:
77
            val = 0xff;
78
            break;
79
        case 2:
80
            val = 0xffff;
81
            break;
82
        default:
83
        case 4:
84
            val = 0xffffffff;
85
            break;
86
        }
87
    } else {
88
        val = pci_dev->config_read(pci_dev,
89
                                   PCIE_MMCFG_CONFOFFSET(mmcfg_addr), len);
90
    }
91

  
92
    return val;
93
}
94

  
95
static void pcie_mmcfg_data_writeb(void *opaque,
96
                                   target_phys_addr_t addr, uint32_t value)
97
{
98
    PCIExpressHost *e = opaque;
99
    pcie_mmcfg_data_write(e->pci.bus, addr - e->base_addr, value, 1);
100
}
101

  
102
static void pcie_mmcfg_data_writew(void *opaque,
103
                                   target_phys_addr_t addr, uint32_t value)
104
{
105
    PCIExpressHost *e = opaque;
106
    pcie_mmcfg_data_write(e->pci.bus, addr - e->base_addr, value, 2);
107
}
108

  
109
static void pcie_mmcfg_data_writel(void *opaque,
110
                                   target_phys_addr_t addr, uint32_t value)
111
{
112
    PCIExpressHost *e = opaque;
113
    pcie_mmcfg_data_write(e->pci.bus, addr - e->base_addr, value, 4);
114
}
115

  
116
static uint32_t pcie_mmcfg_data_readb(void *opaque, target_phys_addr_t addr)
117
{
118
    PCIExpressHost *e = opaque;
119
    return pcie_mmcfg_data_read(e->pci.bus, addr - e->base_addr, 1);
120
}
121

  
122
static uint32_t pcie_mmcfg_data_readw(void *opaque, target_phys_addr_t addr)
123
{
124
    PCIExpressHost *e = opaque;
125
    return pcie_mmcfg_data_read(e->pci.bus, addr - e->base_addr, 2);
126
}
127

  
128
static uint32_t pcie_mmcfg_data_readl(void *opaque, target_phys_addr_t addr)
129
{
130
    PCIExpressHost *e = opaque;
131
    return pcie_mmcfg_data_read(e->pci.bus, addr - e->base_addr, 4);
132
}
133

  
134

  
135
static CPUWriteMemoryFunc * const pcie_mmcfg_write[] =
136
{
137
    pcie_mmcfg_data_writeb,
138
    pcie_mmcfg_data_writew,
139
    pcie_mmcfg_data_writel,
140
};
141

  
142
static CPUReadMemoryFunc * const pcie_mmcfg_read[] =
143
{
144
    pcie_mmcfg_data_readb,
145
    pcie_mmcfg_data_readw,
146
    pcie_mmcfg_data_readl,
147
};
148

  
149
/* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */
150
#define PCIE_BASE_ADDR_UNMAPPED  ((target_phys_addr_t)-1ULL)
151

  
152
int pcie_host_init(PCIExpressHost *e)
153
{
154
    e->base_addr = PCIE_BASE_ADDR_UNMAPPED;
155
    e->mmio_index =
156
        cpu_register_io_memory(pcie_mmcfg_read, pcie_mmcfg_write, e);
157
    if (e->mmio_index < 0) {
158
        return -1;
159
    }
160

  
161
    return 0;
162
}
163

  
164
void pcie_host_mmcfg_unmap(PCIExpressHost *e)
165
{
166
    if (e->base_addr != PCIE_BASE_ADDR_UNMAPPED) {
167
        cpu_register_physical_memory(e->base_addr, e->size, IO_MEM_UNASSIGNED);
168
        e->base_addr = PCIE_BASE_ADDR_UNMAPPED;
169
    }
170
}
171

  
172
void pcie_host_mmcfg_map(PCIExpressHost *e,
173
                         target_phys_addr_t addr, uint32_t size)
174
{
175
    assert(!(size & (size - 1)));       /* power of 2 */
176
    assert(size >= PCIE_MMCFG_SIZE_MIN);
177
    assert(size <= PCIE_MMCFG_SIZE_MAX);
178

  
179
    e->base_addr = addr;
180
    e->size = size;
181
    cpu_register_physical_memory(e->base_addr, e->size, e->mmio_index);
182
}
183

  
184
void pcie_host_mmcfg_update(PCIExpressHost *e,
185
                            int enable,
186
                            target_phys_addr_t addr, uint32_t size)
187
{
188
    pcie_host_mmcfg_unmap(e);
189
    if (enable) {
190
        pcie_host_mmcfg_map(e, addr, size);
191
    }
192
}
b/hw/pcie_host.h
1
/*
2
 * pcie_host.h
3
 *
4
 * Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
5
 *                    VA Linux Systems Japan K.K.
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11

  
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16

  
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
 */
21

  
22
#ifndef PCIE_HOST_H
23
#define PCIE_HOST_H
24

  
25
#include "pci_host.h"
26

  
27
typedef struct {
28
    PCIHostState pci;
29

  
30
    /* express part */
31

  
32
    /* base address where MMCONFIG area is mapped. */
33
    target_phys_addr_t  base_addr;
34

  
35
    /* the size of MMCONFIG area. It's host bridge dependent */
36
    target_phys_addr_t  size;
37

  
38
    /* result of cpu_register_io_memory() to map MMCONFIG area */
39
    int mmio_index;
40
} PCIExpressHost;
41

  
42
int pcie_host_init(PCIExpressHost *e);
43
void pcie_host_mmcfg_unmap(PCIExpressHost *e);
44
void pcie_host_mmcfg_map(PCIExpressHost *e,
45
                         target_phys_addr_t addr, uint32_t size);
46
void pcie_host_mmcfg_update(PCIExpressHost *e,
47
                            int enable,
48
                            target_phys_addr_t addr, uint32_t size);
49

  
50
#endif /* PCIE_HOST_H */

Also available in: Unified diff