1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "qemu/osdep.h"
28#include "hw/sysbus.h"
29#include "hw/register.h"
30#include "qemu/bitops.h"
31#include "qemu/log.h"
32#include "qapi/error.h"
33#include "migration/vmstate.h"
34#include "hw/qdev-properties.h"
35
36#include "hw/pci/msi.h"
37
38#include "hw/pci/pci.h"
39#include "hw/pci/pcie.h"
40#include "hw/pci/pci_bus.h"
41#include "hw/pci/pcie_host.h"
42#include "hw/pci/pcie_port.h"
43#include "hw/irq.h"
44
45#ifndef XILINX_AXIPCIE_MAIN_ERR_DEBUG
46#define XILINX_AXIPCIE_MAIN_ERR_DEBUG 0
47#endif
48
49#define TYPE_XILINX_AXIPCIE_MAIN "xlnx.nwl-pcie-main"
50#define TYPE_XILINX_AXIPCIE_MAIN_IOMMU_MEMORY_REGION "xlnx.nwl-pcie-main-iommu-memory-region"
51
52#define XILINX_AXIPCIE_MAIN(obj) \
53 OBJECT_CHECK(AXIPCIE_MAIN, (obj), TYPE_XILINX_AXIPCIE_MAIN)
54
55REG32(BRIDGE_CORE_CFG_PCIE_RX0, 0x0)
56 FIELD(BRIDGE_CORE_CFG_PCIE_RX0, CFG_DISABLE_PCIE_DMA_REG_ACCESS, 17, 1)
57 FIELD(BRIDGE_CORE_CFG_PCIE_RX0, CFG_DISABLE_PCIE_BRIDGE_REG_ACCESS, 16, 1)
58 FIELD(BRIDGE_CORE_CFG_PCIE_RX0, CFG_DMA_REG_BAR, 0, 3)
59REG32(BRIDGE_CORE_CFG_PCIE_RX1, 0x4)
60 FIELD(BRIDGE_CORE_CFG_PCIE_RX1, CFG_RD_UR_IS_UR_OK1S_N, 8, 1)
61 FIELD(BRIDGE_CORE_CFG_PCIE_RX1, CFG_PCIE_RX_ARCACHE, 4, 4)
62 FIELD(BRIDGE_CORE_CFG_PCIE_RX1, CFG_PCIE_RX_AWCACHE, 0, 4)
63REG32(BRIDGE_CORE_CFG_AXI_MASTER, 0x8)
64 FIELD(BRIDGE_CORE_CFG_AXI_MASTER, CFG_M_MAX_RD_REQ_SIZE, 4, 3)
65 FIELD(BRIDGE_CORE_CFG_AXI_MASTER, CFG_M_MAX_WR_REQ_SIZE, 0, 3)
66REG32(BRIDGE_CORE_CFG_PCIE_TX, 0xc)
67 FIELD(BRIDGE_CORE_CFG_PCIE_TX, CFG_PCIE_TX_CUT_THROUGH, 0, 1)
68REG32(BRIDGE_CORE_CFG_INTERRUPT, 0x10)
69 FIELD(BRIDGE_CORE_CFG_INTERRUPT, CFG_PCIE_INT_AXI_PCIE_N, 0, 1)
70REG32(BRIDGE_CORE_CFG_RAM_DISABLE0, 0x14)
71 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_SGL_DST_DIS_COR, 14, 1)
72 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_SGL_SRC_DIS_COR, 13, 1)
73 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_CH_REG_DIS_COR, 12, 1)
74 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_MSIX_TAB_DIS_COR, 11, 1)
75 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_AXI_S_W_DIS_COR, 8, 1)
76 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_AXI_M_R_DIS_COR, 6, 1)
77 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_PCIE_S_CD_DIS_COR, 5, 1)
78 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_PCIE_S_RA_DIS_COR, 4, 1)
79 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_PCIE_S_W_DIS_COR, 3, 1)
80 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_PCIE_S_WA_DIS_COR, 2, 1)
81 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_PCIE_TX_W_DIS_COR, 1, 1)
82 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_PCIE_M_R_DIS_COR, 0, 1)
83REG32(BRIDGE_CORE_CFG_RAM_DISABLE1, 0x18)
84 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_SGL_DST_DIS_ERR, 14, 1)
85 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_SGL_SRC_DIS_ERR, 13, 1)
86 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_CH_REG_DIS_ERR, 12, 1)
87 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_MSIX_TAB_DIS_ERR, 11, 1)
88 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_AXI_S_W_DIS_ERR, 8, 1)
89 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_AXI_M_R_DIS_ERR, 6, 1)
90 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_PCIE_S_CD_DIS_ERR, 5, 1)
91 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_PCIE_S_RA_DIS_ERR, 4, 1)
92 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_PCIE_S_W_DIS_ERR, 3, 1)
93 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_PCIE_S_WA_DIS_ERR, 2, 1)
94 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_PCIE_TX_W_DIS_ERR, 1, 1)
95 FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_PCIE_M_R_DIS_ERR, 0, 1)
96REG32(BRIDGE_CORE_CFG_PCIE_RELAXED_ORDER, 0x1c)
97 FIELD(BRIDGE_CORE_CFG_PCIE_RELAXED_ORDER, CFG_ENABLE_CFGIO_WR_RO, 1, 1)
98 FIELD(BRIDGE_CORE_CFG_PCIE_RELAXED_ORDER, CFG_ENABLE_DMA_RO, 0, 1)
99REG32(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, 0x20)
100 FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER,
101 CFG_DESIRED_VEN_MSG_VEN_ID, 16, 16)
102 FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER,
103 CFG_DESIRED_VEN_MSG_VEN_INV, 15, 1)
104 FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_DESIRED_VEN_MSG_EN, 14, 1)
105 FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_ENABLE_OTH_MSG_FWD, 13, 1)
106 FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_ENABLE_VEN_MSG_FWD, 7, 1)
107 FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_ENABLE_SLT_MSG_FWD, 5, 1)
108 FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_ENABLE_ERR_MSG_FWD, 3, 1)
109 FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_ENABLE_INT_MSG_FWD, 2, 1)
110 FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_ENABLE_PM_MSG_FWD, 1, 1)
111REG32(BRIDGE_CORE_CFG_RQ_REQ_ORDER, 0x24)
112 FIELD(BRIDGE_CORE_CFG_RQ_REQ_ORDER, CFG_PCIE_REQ_ORDER_STRICT, 31, 1)
113 FIELD(BRIDGE_CORE_CFG_RQ_REQ_ORDER, CFG_AXI_REQ_ORDER_STRICT, 30, 1)
114 FIELD(BRIDGE_CORE_CFG_RQ_REQ_ORDER, CFG_AXI_REQ_ORDER_ID_MASK, 0, 16)
115REG32(BRIDGE_CORE_CFG_PCIE_CREDIT, 0x28)
116 FIELD(BRIDGE_CORE_CFG_PCIE_CREDIT, CFG_PCIE_CREDIT_EN, 31, 1)
117 FIELD(BRIDGE_CORE_CFG_PCIE_CREDIT, CFG_PCIE_CREDIT_CH_INF, 30, 1)
118 FIELD(BRIDGE_CORE_CFG_PCIE_CREDIT, CFG_PCIE_CREDIT_CD_INF, 29, 1)
119 FIELD(BRIDGE_CORE_CFG_PCIE_CREDIT, CFG_PCIE_CREDIT_CH_VAL, 16, 8)
120 FIELD(BRIDGE_CORE_CFG_PCIE_CREDIT, CFG_PCIE_CREDIT_CD_VAL, 0, 12)
121REG32(BRIDGE_CORE_CFG_AXI_M_W_TICK_COUNT, 0x2c)
122 FIELD(BRIDGE_CORE_CFG_AXI_M_W_TICK_COUNT, AXI_M_W_TICK_COUNT, 0, 16)
123REG32(BRIDGE_CORE_CFG_AXI_M_R_TICK_COUNT, 0x30)
124 FIELD(BRIDGE_CORE_CFG_AXI_M_R_TICK_COUNT, AXI_M_R_TICK_COUNT, 0, 16)
125REG32(BRIDGE_CORE_CFG_CRS_RPL_TICK_COUNT, 0x34)
126 FIELD(BRIDGE_CORE_CFG_CRS_RPL_TICK_COUNT, CRS_RPL_TICK_COUNT, 0, 16)
127REG32(E_BREG_CAPABILITIES, 0x200)
128 FIELD(E_BREG_CAPABILITIES, BREG_SIZE_MAX, 24, 8)
129 FIELD(E_BREG_CAPABILITIES, BREG_SIZE_OFFSET, 16, 8)
130 FIELD(E_BREG_CAPABILITIES, BREG_PRESENT, 0, 1)
131REG32(E_BREG_STATUS, 0x204)
132 FIELD(E_BREG_STATUS, WR_PENDING_CTR, 16, 9)
133 FIELD(E_BREG_STATUS, RD_PENDING_CTR, 0, 9)
134REG32(E_BREG_CONTROL, 0x208)
135 FIELD(E_BREG_CONTROL, BREG_SIZE, 16, 2)
136 FIELD(E_BREG_CONTROL, BREG_SECURITY_ENABLE, 2, 1)
137 FIELD(E_BREG_CONTROL, BREG_ENABLE_FORCE, 1, 1)
138 FIELD(E_BREG_CONTROL, BREG_ENABLE, 0, 1)
139REG32(E_BREG_BASE_LO, 0x210)
140 FIELD(E_BREG_BASE_LO, BREG_BASE_LO, 12, 20)
141REG32(E_BREG_BASE_HI, 0x214)
142REG32(E_ECAM_CAPABILITIES, 0x220)
143 FIELD(E_ECAM_CAPABILITIES, ECAM_SIZE_MAX, 24, 8)
144 FIELD(E_ECAM_CAPABILITIES, ECAM_SIZE_OFFSET, 16, 8)
145 FIELD(E_ECAM_CAPABILITIES, ECAM_PRESENT, 0, 1)
146REG32(E_ECAM_STATUS, 0x224)
147 FIELD(E_ECAM_STATUS, WR_PENDING_CTR, 16, 9)
148 FIELD(E_ECAM_STATUS, RD_PENDING_CTR, 0, 9)
149REG32(E_ECAM_CONTROL, 0x228)
150 FIELD(E_ECAM_CONTROL, ECAM_SIZE, 16, 5)
151 FIELD(E_ECAM_CONTROL, ECAM_SECURITY_ENABLE, 2, 1)
152 FIELD(E_ECAM_CONTROL, ECAM_ENABLE, 0, 1)
153REG32(E_ECAM_BASE_LO, 0x230)
154 FIELD(E_ECAM_BASE_LO, ECAM_BASE_LO, 12, 20)
155REG32(E_ECAM_BASE_HI, 0x234)
156REG32(E_MSXT_CAPABILITIES, 0x240)
157 FIELD(E_MSXT_CAPABILITIES, MSXT_SIZE_MAX, 24, 8)
158 FIELD(E_MSXT_CAPABILITIES, MSXT_SIZE_OFFSET, 16, 8)
159 FIELD(E_MSXT_CAPABILITIES, MSXT_PRESENT, 0, 1)
160REG32(E_MSXT_STATUS, 0x244)
161 FIELD(E_MSXT_STATUS, WR_PENDING_CTR, 16, 9)
162 FIELD(E_MSXT_STATUS, RD_PENDING_CTR, 0, 9)
163REG32(E_MSXT_CONTROL, 0x248)
164 FIELD(E_MSXT_CONTROL, MSXT_SIZE, 16, 2)
165 FIELD(E_MSXT_CONTROL, MSXT_SECURITY_ENABLE, 2, 1)
166 FIELD(E_MSXT_CONTROL, MSXT_ENABLE, 0, 1)
167REG32(E_MSXT_BASE_LO, 0x250)
168 FIELD(E_MSXT_BASE_LO, MSXT_BASE_LO, 12, 20)
169REG32(E_MSXT_BASE_HI, 0x254)
170REG32(E_MSXP_CAPABILITIES, 0x260)
171 FIELD(E_MSXP_CAPABILITIES, MSXP_SIZE_MAX, 24, 8)
172 FIELD(E_MSXP_CAPABILITIES, MSXP_SIZE_OFFSET, 16, 8)
173 FIELD(E_MSXP_CAPABILITIES, MSXP_PRESENT, 0, 1)
174REG32(E_MSXP_STATUS, 0x264)
175 FIELD(E_MSXP_STATUS, WR_PENDING_CTR, 16, 9)
176 FIELD(E_MSXP_STATUS, RD_PENDING_CTR, 0, 9)
177REG32(E_MSXP_CONTROL, 0x268)
178 FIELD(E_MSXP_CONTROL, MSXP_SIZE, 16, 2)
179 FIELD(E_MSXP_CONTROL, MSXP_SECURITY_ENABLE, 2, 1)
180 FIELD(E_MSXP_CONTROL, MSXP_ENABLE, 0, 1)
181REG32(E_MSXP_BASE_LO, 0x270)
182 FIELD(E_MSXP_BASE_LO, MSXP_BASE_LO, 12, 20)
183REG32(E_MSXP_BASE_HI, 0x274)
184REG32(E_DREG_CAPABILITIES, 0x280)
185 FIELD(E_DREG_CAPABILITIES, DMA_SIZE_MAX, 24, 8)
186 FIELD(E_DREG_CAPABILITIES, DMA_SIZE_OFFSET, 16, 8)
187 FIELD(E_DREG_CAPABILITIES, DMA_PRESENT, 0, 1)
188REG32(E_DREG_STATUS, 0x284)
189 FIELD(E_DREG_STATUS, WR_PENDING_CTR, 16, 9)
190 FIELD(E_DREG_STATUS, RD_PENDING_CTR, 0, 9)
191REG32(E_DREG_CONTROL, 0x288)
192 FIELD(E_DREG_CONTROL, DMA_SIZE, 16, 2)
193 FIELD(E_DREG_CONTROL, DMA_SECURITY_ENABLE, 2, 1)
194 FIELD(E_DREG_CONTROL, DMA_ENABLE, 0, 1)
195REG32(E_DREG_BASE_LO, 0x290)
196 FIELD(E_DREG_BASE_LO, DMA_BASE_LO, 12, 20)
197REG32(E_DREG_BASE_HI, 0x294)
198REG32(E_ESUB_CAPABILITIES, 0x2e0)
199 FIELD(E_ESUB_CAPABILITIES, SUBTRACTIVE_DECODE_PRESENT, 0, 1)
200REG32(E_ESUB_STATUS, 0x2e4)
201 FIELD(E_ESUB_STATUS, WR_PENDING_CTR, 16, 9)
202 FIELD(E_ESUB_STATUS, RD_PENDING_CTR, 0, 9)
203REG32(E_ESUB_CONTROL, 0x2e8)
204 FIELD(E_ESUB_CONTROL, EGRESS_SUB_ENABLE, 0, 1)
205REG32(I_MSII_CAPABILITIES, 0x300)
206 FIELD(I_MSII_CAPABILITIES, I_MSII_SIZE_MAX, 24, 8)
207 FIELD(I_MSII_CAPABILITIES, I_MSII_SIZE_OFFSET, 16, 8)
208 FIELD(I_MSII_CAPABILITIES, I_MSII_PRESENT, 0, 1)
209REG32(I_MSII_CONTROL, 0x308)
210 FIELD(I_MSII_CONTROL, I_MSII_SIZE, 16, 5)
211 FIELD(I_MSII_CONTROL, I_MSII_STATUS_ENABLE, 15, 1)
212 FIELD(I_MSII_CONTROL, I_MSII_ENABLE, 0, 1)
213REG32(I_MSII_BASE_LO, 0x310)
214 FIELD(I_MSII_BASE_LO, I_MSII_BASE_LO, 12, 20)
215REG32(I_MSII_BASE_HI, 0x314)
216REG32(I_MSIX_CAPABILITIES, 0x320)
217 FIELD(I_MSIX_CAPABILITIES, I_MSIX_SIZE_MAX, 24, 8)
218 FIELD(I_MSIX_CAPABILITIES, I_MSIX_SIZE_OFFSET, 16, 8)
219 FIELD(I_MSIX_CAPABILITIES, I_MSIX_PRESENT, 0, 1)
220REG32(I_MSIX_CONTROL, 0x328)
221 FIELD(I_MSIX_CONTROL, I_MSIX_SIZE, 16, 5)
222 FIELD(I_MSIX_CONTROL, I_MSIX_ENABLE, 0, 1)
223REG32(I_MSIX_BASE_LO, 0x330)
224 FIELD(I_MSIX_BASE_LO, I_MSIX_BASE_LO, 12, 20)
225REG32(I_MSIX_BASE_HI, 0x334)
226REG32(I_ISUB_CAPABILITIES, 0x3e0)
227 FIELD(I_ISUB_CAPABILITIES, SUBTRACTIVE_DECODE_PRESENT, 0, 1)
228REG32(I_ISUB_STATUS, 0x3e4)
229 FIELD(I_ISUB_STATUS, WR_PENDING_CTR, 16, 9)
230 FIELD(I_ISUB_STATUS, RD_PENDING_CTR, 0, 9)
231REG32(I_ISUB_CONTROL, 0x3e8)
232 FIELD(I_ISUB_CONTROL, INGRESS_SUB_ENABLE, 0, 1)
233REG32(MSGF_MISC_STATUS, 0x400)
234 FIELD(MSGF_MISC_STATUS, PCIE_CORE_EVENT, 16, 16)
235 FIELD(MSGF_MISC_STATUS, EGRESS_ADDRESS_TRANSLATION_ERROR, 7, 1)
236 FIELD(MSGF_MISC_STATUS, INGRESS_ADDRESS_TRANSLATION_ERROR, 6, 1)
237 FIELD(MSGF_MISC_STATUS, MASTER_ERROR, 5, 1)
238 FIELD(MSGF_MISC_STATUS, SLAVE_ERROR, 4, 1)
239 FIELD(MSGF_MISC_STATUS, UNCORRECTABLE_WRITE_ERROR, 3, 1)
240 FIELD(MSGF_MISC_STATUS, RX_MSG_OVERFLOW, 1, 1)
241 FIELD(MSGF_MISC_STATUS, RX_MSG_AVAIL, 0, 1)
242REG32(MSGF_MISC_MASK, 0x404)
243 FIELD(MSGF_MISC_MASK, PCIE_CORE_EVENT_MASK, 16, 16)
244 FIELD(MSGF_MISC_MASK, EGRESS_ADDRESS_TRANSLATION_ERROR_MASK, 7, 1)
245 FIELD(MSGF_MISC_MASK, INGRESS_ADDRESS_TRANSLATION_ERROR_MASK, 6, 1)
246 FIELD(MSGF_MISC_MASK, MASTER_ERROR_MASK, 5, 1)
247 FIELD(MSGF_MISC_MASK, SLAVE_ERROR_MASK, 4, 1)
248 FIELD(MSGF_MISC_MASK, UNCORRECTABLE_WRITE_ERROR_MASK, 3, 1)
249 FIELD(MSGF_MISC_MASK, RX_MSG_OVERFLOW_MASK, 1, 1)
250 FIELD(MSGF_MISC_MASK, RX_MSG_AVAIL_MASK, 0, 1)
251REG32(MSGF_MISC_SLAVE_ID, 0x408)
252 FIELD(MSGF_MISC_SLAVE_ID, SLAVE_ERROR_ID, 0, 8)
253REG32(MSGF_MISC_MASTER_ID, 0x40c)
254 FIELD(MSGF_MISC_MASTER_ID, MASTER_ERROR_ID, 0, 8)
255REG32(MSGF_MISC_INGRESS_ID, 0x410)
256 FIELD(MSGF_MISC_INGRESS_ID, INGRESS_ERROR_ID, 0, 8)
257REG32(MSGF_MISC_EGRESS_ID, 0x414)
258 FIELD(MSGF_MISC_EGRESS_ID, EGRESS_ERROR_ID, 0, 8)
259REG32(MSGF_LEG_STATUS, 0x420)
260 FIELD(MSGF_LEG_STATUS, MSGF_LEG_STATUS_INTD, 3, 1)
261 FIELD(MSGF_LEG_STATUS, MSGF_LEG_STATUS_INTC, 2, 1)
262 FIELD(MSGF_LEG_STATUS, MSGF_LEG_STATUS_INTB, 1, 1)
263 FIELD(MSGF_LEG_STATUS, MSGF_LEG_STATUS_INTA, 0, 1)
264REG32(MSGF_LEG_MASK, 0x424)
265 FIELD(MSGF_LEG_MASK, MSGF_LEG_MASK_INTD, 3, 1)
266 FIELD(MSGF_LEG_MASK, MSGF_LEG_MASK_INTC, 2, 1)
267 FIELD(MSGF_LEG_MASK, MSGF_LEG_MASK_INTB, 1, 1)
268 FIELD(MSGF_LEG_MASK, MSGF_LEG_MASK_INTA, 0, 1)
269REG32(MSGF_MSI_STATUS_LO, 0x440)
270REG32(MSGF_MSI_STATUS_HI, 0x444)
271REG32(MSGF_MSI_MASK_LO, 0x448)
272REG32(MSGF_MSI_MASK_HI, 0x44c)
273REG32(MSGF_DMA_STATUS, 0x460)
274 FIELD(MSGF_DMA_STATUS, MSGF_DMA_STATUS, 0, 1)
275REG32(MSGF_DMA_MASK, 0x464)
276 FIELD(MSGF_DMA_MASK, MSGF_DMA_MASK, 0, 1)
277REG32(MSGF_RX_FIFO_LEVEL, 0x480)
278 FIELD(MSGF_RX_FIFO_LEVEL, LEVEL, 0, 8)
279REG32(MSGF_RX_FIFO_POP, 0x484)
280 FIELD(MSGF_RX_FIFO_POP, POP, 0, 1)
281REG32(MSGF_RX_FIFO_TYPE, 0x488)
282 FIELD(MSGF_RX_FIFO_TYPE, REQUESTER_ID, 16, 16)
283 FIELD(MSGF_RX_FIFO_TYPE, INTR_TYPE, 0, 2)
284REG32(MSGF_RX_FIFO_MSG, 0x48c)
285 FIELD(MSGF_RX_FIFO_MSG, MESSAGE_TAG, 16, 8)
286 FIELD(MSGF_RX_FIFO_MSG, MESSAGE_CODE, 8, 8)
287 FIELD(MSGF_RX_FIFO_MSG, MESSAGE_PAYLOAD_PRESENT, 3, 1)
288 FIELD(MSGF_RX_FIFO_MSG, MESSAGE_ROUTING, 0, 3)
289REG32(MSGF_RX_FIFO_ADDRESS_LO, 0x490)
290REG32(MSGF_RX_FIFO_ADDRESS_HI, 0x494)
291REG32(MSGF_RX_FIFO_DATA, 0x498)
292REG32(TX_PCIE_MSG_EXECUTE, 0x620)
293 FIELD(TX_PCIE_MSG_EXECUTE, MSG_DONE_STATUS, 24, 2)
294 FIELD(TX_PCIE_MSG_EXECUTE, MSG_DONE, 16, 1)
295 FIELD(TX_PCIE_MSG_EXECUTE, MSG_BUSY, 8, 1)
296 FIELD(TX_PCIE_MSG_EXECUTE, MSG_EXECUTE, 0, 1)
297REG32(TX_PCIE_MSG_CONTROL, 0x624)
298 FIELD(TX_PCIE_MSG_CONTROL, MSG_HAS_DATA, 24, 1)
299 FIELD(TX_PCIE_MSG_CONTROL, MSG_TAG, 16, 8)
300 FIELD(TX_PCIE_MSG_CONTROL, MSG_CODE, 8, 8)
301 FIELD(TX_PCIE_MSG_CONTROL, MSG_FMT_TYPE, 0, 8)
302REG32(TX_PCIE_MSG_SPECIFIC_LO, 0x628)
303 FIELD(TX_PCIE_MSG_SPECIFIC_LO, MSG_TLP_HDR11, 24, 8)
304 FIELD(TX_PCIE_MSG_SPECIFIC_LO, MSG_TLP_HDR10, 16, 8)
305 FIELD(TX_PCIE_MSG_SPECIFIC_LO, MSG_TLP_HDR9, 8, 8)
306 FIELD(TX_PCIE_MSG_SPECIFIC_LO, MSG_TLP_HDR8, 0, 8)
307REG32(TX_PCIE_MSG_SPECIFIC_HI, 0x62c)
308 FIELD(TX_PCIE_MSG_SPECIFIC_HI, MSG_TLP_HDR15, 24, 8)
309 FIELD(TX_PCIE_MSG_SPECIFIC_HI, MSG_TLP_HDR14, 16, 8)
310 FIELD(TX_PCIE_MSG_SPECIFIC_HI, MSG_TLP_HDR13, 8, 8)
311 FIELD(TX_PCIE_MSG_SPECIFIC_HI, MSG_TLP_HDR12, 0, 8)
312REG32(TX_PCIE_MSG_DATA, 0x630)
313
314#define R_MAX (R_TX_PCIE_MSG_DATA + 1)
315
316typedef struct AXIPCIE_MAIN {
317 PCIExpressHost parent_obj;
318 MemoryRegion *dma_mr;
319 AddressSpace *dma_as;
320 MemTxAttrs *attr;
321
322 IOMMUMemoryRegion iommu_attr;
323 AddressSpace *iommu_attr_as;
324
325 MemoryRegion iomem;
326 MemoryRegion io_ioport;
327 MemoryRegion io_mmio;
328 MemoryRegion io_msi;
329
330 qemu_irq irq_legacy;
331 qemu_irq irq_msi[2];
332
333 uint32_t regs[R_MAX];
334 RegisterInfo regs_info[R_MAX];
335} AXIPCIE_MAIN;
336
337static void axipcie_main_update_irq(AXIPCIE_MAIN *s)
338{
339 bool legacy;
340
341 legacy = s->regs[R_MSGF_LEG_STATUS] & s->regs[R_MSGF_LEG_MASK];
342 qemu_set_irq(s->irq_legacy, legacy);
343}
344
345static void axipcie_set_irq(void *opaque, int irq_num, int level)
346{
347 AXIPCIE_MAIN *s = opaque;
348
349 s->regs[R_MSGF_LEG_STATUS] &= ~(1 << irq_num);
350 s->regs[R_MSGF_LEG_STATUS] |= (!!level) << irq_num;
351 axipcie_main_update_irq(s);
352}
353
354static void legacy_mask_pw(RegisterInfo *reg, uint64_t val64)
355{
356 AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(reg->opaque);
357 axipcie_main_update_irq(s);
358}
359
360static void update_msi_irqs(AXIPCIE_MAIN *s)
361{
362 uint32_t p, m;
363
364 p = s->regs[R_MSGF_MSI_STATUS_LO];
365 m = s->regs[R_MSGF_MSI_MASK_LO];
366 qemu_set_irq(s->irq_msi[0], p & m);
367
368 p = s->regs[R_MSGF_MSI_STATUS_HI];
369 m = s->regs[R_MSGF_MSI_MASK_HI];
370 qemu_set_irq(s->irq_msi[1], p & m);
371}
372
373static void msi_update_pw(RegisterInfo *reg, uint64_t val64)
374{
375 AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(reg->opaque);
376 update_msi_irqs(s);
377}
378
379static void msi_mr_update(AXIPCIE_MAIN *s)
380{
381 bool msi_en = ARRAY_FIELD_EX32(s->regs, I_MSII_CONTROL, I_MSII_ENABLE);
382 bool msix_en = ARRAY_FIELD_EX32(s->regs, I_MSIX_CONTROL, I_MSIX_ENABLE);
383 memory_region_set_enabled(&s->io_msi, msi_en || msix_en);
384}
385
386static void msi_mr_pw(RegisterInfo *reg, uint64_t val64)
387{
388 AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(reg->opaque);
389 msi_mr_update(s);
390}
391
392static const RegisterAccessInfo axipcie_main_regs_info[] = {
393 { .name = "BRIDGE_CORE_CFG_PCIE_RX0", .addr = A_BRIDGE_CORE_CFG_PCIE_RX0,
394 .reset = 0x10000,
395 .rsvd = 0xfffcfff8,
396 .ro = 0xfffcfff8,
397 },{ .name = "BRIDGE_CORE_CFG_PCIE_RX1", .addr = A_BRIDGE_CORE_CFG_PCIE_RX1,
398 .rsvd = 0xfffffe00,
399 .ro = 0xfffffe00,
400 },{ .name = "BRIDGE_CORE_CFG_AXI_MASTER",
401 .addr = A_BRIDGE_CORE_CFG_AXI_MASTER,
402 .rsvd = 0xffffff88,
403 .ro = 0xffffff88,
404 },{ .name = "BRIDGE_CORE_CFG_PCIE_TX", .addr = A_BRIDGE_CORE_CFG_PCIE_TX,
405 .rsvd = 0xfffffffe,
406 .ro = 0xfffffffe,
407 },{ .name = "BRIDGE_CORE_CFG_INTERRUPT",
408 .addr = A_BRIDGE_CORE_CFG_INTERRUPT,
409 .rsvd = 0xfffffffe,
410 .ro = 0xfffffffe,
411 },{ .name = "BRIDGE_CORE_CFG_RAM_DISABLE0",
412 .addr = A_BRIDGE_CORE_CFG_RAM_DISABLE0,
413 .rsvd = 0xffff8680,
414 .ro = 0xffff8680,
415 },{ .name = "BRIDGE_CORE_CFG_RAM_DISABLE1",
416 .addr = A_BRIDGE_CORE_CFG_RAM_DISABLE1,
417 .rsvd = 0xffff8680,
418 .ro = 0xffff8680,
419 },{ .name = "BRIDGE_CORE_CFG_PCIE_RELAXED_ORDER",
420 .addr = A_BRIDGE_CORE_CFG_PCIE_RELAXED_ORDER,
421 .reset = 0x3,
422 .rsvd = 0xfffffffc,
423 .ro = 0xfffffffc,
424 },{ .name = "BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER",
425 .addr = A_BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER,
426 .rsvd = 0x1f51,
427 .ro = 0x1f51,
428 },{ .name = "BRIDGE_CORE_CFG_RQ_REQ_ORDER",
429 .addr = A_BRIDGE_CORE_CFG_RQ_REQ_ORDER,
430 .rsvd = 0x3fff0000,
431 .ro = 0x3fff0000,
432 },{ .name = "BRIDGE_CORE_CFG_PCIE_CREDIT",
433 .addr = A_BRIDGE_CORE_CFG_PCIE_CREDIT,
434 .reset = 0x200200,
435 .rsvd = 0x1f00f000,
436 .ro = 0x1f00f000,
437 },{ .name = "BRIDGE_CORE_CFG_AXI_M_W_TICK_COUNT",
438 .addr = A_BRIDGE_CORE_CFG_AXI_M_W_TICK_COUNT,
439 .reset = 0xbea,
440 .rsvd = 0xffff0000,
441 .ro = 0xffff0000,
442 },{ .name = "BRIDGE_CORE_CFG_AXI_M_R_TICK_COUNT",
443 .addr = A_BRIDGE_CORE_CFG_AXI_M_R_TICK_COUNT,
444 .reset = 0xbea,
445 .rsvd = 0xffff0000,
446 .ro = 0xffff0000,
447 },{ .name = "BRIDGE_CORE_CFG_CRS_RPL_TICK_COUNT",
448 .addr = A_BRIDGE_CORE_CFG_CRS_RPL_TICK_COUNT,
449 .reset = 0x2210,
450 .rsvd = 0xffff0000,
451 .ro = 0xffff0000,
452 },{ .name = "E_BREG_CAPABILITIES", .addr = A_E_BREG_CAPABILITIES,
453 .reset = 0x30c0001,
454 .rsvd = 0xfffe,
455 .ro = 0xffffffff,
456 },{ .name = "E_BREG_STATUS", .addr = A_E_BREG_STATUS,
457 .rsvd = 0xfe00fe00,
458 .ro = 0xffffffff,
459 },{ .name = "E_BREG_CONTROL", .addr = A_E_BREG_CONTROL,
460 .reset = 0x2,
461 .rsvd = 0xfffcfff8,
462 .ro = 0xfffcfff8,
463 },{ .name = "E_BREG_BASE_LO", .addr = A_E_BREG_BASE_LO,
464 .rsvd = 0xfff,
465 .ro = 0xfff,
466 },{ .name = "E_BREG_BASE_HI", .addr = A_E_BREG_BASE_HI,
467 },{ .name = "E_ECAM_CAPABILITIES", .addr = A_E_ECAM_CAPABILITIES,
468 .reset = 0x100c0001,
469 .rsvd = 0xfffe,
470 .ro = 0xffffffff,
471 },{ .name = "E_ECAM_STATUS", .addr = A_E_ECAM_STATUS,
472 .rsvd = 0xfe00fe00,
473 .ro = 0xffffffff,
474 },{ .name = "E_ECAM_CONTROL", .addr = A_E_ECAM_CONTROL,
475 .rsvd = 0xffe0fffa,
476 .ro = 0xffe0fffa,
477 },{ .name = "E_ECAM_BASE_LO", .addr = A_E_ECAM_BASE_LO,
478 .rsvd = 0xfff,
479 .ro = 0xfff,
480 },{ .name = "E_ECAM_BASE_HI", .addr = A_E_ECAM_BASE_HI,
481 },{ .name = "E_MSXT_CAPABILITIES", .addr = A_E_MSXT_CAPABILITIES,
482 .reset = 0x30c0001,
483 .rsvd = 0xfffe,
484 .ro = 0xffffffff,
485 },{ .name = "E_MSXT_STATUS", .addr = A_E_MSXT_STATUS,
486 .rsvd = 0xfe00fe00,
487 .ro = 0xffffffff,
488 },{ .name = "E_MSXT_CONTROL", .addr = A_E_MSXT_CONTROL,
489 .rsvd = 0xfffcfffa,
490 .ro = 0xfffcfffa,
491 },{ .name = "E_MSXT_BASE_LO", .addr = A_E_MSXT_BASE_LO,
492 .rsvd = 0xfff,
493 .ro = 0xfff,
494 },{ .name = "E_MSXT_BASE_HI", .addr = A_E_MSXT_BASE_HI,
495 },{ .name = "E_MSXP_CAPABILITIES", .addr = A_E_MSXP_CAPABILITIES,
496 .reset = 0x30c0001,
497 .rsvd = 0xfffe,
498 .ro = 0xffffffff,
499 },{ .name = "E_MSXP_STATUS", .addr = A_E_MSXP_STATUS,
500 .rsvd = 0xfe00fe00,
501 .ro = 0xffffffff,
502 },{ .name = "E_MSXP_CONTROL", .addr = A_E_MSXP_CONTROL,
503 .rsvd = 0xfffcfffa,
504 .ro = 0xfffcfffa,
505 },{ .name = "E_MSXP_BASE_LO", .addr = A_E_MSXP_BASE_LO,
506 .rsvd = 0xfff,
507 .ro = 0xfff,
508 },{ .name = "E_MSXP_BASE_HI", .addr = A_E_MSXP_BASE_HI,
509 },{ .name = "E_DREG_CAPABILITIES", .addr = A_E_DREG_CAPABILITIES,
510 .reset = 0x30c0001,
511 .rsvd = 0xfffe,
512 .ro = 0xffffffff,
513 },{ .name = "E_DREG_STATUS", .addr = A_E_DREG_STATUS,
514 .rsvd = 0xfe00fe00,
515 .ro = 0xffffffff,
516 },{ .name = "E_DREG_CONTROL", .addr = A_E_DREG_CONTROL,
517 .rsvd = 0xfffcfffa,
518 .ro = 0xfffcfffa,
519 },{ .name = "E_DREG_BASE_LO", .addr = A_E_DREG_BASE_LO,
520 .rsvd = 0xfff,
521 .ro = 0xfff,
522 },{ .name = "E_DREG_BASE_HI", .addr = A_E_DREG_BASE_HI,
523 },{ .name = "E_ESUB_CAPABILITIES", .addr = A_E_ESUB_CAPABILITIES,
524 .reset = 0x1,
525 .rsvd = 0xfffffffe,
526 .ro = 0xffffffff,
527 },{ .name = "E_ESUB_STATUS", .addr = A_E_ESUB_STATUS,
528 .rsvd = 0xfe00fe00,
529 .ro = 0xffffffff,
530 },{ .name = "E_ESUB_CONTROL", .addr = A_E_ESUB_CONTROL,
531 .reset = 0x1,
532 .rsvd = 0xfffffffe,
533 .ro = 0xfffffffe,
534 },{ .name = "I_MSII_CAPABILITIES", .addr = A_I_MSII_CAPABILITIES,
535 .reset = 0x1f0c0001,
536 .rsvd = 0xfffe,
537 .ro = 0xffffffff,
538 },{ .name = "I_MSII_CONTROL", .addr = A_I_MSII_CONTROL,
539 .rsvd = 0xffe07ffe,
540 .ro = 0xffe07ffe,
541 .post_write = msi_mr_pw,
542 },{ .name = "I_MSII_BASE_LO", .addr = A_I_MSII_BASE_LO,
543 .rsvd = 0xfff,
544 .ro = 0xfff,
545 },{ .name = "I_MSII_BASE_HI", .addr = A_I_MSII_BASE_HI,
546 },{ .name = "I_MSIX_CAPABILITIES", .addr = A_I_MSIX_CAPABILITIES,
547 .reset = 0x1f0c0001,
548 .rsvd = 0xfffe,
549 .ro = 0xffffffff,
550 },{ .name = "I_MSIX_CONTROL", .addr = A_I_MSIX_CONTROL,
551 .rsvd = 0xffe0fffe,
552 .ro = 0xffe0fffe,
553 .post_write = msi_mr_pw,
554 },{ .name = "I_MSIX_BASE_LO", .addr = A_I_MSIX_BASE_LO,
555 .rsvd = 0xfff,
556 .ro = 0xfff,
557 },{ .name = "I_MSIX_BASE_HI", .addr = A_I_MSIX_BASE_HI,
558 },{ .name = "I_ISUB_CAPABILITIES", .addr = A_I_ISUB_CAPABILITIES,
559 .reset = 0x1,
560 .rsvd = 0xfffffffe,
561 .ro = 0xffffffff,
562 },{ .name = "I_ISUB_STATUS", .addr = A_I_ISUB_STATUS,
563 .rsvd = 0xfe00fe00,
564 .ro = 0xffffffff,
565 },{ .name = "I_ISUB_CONTROL", .addr = A_I_ISUB_CONTROL,
566 .rsvd = 0xfffffffe,
567 .ro = 0xfffffffe,
568 },{ .name = "MSGF_MISC_STATUS", .addr = A_MSGF_MISC_STATUS,
569 .rsvd = 0xff04,
570 .ro = 0xff04,
571 .w1c = 0xffff00fb,
572 },{ .name = "MSGF_MISC_MASK", .addr = A_MSGF_MISC_MASK,
573 .rsvd = 0xff04,
574 .ro = 0xff04,
575 },{ .name = "MSGF_MISC_SLAVE_ID", .addr = A_MSGF_MISC_SLAVE_ID,
576 .rsvd = 0xffffff00,
577 .ro = 0xffffffff,
578 },{ .name = "MSGF_MISC_MASTER_ID", .addr = A_MSGF_MISC_MASTER_ID,
579 .rsvd = 0xffffff00,
580 .ro = 0xffffffff,
581 },{ .name = "MSGF_MISC_INGRESS_ID", .addr = A_MSGF_MISC_INGRESS_ID,
582 .rsvd = 0xffffff00,
583 .ro = 0xffffffff,
584 },{ .name = "MSGF_MISC_EGRESS_ID", .addr = A_MSGF_MISC_EGRESS_ID,
585 .rsvd = 0xffffff00,
586 .ro = 0xffffffff,
587 },{ .name = "MSGF_LEG_STATUS", .addr = A_MSGF_LEG_STATUS,
588 .rsvd = 0xfffffff0,
589 .ro = 0xffffffff,
590 },{ .name = "MSGF_LEG_MASK", .addr = A_MSGF_LEG_MASK,
591 .rsvd = 0xfffffff0,
592 .ro = 0xfffffff0,
593 .post_write = legacy_mask_pw,
594 },{ .name = "MSGF_MSI_STATUS_LO", .addr = A_MSGF_MSI_STATUS_LO,
595 .w1c = 0xffffffff,
596 .post_write = msi_update_pw,
597 },{ .name = "MSGF_MSI_STATUS_HI", .addr = A_MSGF_MSI_STATUS_HI,
598 .w1c = 0xffffffff,
599 .post_write = msi_update_pw,
600 },{ .name = "MSGF_MSI_MASK_LO", .addr = A_MSGF_MSI_MASK_LO,
601 .post_write = msi_update_pw,
602 },{ .name = "MSGF_MSI_MASK_HI", .addr = A_MSGF_MSI_MASK_HI,
603 .post_write = msi_update_pw,
604 },{ .name = "MSGF_DMA_STATUS", .addr = A_MSGF_DMA_STATUS,
605 .rsvd = 0xfffffffe,
606 .ro = 0xffffffff,
607 },{ .name = "MSGF_DMA_MASK", .addr = A_MSGF_DMA_MASK,
608 .rsvd = 0xfffffffe,
609 .ro = 0xfffffffe,
610 },{ .name = "MSGF_RX_FIFO_LEVEL", .addr = A_MSGF_RX_FIFO_LEVEL,
611 .rsvd = 0xffffff00,
612 .ro = 0xffffffff,
613 },{ .name = "MSGF_RX_FIFO_POP", .addr = A_MSGF_RX_FIFO_POP,
614 .rsvd = 0xfffffffe,
615 .ro = 0xffffffff,
616 },{ .name = "MSGF_RX_FIFO_TYPE", .addr = A_MSGF_RX_FIFO_TYPE,
617 .rsvd = 0xfffc,
618 .ro = 0xffffffff,
619 },{ .name = "MSGF_RX_FIFO_MSG", .addr = A_MSGF_RX_FIFO_MSG,
620 .rsvd = 0xff0000f0,
621 .ro = 0xffffffff,
622 },{ .name = "MSGF_RX_FIFO_ADDRESS_LO", .addr = A_MSGF_RX_FIFO_ADDRESS_LO,
623 .ro = 0xffffffff,
624 },{ .name = "MSGF_RX_FIFO_ADDRESS_HI", .addr = A_MSGF_RX_FIFO_ADDRESS_HI,
625 .ro = 0xffffffff,
626 },{ .name = "MSGF_RX_FIFO_DATA", .addr = A_MSGF_RX_FIFO_DATA,
627 .ro = 0xffffffff,
628 },{ .name = "TX_PCIE_MSG_EXECUTE", .addr = A_TX_PCIE_MSG_EXECUTE,
629 .rsvd = 0xfcfefefe,
630 .ro = 0xffffffff,
631 },{ .name = "TX_PCIE_MSG_CONTROL", .addr = A_TX_PCIE_MSG_CONTROL,
632 .rsvd = 0xfe000000,
633 .ro = 0xfe000000,
634 },{ .name = "TX_PCIE_MSG_SPECIFIC_LO", .addr = A_TX_PCIE_MSG_SPECIFIC_LO,
635 },{ .name = "TX_PCIE_MSG_SPECIFIC_HI", .addr = A_TX_PCIE_MSG_SPECIFIC_HI,
636 },{ .name = "TX_PCIE_MSG_DATA", .addr = A_TX_PCIE_MSG_DATA,
637 }
638};
639
640static void axipcie_main_reset(DeviceState *dev)
641{
642 AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(dev);
643 unsigned int i;
644
645 for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
646 register_reset(&s->regs_info[i]);
647 }
648
649 msi_mr_update(s);
650}
651
652static const MemoryRegionOps axipcie_main_ops = {
653 .read = register_read_memory,
654 .write = register_write_memory,
655 .endianness = DEVICE_LITTLE_ENDIAN,
656 .valid = {
657 .min_access_size = 4,
658 .max_access_size = 4,
659 },
660};
661
662
663static uint64_t axipcie_msi_read(void *opaque, hwaddr addr, unsigned size)
664{
665 return 0;
666}
667
668static void axipcie_msi_write(void *opaque, hwaddr addr, uint64_t value,
669 unsigned size)
670{
671 AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(opaque);
672 unsigned int irq = value & 63;
673
674 if (irq < 32) {
675 s->regs[R_MSGF_MSI_STATUS_LO] |= 1 << irq;
676 } else {
677 s->regs[R_MSGF_MSI_STATUS_HI] |= 1 << (irq - 32);
678 }
679 update_msi_irqs(s);
680}
681
682static const MemoryRegionOps axipcie_msi_ops = {
683 .read = axipcie_msi_read,
684 .write = axipcie_msi_write,
685 .endianness = DEVICE_LITTLE_ENDIAN,
686 .valid = {
687 .min_access_size = 4,
688 .max_access_size = 4,
689 },
690};
691
692static IOMMUTLBEntry axipcie_translate(IOMMUMemoryRegion *mr, hwaddr addr,
693 bool is_write, MemTxAttrs *attr)
694{
695 AXIPCIE_MAIN *s = container_of(mr, AXIPCIE_MAIN, iommu_attr);
696 IOMMUTLBEntry ret = {
697 .iova = addr,
698 .translated_addr = addr,
699 .addr_mask = ~(hwaddr)0,
700 .perm = IOMMU_RW,
701 .target_as = s->dma_as,
702 };
703
704 if (s->attr) {
705 *attr = *s->attr;
706 }
707 return ret;
708}
709
710static AddressSpace *axipcie_dma_as(PCIBus *bus, void *opaque, int devfn)
711{
712 return opaque;
713}
714
715static void axipcie_main_realize(DeviceState *dev, Error **errp)
716{
717 AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(dev);
718 PCIHostState *pci = PCI_HOST_BRIDGE(dev);
719 PCIExpressHost *pex = PCIE_HOST_BRIDGE(dev);
720 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
721
722 assert(s->dma_mr);
723 s->dma_as = s->dma_mr ? address_space_init_shareable(s->dma_mr, NULL)
724 : &address_space_memory;
725
726 pcie_host_mmcfg_init(pex, PCIE_MMCFG_SIZE_MAX);
727 memory_region_init(&s->io_mmio, OBJECT(s), "mmio", UINT64_MAX);
728
729
730 memory_region_init(&s->io_ioport, OBJECT(s), "ioport", 64 * 1024);
731
732 sysbus_init_mmio(sbd, &pex->mmio);
733 sysbus_init_mmio(sbd, &s->io_mmio);
734 sysbus_init_irq(sbd, &s->irq_legacy);
735 sysbus_init_irq(sbd, &s->irq_msi[0]);
736 sysbus_init_irq(sbd, &s->irq_msi[1]);
737
738 pci->bus = pci_register_root_bus(dev, "pcie.0", axipcie_set_irq,
739 pci_swizzle_map_irq_fn, s, &s->io_mmio,
740 &s->io_ioport, PCI_DEVFN(0, 0), 4,
741 TYPE_PCIE_BUS);
742
743 memory_region_init_iommu(&s->iommu_attr, sizeof(s->iommu_attr),
744 TYPE_XILINX_AXIPCIE_MAIN_IOMMU_MEMORY_REGION,
745 OBJECT(s),
746 "axipcie-attr-iommu", UINT64_MAX);
747 s->iommu_attr_as = address_space_init_shareable(MEMORY_REGION(&s->iommu_attr), NULL);
748
749 pci_setup_iommu(pci->bus, axipcie_dma_as, s->iommu_attr_as);
750}
751
752static void axipcie_main_init(Object *obj)
753{
754 AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(obj);
755 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
756 RegisterInfoArray *reg_array;
757
758 memory_region_init(&s->iomem, obj, TYPE_XILINX_AXIPCIE_MAIN, R_MAX * 4);
759 reg_array =
760 register_init_block32(DEVICE(obj), axipcie_main_regs_info,
761 ARRAY_SIZE(axipcie_main_regs_info),
762 s->regs_info, s->regs,
763 &axipcie_main_ops,
764 XILINX_AXIPCIE_MAIN_ERR_DEBUG,
765 R_MAX * 4);
766 memory_region_add_subregion(&s->iomem, 0x0, ®_array->mem);
767 sysbus_init_mmio(sbd, &s->iomem);
768 memory_region_init_io(&s->io_msi, obj, &axipcie_msi_ops, s,
769 "axipcie-msi", 0x100);
770 sysbus_init_mmio(sbd, &s->io_msi);
771 msi_nonbroken = true;
772
773 object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
774 (Object **)&s->dma_mr,
775 qdev_prop_allow_set_link_before_realize,
776 OBJ_PROP_LINK_STRONG);
777 object_property_add_link(obj, "memattr", TYPE_MEMORY_TRANSACTION_ATTR,
778 (Object **)&s->attr,
779 qdev_prop_allow_set_link_before_realize,
780 OBJ_PROP_LINK_STRONG);
781}
782
783static const VMStateDescription vmstate_axipcie_main = {
784 .name = TYPE_XILINX_AXIPCIE_MAIN,
785 .version_id = 1,
786 .minimum_version_id = 1,
787 .minimum_version_id_old = 1,
788 .fields = (VMStateField[]) {
789 VMSTATE_UINT32_ARRAY(regs, AXIPCIE_MAIN, R_MAX),
790 VMSTATE_END_OF_LIST(),
791 }
792};
793
794static const char *axipcie_main_host_root_bus_path(PCIHostState *host_bridge,
795 PCIBus *rootbus)
796{
797 return "0000:00";
798}
799
800static void axipcie_main_class_init(ObjectClass *klass, void *data)
801{
802 DeviceClass *dc = DEVICE_CLASS(klass);
803 PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
804
805 dc->reset = axipcie_main_reset;
806 dc->realize = axipcie_main_realize;
807 dc->vmsd = &vmstate_axipcie_main;
808
809 hc->root_bus_path = axipcie_main_host_root_bus_path;
810}
811
812static void axipcie_main_iommu_memory_region_class_init(ObjectClass *klass,
813 void *data)
814{
815 IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
816
817 imrc->translate_attr = axipcie_translate;
818}
819
820static const TypeInfo axipcie_main_info = {
821 .name = TYPE_XILINX_AXIPCIE_MAIN,
822 .parent = TYPE_PCIE_HOST_BRIDGE,
823 .instance_size = sizeof(AXIPCIE_MAIN),
824 .class_init = axipcie_main_class_init,
825 .instance_init = axipcie_main_init,
826};
827
828static const TypeInfo axipcie_main_iommu_memory_region_info = {
829 .name = TYPE_XILINX_AXIPCIE_MAIN_IOMMU_MEMORY_REGION,
830 .parent = TYPE_IOMMU_MEMORY_REGION,
831 .class_init = axipcie_main_iommu_memory_region_class_init,
832};
833
834
835static void axipcie_main_register_types(void)
836{
837 type_register_static(&axipcie_main_info);
838 type_register_static(&axipcie_main_iommu_memory_region_info);
839}
840
841type_init(axipcie_main_register_types)
842