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
28
29
30
31#include "qemu/osdep.h"
32#include "hw/sysbus.h"
33#include "hw/register.h"
34#include "hw/irq.h"
35#include "qapi/error.h"
36#include "qemu/bitops.h"
37#include "qemu/log.h"
38#include "qemu/cutils.h"
39#include "sysemu/sysemu.h"
40#include "migration/vmstate.h"
41#include "hw/qdev-properties.h"
42#include "net/can_emu.h"
43#include "net/can_host.h"
44#include "qemu/event_notifier.h"
45#include "qom/object_interfaces.h"
46#include "hw/net/xlnx-zynqmp-can.h"
47#include "qemu/fifo.h"
48
49#ifndef XLNX_ZYNQMP_CAN_ERR_DEBUG
50#define XLNX_ZYNQMP_CAN_ERR_DEBUG 0
51#endif
52
53#define DB_PRINT(...) do { \
54 if (XLNX_ZYNQMP_CAN_ERR_DEBUG) { \
55 qemu_log(__VA_ARGS__); \
56 } \
57} while (0);
58
59#define MAX_DLC 8
60#undef ERROR
61
62REG32(SOFTWARE_RESET_REGISTER, 0x0)
63 FIELD(SOFTWARE_RESET_REGISTER, CEN, 1, 1)
64 FIELD(SOFTWARE_RESET_REGISTER, SRST, 0, 1)
65REG32(MODE_SELECT_REGISTER, 0x4)
66 FIELD(MODE_SELECT_REGISTER, SNOOP, 2, 1)
67 FIELD(MODE_SELECT_REGISTER, LBACK, 1, 1)
68 FIELD(MODE_SELECT_REGISTER, SLEEP, 0, 1)
69REG32(ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER, 0x8)
70 FIELD(ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER, BRP, 0, 8)
71REG32(ARBITRATION_PHASE_BIT_TIMING_REGISTER, 0xc)
72 FIELD(ARBITRATION_PHASE_BIT_TIMING_REGISTER, SJW, 7, 2)
73 FIELD(ARBITRATION_PHASE_BIT_TIMING_REGISTER, TS2, 4, 3)
74 FIELD(ARBITRATION_PHASE_BIT_TIMING_REGISTER, TS1, 0, 4)
75REG32(ERROR_COUNTER_REGISTER, 0x10)
76 FIELD(ERROR_COUNTER_REGISTER, REC, 8, 8)
77 FIELD(ERROR_COUNTER_REGISTER, TEC, 0, 8)
78REG32(ERROR_STATUS_REGISTER, 0x14)
79 FIELD(ERROR_STATUS_REGISTER, ACKER, 4, 1)
80 FIELD(ERROR_STATUS_REGISTER, BERR, 3, 1)
81 FIELD(ERROR_STATUS_REGISTER, STER, 2, 1)
82 FIELD(ERROR_STATUS_REGISTER, FMER, 1, 1)
83 FIELD(ERROR_STATUS_REGISTER, CRCER, 0, 1)
84REG32(STATUS_REGISTER, 0x18)
85 FIELD(STATUS_REGISTER, SNOOP, 12, 1)
86 FIELD(STATUS_REGISTER, ACFBSY, 11, 1)
87 FIELD(STATUS_REGISTER, TXFLL, 10, 1)
88 FIELD(STATUS_REGISTER, TXBFLL, 9, 1)
89 FIELD(STATUS_REGISTER, ESTAT, 7, 2)
90 FIELD(STATUS_REGISTER, ERRWRN, 6, 1)
91 FIELD(STATUS_REGISTER, BBSY, 5, 1)
92 FIELD(STATUS_REGISTER, BIDLE, 4, 1)
93 FIELD(STATUS_REGISTER, NORMAL, 3, 1)
94 FIELD(STATUS_REGISTER, SLEEP, 2, 1)
95 FIELD(STATUS_REGISTER, LBACK, 1, 1)
96 FIELD(STATUS_REGISTER, CONFIG, 0, 1)
97REG32(INTERRUPT_STATUS_REGISTER, 0x1c)
98 FIELD(INTERRUPT_STATUS_REGISTER, TXFEMP, 14, 1)
99 FIELD(INTERRUPT_STATUS_REGISTER, TXFWMEMP, 13, 1)
100 FIELD(INTERRUPT_STATUS_REGISTER, RXFWMFLL, 12, 1)
101 FIELD(INTERRUPT_STATUS_REGISTER, WKUP, 11, 1)
102 FIELD(INTERRUPT_STATUS_REGISTER, SLP, 10, 1)
103 FIELD(INTERRUPT_STATUS_REGISTER, BSOFF, 9, 1)
104 FIELD(INTERRUPT_STATUS_REGISTER, ERROR, 8, 1)
105 FIELD(INTERRUPT_STATUS_REGISTER, RXNEMP, 7, 1)
106 FIELD(INTERRUPT_STATUS_REGISTER, RXOFLW, 6, 1)
107 FIELD(INTERRUPT_STATUS_REGISTER, RXUFLW, 5, 1)
108 FIELD(INTERRUPT_STATUS_REGISTER, RXOK, 4, 1)
109 FIELD(INTERRUPT_STATUS_REGISTER, TXBFLL, 3, 1)
110 FIELD(INTERRUPT_STATUS_REGISTER, TXFLL, 2, 1)
111 FIELD(INTERRUPT_STATUS_REGISTER, TXOK, 1, 1)
112 FIELD(INTERRUPT_STATUS_REGISTER, ARBLST, 0, 1)
113REG32(INTERRUPT_ENABLE_REGISTER, 0x20)
114 FIELD(INTERRUPT_ENABLE_REGISTER, ETXFEMP, 14, 1)
115 FIELD(INTERRUPT_ENABLE_REGISTER, ETXFWMEMP, 13, 1)
116 FIELD(INTERRUPT_ENABLE_REGISTER, ERXFWMFLL, 12, 1)
117 FIELD(INTERRUPT_ENABLE_REGISTER, EWKUP, 11, 1)
118 FIELD(INTERRUPT_ENABLE_REGISTER, ESLP, 10, 1)
119 FIELD(INTERRUPT_ENABLE_REGISTER, EBSOFF, 9, 1)
120 FIELD(INTERRUPT_ENABLE_REGISTER, EERROR, 8, 1)
121 FIELD(INTERRUPT_ENABLE_REGISTER, ERXNEMP, 7, 1)
122 FIELD(INTERRUPT_ENABLE_REGISTER, ERXOFLW, 6, 1)
123 FIELD(INTERRUPT_ENABLE_REGISTER, ERXUFLW, 5, 1)
124 FIELD(INTERRUPT_ENABLE_REGISTER, ERXOK, 4, 1)
125 FIELD(INTERRUPT_ENABLE_REGISTER, ETXBFLL, 3, 1)
126 FIELD(INTERRUPT_ENABLE_REGISTER, ETXFLL, 2, 1)
127 FIELD(INTERRUPT_ENABLE_REGISTER, ETXOK, 1, 1)
128 FIELD(INTERRUPT_ENABLE_REGISTER, EARBLST, 0, 1)
129REG32(INTERRUPT_CLEAR_REGISTER, 0x24)
130 FIELD(INTERRUPT_CLEAR_REGISTER, CTXFEMP, 14, 1)
131 FIELD(INTERRUPT_CLEAR_REGISTER, CTXFWMEMP, 13, 1)
132 FIELD(INTERRUPT_CLEAR_REGISTER, CRXFWMFLL, 12, 1)
133 FIELD(INTERRUPT_CLEAR_REGISTER, CWKUP, 11, 1)
134 FIELD(INTERRUPT_CLEAR_REGISTER, CSLP, 10, 1)
135 FIELD(INTERRUPT_CLEAR_REGISTER, CBSOFF, 9, 1)
136 FIELD(INTERRUPT_CLEAR_REGISTER, CERROR, 8, 1)
137 FIELD(INTERRUPT_CLEAR_REGISTER, CRXNEMP, 7, 1)
138 FIELD(INTERRUPT_CLEAR_REGISTER, CRXOFLW, 6, 1)
139 FIELD(INTERRUPT_CLEAR_REGISTER, CRXUFLW, 5, 1)
140 FIELD(INTERRUPT_CLEAR_REGISTER, CRXOK, 4, 1)
141 FIELD(INTERRUPT_CLEAR_REGISTER, CTXBFLL, 3, 1)
142 FIELD(INTERRUPT_CLEAR_REGISTER, CTXFLL, 2, 1)
143 FIELD(INTERRUPT_CLEAR_REGISTER, CTXOK, 1, 1)
144 FIELD(INTERRUPT_CLEAR_REGISTER, CARBLST, 0, 1)
145REG32(TIMESTAMP_REGISTER, 0x28)
146 FIELD(TIMESTAMP_REGISTER, CTS, 0, 1)
147REG32(WIR, 0x2c)
148 FIELD(WIR, EW, 8, 8)
149 FIELD(WIR, FW, 0, 8)
150REG32(TXFIFO_ID, 0x30)
151 FIELD(TXFIFO_ID, IDH, 21, 11)
152 FIELD(TXFIFO_ID, SRRRTR, 20, 1)
153 FIELD(TXFIFO_ID, IDE, 19, 1)
154 FIELD(TXFIFO_ID, IDL, 1, 18)
155 FIELD(TXFIFO_ID, RTR, 0, 1)
156REG32(TXFIFO_DLC, 0x34)
157 FIELD(TXFIFO_DLC, DLC, 28, 4)
158REG32(TXFIFO_DATA1, 0x38)
159 FIELD(TXFIFO_DATA1, DB0, 24, 8)
160 FIELD(TXFIFO_DATA1, DB1, 16, 8)
161 FIELD(TXFIFO_DATA1, DB2, 8, 8)
162 FIELD(TXFIFO_DATA1, DB3, 0, 8)
163REG32(TXFIFO_DATA2, 0x3c)
164 FIELD(TXFIFO_DATA2, DB4, 24, 8)
165 FIELD(TXFIFO_DATA2, DB5, 16, 8)
166 FIELD(TXFIFO_DATA2, DB6, 8, 8)
167 FIELD(TXFIFO_DATA2, DB7, 0, 8)
168REG32(TXHPB_ID, 0x40)
169 FIELD(TXHPB_ID, IDH, 21, 11)
170 FIELD(TXHPB_ID, SRRRTR, 20, 1)
171 FIELD(TXHPB_ID, IDE, 19, 1)
172 FIELD(TXHPB_ID, IDL, 1, 18)
173 FIELD(TXHPB_ID, RTR, 0, 1)
174REG32(TXHPB_DLC, 0x44)
175 FIELD(TXHPB_DLC, DLC, 28, 4)
176REG32(TXHPB_DATA1, 0x48)
177 FIELD(TXHPB_DATA1, DB0, 24, 8)
178 FIELD(TXHPB_DATA1, DB1, 16, 8)
179 FIELD(TXHPB_DATA1, DB2, 8, 8)
180 FIELD(TXHPB_DATA1, DB3, 0, 8)
181REG32(TXHPB_DATA2, 0x4c)
182 FIELD(TXHPB_DATA2, DB4, 24, 8)
183 FIELD(TXHPB_DATA2, DB5, 16, 8)
184 FIELD(TXHPB_DATA2, DB6, 8, 8)
185 FIELD(TXHPB_DATA2, DB7, 0, 8)
186REG32(RXFIFO_ID, 0x50)
187 FIELD(RXFIFO_ID, IDH, 21, 11)
188 FIELD(RXFIFO_ID, SRRRTR, 20, 1)
189 FIELD(RXFIFO_ID, IDE, 19, 1)
190 FIELD(RXFIFO_ID, IDL, 1, 18)
191 FIELD(RXFIFO_ID, RTR, 0, 1)
192REG32(RXFIFO_DLC, 0x54)
193 FIELD(RXFIFO_DLC, DLC, 28, 4)
194 FIELD(RXFIFO_DLC, RXT, 0, 16)
195REG32(RXFIFO_DATA1, 0x58)
196 FIELD(RXFIFO_DATA1, DB0, 24, 8)
197 FIELD(RXFIFO_DATA1, DB1, 16, 8)
198 FIELD(RXFIFO_DATA1, DB2, 8, 8)
199 FIELD(RXFIFO_DATA1, DB3, 0, 8)
200REG32(RXFIFO_DATA2, 0x5c)
201 FIELD(RXFIFO_DATA2, DB4, 24, 8)
202 FIELD(RXFIFO_DATA2, DB5, 16, 8)
203 FIELD(RXFIFO_DATA2, DB6, 8, 8)
204 FIELD(RXFIFO_DATA2, DB7, 0, 8)
205REG32(AFR, 0x60)
206 FIELD(AFR, UAF4, 3, 1)
207 FIELD(AFR, UAF3, 2, 1)
208 FIELD(AFR, UAF2, 1, 1)
209 FIELD(AFR, UAF1, 0, 1)
210REG32(AFMR1, 0x64)
211 FIELD(AFMR1, AMIDH, 21, 11)
212 FIELD(AFMR1, AMSRR, 20, 1)
213 FIELD(AFMR1, AMIDE, 19, 1)
214 FIELD(AFMR1, AMIDL, 1, 18)
215 FIELD(AFMR1, AMRTR, 0, 1)
216REG32(AFIR1, 0x68)
217 FIELD(AFIR1, AIIDH, 21, 11)
218 FIELD(AFIR1, AISRR, 20, 1)
219 FIELD(AFIR1, AIIDE, 19, 1)
220 FIELD(AFIR1, AIIDL, 1, 18)
221 FIELD(AFIR1, AIRTR, 0, 1)
222REG32(AFMR2, 0x6c)
223 FIELD(AFMR2, AMIDH, 21, 11)
224 FIELD(AFMR2, AMSRR, 20, 1)
225 FIELD(AFMR2, AMIDE, 19, 1)
226 FIELD(AFMR2, AMIDL, 1, 18)
227 FIELD(AFMR2, AMRTR, 0, 1)
228REG32(AFIR2, 0x70)
229 FIELD(AFIR2, AIIDH, 21, 11)
230 FIELD(AFIR2, AISRR, 20, 1)
231 FIELD(AFIR2, AIIDE, 19, 1)
232 FIELD(AFIR2, AIIDL, 1, 18)
233 FIELD(AFIR2, AIRTR, 0, 1)
234REG32(AFMR3, 0x74)
235 FIELD(AFMR3, AMIDH, 21, 11)
236 FIELD(AFMR3, AMSRR, 20, 1)
237 FIELD(AFMR3, AMIDE, 19, 1)
238 FIELD(AFMR3, AMIDL, 1, 18)
239 FIELD(AFMR3, AMRTR, 0, 1)
240REG32(AFIR3, 0x78)
241 FIELD(AFIR3, AIIDH, 21, 11)
242 FIELD(AFIR3, AISRR, 20, 1)
243 FIELD(AFIR3, AIIDE, 19, 1)
244 FIELD(AFIR3, AIIDL, 1, 18)
245 FIELD(AFIR3, AIRTR, 0, 1)
246REG32(AFMR4, 0x7c)
247 FIELD(AFMR4, AMIDH, 21, 11)
248 FIELD(AFMR4, AMSRR, 20, 1)
249 FIELD(AFMR4, AMIDE, 19, 1)
250 FIELD(AFMR4, AMIDL, 1, 18)
251 FIELD(AFMR4, AMRTR, 0, 1)
252REG32(AFIR4, 0x80)
253 FIELD(AFIR4, AIIDH, 21, 11)
254 FIELD(AFIR4, AISRR, 20, 1)
255 FIELD(AFIR4, AIIDE, 19, 1)
256 FIELD(AFIR4, AIIDL, 1, 18)
257 FIELD(AFIR4, AIRTR, 0, 1)
258
259static void can_update_irq(XlnxZynqMPCAN *s)
260{
261 unsigned int irq;
262
263
264 if ((fifo_num_free(&s->tx_fifo) / CAN_FRAME_SIZE) >
265 ARRAY_FIELD_EX32(s->regs, WIR, EW)) {
266 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFWMEMP, 1);
267 }
268
269 if ((fifo_num_used(&s->rx_fifo) / CAN_FRAME_SIZE) >
270 ARRAY_FIELD_EX32(s->regs, WIR, FW)) {
271 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXFWMFLL, 1);
272 }
273
274
275 if (fifo_num_used(&s->rx_fifo) >= CAN_FRAME_SIZE) {
276 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXNEMP, 1);
277 }
278
279
280 if (fifo_is_empty(&s->tx_fifo)) {
281 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFEMP, 1);
282 }
283
284 if (fifo_is_full(&s->tx_fifo)) {
285 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFLL, 1);
286 }
287
288 if (fifo_is_full(&s->txhpb_fifo)) {
289 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXBFLL, 1);
290 }
291
292 irq = s->regs[R_INTERRUPT_STATUS_REGISTER];
293 irq &= s->regs[R_INTERRUPT_ENABLE_REGISTER];
294
295 qemu_set_irq(s->irq, irq);
296}
297
298static void can_ier_post_write(RegisterInfo *reg, uint64_t val64)
299{
300 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
301
302 can_update_irq(s);
303}
304
305static uint64_t can_icr_pre_write(RegisterInfo *reg, uint64_t val64)
306{
307 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
308 uint32_t val = val64;
309
310 s->regs[R_INTERRUPT_STATUS_REGISTER] &= ~val;
311 can_update_irq(s);
312
313 return 0;
314}
315
316static void can_config_reset(XlnxZynqMPCAN *s)
317{
318
319 register_reset(&s->reg_info[R_SOFTWARE_RESET_REGISTER]);
320 register_reset(&s->reg_info[R_MODE_SELECT_REGISTER]);
321 register_reset(
322 &s->reg_info[R_ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER]);
323 register_reset(&s->reg_info[R_ARBITRATION_PHASE_BIT_TIMING_REGISTER]);
324 register_reset(&s->reg_info[R_STATUS_REGISTER]);
325 register_reset(&s->reg_info[R_INTERRUPT_STATUS_REGISTER]);
326 register_reset(&s->reg_info[R_INTERRUPT_ENABLE_REGISTER]);
327 register_reset(&s->reg_info[R_INTERRUPT_CLEAR_REGISTER]);
328 register_reset(&s->reg_info[R_WIR]);
329}
330
331static void can_config_mode(XlnxZynqMPCAN *s)
332{
333 register_reset(&s->reg_info[R_ERROR_COUNTER_REGISTER]);
334 register_reset(&s->reg_info[R_ERROR_STATUS_REGISTER]);
335
336
337 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, CONFIG, 1);
338 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, WKUP, 0);
339 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, SLP, 0);
340 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, BSOFF, 0);
341 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, ERROR, 0);
342 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOFLW, 0);
343 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 0);
344 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXOK, 0);
345 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, ARBLST, 0);
346
347 can_update_irq(s);
348}
349
350static void update_status_register_mode_bits(XlnxZynqMPCAN *s)
351{
352
353 bool wakeup_irq_val = (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER,
354 SLEEP) == 0) && ARRAY_FIELD_EX32(s->regs,
355 STATUS_REGISTER, SLEEP);
356
357
358 bool sleep_irq_val = (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER,
359 SLEEP) && (ARRAY_FIELD_EX32(s->regs,
360 STATUS_REGISTER, SLEEP) == 0));
361
362
363 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, LBACK, 0);
364 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SLEEP, 0);
365 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SNOOP, 0);
366 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, NORMAL, 0);
367
368
369 if (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, LBACK)) {
370 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, LBACK, 1);
371 } else if (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, SLEEP)) {
372 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SLEEP, 1);
373 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, SLP,
374 sleep_irq_val);
375 } else if (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, SNOOP)) {
376 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SNOOP, 1);
377 } else {
378
379 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, NORMAL, 1);
380
381 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, WKUP,
382 wakeup_irq_val);
383 }
384
385 can_update_irq(s);
386}
387
388static void can_exit_sleep_mode(XlnxZynqMPCAN *s)
389{
390 ARRAY_FIELD_DP32(s->regs, MODE_SELECT_REGISTER, SLEEP, 0);
391 update_status_register_mode_bits(s);
392}
393
394static void generate_frame(qemu_can_frame *frame, uint32_t *data)
395{
396 frame->can_id = data[0];
397 frame->can_dlc = FIELD_EX32(data[1], TXFIFO_DLC, DLC);
398
399 frame->data[0] = FIELD_EX32(data[2], TXFIFO_DATA1, DB3);
400 frame->data[1] = FIELD_EX32(data[2], TXFIFO_DATA1, DB2);
401 frame->data[2] = FIELD_EX32(data[2], TXFIFO_DATA1, DB1);
402 frame->data[3] = FIELD_EX32(data[2], TXFIFO_DATA1, DB0);
403
404 frame->data[4] = FIELD_EX32(data[3], TXFIFO_DATA2, DB7);
405 frame->data[5] = FIELD_EX32(data[3], TXFIFO_DATA2, DB6);
406 frame->data[6] = FIELD_EX32(data[3], TXFIFO_DATA2, DB5);
407 frame->data[7] = FIELD_EX32(data[3], TXFIFO_DATA2, DB4);
408}
409
410static bool tx_ready_check(XlnxZynqMPCAN *s)
411{
412 if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, SRST)) {
413 qemu_log_mask(LOG_GUEST_ERROR, "Attempting to transfer data while"
414 " XlnxZynqMPCAN%d is in reset mode\n", s->cfg.ctrl_idx);
415 return false;
416 }
417
418 if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
419 qemu_log_mask(LOG_GUEST_ERROR, "Attempting to transfer data while"
420 " XlnxZynqMPCAN%d is in configuration mode.Reset the"
421 " core so operations can start fresh\n",
422 s->cfg.ctrl_idx);
423 return false;
424 }
425
426 if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SNOOP)) {
427 qemu_log_mask(LOG_GUEST_ERROR, "Attempting to transfer data while"
428 " XlnxZynqMPCAN%d is in SNOOP MODE\n",
429 s->cfg.ctrl_idx);
430 return false;
431 }
432
433 return true;
434}
435
436static void transfer_fifo(XlnxZynqMPCAN *s, Fifo *fifo)
437{
438 qemu_can_frame frame;
439 uint32_t data[CAN_FRAME_SIZE];
440 int i;
441 bool can_tx = tx_ready_check(s);
442
443 if (can_tx) {
444 while (!fifo_is_empty(fifo)) {
445 for (i = 0; i < CAN_FRAME_SIZE; i++) {
446 data[i] = fifo_pop32(fifo);
447 }
448
449 if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, LBACK)) {
450
451
452
453
454
455
456
457 if (fifo_is_full(&s->rx_fifo)) {
458 DB_PRINT("Loopback: RX FIFO is full."
459 "TX FIFO will be flushed.\n");
460
461 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER,
462 RXOFLW, 1);
463 } else {
464 for (i = 0; i < CAN_FRAME_SIZE; i++) {
465 fifo_push32(&s->rx_fifo, data[i]);
466 }
467
468 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER,
469 RXOK, 1);
470 }
471 } else {
472
473 generate_frame(&frame, data);
474
475 can_bus_client_send(&s->bus_client, &frame, 1);
476 }
477 }
478
479 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXOK, 1);
480 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, TXBFLL, 0);
481
482 if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP)) {
483 can_exit_sleep_mode(s);
484 }
485 } else {
486 DB_PRINT("CAN is not enabled for data transfer.\n")
487 }
488
489 can_update_irq(s);
490}
491
492static uint64_t can_srr_pre_write(RegisterInfo *reg, uint64_t val64)
493{
494 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
495 uint32_t val = val64;
496
497 ARRAY_FIELD_DP32(s->regs, SOFTWARE_RESET_REGISTER, CEN,
498 FIELD_EX32(val, SOFTWARE_RESET_REGISTER, CEN));
499
500 if (FIELD_EX32(val, SOFTWARE_RESET_REGISTER, SRST)) {
501 DB_PRINT("Resetting XlnxZynqMPCAN%d\n", s->cfg.ctrl_idx);
502
503
504 can_config_reset(s);
505 }
506
507 if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
508 can_config_mode(s);
509
510 } else {
511
512
513
514
515
516 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, CONFIG, 0);
517
518
519 transfer_fifo(s, &s->txhpb_fifo);
520 transfer_fifo(s, &s->tx_fifo);
521
522 update_status_register_mode_bits(s);
523 }
524
525 return s->regs[R_SOFTWARE_RESET_REGISTER];
526}
527
528static uint64_t can_msr_pre_write(RegisterInfo *reg, uint64_t val64)
529{
530 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
531 uint32_t val = val64;
532 uint8_t multi_mode = 0;
533
534
535
536
537
538 multi_mode = FIELD_EX32(val, MODE_SELECT_REGISTER, LBACK) +
539 FIELD_EX32(val, MODE_SELECT_REGISTER, SLEEP) +
540 FIELD_EX32(val, MODE_SELECT_REGISTER, SNOOP);
541
542 if (multi_mode > 1) {
543 qemu_log_mask(LOG_GUEST_ERROR, "Attempting to configure several modes "
544 "simultaneously. One mode will be selected according to "
545 "their priority: LBACK > SLEEP > SNOOP.\n ");
546 }
547
548 if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
549
550 s->regs[R_MODE_SELECT_REGISTER] = val;
551 } else {
552 bool sleep_mode_bit = FIELD_EX32(val, MODE_SELECT_REGISTER, SLEEP);
553
554 ARRAY_FIELD_DP32(s->regs, MODE_SELECT_REGISTER, SLEEP, sleep_mode_bit);
555
556 if (FIELD_EX32(val, MODE_SELECT_REGISTER, LBACK)) {
557 qemu_log_mask(LOG_GUEST_ERROR, "Attempting to set LBACK mode "
558 "without setting CEN bit as 0\n");
559 } else if (FIELD_EX32(val, MODE_SELECT_REGISTER, SNOOP)) {
560 qemu_log_mask(LOG_GUEST_ERROR, "Attempting to set SNOOP mode "
561 "without setting CEN bit as 0\n");
562 }
563 update_status_register_mode_bits(s);
564 }
565 return s->regs[R_MODE_SELECT_REGISTER];
566}
567
568static uint64_t can_brpr_pre_write(RegisterInfo *reg, uint64_t val64)
569{
570 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
571 uint32_t val = val64;
572
573
574 if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) {
575 val = s->regs[R_ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER];
576 }
577
578 return val;
579}
580
581static uint64_t can_btr_pre_write(RegisterInfo *reg, uint64_t val64)
582{
583 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
584 uint32_t val = val64;
585
586
587 if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) {
588 val = s->regs[R_ARBITRATION_PHASE_BIT_TIMING_REGISTER];
589 }
590
591 return val;
592}
593
594static uint64_t can_tcr_pre_write(RegisterInfo *reg, uint64_t val64)
595{
596 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
597 uint32_t val = val64;
598
599 if (FIELD_EX32(val, TIMESTAMP_REGISTER, CTS)) {
600 s->rx_time_stamp = 0;
601 }
602
603 return 0;
604}
605
606static void update_rx_fifo(XlnxZynqMPCAN *s, const qemu_can_frame *frame)
607{
608 uint32_t filter_pass = 0;
609
610
611 if (!((ARRAY_FIELD_EX32(s->regs, AFR, UAF1)) |
612 (ARRAY_FIELD_EX32(s->regs, AFR, UAF2)) |
613 (ARRAY_FIELD_EX32(s->regs, AFR, UAF3)) |
614 (ARRAY_FIELD_EX32(s->regs, AFR, UAF4)))) {
615 filter_pass = 1;
616 }
617
618
619
620
621
622 if (ARRAY_FIELD_EX32(s->regs, AFR, UAF1)) {
623 uint32_t id_masked = s->regs[R_AFMR1] & frame->can_id;
624 uint32_t filter_id_masked = s->regs[R_AFMR1] & s->regs[R_AFIR1];
625
626 if (filter_id_masked == id_masked) {
627 filter_pass = 1;
628 }
629 }
630
631 if (ARRAY_FIELD_EX32(s->regs, AFR, UAF2)) {
632 uint32_t id_masked = s->regs[R_AFMR2] & frame->can_id;
633 uint32_t filter_id_masked = s->regs[R_AFMR2] & s->regs[R_AFIR2];
634
635 if (filter_id_masked == id_masked) {
636 filter_pass = 1;
637 }
638 }
639
640 if (ARRAY_FIELD_EX32(s->regs, AFR, UAF3)) {
641 uint32_t id_masked = s->regs[R_AFMR3] & frame->can_id;
642 uint32_t filter_id_masked = s->regs[R_AFMR3] & s->regs[R_AFIR3];
643
644 if (filter_id_masked == id_masked) {
645 filter_pass = 1;
646 }
647 }
648
649 if (ARRAY_FIELD_EX32(s->regs, AFR, UAF4)) {
650 uint32_t id_masked = s->regs[R_AFMR4] & frame->can_id;
651 uint32_t filter_id_masked = s->regs[R_AFMR4] & s->regs[R_AFIR4];
652
653 if (filter_id_masked == id_masked) {
654 filter_pass = 1;
655 }
656 }
657
658
659 if (filter_pass && frame->can_dlc <= MAX_DLC) {
660
661 if (fifo_is_full(&s->rx_fifo)) {
662 DB_PRINT("RX FIFO is full.\n");
663
664 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOFLW, 1);
665 } else {
666 s->rx_time_stamp += 1;
667
668 fifo_push32(&s->rx_fifo, frame->can_id);
669
670 fifo_push32(&s->rx_fifo, (deposit32(0, R_RXFIFO_DLC_DLC_SHIFT,
671 R_RXFIFO_DLC_DLC_LENGTH,
672 frame->can_dlc) |
673 deposit32(0, R_RXFIFO_DLC_RXT_SHIFT,
674 R_RXFIFO_DLC_RXT_LENGTH,
675 s->rx_time_stamp)));
676
677
678 fifo_push32(&s->rx_fifo, (deposit32(0, R_TXFIFO_DATA1_DB3_SHIFT,
679 R_TXFIFO_DATA1_DB3_LENGTH,
680 frame->data[0]) |
681 deposit32(0, R_TXFIFO_DATA1_DB2_SHIFT,
682 R_TXFIFO_DATA1_DB2_LENGTH,
683 frame->data[1]) |
684 deposit32(0, R_TXFIFO_DATA1_DB1_SHIFT,
685 R_TXFIFO_DATA1_DB1_LENGTH,
686 frame->data[2]) |
687 deposit32(0, R_TXFIFO_DATA1_DB0_SHIFT,
688 R_TXFIFO_DATA1_DB0_LENGTH,
689 frame->data[3])));
690
691 fifo_push32(&s->rx_fifo, (deposit32(0, R_TXFIFO_DATA2_DB7_SHIFT,
692 R_TXFIFO_DATA2_DB7_LENGTH,
693 frame->data[4]) |
694 deposit32(0, R_TXFIFO_DATA2_DB6_SHIFT,
695 R_TXFIFO_DATA2_DB6_LENGTH,
696 frame->data[5]) |
697 deposit32(0, R_TXFIFO_DATA2_DB5_SHIFT,
698 R_TXFIFO_DATA2_DB5_LENGTH,
699 frame->data[6]) |
700 deposit32(0, R_TXFIFO_DATA2_DB4_SHIFT,
701 R_TXFIFO_DATA2_DB4_LENGTH,
702 frame->data[7])));
703
704 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 1);
705 }
706
707 can_update_irq(s);
708
709 } else {
710 DB_PRINT("Message didn't pass through any filter"
711 "or dlc is not in range\n");
712 }
713}
714
715static uint64_t can_rxfifo_pre_read(RegisterInfo *reg, uint64_t val64)
716{
717 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
718 uint32_t r = 0;
719
720 if (!fifo_is_empty(&s->rx_fifo)) {
721 r = fifo_pop32(&s->rx_fifo);
722 } else {
723 DB_PRINT("No message in RXFIFO\n");
724
725 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXUFLW, 1);
726 }
727
728 can_update_irq(s);
729 return r;
730}
731
732static void can_filter_enable_post_write(RegisterInfo *reg, uint64_t val64)
733{
734 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
735
736 if (ARRAY_FIELD_EX32(s->regs, AFR, UAF1) &&
737 ARRAY_FIELD_EX32(s->regs, AFR, UAF2) &&
738 ARRAY_FIELD_EX32(s->regs, AFR, UAF3) &&
739 ARRAY_FIELD_EX32(s->regs, AFR, UAF4)) {
740
741 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, ACFBSY, 1);
742
743 } else {
744 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, ACFBSY, 0);
745 }
746}
747
748static uint64_t can_filter_mask_pre_write(RegisterInfo *reg, uint64_t val64)
749{
750 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
751 uint32_t reg_idx = (reg->access->addr) / 4;
752 uint32_t val = val64;
753 uint32_t filter_number = (reg_idx - R_AFMR1) / 2;
754
755
756 if (!(s->regs[R_AFR] & (1 << filter_number))) {
757 s->regs[reg_idx] = val;
758 } else {
759 DB_PRINT("Acceptance filter %d mask is not set as it's corresponding "
760 "UAF bit is not set to 0\n", filter_number + 1);
761 }
762
763 return s->regs[reg_idx];
764}
765
766static uint64_t can_filter_id_pre_write(RegisterInfo *reg, uint64_t val64)
767{
768 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
769 uint32_t reg_idx = (reg->access->addr) / 4;
770 uint32_t val = val64;
771 uint32_t filter_number = (reg_idx - R_AFIR1) / 2;
772
773 if (!(s->regs[R_AFR] & (1 << filter_number))) {
774 s->regs[reg_idx] = val;
775 } else {
776 DB_PRINT("Acceptance filter %d id is not set as it's corresponding "
777 "UAF bit is not set to 0\n", filter_number + 1);
778 }
779
780 return s->regs[reg_idx];
781}
782
783static void can_tx_post_write(RegisterInfo *reg, uint64_t val64)
784{
785 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
786 uint32_t val = val64;
787
788 bool is_txhpb = reg->access->addr > A_TXFIFO_DATA2;
789
790 bool initiate_transfer = (reg->access->addr == A_TXFIFO_DATA2) ||
791 (reg->access->addr == A_TXHPB_DATA2);
792
793 Fifo *f = is_txhpb ? &s->txhpb_fifo : &s->tx_fifo;
794
795 DB_PRINT("TX FIFO write for CAN%d\n", s->cfg.ctrl_idx);
796
797 if (!fifo_is_full(f)) {
798 fifo_push32(f, val);
799 } else {
800 DB_PRINT("TX FIFO is full.\n");
801 }
802
803
804 if (initiate_transfer &&
805 ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) {
806 transfer_fifo(s, f);
807 }
808
809 can_update_irq(s);
810}
811
812static const RegisterAccessInfo can_regs_info[] = {
813 { .name = "SOFTWARE_RESET_REGISTER",
814 .addr = A_SOFTWARE_RESET_REGISTER,
815 .rsvd = 0xfffffffc,
816 .pre_write = can_srr_pre_write,
817 },{ .name = "MODE_SELECT_REGISTER",
818 .addr = A_MODE_SELECT_REGISTER,
819 .rsvd = 0xfffffff8,
820 .pre_write = can_msr_pre_write,
821 },{ .name = "ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER",
822 .addr = A_ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER,
823 .rsvd = 0xffffff00,
824 .pre_write = can_brpr_pre_write,
825 },{ .name = "ARBITRATION_PHASE_BIT_TIMING_REGISTER",
826 .addr = A_ARBITRATION_PHASE_BIT_TIMING_REGISTER,
827 .rsvd = 0xfffffe00,
828 .pre_write = can_btr_pre_write,
829 },{ .name = "ERROR_COUNTER_REGISTER",
830 .addr = A_ERROR_COUNTER_REGISTER,
831 .rsvd = 0xffff0000,
832 .ro = 0xffffffff,
833 },{ .name = "ERROR_STATUS_REGISTER",
834 .addr = A_ERROR_STATUS_REGISTER,
835 .rsvd = 0xffffffe0,
836 .w1c = 0x1f,
837 },{ .name = "STATUS_REGISTER", .addr = A_STATUS_REGISTER,
838 .reset = 0x1,
839 .rsvd = 0xffffe000,
840 .ro = 0x1fff,
841 },{ .name = "INTERRUPT_STATUS_REGISTER",
842 .addr = A_INTERRUPT_STATUS_REGISTER,
843 .reset = 0x6000,
844 .rsvd = 0xffff8000,
845 .ro = 0x7fff,
846 },{ .name = "INTERRUPT_ENABLE_REGISTER",
847 .addr = A_INTERRUPT_ENABLE_REGISTER,
848 .rsvd = 0xffff8000,
849 .post_write = can_ier_post_write,
850 },{ .name = "INTERRUPT_CLEAR_REGISTER",
851 .addr = A_INTERRUPT_CLEAR_REGISTER,
852 .rsvd = 0xffff8000,
853 .pre_write = can_icr_pre_write,
854 },{ .name = "TIMESTAMP_REGISTER",
855 .addr = A_TIMESTAMP_REGISTER,
856 .rsvd = 0xfffffffe,
857 .pre_write = can_tcr_pre_write,
858 },{ .name = "WIR", .addr = A_WIR,
859 .reset = 0x3f3f,
860 .rsvd = 0xffff0000,
861 },{ .name = "TXFIFO_ID", .addr = A_TXFIFO_ID,
862 .post_write = can_tx_post_write,
863 },{ .name = "TXFIFO_DLC", .addr = A_TXFIFO_DLC,
864 .rsvd = 0xfffffff,
865 .post_write = can_tx_post_write,
866 },{ .name = "TXFIFO_DATA1", .addr = A_TXFIFO_DATA1,
867 .post_write = can_tx_post_write,
868 },{ .name = "TXFIFO_DATA2", .addr = A_TXFIFO_DATA2,
869 .post_write = can_tx_post_write,
870 },{ .name = "TXHPB_ID", .addr = A_TXHPB_ID,
871 .post_write = can_tx_post_write,
872 },{ .name = "TXHPB_DLC", .addr = A_TXHPB_DLC,
873 .rsvd = 0xfffffff,
874 .post_write = can_tx_post_write,
875 },{ .name = "TXHPB_DATA1", .addr = A_TXHPB_DATA1,
876 .post_write = can_tx_post_write,
877 },{ .name = "TXHPB_DATA2", .addr = A_TXHPB_DATA2,
878 .post_write = can_tx_post_write,
879 },{ .name = "RXFIFO_ID", .addr = A_RXFIFO_ID,
880 .ro = 0xffffffff,
881 .post_read = can_rxfifo_pre_read,
882 },{ .name = "RXFIFO_DLC", .addr = A_RXFIFO_DLC,
883 .rsvd = 0xfff0000,
884 .post_read = can_rxfifo_pre_read,
885 },{ .name = "RXFIFO_DATA1", .addr = A_RXFIFO_DATA1,
886 .post_read = can_rxfifo_pre_read,
887 },{ .name = "RXFIFO_DATA2", .addr = A_RXFIFO_DATA2,
888 .post_read = can_rxfifo_pre_read,
889 },{ .name = "AFR", .addr = A_AFR,
890 .rsvd = 0xfffffff0,
891 .post_write = can_filter_enable_post_write,
892 },{ .name = "AFMR1", .addr = A_AFMR1,
893 .pre_write = can_filter_mask_pre_write,
894 },{ .name = "AFIR1", .addr = A_AFIR1,
895 .pre_write = can_filter_id_pre_write,
896 },{ .name = "AFMR2", .addr = A_AFMR2,
897 .pre_write = can_filter_mask_pre_write,
898 },{ .name = "AFIR2", .addr = A_AFIR2,
899 .pre_write = can_filter_id_pre_write,
900 },{ .name = "AFMR3", .addr = A_AFMR3,
901 .pre_write = can_filter_mask_pre_write,
902 },{ .name = "AFIR3", .addr = A_AFIR3,
903 .pre_write = can_filter_id_pre_write,
904 },{ .name = "AFMR4", .addr = A_AFMR4,
905 .pre_write = can_filter_mask_pre_write,
906 },{ .name = "AFIR4", .addr = A_AFIR4,
907 .pre_write = can_filter_id_pre_write,
908 }
909};
910
911static const MemoryRegionOps can_ops = {
912 .read = register_read_memory,
913 .write = register_write_memory,
914 .endianness = DEVICE_LITTLE_ENDIAN,
915 .valid = {
916 .min_access_size = 4,
917 .max_access_size = 4,
918 },
919};
920
921static void xlnx_zynqmp_can_reset(DeviceState *dev)
922{
923 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(dev);
924 unsigned int i;
925
926 for (i = 0; i < ARRAY_SIZE(s->reg_info); ++i) {
927 register_reset(&s->reg_info[i]);
928 }
929
930
931
932
933
934
935
936 fifo_reset(&s->rx_fifo);
937 fifo_reset(&s->tx_fifo);
938 fifo_reset(&s->txhpb_fifo);
939}
940
941static bool xlnx_zynqmp_can_can_receive(CanBusClientState *client)
942{
943 XlnxZynqMPCAN *s = container_of(client, XlnxZynqMPCAN, bus_client);
944
945 if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, SRST)) {
946 DB_PRINT("XlnxZynqMPCAN%d Controller is reset\n", s->cfg.ctrl_idx);
947 return 0;
948 } else if ((ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) == 0) {
949 DB_PRINT("XlnxZynqMPCAN%d is disabled. Messages will be discarded\n",
950 s->cfg.ctrl_idx);
951 return 0;
952 } else {
953 return 1;
954 }
955}
956
957static ssize_t xlnx_zynqmp_can_receive(CanBusClientState *client,
958 const qemu_can_frame *buf, size_t buf_size) {
959 XlnxZynqMPCAN *s = container_of(client, XlnxZynqMPCAN, bus_client);
960 const qemu_can_frame *frame = buf;
961
962 DB_PRINT("Incoming data for CAN%d\n", s->cfg.ctrl_idx);
963
964 if (buf_size <= 0) {
965 DB_PRINT("junk data received on XlnxZynqMPCAN bus\n");
966 return 0;
967 }
968 if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, LBACK)) {
969
970
971
972
973 DB_PRINT("XlnxZynqMPCAN is in loopback mode."
974 " It will not receive data.\n");
975
976 } else if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SNOOP)) {
977
978 update_rx_fifo(s, frame);
979 } else if ((ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP))) {
980
981
982
983
984 can_exit_sleep_mode(s);
985 update_rx_fifo(s, frame);
986 } else if ((ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP)) == 0) {
987 update_rx_fifo(s, frame);
988 } else {
989 DB_PRINT("Can't receive data as XlnxZynqMPCAN is not set correctly.\n");
990 }
991
992 return 1;
993}
994
995static CanBusClientInfo can_xilinx_bus_client_info = {
996 .can_receive = xlnx_zynqmp_can_can_receive,
997 .receive = xlnx_zynqmp_can_receive,
998};
999
1000static int xlnx_zynqmp_can_connect_to_bus(XlnxZynqMPCAN *s, CanBusState *bus)
1001{
1002 s->bus_client.info = &can_xilinx_bus_client_info;
1003
1004 if (can_bus_insert_client(bus, &s->bus_client) < 0) {
1005 return -1;
1006 }
1007 return 0;
1008}
1009
1010static void xlnx_zynqmp_can_realize(DeviceState *dev, Error **errp)
1011{
1012 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(dev);
1013
1014 if (s->cfg.ctrl_idx > MAX_CAN_CTRLS) {
1015 error_setg(errp, "ctrl-idx: %d exceeds max XlnxZynqMPCAN controller "
1016 "index", s->cfg.ctrl_idx);
1017 return;
1018 }
1019
1020 if (s->canbus[s->cfg.ctrl_idx]) {
1021 if (xlnx_zynqmp_can_connect_to_bus(s, s->canbus[s->cfg.ctrl_idx]) < 0) {
1022 error_setg(errp, "xlnx_zynqmp_can_connect_to_bus failed");
1023 }
1024
1025 } else {
1026
1027 DB_PRINT("Canbus%d property is not set for xlnxCAN%d\n",
1028 s->cfg.ctrl_idx, s->cfg.ctrl_idx);
1029 }
1030
1031
1032 fifo_create32(&s->rx_fifo, RXFIFO_SIZE);
1033 fifo_create32(&s->tx_fifo, RXFIFO_SIZE);
1034 fifo_create32(&s->txhpb_fifo, CAN_FRAME_SIZE);
1035}
1036
1037static void xlnx_zynqmp_can_init(Object *obj)
1038{
1039 XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(obj);
1040 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1041
1042 RegisterInfoArray *reg_array;
1043
1044 memory_region_init(&s->iomem, obj, TYPE_XLNX_ZYNQMP_CAN,
1045 XLNX_ZYNQMP_CAN_R_MAX * 4);
1046 reg_array = register_init_block32(DEVICE(obj), can_regs_info,
1047 ARRAY_SIZE(can_regs_info),
1048 s->reg_info, s->regs,
1049 &can_ops,
1050 XLNX_ZYNQMP_CAN_ERR_DEBUG,
1051 XLNX_ZYNQMP_CAN_R_MAX * 4);
1052
1053 memory_region_add_subregion(&s->iomem, 0x00, ®_array->mem);
1054 sysbus_init_mmio(sbd, &s->iomem);
1055 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
1056
1057 object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
1058 (Object **)&s->canbus[0],
1059 qdev_prop_allow_set_link_before_realize,
1060 0);
1061
1062 object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
1063 (Object **)&s->canbus[1],
1064 qdev_prop_allow_set_link_before_realize,
1065 0);
1066}
1067
1068static const VMStateDescription vmstate_can = {
1069 .name = TYPE_XLNX_ZYNQMP_CAN,
1070 .version_id = 1,
1071 .minimum_version_id = 1,
1072 .fields = (VMStateField[]) {
1073 VMSTATE_FIFO(rx_fifo, XlnxZynqMPCAN),
1074 VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPCAN, XLNX_ZYNQMP_CAN_R_MAX),
1075 VMSTATE_UINT8(cfg.ctrl_idx, XlnxZynqMPCAN),
1076 VMSTATE_END_OF_LIST(),
1077 }
1078};
1079
1080static Property xlnx_zynqmp_can_properties[] = {
1081 DEFINE_PROP_UINT8("ctrl-idx", XlnxZynqMPCAN, cfg.ctrl_idx, 0),
1082 DEFINE_PROP_END_OF_LIST(),
1083};
1084
1085static void xlnx_zynqmp_can_class_init(ObjectClass *klass, void *data)
1086{
1087 DeviceClass *dc = DEVICE_CLASS(klass);
1088 dc->reset = xlnx_zynqmp_can_reset;
1089 dc->realize = xlnx_zynqmp_can_realize;
1090 device_class_set_props(dc, xlnx_zynqmp_can_properties);
1091 dc->vmsd = &vmstate_can;
1092}
1093
1094static const TypeInfo can_info = {
1095 .name = TYPE_XLNX_ZYNQMP_CAN,
1096 .parent = TYPE_SYS_BUS_DEVICE,
1097 .instance_size = sizeof(XlnxZynqMPCAN),
1098 .class_init = xlnx_zynqmp_can_class_init,
1099 .instance_init = xlnx_zynqmp_can_init,
1100};
1101
1102static void can_register_types(void)
1103{
1104 type_register_static(&can_info);
1105}
1106
1107type_init(can_register_types)
1108