]> git.proxmox.com Git - mirror_qemu.git/blame - hw/net/can/xlnx-zynqmp-can.c
vmstate-static-checker: Recognize "num" field
[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"
98e5d7a2
VG
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 /* Watermark register interrupts. */
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 /* RX Interrupts. */
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 /* TX interrupts. */
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 /* Reset all the configuration registers. */
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 /* Put XlnxZynqMPCAN in configuration mode. */
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 /* Wake up interrupt bit. */
350 bool wakeup_irq_val = sleep_status && (sleep_mode == 0);
351 /* Sleep interrupt bit. */
352 bool sleep_irq_val = sleep_mode && (sleep_status == 0);
353
354 /* Clear previous core mode status bits. */
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 /* set current mode bit and generate irqs accordingly. */
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 * If all bits are zero then XlnxZynqMPCAN is set in normal mode.
372 */
373 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, NORMAL, 1);
374 /* Set wakeup interrupt bit. */
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 * Controller is in loopback. In Loopback mode, the CAN core
461 * transmits a recessive bitstream on to the XlnxZynqMPCAN Bus.
462 * Any message transmitted is looped back to the RX line and
463 * acknowledged. The XlnxZynqMPCAN core receives any message
464 * that it transmits.
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 /* Normal mode Tx. */
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 /* First, core will do software reset then will enter in config mode. */
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 * Leave config mode. Now XlnxZynqMPCAN core will enter normal,
517 * sleep, snoop or loopback mode depending upon LBACK, SLEEP, SNOOP
518 * register states.
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 /* XlnxZynqMPCAN is out of config mode. It will send pending data. */
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 * Multiple mode set check. This is done to make sure user doesn't set
543 * multiple modes.
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 /* We are in configuration mode, any mode can be selected. */
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 /* Only allow writes when in config mode. */
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 /* Only allow writes when in config mode. */
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 /* If no filter is enabled. Message will be stored in FIFO. */
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 * Messages that pass any of the acceptance filters will be stored in
638 * the RX FIFO.
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 /* Store the message in fifo if it passed through any of the filters. */
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 /* First 32 bit of the data. */
fb96d131
AK
699 fifo32_push(&s->rx_fifo, deposit32(0, R_RXFIFO_DATA1_DB3_SHIFT,
700 R_RXFIFO_DATA1_DB3_LENGTH,
98e5d7a2 701 frame->data[0]) |
fb96d131
AK
702 deposit32(0, R_RXFIFO_DATA1_DB2_SHIFT,
703 R_RXFIFO_DATA1_DB2_LENGTH,
98e5d7a2 704 frame->data[1]) |
fb96d131
AK
705 deposit32(0, R_RXFIFO_DATA1_DB1_SHIFT,
706 R_RXFIFO_DATA1_DB1_LENGTH,
98e5d7a2 707 frame->data[2]) |
fb96d131
AK
708 deposit32(0, R_RXFIFO_DATA1_DB0_SHIFT,
709 R_RXFIFO_DATA1_DB0_LENGTH,
98e5d7a2
VG
710 frame->data[3]));
711 /* Last 32 bit of the data. */
fb96d131
AK
712 fifo32_push(&s->rx_fifo, deposit32(0, R_RXFIFO_DATA2_DB7_SHIFT,
713 R_RXFIFO_DATA2_DB7_LENGTH,
98e5d7a2 714 frame->data[4]) |
fb96d131
AK
715 deposit32(0, R_RXFIFO_DATA2_DB6_SHIFT,
716 R_RXFIFO_DATA2_DB6_LENGTH,
98e5d7a2 717 frame->data[5]) |
fb96d131
AK
718 deposit32(0, R_RXFIFO_DATA2_DB5_SHIFT,
719 R_RXFIFO_DATA2_DB5_LENGTH,
98e5d7a2 720 frame->data[6]) |
fb96d131
AK
721 deposit32(0, R_RXFIFO_DATA2_DB4_SHIFT,
722 R_RXFIFO_DATA2_DB4_LENGTH,
98e5d7a2
VG
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 /* modify an acceptance filter, the corresponding UAF bit should be '0'. */
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 /* Initiate the message send if TX register is written. */
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 /* No action required on the timer rollover. */
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 * Reset FIFOs when CAN model is reset. This will clear the fifo writes
975 * done by post_write which gets called from register_reset function,
976 * post_write handle will not be able to trigger tx because CAN will be
977 * disabled when software_reset_register is cleared first.
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 /* Snoop Mode: Just keep the data. no response back. */
1024 update_rx_fifo(s, frame);
1025 } else if ((ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP))) {
1026 /*
1027 * XlnxZynqMPCAN is in sleep mode. Any data on bus will bring it to wake
1028 * up state.
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 * XlnxZynqMPCAN will not participate in normal bus communication
1037 * and will not receive any messages transmitted by other CAN nodes.
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 /* Create RX FIFO, TXFIFO, TXHPB storage. */
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 /* Allocate a new timer. */
1081 s->can_timer = ptimer_init(xlnx_zynqmp_can_ptimer_cb, s,
9598c1bb 1082 PTIMER_POLICY_LEGACY);
98e5d7a2
VG
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, &reg_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 DEFINE_PROP_END_OF_LIST(),
1133};
1134
1135static void xlnx_zynqmp_can_class_init(ObjectClass *klass, void *data)
1136{
1137 DeviceClass *dc = DEVICE_CLASS(klass);
1138 ResettableClass *rc = RESETTABLE_CLASS(klass);
1139
1140 rc->phases.enter = xlnx_zynqmp_can_reset_init;
1141 rc->phases.hold = xlnx_zynqmp_can_reset_hold;
1142 dc->realize = xlnx_zynqmp_can_realize;
1143 device_class_set_props(dc, xlnx_zynqmp_can_properties);
1144 dc->vmsd = &vmstate_can;
1145}
1146
1147static const TypeInfo can_info = {
1148 .name = TYPE_XLNX_ZYNQMP_CAN,
1149 .parent = TYPE_SYS_BUS_DEVICE,
1150 .instance_size = sizeof(XlnxZynqMPCANState),
1151 .class_init = xlnx_zynqmp_can_class_init,
1152 .instance_init = xlnx_zynqmp_can_init,
1153};
1154
1155static void can_register_types(void)
1156{
1157 type_register_static(&can_info);
1158}
1159
1160type_init(can_register_types)