]> git.proxmox.com Git - mirror_qemu.git/blame - hw/net/can/xlnx-zynqmp-can.c
hw/net/can: Introduce Xilinx ZynqMP CAN controller
[mirror_qemu.git] / hw / net / can / xlnx-zynqmp-can.c
CommitLineData
98e5d7a2
VG
1/*
2 * QEMU model of the Xilinx ZynqMP CAN controller.
3 * This implementation is based on the following datasheet:
4 * https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
5 *
6 * Copyright (c) 2020 Xilinx Inc.
7 *
8 * Written-by: Vikram Garhwal<fnu.vikram@xilinx.com>
9 *
10 * Based on QEMU CAN Device emulation implemented by Jin Yang, Deniz Eren and
11 * Pavel Pisa
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining a copy
14 * of this software and associated documentation files (the "Software"), to deal
15 * in the Software without restriction, including without limitation the rights
16 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 * copies of the Software, and to permit persons to whom the Software is
18 * furnished to do so, subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice shall be included in
21 * all copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 * THE SOFTWARE.
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 /* Watermark register interrupts. */
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 /* RX Interrupts. */
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 /* TX interrupts. */
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 /* Reset all the configuration registers. */
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 /* Put XlnxZynqMPCAN in configuration mode. */
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 /* Wake up interrupt bit. */
351 bool wakeup_irq_val = sleep_status && (sleep_mode == 0);
352 /* Sleep interrupt bit. */
353 bool sleep_irq_val = sleep_mode && (sleep_status == 0);
354
355 /* Clear previous core mode status bits. */
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 /* set current mode bit and generate irqs accordingly. */
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 * If all bits are zero then XlnxZynqMPCAN is set in normal mode.
373 */
374 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, NORMAL, 1);
375 /* Set wakeup interrupt bit. */
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 * Controller is in loopback. In Loopback mode, the CAN core
462 * transmits a recessive bitstream on to the XlnxZynqMPCAN Bus.
463 * Any message transmitted is looped back to the RX line and
464 * acknowledged. The XlnxZynqMPCAN core receives any message
465 * that it transmits.
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 /* Normal mode Tx. */
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 /* First, core will do software reset then will enter in config mode. */
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 * Leave config mode. Now XlnxZynqMPCAN core will enter normal,
518 * sleep, snoop or loopback mode depending upon LBACK, SLEEP, SNOOP
519 * register states.
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 /* XlnxZynqMPCAN is out of config mode. It will send pending data. */
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 * Multiple mode set check. This is done to make sure user doesn't set
544 * multiple modes.
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 /* We are in configuration mode, any mode can be selected. */
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 /* Only allow writes when in config mode. */
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 /* Only allow writes when in config mode. */
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 /* If no filter is enabled. Message will be stored in FIFO. */
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 * Messages that pass any of the acceptance filters will be stored in
639 * the RX FIFO.
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 /* Store the message in fifo if it passed through any of the filters. */
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 /* First 32 bit of the data. */
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 /* Last 32 bit of the data. */
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 /* modify an acceptance filter, the corresponding UAF bit should be '0'. */
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 /* Initiate the message send if TX register is written. */
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 /* No action required on the timer rollover. */
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 * Reset FIFOs when CAN model is reset. This will clear the fifo writes
976 * done by post_write which gets called from register_reset function,
977 * post_write handle will not be able to trigger tx because CAN will be
978 * disabled when software_reset_register is cleared first.
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 /* Snoop Mode: Just keep the data. no response back. */
1025 update_rx_fifo(s, frame);
1026 } else if ((ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP))) {
1027 /*
1028 * XlnxZynqMPCAN is in sleep mode. Any data on bus will bring it to wake
1029 * up state.
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 * XlnxZynqMPCAN will not participate in normal bus communication
1038 * and will not receive any messages transmitted by other CAN nodes.
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 /* Create RX FIFO, TXFIFO, TXHPB storage. */
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 /* Allocate a new timer. */
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, &reg_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)