qemu/hw/net/can/xlnx-zynqmp-can.c
<<
>>
Prefs
   1/*
   2 * QEMU model of the Xilinx CAN device.
   3 *
   4 * Copyright (c) 2019 Xilinx Inc.
   5 * Partially autogenerated by xregqemu.py 2019-06-20.
   6 *
   7 * Written-by: Vikram Garhwal<fnu.vikram@xilinx.com>
   8 *
   9 * Based on QEMU CAN Device emulation implemented by Jin Yang, Deniz Eren and
  10 * Pavel Pisa
  11 *
  12 * Permission is hereby granted, free of charge, to any person obtaining a copy
  13 * of this software and associated documentation files (the "Software"), to deal
  14 * in the Software without restriction, including without limitation the rights
  15 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  16 * copies of the Software, and to permit persons to whom the Software is
  17 * furnished to do so, subject to the following conditions:
  18 *
  19 * The above copyright notice and this permission notice shall be included in
  20 * all copies or substantial portions of the Software.
  21 *
  22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  25 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  28 * THE SOFTWARE.
  29 */
  30
  31#include "qemu/osdep.h"
  32#include "hw/sysbus.h"
  33#include "hw/register.h"
  34#include "hw/irq.h"
  35#include "qapi/error.h"
  36#include "qemu/bitops.h"
  37#include "qemu/log.h"
  38#include "qemu/cutils.h"
  39#include "sysemu/sysemu.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 "qemu/fifo.h"
  48
  49#ifndef XLNX_ZYNQMP_CAN_ERR_DEBUG
  50#define XLNX_ZYNQMP_CAN_ERR_DEBUG 0
  51#endif
  52
  53#define DB_PRINT(...) do { \
  54    if (XLNX_ZYNQMP_CAN_ERR_DEBUG) { \
  55        qemu_log(__VA_ARGS__); \
  56    } \
  57} while (0);
  58
  59#define MAX_DLC            8
  60#undef ERROR
  61
  62REG32(SOFTWARE_RESET_REGISTER, 0x0)
  63    FIELD(SOFTWARE_RESET_REGISTER, CEN, 1, 1)
  64    FIELD(SOFTWARE_RESET_REGISTER, SRST, 0, 1)
  65REG32(MODE_SELECT_REGISTER, 0x4)
  66    FIELD(MODE_SELECT_REGISTER, SNOOP, 2, 1)
  67    FIELD(MODE_SELECT_REGISTER, LBACK, 1, 1)
  68    FIELD(MODE_SELECT_REGISTER, SLEEP, 0, 1)
  69REG32(ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER, 0x8)
  70    FIELD(ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER, BRP, 0, 8)
  71REG32(ARBITRATION_PHASE_BIT_TIMING_REGISTER, 0xc)
  72    FIELD(ARBITRATION_PHASE_BIT_TIMING_REGISTER, SJW, 7, 2)
  73    FIELD(ARBITRATION_PHASE_BIT_TIMING_REGISTER, TS2, 4, 3)
  74    FIELD(ARBITRATION_PHASE_BIT_TIMING_REGISTER, TS1, 0, 4)
  75REG32(ERROR_COUNTER_REGISTER, 0x10)
  76    FIELD(ERROR_COUNTER_REGISTER, REC, 8, 8)
  77    FIELD(ERROR_COUNTER_REGISTER, TEC, 0, 8)
  78REG32(ERROR_STATUS_REGISTER, 0x14)
  79    FIELD(ERROR_STATUS_REGISTER, ACKER, 4, 1)
  80    FIELD(ERROR_STATUS_REGISTER, BERR, 3, 1)
  81    FIELD(ERROR_STATUS_REGISTER, STER, 2, 1)
  82    FIELD(ERROR_STATUS_REGISTER, FMER, 1, 1)
  83    FIELD(ERROR_STATUS_REGISTER, CRCER, 0, 1)
  84REG32(STATUS_REGISTER, 0x18)
  85    FIELD(STATUS_REGISTER, SNOOP, 12, 1)
  86    FIELD(STATUS_REGISTER, ACFBSY, 11, 1)
  87    FIELD(STATUS_REGISTER, TXFLL, 10, 1)
  88    FIELD(STATUS_REGISTER, TXBFLL, 9, 1)
  89    FIELD(STATUS_REGISTER, ESTAT, 7, 2)
  90    FIELD(STATUS_REGISTER, ERRWRN, 6, 1)
  91    FIELD(STATUS_REGISTER, BBSY, 5, 1)
  92    FIELD(STATUS_REGISTER, BIDLE, 4, 1)
  93    FIELD(STATUS_REGISTER, NORMAL, 3, 1)
  94    FIELD(STATUS_REGISTER, SLEEP, 2, 1)
  95    FIELD(STATUS_REGISTER, LBACK, 1, 1)
  96    FIELD(STATUS_REGISTER, CONFIG, 0, 1)
  97REG32(INTERRUPT_STATUS_REGISTER, 0x1c)
  98    FIELD(INTERRUPT_STATUS_REGISTER, TXFEMP, 14, 1)
  99    FIELD(INTERRUPT_STATUS_REGISTER, TXFWMEMP, 13, 1)
 100    FIELD(INTERRUPT_STATUS_REGISTER, RXFWMFLL, 12, 1)
 101    FIELD(INTERRUPT_STATUS_REGISTER, WKUP, 11, 1)
 102    FIELD(INTERRUPT_STATUS_REGISTER, SLP, 10, 1)
 103    FIELD(INTERRUPT_STATUS_REGISTER, BSOFF, 9, 1)
 104    FIELD(INTERRUPT_STATUS_REGISTER, ERROR, 8, 1)
 105    FIELD(INTERRUPT_STATUS_REGISTER, RXNEMP, 7, 1)
 106    FIELD(INTERRUPT_STATUS_REGISTER, RXOFLW, 6, 1)
 107    FIELD(INTERRUPT_STATUS_REGISTER, RXUFLW, 5, 1)
 108    FIELD(INTERRUPT_STATUS_REGISTER, RXOK, 4, 1)
 109    FIELD(INTERRUPT_STATUS_REGISTER, TXBFLL, 3, 1)
 110    FIELD(INTERRUPT_STATUS_REGISTER, TXFLL, 2, 1)
 111    FIELD(INTERRUPT_STATUS_REGISTER, TXOK, 1, 1)
 112    FIELD(INTERRUPT_STATUS_REGISTER, ARBLST, 0, 1)
 113REG32(INTERRUPT_ENABLE_REGISTER, 0x20)
 114    FIELD(INTERRUPT_ENABLE_REGISTER, ETXFEMP, 14, 1)
 115    FIELD(INTERRUPT_ENABLE_REGISTER, ETXFWMEMP, 13, 1)
 116    FIELD(INTERRUPT_ENABLE_REGISTER, ERXFWMFLL, 12, 1)
 117    FIELD(INTERRUPT_ENABLE_REGISTER, EWKUP, 11, 1)
 118    FIELD(INTERRUPT_ENABLE_REGISTER, ESLP, 10, 1)
 119    FIELD(INTERRUPT_ENABLE_REGISTER, EBSOFF, 9, 1)
 120    FIELD(INTERRUPT_ENABLE_REGISTER, EERROR, 8, 1)
 121    FIELD(INTERRUPT_ENABLE_REGISTER, ERXNEMP, 7, 1)
 122    FIELD(INTERRUPT_ENABLE_REGISTER, ERXOFLW, 6, 1)
 123    FIELD(INTERRUPT_ENABLE_REGISTER, ERXUFLW, 5, 1)
 124    FIELD(INTERRUPT_ENABLE_REGISTER, ERXOK, 4, 1)
 125    FIELD(INTERRUPT_ENABLE_REGISTER, ETXBFLL, 3, 1)
 126    FIELD(INTERRUPT_ENABLE_REGISTER, ETXFLL, 2, 1)
 127    FIELD(INTERRUPT_ENABLE_REGISTER, ETXOK, 1, 1)
 128    FIELD(INTERRUPT_ENABLE_REGISTER, EARBLST, 0, 1)
 129REG32(INTERRUPT_CLEAR_REGISTER, 0x24)
 130    FIELD(INTERRUPT_CLEAR_REGISTER, CTXFEMP, 14, 1)
 131    FIELD(INTERRUPT_CLEAR_REGISTER, CTXFWMEMP, 13, 1)
 132    FIELD(INTERRUPT_CLEAR_REGISTER, CRXFWMFLL, 12, 1)
 133    FIELD(INTERRUPT_CLEAR_REGISTER, CWKUP, 11, 1)
 134    FIELD(INTERRUPT_CLEAR_REGISTER, CSLP, 10, 1)
 135    FIELD(INTERRUPT_CLEAR_REGISTER, CBSOFF, 9, 1)
 136    FIELD(INTERRUPT_CLEAR_REGISTER, CERROR, 8, 1)
 137    FIELD(INTERRUPT_CLEAR_REGISTER, CRXNEMP, 7, 1)
 138    FIELD(INTERRUPT_CLEAR_REGISTER, CRXOFLW, 6, 1)
 139    FIELD(INTERRUPT_CLEAR_REGISTER, CRXUFLW, 5, 1)
 140    FIELD(INTERRUPT_CLEAR_REGISTER, CRXOK, 4, 1)
 141    FIELD(INTERRUPT_CLEAR_REGISTER, CTXBFLL, 3, 1)
 142    FIELD(INTERRUPT_CLEAR_REGISTER, CTXFLL, 2, 1)
 143    FIELD(INTERRUPT_CLEAR_REGISTER, CTXOK, 1, 1)
 144    FIELD(INTERRUPT_CLEAR_REGISTER, CARBLST, 0, 1)
 145REG32(TIMESTAMP_REGISTER, 0x28)
 146    FIELD(TIMESTAMP_REGISTER, CTS, 0, 1)
 147REG32(WIR, 0x2c)
 148    FIELD(WIR, EW, 8, 8)
 149    FIELD(WIR, FW, 0, 8)
 150REG32(TXFIFO_ID, 0x30)
 151    FIELD(TXFIFO_ID, IDH, 21, 11)
 152    FIELD(TXFIFO_ID, SRRRTR, 20, 1)
 153    FIELD(TXFIFO_ID, IDE, 19, 1)
 154    FIELD(TXFIFO_ID, IDL, 1, 18)
 155    FIELD(TXFIFO_ID, RTR, 0, 1)
 156REG32(TXFIFO_DLC, 0x34)
 157    FIELD(TXFIFO_DLC, DLC, 28, 4)
 158REG32(TXFIFO_DATA1, 0x38)
 159    FIELD(TXFIFO_DATA1, DB0, 24, 8)
 160    FIELD(TXFIFO_DATA1, DB1, 16, 8)
 161    FIELD(TXFIFO_DATA1, DB2, 8, 8)
 162    FIELD(TXFIFO_DATA1, DB3, 0, 8)
 163REG32(TXFIFO_DATA2, 0x3c)
 164    FIELD(TXFIFO_DATA2, DB4, 24, 8)
 165    FIELD(TXFIFO_DATA2, DB5, 16, 8)
 166    FIELD(TXFIFO_DATA2, DB6, 8, 8)
 167    FIELD(TXFIFO_DATA2, DB7, 0, 8)
 168REG32(TXHPB_ID, 0x40)
 169    FIELD(TXHPB_ID, IDH, 21, 11)
 170    FIELD(TXHPB_ID, SRRRTR, 20, 1)
 171    FIELD(TXHPB_ID, IDE, 19, 1)
 172    FIELD(TXHPB_ID, IDL, 1, 18)
 173    FIELD(TXHPB_ID, RTR, 0, 1)
 174REG32(TXHPB_DLC, 0x44)
 175    FIELD(TXHPB_DLC, DLC, 28, 4)
 176REG32(TXHPB_DATA1, 0x48)
 177    FIELD(TXHPB_DATA1, DB0, 24, 8)
 178    FIELD(TXHPB_DATA1, DB1, 16, 8)
 179    FIELD(TXHPB_DATA1, DB2, 8, 8)
 180    FIELD(TXHPB_DATA1, DB3, 0, 8)
 181REG32(TXHPB_DATA2, 0x4c)
 182    FIELD(TXHPB_DATA2, DB4, 24, 8)
 183    FIELD(TXHPB_DATA2, DB5, 16, 8)
 184    FIELD(TXHPB_DATA2, DB6, 8, 8)
 185    FIELD(TXHPB_DATA2, DB7, 0, 8)
 186REG32(RXFIFO_ID, 0x50)
 187    FIELD(RXFIFO_ID, IDH, 21, 11)
 188    FIELD(RXFIFO_ID, SRRRTR, 20, 1)
 189    FIELD(RXFIFO_ID, IDE, 19, 1)
 190    FIELD(RXFIFO_ID, IDL, 1, 18)
 191    FIELD(RXFIFO_ID, RTR, 0, 1)
 192REG32(RXFIFO_DLC, 0x54)
 193    FIELD(RXFIFO_DLC, DLC, 28, 4)
 194    FIELD(RXFIFO_DLC, RXT, 0, 16)
 195REG32(RXFIFO_DATA1, 0x58)
 196    FIELD(RXFIFO_DATA1, DB0, 24, 8)
 197    FIELD(RXFIFO_DATA1, DB1, 16, 8)
 198    FIELD(RXFIFO_DATA1, DB2, 8, 8)
 199    FIELD(RXFIFO_DATA1, DB3, 0, 8)
 200REG32(RXFIFO_DATA2, 0x5c)
 201    FIELD(RXFIFO_DATA2, DB4, 24, 8)
 202    FIELD(RXFIFO_DATA2, DB5, 16, 8)
 203    FIELD(RXFIFO_DATA2, DB6, 8, 8)
 204    FIELD(RXFIFO_DATA2, DB7, 0, 8)
 205REG32(AFR, 0x60)
 206    FIELD(AFR, UAF4, 3, 1)
 207    FIELD(AFR, UAF3, 2, 1)
 208    FIELD(AFR, UAF2, 1, 1)
 209    FIELD(AFR, UAF1, 0, 1)
 210REG32(AFMR1, 0x64)
 211    FIELD(AFMR1, AMIDH, 21, 11)
 212    FIELD(AFMR1, AMSRR, 20, 1)
 213    FIELD(AFMR1, AMIDE, 19, 1)
 214    FIELD(AFMR1, AMIDL, 1, 18)
 215    FIELD(AFMR1, AMRTR, 0, 1)
 216REG32(AFIR1, 0x68)
 217    FIELD(AFIR1, AIIDH, 21, 11)
 218    FIELD(AFIR1, AISRR, 20, 1)
 219    FIELD(AFIR1, AIIDE, 19, 1)
 220    FIELD(AFIR1, AIIDL, 1, 18)
 221    FIELD(AFIR1, AIRTR, 0, 1)
 222REG32(AFMR2, 0x6c)
 223    FIELD(AFMR2, AMIDH, 21, 11)
 224    FIELD(AFMR2, AMSRR, 20, 1)
 225    FIELD(AFMR2, AMIDE, 19, 1)
 226    FIELD(AFMR2, AMIDL, 1, 18)
 227    FIELD(AFMR2, AMRTR, 0, 1)
 228REG32(AFIR2, 0x70)
 229    FIELD(AFIR2, AIIDH, 21, 11)
 230    FIELD(AFIR2, AISRR, 20, 1)
 231    FIELD(AFIR2, AIIDE, 19, 1)
 232    FIELD(AFIR2, AIIDL, 1, 18)
 233    FIELD(AFIR2, AIRTR, 0, 1)
 234REG32(AFMR3, 0x74)
 235    FIELD(AFMR3, AMIDH, 21, 11)
 236    FIELD(AFMR3, AMSRR, 20, 1)
 237    FIELD(AFMR3, AMIDE, 19, 1)
 238    FIELD(AFMR3, AMIDL, 1, 18)
 239    FIELD(AFMR3, AMRTR, 0, 1)
 240REG32(AFIR3, 0x78)
 241    FIELD(AFIR3, AIIDH, 21, 11)
 242    FIELD(AFIR3, AISRR, 20, 1)
 243    FIELD(AFIR3, AIIDE, 19, 1)
 244    FIELD(AFIR3, AIIDL, 1, 18)
 245    FIELD(AFIR3, AIRTR, 0, 1)
 246REG32(AFMR4, 0x7c)
 247    FIELD(AFMR4, AMIDH, 21, 11)
 248    FIELD(AFMR4, AMSRR, 20, 1)
 249    FIELD(AFMR4, AMIDE, 19, 1)
 250    FIELD(AFMR4, AMIDL, 1, 18)
 251    FIELD(AFMR4, AMRTR, 0, 1)
 252REG32(AFIR4, 0x80)
 253    FIELD(AFIR4, AIIDH, 21, 11)
 254    FIELD(AFIR4, AISRR, 20, 1)
 255    FIELD(AFIR4, AIIDE, 19, 1)
 256    FIELD(AFIR4, AIIDL, 1, 18)
 257    FIELD(AFIR4, AIRTR, 0, 1)
 258
 259static void can_update_irq(XlnxZynqMPCAN *s)
 260{
 261    unsigned int irq;
 262
 263    /* Watermark register interrupts. */
 264    if ((fifo_num_free(&s->tx_fifo) / CAN_FRAME_SIZE) >
 265            ARRAY_FIELD_EX32(s->regs, WIR, EW)) {
 266        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFWMEMP, 1);
 267    }
 268
 269    if ((fifo_num_used(&s->rx_fifo) / CAN_FRAME_SIZE) >
 270            ARRAY_FIELD_EX32(s->regs, WIR, FW)) {
 271        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXFWMFLL, 1);
 272    }
 273
 274    /* RX Interrupts. */
 275    if (fifo_num_used(&s->rx_fifo) >= CAN_FRAME_SIZE) {
 276        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXNEMP, 1);
 277    }
 278
 279    /* TX interrupts. */
 280    if (fifo_is_empty(&s->tx_fifo)) {
 281        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFEMP, 1);
 282    }
 283
 284    if (fifo_is_full(&s->tx_fifo)) {
 285        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFLL, 1);
 286    }
 287
 288    if (fifo_is_full(&s->txhpb_fifo)) {
 289        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXBFLL, 1);
 290    }
 291
 292    irq = s->regs[R_INTERRUPT_STATUS_REGISTER];
 293    irq &= s->regs[R_INTERRUPT_ENABLE_REGISTER];
 294
 295    qemu_set_irq(s->irq, irq);
 296}
 297
 298static void can_ier_post_write(RegisterInfo *reg, uint64_t val64)
 299{
 300    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
 301
 302    can_update_irq(s);
 303}
 304
 305static uint64_t can_icr_pre_write(RegisterInfo *reg, uint64_t val64)
 306{
 307    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
 308    uint32_t val = val64;
 309
 310    s->regs[R_INTERRUPT_STATUS_REGISTER] &= ~val;
 311    can_update_irq(s);
 312
 313    return 0;
 314}
 315
 316static void can_config_reset(XlnxZynqMPCAN *s)
 317{
 318    /* Reset all the configuration registers. */
 319    register_reset(&s->reg_info[R_SOFTWARE_RESET_REGISTER]);
 320    register_reset(&s->reg_info[R_MODE_SELECT_REGISTER]);
 321    register_reset(
 322              &s->reg_info[R_ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER]);
 323    register_reset(&s->reg_info[R_ARBITRATION_PHASE_BIT_TIMING_REGISTER]);
 324    register_reset(&s->reg_info[R_STATUS_REGISTER]);
 325    register_reset(&s->reg_info[R_INTERRUPT_STATUS_REGISTER]);
 326    register_reset(&s->reg_info[R_INTERRUPT_ENABLE_REGISTER]);
 327    register_reset(&s->reg_info[R_INTERRUPT_CLEAR_REGISTER]);
 328    register_reset(&s->reg_info[R_WIR]);
 329}
 330
 331static void can_config_mode(XlnxZynqMPCAN *s)
 332{
 333    register_reset(&s->reg_info[R_ERROR_COUNTER_REGISTER]);
 334    register_reset(&s->reg_info[R_ERROR_STATUS_REGISTER]);
 335
 336    /* Put XlnxZynqMPCAN in configuration mode. */
 337    ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, CONFIG, 1);
 338    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, WKUP, 0);
 339    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, SLP, 0);
 340    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, BSOFF, 0);
 341    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, ERROR, 0);
 342    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOFLW, 0);
 343    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 0);
 344    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXOK, 0);
 345    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, ARBLST, 0);
 346
 347    can_update_irq(s);
 348}
 349
 350static void update_status_register_mode_bits(XlnxZynqMPCAN *s)
 351{
 352    /* Wake up interrupt bit. */
 353    bool wakeup_irq_val = (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER,
 354                            SLEEP) == 0) && ARRAY_FIELD_EX32(s->regs,
 355                            STATUS_REGISTER, SLEEP);
 356
 357    /* Sleep interrupt bit. */
 358    bool sleep_irq_val = (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER,
 359                            SLEEP) && (ARRAY_FIELD_EX32(s->regs,
 360                            STATUS_REGISTER, SLEEP) == 0));
 361
 362    /* Clear previous core mode status bits. */
 363    ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, LBACK, 0);
 364    ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SLEEP, 0);
 365    ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SNOOP, 0);
 366    ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, NORMAL, 0);
 367
 368    /* set current mode bit and generate irqs accordingly. */
 369    if (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, LBACK)) {
 370        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, LBACK, 1);
 371    } else if (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, SLEEP)) {
 372        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SLEEP, 1);
 373        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, SLP,
 374                            sleep_irq_val);
 375    } else if (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, SNOOP)) {
 376        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SNOOP, 1);
 377    } else {
 378        /* If all bits are zero then XlnxZynqMPCAN is set in normal mode. */
 379        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, NORMAL, 1);
 380        /* Set wakeup interrupt bit. */
 381        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, WKUP,
 382                            wakeup_irq_val);
 383    }
 384
 385    can_update_irq(s);
 386}
 387
 388static void can_exit_sleep_mode(XlnxZynqMPCAN *s)
 389{
 390    ARRAY_FIELD_DP32(s->regs, MODE_SELECT_REGISTER, SLEEP, 0);
 391    update_status_register_mode_bits(s);
 392}
 393
 394static void generate_frame(qemu_can_frame *frame, uint32_t *data)
 395{
 396    frame->can_id = data[0];
 397    frame->can_dlc = FIELD_EX32(data[1], TXFIFO_DLC, DLC);
 398
 399    frame->data[0] = FIELD_EX32(data[2], TXFIFO_DATA1, DB3);
 400    frame->data[1] = FIELD_EX32(data[2], TXFIFO_DATA1, DB2);
 401    frame->data[2] = FIELD_EX32(data[2], TXFIFO_DATA1, DB1);
 402    frame->data[3] = FIELD_EX32(data[2], TXFIFO_DATA1, DB0);
 403
 404    frame->data[4] = FIELD_EX32(data[3], TXFIFO_DATA2, DB7);
 405    frame->data[5] = FIELD_EX32(data[3], TXFIFO_DATA2, DB6);
 406    frame->data[6] = FIELD_EX32(data[3], TXFIFO_DATA2, DB5);
 407    frame->data[7] = FIELD_EX32(data[3], TXFIFO_DATA2, DB4);
 408}
 409
 410static bool tx_ready_check(XlnxZynqMPCAN *s)
 411{
 412    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, SRST)) {
 413        qemu_log_mask(LOG_GUEST_ERROR, "Attempting to transfer data while"
 414                      " XlnxZynqMPCAN%d is in reset mode\n", s->cfg.ctrl_idx);
 415        return false;
 416    }
 417
 418    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
 419        qemu_log_mask(LOG_GUEST_ERROR, "Attempting to transfer data while"
 420                      " XlnxZynqMPCAN%d is in configuration mode.Reset the"
 421                      " core so operations can start fresh\n",
 422                      s->cfg.ctrl_idx);
 423        return false;
 424    }
 425
 426    if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SNOOP)) {
 427        qemu_log_mask(LOG_GUEST_ERROR, "Attempting to transfer data while"
 428                        " XlnxZynqMPCAN%d is in SNOOP MODE\n",
 429                         s->cfg.ctrl_idx);
 430        return false;
 431    }
 432
 433    return true;
 434}
 435
 436static void transfer_fifo(XlnxZynqMPCAN *s, Fifo *fifo)
 437{
 438    qemu_can_frame frame;
 439    uint32_t data[CAN_FRAME_SIZE];
 440    int i;
 441    bool can_tx = tx_ready_check(s);
 442
 443    if (can_tx) {
 444        while (!fifo_is_empty(fifo)) {
 445            for (i = 0; i < CAN_FRAME_SIZE; i++) {
 446                data[i] = fifo_pop32(fifo);
 447            }
 448
 449            if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, LBACK)) {
 450                /*
 451                 * Controller in loopback. In Loopback mode, the XlnxZynqMPCAN
 452                 * core transmits a recessive bitstream on to the XlnxZynqMPCAN
 453                 * Bus. Any message transmitted is looped back to the RX line
 454                 * and acknowledged. The XlnxZynqMPCAN core receives any
 455                 * message that it transmits.
 456                 */
 457                if (fifo_is_full(&s->rx_fifo)) {
 458                    DB_PRINT("Loopback: RX FIFO is full."
 459                             "TX FIFO will be flushed.\n");
 460
 461                    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER,
 462                                      RXOFLW, 1);
 463                } else {
 464                    for (i = 0; i < CAN_FRAME_SIZE; i++) {
 465                        fifo_push32(&s->rx_fifo, data[i]);
 466                    }
 467
 468                    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER,
 469                                      RXOK, 1);
 470                }
 471            } else {
 472                /* Normal mode Tx. */
 473                generate_frame(&frame, data);
 474
 475                can_bus_client_send(&s->bus_client, &frame, 1);
 476            }
 477        }
 478
 479        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXOK, 1);
 480        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, TXBFLL, 0);
 481
 482        if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP)) {
 483            can_exit_sleep_mode(s);
 484        }
 485    } else {
 486        DB_PRINT("CAN is not enabled for data transfer.\n")
 487    }
 488
 489    can_update_irq(s);
 490}
 491
 492static uint64_t can_srr_pre_write(RegisterInfo *reg, uint64_t val64)
 493{
 494    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
 495    uint32_t val = val64;
 496
 497    ARRAY_FIELD_DP32(s->regs, SOFTWARE_RESET_REGISTER, CEN,
 498                        FIELD_EX32(val, SOFTWARE_RESET_REGISTER, CEN));
 499
 500    if (FIELD_EX32(val, SOFTWARE_RESET_REGISTER, SRST)) {
 501        DB_PRINT("Resetting XlnxZynqMPCAN%d\n", s->cfg.ctrl_idx);
 502
 503        /* First, core will do software reset then will enter in config mode. */
 504        can_config_reset(s);
 505    }
 506
 507    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
 508        can_config_mode(s);
 509
 510    } else {
 511        /*
 512         * Leave config mode. Now XlnxZynqMPCAN core will enter Normal, Sleep,
 513         * snoop or Loopback mode depending upon LBACK, SLEEP, SNOOP regsiter
 514         * states.
 515         */
 516        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, CONFIG, 0);
 517
 518        /* XlnxZynqMP CAN is out of config mode. it will send pending data. */
 519        transfer_fifo(s, &s->txhpb_fifo);
 520        transfer_fifo(s, &s->tx_fifo);
 521
 522        update_status_register_mode_bits(s);
 523    }
 524
 525    return s->regs[R_SOFTWARE_RESET_REGISTER];
 526}
 527
 528static uint64_t can_msr_pre_write(RegisterInfo *reg, uint64_t val64)
 529{
 530    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
 531    uint32_t val = val64;
 532    uint8_t multi_mode = 0;
 533
 534    /*
 535     * Multiple mode set check. This is done to make sure user doesn't set
 536     * multiple modes.
 537     */
 538    multi_mode = FIELD_EX32(val, MODE_SELECT_REGISTER, LBACK) +
 539                 FIELD_EX32(val, MODE_SELECT_REGISTER, SLEEP) +
 540                 FIELD_EX32(val, MODE_SELECT_REGISTER, SNOOP);
 541
 542    if (multi_mode > 1) {
 543        qemu_log_mask(LOG_GUEST_ERROR, "Attempting to configure several modes "
 544                     "simultaneously. One mode will be selected according to "
 545                     "their priority: LBACK > SLEEP > SNOOP.\n ");
 546    }
 547
 548    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
 549        /* We are in configuration mode, any mode can be selected. */
 550        s->regs[R_MODE_SELECT_REGISTER] = val;
 551    } else {
 552        bool sleep_mode_bit = FIELD_EX32(val, MODE_SELECT_REGISTER, SLEEP);
 553
 554        ARRAY_FIELD_DP32(s->regs, MODE_SELECT_REGISTER, SLEEP, sleep_mode_bit);
 555
 556        if (FIELD_EX32(val, MODE_SELECT_REGISTER, LBACK)) {
 557            qemu_log_mask(LOG_GUEST_ERROR, "Attempting to set LBACK mode "
 558                          "without setting CEN bit as 0\n");
 559        } else if (FIELD_EX32(val, MODE_SELECT_REGISTER, SNOOP)) {
 560            qemu_log_mask(LOG_GUEST_ERROR, "Attempting to set SNOOP mode "
 561                              "without setting CEN bit as 0\n");
 562        }
 563        update_status_register_mode_bits(s);
 564    }
 565    return s->regs[R_MODE_SELECT_REGISTER];
 566}
 567
 568static uint64_t can_brpr_pre_write(RegisterInfo  *reg, uint64_t val64)
 569{
 570    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
 571    uint32_t val = val64;
 572
 573    /* Only allow writes when in config mode. */
 574    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) {
 575        val = s->regs[R_ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER];
 576    }
 577
 578    return val;
 579}
 580
 581static uint64_t can_btr_pre_write(RegisterInfo  *reg, uint64_t val64)
 582{
 583    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
 584    uint32_t val = val64;
 585
 586    /* Only allow writes when in config mode. */
 587    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) {
 588        val = s->regs[R_ARBITRATION_PHASE_BIT_TIMING_REGISTER];
 589    }
 590
 591    return val;
 592}
 593
 594static uint64_t can_tcr_pre_write(RegisterInfo  *reg, uint64_t val64)
 595{
 596    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
 597    uint32_t val = val64;
 598
 599    if (FIELD_EX32(val, TIMESTAMP_REGISTER, CTS)) {
 600        s->rx_time_stamp = 0;
 601    }
 602
 603    return 0;
 604}
 605
 606static void update_rx_fifo(XlnxZynqMPCAN *s, const qemu_can_frame *frame)
 607{
 608    uint32_t filter_pass = 0;
 609
 610    /* If no filter is enabled. Message will be stored in FIFO. */
 611    if (!((ARRAY_FIELD_EX32(s->regs, AFR, UAF1)) |
 612       (ARRAY_FIELD_EX32(s->regs, AFR, UAF2)) |
 613       (ARRAY_FIELD_EX32(s->regs, AFR, UAF3)) |
 614       (ARRAY_FIELD_EX32(s->regs, AFR, UAF4)))) {
 615        filter_pass = 1;
 616    }
 617
 618    /*
 619     * Messages that pass any of the acceptance filters will be stored in
 620     * the RX FIFO.
 621    */
 622    if (ARRAY_FIELD_EX32(s->regs, AFR, UAF1)) {
 623        uint32_t id_masked = s->regs[R_AFMR1] & frame->can_id;
 624        uint32_t filter_id_masked = s->regs[R_AFMR1] & s->regs[R_AFIR1];
 625
 626        if (filter_id_masked == id_masked) {
 627            filter_pass = 1;
 628        }
 629    }
 630
 631    if (ARRAY_FIELD_EX32(s->regs, AFR, UAF2)) {
 632        uint32_t id_masked = s->regs[R_AFMR2] & frame->can_id;
 633        uint32_t filter_id_masked = s->regs[R_AFMR2] & s->regs[R_AFIR2];
 634
 635        if (filter_id_masked == id_masked) {
 636            filter_pass = 1;
 637        }
 638    }
 639
 640    if (ARRAY_FIELD_EX32(s->regs, AFR, UAF3)) {
 641        uint32_t id_masked = s->regs[R_AFMR3] & frame->can_id;
 642        uint32_t filter_id_masked = s->regs[R_AFMR3] & s->regs[R_AFIR3];
 643
 644        if (filter_id_masked == id_masked) {
 645            filter_pass = 1;
 646        }
 647    }
 648
 649    if (ARRAY_FIELD_EX32(s->regs, AFR, UAF4)) {
 650        uint32_t id_masked = s->regs[R_AFMR4] & frame->can_id;
 651        uint32_t filter_id_masked = s->regs[R_AFMR4] & s->regs[R_AFIR4];
 652
 653        if (filter_id_masked == id_masked) {
 654            filter_pass = 1;
 655        }
 656    }
 657
 658    /* Store the message in fifo if it passed through any of the filters. */
 659    if (filter_pass && frame->can_dlc <= MAX_DLC) {
 660
 661        if (fifo_is_full(&s->rx_fifo)) {
 662            DB_PRINT("RX FIFO is full.\n");
 663
 664            ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOFLW, 1);
 665        } else {
 666            s->rx_time_stamp += 1;
 667
 668            fifo_push32(&s->rx_fifo, frame->can_id);
 669
 670            fifo_push32(&s->rx_fifo, (deposit32(0, R_RXFIFO_DLC_DLC_SHIFT,
 671                                                R_RXFIFO_DLC_DLC_LENGTH,
 672                                                frame->can_dlc) |
 673                                      deposit32(0, R_RXFIFO_DLC_RXT_SHIFT,
 674                                                R_RXFIFO_DLC_RXT_LENGTH,
 675                                                s->rx_time_stamp)));
 676
 677            /* First 32 bit of the data. */
 678            fifo_push32(&s->rx_fifo, (deposit32(0, R_TXFIFO_DATA1_DB3_SHIFT,
 679                                        R_TXFIFO_DATA1_DB3_LENGTH,
 680                                        frame->data[0]) |
 681                                      deposit32(0, R_TXFIFO_DATA1_DB2_SHIFT,
 682                                        R_TXFIFO_DATA1_DB2_LENGTH,
 683                                        frame->data[1]) |
 684                                      deposit32(0, R_TXFIFO_DATA1_DB1_SHIFT,
 685                                        R_TXFIFO_DATA1_DB1_LENGTH,
 686                                        frame->data[2]) |
 687                                      deposit32(0, R_TXFIFO_DATA1_DB0_SHIFT,
 688                                        R_TXFIFO_DATA1_DB0_LENGTH,
 689                                        frame->data[3])));
 690            /* Last 32 bit of the data. */
 691            fifo_push32(&s->rx_fifo, (deposit32(0, R_TXFIFO_DATA2_DB7_SHIFT,
 692                                         R_TXFIFO_DATA2_DB7_LENGTH,
 693                                         frame->data[4]) |
 694                                      deposit32(0, R_TXFIFO_DATA2_DB6_SHIFT,
 695                                         R_TXFIFO_DATA2_DB6_LENGTH,
 696                                         frame->data[5]) |
 697                                      deposit32(0, R_TXFIFO_DATA2_DB5_SHIFT,
 698                                         R_TXFIFO_DATA2_DB5_LENGTH,
 699                                         frame->data[6]) |
 700                                      deposit32(0, R_TXFIFO_DATA2_DB4_SHIFT,
 701                                          R_TXFIFO_DATA2_DB4_LENGTH,
 702                                          frame->data[7])));
 703
 704            ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 1);
 705        }
 706
 707        can_update_irq(s);
 708
 709    } else {
 710        DB_PRINT("Message didn't pass through any filter"
 711                  "or dlc is not in range\n");
 712    }
 713}
 714
 715static uint64_t can_rxfifo_pre_read(RegisterInfo *reg, uint64_t val64)
 716{
 717    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
 718    uint32_t r = 0;
 719
 720    if (!fifo_is_empty(&s->rx_fifo)) {
 721        r = fifo_pop32(&s->rx_fifo);
 722    } else {
 723        DB_PRINT("No message in RXFIFO\n");
 724
 725        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXUFLW, 1);
 726    }
 727
 728    can_update_irq(s);
 729    return r;
 730}
 731
 732static void can_filter_enable_post_write(RegisterInfo *reg, uint64_t val64)
 733{
 734    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
 735
 736    if (ARRAY_FIELD_EX32(s->regs, AFR, UAF1) &&
 737        ARRAY_FIELD_EX32(s->regs, AFR, UAF2) &&
 738        ARRAY_FIELD_EX32(s->regs, AFR, UAF3) &&
 739        ARRAY_FIELD_EX32(s->regs, AFR, UAF4)) {
 740
 741        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, ACFBSY, 1);
 742
 743    } else {
 744        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, ACFBSY, 0);
 745    }
 746}
 747
 748static uint64_t can_filter_mask_pre_write(RegisterInfo *reg, uint64_t val64)
 749{
 750    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
 751    uint32_t reg_idx = (reg->access->addr) / 4;
 752    uint32_t val = val64;
 753    uint32_t filter_number = (reg_idx - R_AFMR1) / 2;
 754
 755    /* modify an acceptance filter, the corresponding UAF bit should be '0.' */
 756    if (!(s->regs[R_AFR] & (1 << filter_number))) {
 757        s->regs[reg_idx] = val;
 758    } else {
 759        DB_PRINT("Acceptance filter %d mask is not set as it's corresponding "
 760                 "UAF bit is not set to 0\n", filter_number + 1);
 761    }
 762
 763    return s->regs[reg_idx];
 764}
 765
 766static uint64_t can_filter_id_pre_write(RegisterInfo *reg, uint64_t val64)
 767{
 768    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
 769    uint32_t reg_idx = (reg->access->addr) / 4;
 770    uint32_t val = val64;
 771    uint32_t filter_number = (reg_idx - R_AFIR1) / 2;
 772
 773    if (!(s->regs[R_AFR] & (1 << filter_number))) {
 774        s->regs[reg_idx] = val;
 775    } else {
 776        DB_PRINT("Acceptance filter %d id is not set as it's corresponding "
 777                 "UAF bit is not set to 0\n", filter_number + 1);
 778    }
 779
 780    return s->regs[reg_idx];
 781}
 782
 783static void can_tx_post_write(RegisterInfo *reg, uint64_t val64)
 784{
 785    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(reg->opaque);
 786    uint32_t val = val64;
 787
 788    bool is_txhpb = reg->access->addr > A_TXFIFO_DATA2;
 789
 790    bool initiate_transfer = (reg->access->addr == A_TXFIFO_DATA2) ||
 791                             (reg->access->addr == A_TXHPB_DATA2);
 792
 793    Fifo *f = is_txhpb ? &s->txhpb_fifo : &s->tx_fifo;
 794
 795    DB_PRINT("TX FIFO write for CAN%d\n", s->cfg.ctrl_idx);
 796
 797    if (!fifo_is_full(f)) {
 798        fifo_push32(f, val);
 799    } else {
 800        DB_PRINT("TX FIFO is full.\n");
 801    }
 802
 803    /* Initiate the message send if TX register is written. */
 804    if (initiate_transfer &&
 805            ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) {
 806        transfer_fifo(s, f);
 807    }
 808
 809    can_update_irq(s);
 810}
 811
 812static const RegisterAccessInfo can_regs_info[] = {
 813    {   .name = "SOFTWARE_RESET_REGISTER",
 814        .addr = A_SOFTWARE_RESET_REGISTER,
 815        .rsvd = 0xfffffffc,
 816        .pre_write = can_srr_pre_write,
 817    },{ .name = "MODE_SELECT_REGISTER",
 818        .addr = A_MODE_SELECT_REGISTER,
 819        .rsvd = 0xfffffff8,
 820        .pre_write = can_msr_pre_write,
 821    },{ .name = "ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER",
 822        .addr = A_ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER,
 823        .rsvd = 0xffffff00,
 824        .pre_write = can_brpr_pre_write,
 825    },{ .name = "ARBITRATION_PHASE_BIT_TIMING_REGISTER",
 826        .addr = A_ARBITRATION_PHASE_BIT_TIMING_REGISTER,
 827        .rsvd = 0xfffffe00,
 828        .pre_write = can_btr_pre_write,
 829    },{ .name = "ERROR_COUNTER_REGISTER",
 830        .addr = A_ERROR_COUNTER_REGISTER,
 831        .rsvd = 0xffff0000,
 832        .ro = 0xffffffff,
 833    },{ .name = "ERROR_STATUS_REGISTER",
 834        .addr = A_ERROR_STATUS_REGISTER,
 835        .rsvd = 0xffffffe0,
 836        .w1c = 0x1f,
 837    },{ .name = "STATUS_REGISTER",  .addr = A_STATUS_REGISTER,
 838        .reset = 0x1,
 839        .rsvd = 0xffffe000,
 840        .ro = 0x1fff,
 841    },{ .name = "INTERRUPT_STATUS_REGISTER",
 842        .addr = A_INTERRUPT_STATUS_REGISTER,
 843        .reset = 0x6000,
 844        .rsvd = 0xffff8000,
 845        .ro = 0x7fff,
 846    },{ .name = "INTERRUPT_ENABLE_REGISTER",
 847        .addr = A_INTERRUPT_ENABLE_REGISTER,
 848        .rsvd = 0xffff8000,
 849        .post_write = can_ier_post_write,
 850    },{ .name = "INTERRUPT_CLEAR_REGISTER",
 851        .addr = A_INTERRUPT_CLEAR_REGISTER,
 852        .rsvd = 0xffff8000,
 853        .pre_write = can_icr_pre_write,
 854    },{ .name = "TIMESTAMP_REGISTER",
 855        .addr = A_TIMESTAMP_REGISTER,
 856        .rsvd = 0xfffffffe,
 857        .pre_write = can_tcr_pre_write,
 858    },{ .name = "WIR",  .addr = A_WIR,
 859        .reset = 0x3f3f,
 860        .rsvd = 0xffff0000,
 861    },{ .name = "TXFIFO_ID",  .addr = A_TXFIFO_ID,
 862        .post_write = can_tx_post_write,
 863    },{ .name = "TXFIFO_DLC",  .addr = A_TXFIFO_DLC,
 864        .rsvd = 0xfffffff,
 865        .post_write = can_tx_post_write,
 866    },{ .name = "TXFIFO_DATA1",  .addr = A_TXFIFO_DATA1,
 867        .post_write = can_tx_post_write,
 868    },{ .name = "TXFIFO_DATA2",  .addr = A_TXFIFO_DATA2,
 869        .post_write = can_tx_post_write,
 870    },{ .name = "TXHPB_ID",  .addr = A_TXHPB_ID,
 871        .post_write = can_tx_post_write,
 872    },{ .name = "TXHPB_DLC",  .addr = A_TXHPB_DLC,
 873        .rsvd = 0xfffffff,
 874        .post_write = can_tx_post_write,
 875    },{ .name = "TXHPB_DATA1",  .addr = A_TXHPB_DATA1,
 876        .post_write = can_tx_post_write,
 877    },{ .name = "TXHPB_DATA2",  .addr = A_TXHPB_DATA2,
 878        .post_write = can_tx_post_write,
 879    },{ .name = "RXFIFO_ID",  .addr = A_RXFIFO_ID,
 880        .ro = 0xffffffff,
 881        .post_read = can_rxfifo_pre_read,
 882    },{ .name = "RXFIFO_DLC",  .addr = A_RXFIFO_DLC,
 883        .rsvd = 0xfff0000,
 884        .post_read = can_rxfifo_pre_read,
 885    },{ .name = "RXFIFO_DATA1",  .addr = A_RXFIFO_DATA1,
 886        .post_read = can_rxfifo_pre_read,
 887    },{ .name = "RXFIFO_DATA2",  .addr = A_RXFIFO_DATA2,
 888        .post_read = can_rxfifo_pre_read,
 889    },{ .name = "AFR",  .addr = A_AFR,
 890        .rsvd = 0xfffffff0,
 891        .post_write = can_filter_enable_post_write,
 892    },{ .name = "AFMR1",  .addr = A_AFMR1,
 893        .pre_write = can_filter_mask_pre_write,
 894    },{ .name = "AFIR1",  .addr = A_AFIR1,
 895        .pre_write = can_filter_id_pre_write,
 896    },{ .name = "AFMR2",  .addr = A_AFMR2,
 897        .pre_write = can_filter_mask_pre_write,
 898    },{ .name = "AFIR2",  .addr = A_AFIR2,
 899        .pre_write = can_filter_id_pre_write,
 900    },{ .name = "AFMR3",  .addr = A_AFMR3,
 901        .pre_write = can_filter_mask_pre_write,
 902    },{ .name = "AFIR3",  .addr = A_AFIR3,
 903        .pre_write = can_filter_id_pre_write,
 904    },{ .name = "AFMR4",  .addr = A_AFMR4,
 905        .pre_write = can_filter_mask_pre_write,
 906    },{ .name = "AFIR4",  .addr = A_AFIR4,
 907        .pre_write = can_filter_id_pre_write,
 908    }
 909};
 910
 911static const MemoryRegionOps can_ops = {
 912    .read = register_read_memory,
 913    .write = register_write_memory,
 914    .endianness = DEVICE_LITTLE_ENDIAN,
 915    .valid = {
 916        .min_access_size = 4,
 917        .max_access_size = 4,
 918    },
 919};
 920
 921static void xlnx_zynqmp_can_reset(DeviceState *dev)
 922{
 923    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(dev);
 924    unsigned int i;
 925
 926    for (i = 0; i < ARRAY_SIZE(s->reg_info); ++i) {
 927        register_reset(&s->reg_info[i]);
 928    }
 929
 930    /*
 931     * Reset FIFOs when CAN model is reset. This will clear the fifo writes
 932     * done by post_write which gets called from register_reset function,
 933     * post_write handle will not be able to trigger tx because CAN will be
 934     * disabled when software_reset_register is cleared first.
 935     */
 936    fifo_reset(&s->rx_fifo);
 937    fifo_reset(&s->tx_fifo);
 938    fifo_reset(&s->txhpb_fifo);
 939}
 940
 941static bool xlnx_zynqmp_can_can_receive(CanBusClientState *client)
 942{
 943    XlnxZynqMPCAN *s = container_of(client, XlnxZynqMPCAN, bus_client);
 944
 945    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, SRST)) {
 946        DB_PRINT("XlnxZynqMPCAN%d Controller is reset\n", s->cfg.ctrl_idx);
 947        return 0;
 948    } else if ((ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) == 0) {
 949        DB_PRINT("XlnxZynqMPCAN%d is disabled. Messages will be discarded\n",
 950                s->cfg.ctrl_idx);
 951        return 0;
 952    } else {
 953        return 1;
 954    }
 955}
 956
 957static ssize_t xlnx_zynqmp_can_receive(CanBusClientState *client,
 958                               const qemu_can_frame *buf, size_t buf_size) {
 959    XlnxZynqMPCAN *s = container_of(client, XlnxZynqMPCAN, bus_client);
 960    const qemu_can_frame *frame = buf;
 961
 962    DB_PRINT("Incoming data for CAN%d\n", s->cfg.ctrl_idx);
 963
 964    if (buf_size <= 0) {
 965        DB_PRINT("junk data received on XlnxZynqMPCAN bus\n");
 966        return 0;
 967    }
 968    if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, LBACK)) {
 969        /*
 970         * XlnxZynqMPCAN will not participate in normal bus communication and
 971         * does not receive any messages transmitted by other CAN nodes.
 972         */
 973        DB_PRINT("XlnxZynqMPCAN is in loopback mode."
 974                " It will not receive data.\n");
 975
 976    } else if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SNOOP)) {
 977        /* Snoop Mode: Just keep the data. no response back. */
 978        update_rx_fifo(s, frame);
 979    } else if ((ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP))) {
 980        /*
 981         * XlnxZynqMPCAN is in sleep mode. Any data on bus will bring it to wake
 982         * up state.
 983         */
 984        can_exit_sleep_mode(s);
 985        update_rx_fifo(s, frame);
 986    } else if ((ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP)) == 0) {
 987        update_rx_fifo(s, frame);
 988    } else {
 989        DB_PRINT("Can't receive data as XlnxZynqMPCAN is not set correctly.\n");
 990    }
 991
 992    return 1;
 993}
 994
 995static CanBusClientInfo can_xilinx_bus_client_info = {
 996    .can_receive = xlnx_zynqmp_can_can_receive,
 997    .receive = xlnx_zynqmp_can_receive,
 998};
 999
1000static int xlnx_zynqmp_can_connect_to_bus(XlnxZynqMPCAN *s, CanBusState *bus)
1001{
1002    s->bus_client.info = &can_xilinx_bus_client_info;
1003
1004    if (can_bus_insert_client(bus, &s->bus_client) < 0) {
1005        return -1;
1006    }
1007    return 0;
1008}
1009
1010static void xlnx_zynqmp_can_realize(DeviceState *dev, Error **errp)
1011{
1012    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(dev);
1013
1014    if (s->cfg.ctrl_idx > MAX_CAN_CTRLS) {
1015        error_setg(errp, "ctrl-idx: %d exceeds max XlnxZynqMPCAN controller "
1016                    "index", s->cfg.ctrl_idx);
1017        return;
1018    }
1019
1020    if (s->canbus[s->cfg.ctrl_idx]) {
1021        if (xlnx_zynqmp_can_connect_to_bus(s, s->canbus[s->cfg.ctrl_idx]) < 0) {
1022            error_setg(errp, "xlnx_zynqmp_can_connect_to_bus failed");
1023        }
1024
1025    } else {
1026        /* If no bus is set. */
1027        DB_PRINT("Canbus%d property is not set for xlnxCAN%d\n",
1028                    s->cfg.ctrl_idx, s->cfg.ctrl_idx);
1029    }
1030
1031    /* Create RX FIFO, TXFIFO, TXHPB storage. */
1032    fifo_create32(&s->rx_fifo, RXFIFO_SIZE);
1033    fifo_create32(&s->tx_fifo, RXFIFO_SIZE);
1034    fifo_create32(&s->txhpb_fifo, CAN_FRAME_SIZE);
1035}
1036
1037static void xlnx_zynqmp_can_init(Object *obj)
1038{
1039    XlnxZynqMPCAN *s = XLNX_ZYNQMP_CAN(obj);
1040    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1041
1042    RegisterInfoArray *reg_array;
1043
1044    memory_region_init(&s->iomem, obj, TYPE_XLNX_ZYNQMP_CAN,
1045                        XLNX_ZYNQMP_CAN_R_MAX * 4);
1046    reg_array = register_init_block32(DEVICE(obj), can_regs_info,
1047                               ARRAY_SIZE(can_regs_info),
1048                               s->reg_info, s->regs,
1049                               &can_ops,
1050                               XLNX_ZYNQMP_CAN_ERR_DEBUG,
1051                               XLNX_ZYNQMP_CAN_R_MAX * 4);
1052
1053    memory_region_add_subregion(&s->iomem, 0x00, &reg_array->mem);
1054    sysbus_init_mmio(sbd, &s->iomem);
1055    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
1056
1057    object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
1058                             (Object **)&s->canbus[0],
1059                             qdev_prop_allow_set_link_before_realize,
1060                             0);
1061
1062    object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
1063                             (Object **)&s->canbus[1],
1064                             qdev_prop_allow_set_link_before_realize,
1065                             0);
1066}
1067
1068static const VMStateDescription vmstate_can = {
1069    .name = TYPE_XLNX_ZYNQMP_CAN,
1070    .version_id = 1,
1071    .minimum_version_id = 1,
1072    .fields = (VMStateField[]) {
1073        VMSTATE_FIFO(rx_fifo, XlnxZynqMPCAN),
1074        VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPCAN, XLNX_ZYNQMP_CAN_R_MAX),
1075        VMSTATE_UINT8(cfg.ctrl_idx, XlnxZynqMPCAN),
1076        VMSTATE_END_OF_LIST(),
1077    }
1078};
1079
1080static Property xlnx_zynqmp_can_properties[] = {
1081    DEFINE_PROP_UINT8("ctrl-idx", XlnxZynqMPCAN, cfg.ctrl_idx, 0),
1082    DEFINE_PROP_END_OF_LIST(),
1083};
1084
1085static void xlnx_zynqmp_can_class_init(ObjectClass *klass, void *data)
1086{
1087    DeviceClass *dc = DEVICE_CLASS(klass);
1088    dc->reset = xlnx_zynqmp_can_reset;
1089    dc->realize = xlnx_zynqmp_can_realize;
1090    device_class_set_props(dc, xlnx_zynqmp_can_properties);
1091    dc->vmsd = &vmstate_can;
1092}
1093
1094static const TypeInfo can_info = {
1095    .name          = TYPE_XLNX_ZYNQMP_CAN,
1096    .parent        = TYPE_SYS_BUS_DEVICE,
1097    .instance_size = sizeof(XlnxZynqMPCAN),
1098    .class_init    = xlnx_zynqmp_can_class_init,
1099    .instance_init = xlnx_zynqmp_can_init,
1100};
1101
1102static void can_register_types(void)
1103{
1104    type_register_static(&can_info);
1105}
1106
1107type_init(can_register_types)
1108