Revision bc20ba98

b/Makefile.objs
186 186
# PCI watchdog devices
187 187
hw-obj-y += wdt_i6300esb.o
188 188

  
189
hw-obj-y += pcie.o
189
hw-obj-y += pcie.o pcie_port.o
190 190
hw-obj-y += msix.o msi.o
191 191

  
192 192
# PCI network cards
b/hw/pcie_port.c
1
/*
2
 * pcie_port.c
3
 *
4
 * Copyright (c) 2010 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, see <http://www.gnu.org/licenses/>.
19
 */
20

  
21
#include "pcie_port.h"
22

  
23
void pcie_port_init_reg(PCIDevice *d)
24
{
25
    /* Unlike pci bridge,
26
       66MHz and fast back to back don't apply to pci express port. */
27
    pci_set_word(d->config + PCI_STATUS, 0);
28
    pci_set_word(d->config + PCI_SEC_STATUS, 0);
29

  
30
    /* 7.5.3.5 Prefetchable Memory Base Limit
31
     * The Prefetchable Memory Base and Prefetchable Memory Limit registers
32
     * must indicate that 64-bit addresses are supported, as defined in
33
     * PCI-to-PCI Bridge Architecture Specification, Revision 1.2.
34
     */
35
    pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_BASE,
36
                               PCI_PREF_RANGE_TYPE_64);
37
    pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_LIMIT,
38
                               PCI_PREF_RANGE_TYPE_64);
39
}
40

  
41
/**************************************************************************
42
 * (chassis number, pcie physical slot number) -> pcie slot conversion
43
 */
44
struct PCIEChassis {
45
    uint8_t     number;
46

  
47
    QLIST_HEAD(, PCIESlot) slots;
48
    QLIST_ENTRY(PCIEChassis) next;
49
};
50

  
51
static QLIST_HEAD(, PCIEChassis) chassis = QLIST_HEAD_INITIALIZER(chassis);
52

  
53
static struct PCIEChassis *pcie_chassis_find(uint8_t chassis_number)
54
{
55
    struct PCIEChassis *c;
56
    QLIST_FOREACH(c, &chassis, next) {
57
        if (c->number == chassis_number) {
58
            break;
59
        }
60
    }
61
    return c;
62
}
63

  
64
void pcie_chassis_create(uint8_t chassis_number)
65
{
66
    struct PCIEChassis *c;
67
    c = pcie_chassis_find(chassis_number);
68
    if (c) {
69
        return;
70
    }
71
    c = qemu_mallocz(sizeof(*c));
72
    c->number = chassis_number;
73
    QLIST_INIT(&c->slots);
74
    QLIST_INSERT_HEAD(&chassis, c, next);
75
}
76

  
77
static PCIESlot *pcie_chassis_find_slot_with_chassis(struct PCIEChassis *c,
78
                                                     uint8_t slot)
79
{
80
    PCIESlot *s;
81
    QLIST_FOREACH(s, &c->slots, next) {
82
        if (s->slot == slot) {
83
            break;
84
        }
85
    }
86
    return s;
87
}
88

  
89
PCIESlot *pcie_chassis_find_slot(uint8_t chassis_number, uint16_t slot)
90
{
91
    struct PCIEChassis *c;
92
    c = pcie_chassis_find(chassis_number);
93
    if (!c) {
94
        return NULL;
95
    }
96
    return pcie_chassis_find_slot_with_chassis(c, slot);
97
}
98

  
99
int pcie_chassis_add_slot(struct PCIESlot *slot)
100
{
101
    struct PCIEChassis *c;
102
    c = pcie_chassis_find(slot->chassis);
103
    if (!c) {
104
        return -ENODEV;
105
    }
106
    if (pcie_chassis_find_slot_with_chassis(c, slot->slot)) {
107
        return -EBUSY;
108
    }
109
    QLIST_INSERT_HEAD(&c->slots, slot, next);
110
    return 0;
111
}
112

  
113
void pcie_chassis_del_slot(PCIESlot *s)
114
{
115
    QLIST_REMOVE(s, next);
116
}
b/hw/pcie_port.h
1
/*
2
 * pcie_port.h
3
 *
4
 * Copyright (c) 2010 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, see <http://www.gnu.org/licenses/>.
19
 */
20

  
21
#ifndef QEMU_PCIE_PORT_H
22
#define QEMU_PCIE_PORT_H
23

  
24
#include "pci_bridge.h"
25
#include "pci_internals.h"
26

  
27
struct PCIEPort {
28
    PCIBridge   br;
29

  
30
    /* pci express switch port */
31
    uint8_t     port;
32
};
33

  
34
void pcie_port_init_reg(PCIDevice *d);
35

  
36
struct PCIESlot {
37
    PCIEPort    port;
38

  
39
    /* pci express switch port with slot */
40
    uint8_t     chassis;
41
    uint16_t    slot;
42
    QLIST_ENTRY(PCIESlot) next;
43
};
44

  
45
void pcie_chassis_create(uint8_t chassis_number);
46
void pcie_main_chassis_create(void);
47
PCIESlot *pcie_chassis_find_slot(uint8_t chassis, uint16_t slot);
48
int pcie_chassis_add_slot(struct PCIESlot *slot);
49
void pcie_chassis_del_slot(PCIESlot *s);
50

  
51
#endif /* QEMU_PCIE_PORT_H */
b/qemu-common.h
221 221
typedef struct PCIDevice PCIDevice;
222 222
typedef struct PCIExpressDevice PCIExpressDevice;
223 223
typedef struct PCIBridge PCIBridge;
224
typedef struct PCIEPort PCIEPort;
225
typedef struct PCIESlot PCIESlot;
224 226
typedef struct SerialState SerialState;
225 227
typedef struct IRQState *qemu_irq;
226 228
typedef struct PCMCIACardState PCMCIACardState;

Also available in: Unified diff