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