2 * Xilinx PCIe host controller emulation.
4 * Copyright (c) 2016 Imagination Technologies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "qemu/osdep.h"
21 #include "qemu/module.h"
22 #include "qemu/units.h"
23 #include "qapi/error.h"
24 #include "hw/pci/pci_bridge.h"
25 #include "hw/qdev-properties.h"
27 #include "hw/pci-host/xilinx-pcie.h"
30 /* Interrupt Decode Register */
31 ROOTCFG_INTDEC
= 0x138,
33 /* Interrupt Mask Register */
34 ROOTCFG_INTMASK
= 0x13c,
35 /* INTx Interrupt Received */
36 #define ROOTCFG_INTMASK_INTX (1 << 16)
37 /* MSI Interrupt Received */
38 #define ROOTCFG_INTMASK_MSI (1 << 17)
40 /* PHY Status/Control Register */
43 #define ROOTCFG_PSCR_LINK_UP (1 << 11)
45 /* Root Port Status/Control Register */
46 ROOTCFG_RPSCR
= 0x148,
48 #define ROOTCFG_RPSCR_BRIDGEEN (1 << 0)
49 /* Interrupt FIFO Not Empty */
50 #define ROOTCFG_RPSCR_INTNEMPTY (1 << 18)
51 /* Interrupt FIFO Overflow */
52 #define ROOTCFG_RPSCR_INTOVF (1 << 19)
54 /* Root Port Interrupt FIFO Read Register 1 */
55 ROOTCFG_RPIFR1
= 0x158,
56 #define ROOTCFG_RPIFR1_INT_LANE_SHIFT 27
57 #define ROOTCFG_RPIFR1_INT_ASSERT_SHIFT 29
58 #define ROOTCFG_RPIFR1_INT_VALID_SHIFT 31
59 /* Root Port Interrupt FIFO Read Register 2 */
60 ROOTCFG_RPIFR2
= 0x15c,
63 static void xilinx_pcie_update_intr(XilinxPCIEHost
*s
,
64 uint32_t set
, uint32_t clear
)
71 if (s
->intr_fifo_r
!= s
->intr_fifo_w
) {
72 s
->intr
|= ROOTCFG_INTMASK_INTX
;
75 level
= !!(s
->intr
& s
->intr_mask
);
76 qemu_set_irq(s
->irq
, level
);
79 static void xilinx_pcie_queue_intr(XilinxPCIEHost
*s
,
80 uint32_t fifo_reg1
, uint32_t fifo_reg2
)
85 new_w
= (s
->intr_fifo_w
+ 1) % ARRAY_SIZE(s
->intr_fifo
);
86 if (new_w
== s
->intr_fifo_r
) {
87 s
->rpscr
|= ROOTCFG_RPSCR_INTOVF
;
91 intr
= &s
->intr_fifo
[s
->intr_fifo_w
];
92 s
->intr_fifo_w
= new_w
;
94 intr
->fifo_reg1
= fifo_reg1
;
95 intr
->fifo_reg2
= fifo_reg2
;
97 xilinx_pcie_update_intr(s
, ROOTCFG_INTMASK_INTX
, 0);
100 static void xilinx_pcie_set_irq(void *opaque
, int irq_num
, int level
)
102 XilinxPCIEHost
*s
= XILINX_PCIE_HOST(opaque
);
104 xilinx_pcie_queue_intr(s
,
105 (irq_num
<< ROOTCFG_RPIFR1_INT_LANE_SHIFT
) |
106 (level
<< ROOTCFG_RPIFR1_INT_ASSERT_SHIFT
) |
107 (1 << ROOTCFG_RPIFR1_INT_VALID_SHIFT
),
111 static void xilinx_pcie_host_realize(DeviceState
*dev
, Error
**errp
)
113 PCIHostState
*pci
= PCI_HOST_BRIDGE(dev
);
114 XilinxPCIEHost
*s
= XILINX_PCIE_HOST(dev
);
115 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
116 PCIExpressHost
*pex
= PCIE_HOST_BRIDGE(dev
);
118 snprintf(s
->name
, sizeof(s
->name
), "pcie%u", s
->bus_nr
);
120 /* PCI configuration space */
121 pcie_host_mmcfg_init(pex
, s
->cfg_size
);
124 memory_region_init(&s
->mmio
, OBJECT(s
), "mmio", UINT64_MAX
);
125 memory_region_set_enabled(&s
->mmio
, false);
127 /* dummy PCI I/O region (not visible to the CPU) */
128 memory_region_init(&s
->io
, OBJECT(s
), "io", 16);
131 qdev_init_gpio_out_named(dev
, &s
->irq
, "interrupt_out", 1);
133 sysbus_init_mmio(sbd
, &pex
->mmio
);
134 sysbus_init_mmio(sbd
, &s
->mmio
);
136 pci
->bus
= pci_register_root_bus(dev
, s
->name
, xilinx_pcie_set_irq
,
137 pci_swizzle_map_irq_fn
, s
, &s
->mmio
,
138 &s
->io
, 0, 4, TYPE_PCIE_BUS
);
140 qdev_set_parent_bus(DEVICE(&s
->root
), BUS(pci
->bus
));
141 qdev_init_nofail(DEVICE(&s
->root
));
144 static const char *xilinx_pcie_host_root_bus_path(PCIHostState
*host_bridge
,
150 static void xilinx_pcie_host_init(Object
*obj
)
152 XilinxPCIEHost
*s
= XILINX_PCIE_HOST(obj
);
153 XilinxPCIERoot
*root
= &s
->root
;
155 object_initialize_child(obj
, "root", root
, sizeof(*root
),
156 TYPE_XILINX_PCIE_ROOT
, &error_abort
, NULL
);
157 qdev_prop_set_int32(DEVICE(root
), "addr", PCI_DEVFN(0, 0));
158 qdev_prop_set_bit(DEVICE(root
), "multifunction", false);
161 static Property xilinx_pcie_host_props
[] = {
162 DEFINE_PROP_UINT32("bus_nr", XilinxPCIEHost
, bus_nr
, 0),
163 DEFINE_PROP_SIZE("cfg_base", XilinxPCIEHost
, cfg_base
, 0),
164 DEFINE_PROP_SIZE("cfg_size", XilinxPCIEHost
, cfg_size
, 32 * MiB
),
165 DEFINE_PROP_SIZE("mmio_base", XilinxPCIEHost
, mmio_base
, 0),
166 DEFINE_PROP_SIZE("mmio_size", XilinxPCIEHost
, mmio_size
, 1 * MiB
),
167 DEFINE_PROP_BOOL("link_up", XilinxPCIEHost
, link_up
, true),
168 DEFINE_PROP_END_OF_LIST(),
171 static void xilinx_pcie_host_class_init(ObjectClass
*klass
, void *data
)
173 DeviceClass
*dc
= DEVICE_CLASS(klass
);
174 PCIHostBridgeClass
*hc
= PCI_HOST_BRIDGE_CLASS(klass
);
176 hc
->root_bus_path
= xilinx_pcie_host_root_bus_path
;
177 dc
->realize
= xilinx_pcie_host_realize
;
178 set_bit(DEVICE_CATEGORY_BRIDGE
, dc
->categories
);
180 dc
->props
= xilinx_pcie_host_props
;
183 static const TypeInfo xilinx_pcie_host_info
= {
184 .name
= TYPE_XILINX_PCIE_HOST
,
185 .parent
= TYPE_PCIE_HOST_BRIDGE
,
186 .instance_size
= sizeof(XilinxPCIEHost
),
187 .instance_init
= xilinx_pcie_host_init
,
188 .class_init
= xilinx_pcie_host_class_init
,
191 static uint32_t xilinx_pcie_root_config_read(PCIDevice
*d
,
192 uint32_t address
, int len
)
194 XilinxPCIEHost
*s
= XILINX_PCIE_HOST(OBJECT(d
)->parent
);
201 case ROOTCFG_INTMASK
:
205 val
= s
->link_up
? ROOTCFG_PSCR_LINK_UP
: 0;
208 if (s
->intr_fifo_r
!= s
->intr_fifo_w
) {
209 s
->rpscr
&= ~ROOTCFG_RPSCR_INTNEMPTY
;
211 s
->rpscr
|= ROOTCFG_RPSCR_INTNEMPTY
;
216 if (s
->intr_fifo_w
== s
->intr_fifo_r
) {
220 val
= s
->intr_fifo
[s
->intr_fifo_r
].fifo_reg1
;
224 if (s
->intr_fifo_w
== s
->intr_fifo_r
) {
228 val
= s
->intr_fifo
[s
->intr_fifo_r
].fifo_reg2
;
232 val
= pci_default_read_config(d
, address
, len
);
238 static void xilinx_pcie_root_config_write(PCIDevice
*d
, uint32_t address
,
239 uint32_t val
, int len
)
241 XilinxPCIEHost
*s
= XILINX_PCIE_HOST(OBJECT(d
)->parent
);
244 xilinx_pcie_update_intr(s
, 0, val
);
246 case ROOTCFG_INTMASK
:
248 xilinx_pcie_update_intr(s
, 0, 0);
251 s
->rpscr
&= ~ROOTCFG_RPSCR_BRIDGEEN
;
252 s
->rpscr
|= val
& ROOTCFG_RPSCR_BRIDGEEN
;
253 memory_region_set_enabled(&s
->mmio
, val
& ROOTCFG_RPSCR_BRIDGEEN
);
255 if (val
& ROOTCFG_INTMASK_INTX
) {
256 s
->rpscr
&= ~ROOTCFG_INTMASK_INTX
;
261 if (s
->intr_fifo_w
== s
->intr_fifo_r
) {
265 s
->intr_fifo_r
= (s
->intr_fifo_r
+ 1) % ARRAY_SIZE(s
->intr_fifo
);
269 pci_default_write_config(d
, address
, val
, len
);
274 static void xilinx_pcie_root_realize(PCIDevice
*pci_dev
, Error
**errp
)
276 BusState
*bus
= qdev_get_parent_bus(DEVICE(pci_dev
));
277 XilinxPCIEHost
*s
= XILINX_PCIE_HOST(bus
->parent
);
279 pci_set_word(pci_dev
->config
+ PCI_COMMAND
,
280 PCI_COMMAND_MEMORY
| PCI_COMMAND_MASTER
);
281 pci_set_word(pci_dev
->config
+ PCI_MEMORY_BASE
, s
->mmio_base
>> 16);
282 pci_set_word(pci_dev
->config
+ PCI_MEMORY_LIMIT
,
283 ((s
->mmio_base
+ s
->mmio_size
- 1) >> 16) & 0xfff0);
285 pci_bridge_initfn(pci_dev
, TYPE_PCI_BUS
);
287 if (pcie_endpoint_cap_v1_init(pci_dev
, 0x80) < 0) {
288 error_setg(errp
, "Failed to initialize PCIe capability");
292 static void xilinx_pcie_root_class_init(ObjectClass
*klass
, void *data
)
294 PCIDeviceClass
*k
= PCI_DEVICE_CLASS(klass
);
295 DeviceClass
*dc
= DEVICE_CLASS(klass
);
297 set_bit(DEVICE_CATEGORY_BRIDGE
, dc
->categories
);
298 dc
->desc
= "Xilinx AXI-PCIe Host Bridge";
299 k
->vendor_id
= PCI_VENDOR_ID_XILINX
;
300 k
->device_id
= 0x7021;
302 k
->class_id
= PCI_CLASS_BRIDGE_HOST
;
304 k
->realize
= xilinx_pcie_root_realize
;
305 k
->exit
= pci_bridge_exitfn
;
306 dc
->reset
= pci_bridge_reset
;
307 k
->config_read
= xilinx_pcie_root_config_read
;
308 k
->config_write
= xilinx_pcie_root_config_write
;
310 * PCI-facing part of the host bridge, not usable without the
311 * host-facing part, which can't be device_add'ed, yet.
313 dc
->user_creatable
= false;
316 static const TypeInfo xilinx_pcie_root_info
= {
317 .name
= TYPE_XILINX_PCIE_ROOT
,
318 .parent
= TYPE_PCI_BRIDGE
,
319 .instance_size
= sizeof(XilinxPCIERoot
),
320 .class_init
= xilinx_pcie_root_class_init
,
321 .interfaces
= (InterfaceInfo
[]) {
322 { INTERFACE_PCIE_DEVICE
},
327 static void xilinx_pcie_register(void)
329 type_register_static(&xilinx_pcie_root_info
);
330 type_register_static(&xilinx_pcie_host_info
);
333 type_init(xilinx_pcie_register
)