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