qapi/parser: enable pylint checks
[qemu/armbru.git] / hw / net / can / xlnx-zynqmp-can.c
blob22bb8910fa8c1ffaf5a44631b835938eff83d775
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
6 * Copyright (c) 2020 Xilinx Inc.
8 * Written-by: Vikram Garhwal<fnu.vikram@xilinx.com>
10 * Based on QEMU CAN Device emulation implemented by Jin Yang, Deniz Eren and
11 * Pavel Pisa
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:
20 * The above copyright notice and this permission notice shall be included in
21 * all copies or substantial portions of the Software.
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.
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"
49 #ifndef XLNX_ZYNQMP_CAN_ERR_DEBUG
50 #define XLNX_ZYNQMP_CAN_ERR_DEBUG 0
51 #endif
53 #define MAX_DLC 8
54 #undef ERROR
56 REG32(SOFTWARE_RESET_REGISTER, 0x0)
57 FIELD(SOFTWARE_RESET_REGISTER, CEN, 1, 1)
58 FIELD(SOFTWARE_RESET_REGISTER, SRST, 0, 1)
59 REG32(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)
63 REG32(ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER, 0x8)
64 FIELD(ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER, BRP, 0, 8)
65 REG32(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)
69 REG32(ERROR_COUNTER_REGISTER, 0x10)
70 FIELD(ERROR_COUNTER_REGISTER, REC, 8, 8)
71 FIELD(ERROR_COUNTER_REGISTER, TEC, 0, 8)
72 REG32(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)
78 REG32(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)
91 REG32(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)
107 REG32(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)
123 REG32(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)
139 REG32(TIMESTAMP_REGISTER, 0x28)
140 FIELD(TIMESTAMP_REGISTER, CTS, 0, 1)
141 REG32(WIR, 0x2c)
142 FIELD(WIR, EW, 8, 8)
143 FIELD(WIR, FW, 0, 8)
144 REG32(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)
150 REG32(TXFIFO_DLC, 0x34)
151 FIELD(TXFIFO_DLC, DLC, 28, 4)
152 REG32(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)
157 REG32(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)
162 REG32(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)
168 REG32(TXHPB_DLC, 0x44)
169 FIELD(TXHPB_DLC, DLC, 28, 4)
170 REG32(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)
175 REG32(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)
180 REG32(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)
186 REG32(RXFIFO_DLC, 0x54)
187 FIELD(RXFIFO_DLC, DLC, 28, 4)
188 FIELD(RXFIFO_DLC, RXT, 0, 16)
189 REG32(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)
194 REG32(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)
199 REG32(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)
204 REG32(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)
210 REG32(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)
216 REG32(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)
222 REG32(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)
228 REG32(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)
234 REG32(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)
240 REG32(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)
246 REG32(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)
253 static void can_update_irq(XlnxZynqMPCANState *s)
255 uint32_t irq;
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);
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);
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);
273 /* TX interrupts. */
274 if (fifo32_is_empty(&s->tx_fifo)) {
275 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFEMP, 1);
278 if (fifo32_is_full(&s->tx_fifo)) {
279 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFLL, 1);
282 if (fifo32_is_full(&s->txhpb_fifo)) {
283 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXBFLL, 1);
286 irq = s->regs[R_INTERRUPT_STATUS_REGISTER];
287 irq &= s->regs[R_INTERRUPT_ENABLE_REGISTER];
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);
294 static void can_ier_post_write(RegisterInfo *reg, uint64_t val)
296 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
298 can_update_irq(s);
301 static uint64_t can_icr_pre_write(RegisterInfo *reg, uint64_t val)
303 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
305 s->regs[R_INTERRUPT_STATUS_REGISTER] &= ~val;
306 can_update_irq(s);
308 return 0;
311 static void can_config_reset(XlnxZynqMPCANState *s)
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]);
326 static void can_config_mode(XlnxZynqMPCANState *s)
328 register_reset(&s->reg_info[R_ERROR_COUNTER_REGISTER]);
329 register_reset(&s->reg_info[R_ERROR_STATUS_REGISTER]);
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);
342 can_update_irq(s);
345 static void update_status_register_mode_bits(XlnxZynqMPCANState *s)
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);
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);
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 {
371 * If all bits are zero then XlnxZynqMPCAN is set in normal mode.
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);
379 can_update_irq(s);
382 static void can_exit_sleep_mode(XlnxZynqMPCANState *s)
384 ARRAY_FIELD_DP32(s->regs, MODE_SELECT_REGISTER, SLEEP, 0);
385 update_status_register_mode_bits(s);
388 static void generate_frame(qemu_can_frame *frame, uint32_t *data)
390 frame->can_id = data[0];
391 frame->can_dlc = FIELD_EX32(data[1], TXFIFO_DLC, DLC);
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);
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);
404 static bool tx_ready_check(XlnxZynqMPCANState *s)
406 if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, SRST)) {
407 g_autofree char *path = object_get_canonical_path(OBJECT(s));
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;
415 if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
416 g_autofree char *path = object_get_canonical_path(OBJECT(s));
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;
425 if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SNOOP)) {
426 g_autofree char *path = object_get_canonical_path(OBJECT(s));
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;
434 return true;
437 static void transfer_fifo(XlnxZynqMPCANState *s, Fifo32 *fifo)
439 qemu_can_frame frame;
440 uint32_t data[CAN_FRAME_SIZE];
441 int i;
442 bool can_tx = tx_ready_check(s);
444 if (!can_tx) {
445 g_autofree char *path = object_get_canonical_path(OBJECT(s));
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;
453 while (!fifo32_is_empty(fifo)) {
454 for (i = 0; i < CAN_FRAME_SIZE; i++) {
455 data[i] = fifo32_pop(fifo);
458 if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, LBACK)) {
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.
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]);
473 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 1);
475 } else {
476 /* Normal mode Tx. */
477 generate_frame(&frame, data);
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);
488 ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXOK, 1);
489 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, TXBFLL, 0);
491 if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP)) {
492 can_exit_sleep_mode(s);
495 can_update_irq(s);
498 static uint64_t can_srr_pre_write(RegisterInfo *reg, uint64_t val)
500 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
502 ARRAY_FIELD_DP32(s->regs, SOFTWARE_RESET_REGISTER, CEN,
503 FIELD_EX32(val, SOFTWARE_RESET_REGISTER, CEN));
505 if (FIELD_EX32(val, SOFTWARE_RESET_REGISTER, SRST)) {
506 trace_xlnx_can_reset(val);
508 /* First, core will do software reset then will enter in config mode. */
509 can_config_reset(s);
512 if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
513 can_config_mode(s);
514 } else {
516 * Leave config mode. Now XlnxZynqMPCAN core will enter normal,
517 * sleep, snoop or loopback mode depending upon LBACK, SLEEP, SNOOP
518 * register states.
520 ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, CONFIG, 0);
522 ptimer_transaction_begin(s->can_timer);
523 ptimer_set_count(s->can_timer, 0);
524 ptimer_transaction_commit(s->can_timer);
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);
531 update_status_register_mode_bits(s);
533 return s->regs[R_SOFTWARE_RESET_REGISTER];
536 static uint64_t can_msr_pre_write(RegisterInfo *reg, uint64_t val)
538 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
539 uint8_t multi_mode;
542 * Multiple mode set check. This is done to make sure user doesn't set
543 * multiple modes.
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);
549 if (multi_mode > 1) {
550 g_autofree char *path = object_get_canonical_path(OBJECT(s));
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);
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);
564 ARRAY_FIELD_DP32(s->regs, MODE_SELECT_REGISTER, SLEEP, sleep_mode_bit);
566 if (FIELD_EX32(val, MODE_SELECT_REGISTER, LBACK)) {
567 g_autofree char *path = object_get_canonical_path(OBJECT(s));
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));
575 qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to set"
576 " SNOOP mode without setting CEN bit as 0.\n",
577 path);
580 update_status_register_mode_bits(s);
583 return s->regs[R_MODE_SELECT_REGISTER];
586 static uint64_t can_brpr_pre_write(RegisterInfo *reg, uint64_t val)
588 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
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];
595 return val;
598 static uint64_t can_btr_pre_write(RegisterInfo *reg, uint64_t val)
600 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
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];
607 return val;
610 static uint64_t can_tcr_pre_write(RegisterInfo *reg, uint64_t val)
612 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
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);
620 return 0;
623 static void update_rx_fifo(XlnxZynqMPCANState *s, const qemu_can_frame *frame)
625 bool filter_pass = false;
626 uint16_t timestamp = 0;
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;
637 * Messages that pass any of the acceptance filters will be stored in
638 * the RX FIFO.
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];
644 if (filter_id_masked == id_masked) {
645 filter_pass = true;
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];
653 if (filter_id_masked == id_masked) {
654 filter_pass = true;
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];
662 if (filter_id_masked == id_masked) {
663 filter_pass = true;
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];
671 if (filter_id_masked == id_masked) {
672 filter_pass = true;
676 if (!filter_pass) {
677 trace_xlnx_can_rx_fifo_filter_reject(frame->can_id, frame->can_dlc);
678 return;
681 /* Store the message in fifo if it passed through any of the filters. */
682 if (filter_pass && frame->can_dlc <= MAX_DLC) {
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);
689 fifo32_push(&s->rx_fifo, frame->can_id);
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));
698 /* First 32 bit of the data. */
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 /* Last 32 bit of the data. */
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]));
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]);
733 can_update_irq(s);
737 static uint64_t can_rxfifo_pre_read(RegisterInfo *reg, uint64_t val)
739 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
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);
747 can_update_irq(s);
748 return val;
751 static void can_filter_enable_post_write(RegisterInfo *reg, uint64_t val)
753 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
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);
765 static uint64_t can_filter_mask_pre_write(RegisterInfo *reg, uint64_t val)
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;
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;
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));
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);
784 return s->regs[reg_idx];
787 static uint64_t can_filter_id_pre_write(RegisterInfo *reg, uint64_t val)
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;
793 if (!(s->regs[R_AFR] & (1 << filter_number))) {
794 s->regs[reg_idx] = val;
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));
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);
805 return s->regs[reg_idx];
808 static void can_tx_post_write(RegisterInfo *reg, uint64_t val)
810 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
812 bool is_txhpb = reg->access->addr > A_TXFIFO_DATA2;
814 bool initiate_transfer = (reg->access->addr == A_TXFIFO_DATA2) ||
815 (reg->access->addr == A_TXHPB_DATA2);
817 Fifo32 *f = is_txhpb ? &s->txhpb_fifo : &s->tx_fifo;
819 if (!fifo32_is_full(f)) {
820 fifo32_push(f, val);
821 } else {
822 g_autofree char *path = object_get_canonical_path(OBJECT(s));
824 qemu_log_mask(LOG_GUEST_ERROR, "%s: TX FIFO is full.\n", path);
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);
833 can_update_irq(s);
836 static 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,
935 static void xlnx_zynqmp_can_ptimer_cb(void *opaque)
937 /* No action required on the timer rollover. */
940 static 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,
950 static void xlnx_zynqmp_can_reset_init(Object *obj, ResetType type)
952 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(obj);
953 unsigned int i;
955 for (i = R_RXFIFO_ID; i < ARRAY_SIZE(s->reg_info); ++i) {
956 register_reset(&s->reg_info[i]);
959 ptimer_transaction_begin(s->can_timer);
960 ptimer_set_count(s->can_timer, 0);
961 ptimer_transaction_commit(s->can_timer);
964 static void xlnx_zynqmp_can_reset_hold(Object *obj)
966 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(obj);
967 unsigned int i;
969 for (i = 0; i < R_RXFIFO_ID; ++i) {
970 register_reset(&s->reg_info[i]);
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.
979 fifo32_reset(&s->rx_fifo);
980 fifo32_reset(&s->tx_fifo);
981 fifo32_reset(&s->txhpb_fifo);
984 static bool xlnx_zynqmp_can_can_receive(CanBusClientState *client)
986 XlnxZynqMPCANState *s = container_of(client, XlnxZynqMPCANState,
987 bus_client);
989 if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, SRST)) {
990 g_autofree char *path = object_get_canonical_path(OBJECT(s));
992 qemu_log_mask(LOG_GUEST_ERROR, "%s: Controller is in reset state.\n",
993 path);
994 return false;
997 if ((ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) == 0) {
998 g_autofree char *path = object_get_canonical_path(OBJECT(s));
1000 qemu_log_mask(LOG_GUEST_ERROR, "%s: Controller is disabled. Incoming"
1001 " messages will be discarded.\n", path);
1002 return false;
1005 return true;
1008 static 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;
1014 if (buf_size <= 0) {
1015 g_autofree char *path = object_get_canonical_path(OBJECT(s));
1017 qemu_log_mask(LOG_GUEST_ERROR, "%s: Error in the data received.\n",
1018 path);
1019 return 0;
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))) {
1027 * XlnxZynqMPCAN is in sleep mode. Any data on bus will bring it to wake
1028 * up state.
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 {
1036 * XlnxZynqMPCAN will not participate in normal bus communication
1037 * and will not receive any messages transmitted by other CAN nodes.
1039 trace_xlnx_can_rx_discard(s->regs[R_STATUS_REGISTER]);
1042 return 1;
1045 static CanBusClientInfo can_xilinx_bus_client_info = {
1046 .can_receive = xlnx_zynqmp_can_can_receive,
1047 .receive = xlnx_zynqmp_can_receive,
1050 static int xlnx_zynqmp_can_connect_to_bus(XlnxZynqMPCANState *s,
1051 CanBusState *bus)
1053 s->bus_client.info = &can_xilinx_bus_client_info;
1055 if (can_bus_insert_client(bus, &s->bus_client) < 0) {
1056 return -1;
1058 return 0;
1061 static void xlnx_zynqmp_can_realize(DeviceState *dev, Error **errp)
1063 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(dev);
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));
1069 error_setg(errp, "%s: xlnx_zynqmp_can_connect_to_bus"
1070 " failed.", path);
1071 return;
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);
1080 /* Allocate a new timer. */
1081 s->can_timer = ptimer_init(xlnx_zynqmp_can_ptimer_cb, s,
1082 PTIMER_POLICY_DEFAULT);
1084 ptimer_transaction_begin(s->can_timer);
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);
1092 static void xlnx_zynqmp_can_init(Object *obj)
1094 XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(obj);
1095 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1097 RegisterInfoArray *reg_array;
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);
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);
1113 static 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(),
1127 static 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(),
1135 static void xlnx_zynqmp_can_class_init(ObjectClass *klass, void *data)
1137 DeviceClass *dc = DEVICE_CLASS(klass);
1138 ResettableClass *rc = RESETTABLE_CLASS(klass);
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;
1147 static 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,
1155 static void can_register_types(void)
1157 type_register_static(&can_info);
1160 type_init(can_register_types)