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