diff --git a/hw/net/can/xlnx-versal-canfd.c b/hw/net/can/xlnx-versal-canfd.c index 04f9a6d57d..5735639b85 100644 --- a/hw/net/can/xlnx-versal-canfd.c +++ b/hw/net/can/xlnx-versal-canfd.c @@ -1426,46 +1426,6 @@ static void filter_reg_write(XlnxVersalCANFDState *s, hwaddr addr, } } -static uint64_t filter_mask(RegisterInfo *reg, uint64_t val64) -{ - XlnxVersalCANFDState *s = XILINX_CANFD(reg->opaque); - uint32_t reg_idx = (reg->access->addr) / 4; - uint32_t val = val64; - uint32_t filter_offset = (reg_idx - R_AFMR_REGISTER) / 2; - - if (!(s->regs[R_ACCEPTANCE_FILTER_CONTROL_REGISTER] & - (1 << filter_offset))) { - s->regs[reg_idx] = val; - } else { - g_autofree char *path = object_get_canonical_path(OBJECT(s)); - - qemu_log_mask(LOG_GUEST_ERROR, "%s: Acceptance filter %d not enabled\n", - path, filter_offset + 1); - } - - return s->regs[reg_idx]; -} - -static uint64_t filter_id(RegisterInfo *reg, uint64_t val64) -{ - XlnxVersalCANFDState *s = XILINX_CANFD(reg->opaque); - hwaddr reg_idx = (reg->access->addr) / 4; - uint32_t val = val64; - uint32_t filter_offset = (reg_idx - R_AFIR_REGISTER) / 2; - - if (!(s->regs[R_ACCEPTANCE_FILTER_CONTROL_REGISTER] & - (1 << filter_offset))) { - s->regs[reg_idx] = val; - } else { - g_autofree char *path = object_get_canonical_path(OBJECT(s)); - - qemu_log_mask(LOG_GUEST_ERROR, "%s: Acceptance filter %d not enabled\n", - path, filter_offset + 1); - } - - return s->regs[reg_idx]; -} - static uint64_t canfd_tx_fifo_status_prew(RegisterInfo *reg, uint64_t val64) { XlnxVersalCANFDState *s = XILINX_CANFD(reg->opaque); @@ -1591,125 +1551,6 @@ static uint64_t canfd_write_check_prew(RegisterInfo *reg, uint64_t val64) return 0; } -static const RegisterAccessInfo canfd_tx_regs[] = { - { .name = "TB_ID_REGISTER", .addr = A_TB_ID_REGISTER, - },{ .name = "TB0_DLC_REGISTER", .addr = A_TB0_DLC_REGISTER, - },{ .name = "TB_DW0_REGISTER", .addr = A_TB_DW0_REGISTER, - },{ .name = "TB_DW1_REGISTER", .addr = A_TB_DW1_REGISTER, - },{ .name = "TB_DW2_REGISTER", .addr = A_TB_DW2_REGISTER, - },{ .name = "TB_DW3_REGISTER", .addr = A_TB_DW3_REGISTER, - },{ .name = "TB_DW4_REGISTER", .addr = A_TB_DW4_REGISTER, - },{ .name = "TB_DW5_REGISTER", .addr = A_TB_DW5_REGISTER, - },{ .name = "TB_DW6_REGISTER", .addr = A_TB_DW6_REGISTER, - },{ .name = "TB_DW7_REGISTER", .addr = A_TB_DW7_REGISTER, - },{ .name = "TB_DW8_REGISTER", .addr = A_TB_DW8_REGISTER, - },{ .name = "TB_DW9_REGISTER", .addr = A_TB_DW9_REGISTER, - },{ .name = "TB_DW10_REGISTER", .addr = A_TB_DW10_REGISTER, - },{ .name = "TB_DW11_REGISTER", .addr = A_TB_DW11_REGISTER, - },{ .name = "TB_DW12_REGISTER", .addr = A_TB_DW12_REGISTER, - },{ .name = "TB_DW13_REGISTER", .addr = A_TB_DW13_REGISTER, - },{ .name = "TB_DW14_REGISTER", .addr = A_TB_DW14_REGISTER, - },{ .name = "TB_DW15_REGISTER", .addr = A_TB_DW15_REGISTER, - } -}; - -static const RegisterAccessInfo canfd_rx0_regs[] = { - { .name = "RB_ID_REGISTER", .addr = A_RB_ID_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DLC_REGISTER", .addr = A_RB_DLC_REGISTER, - .ro = 0xfe1fffff, - },{ .name = "RB_DW0_REGISTER", .addr = A_RB_DW0_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW1_REGISTER", .addr = A_RB_DW1_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW2_REGISTER", .addr = A_RB_DW2_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW3_REGISTER", .addr = A_RB_DW3_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW4_REGISTER", .addr = A_RB_DW4_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW5_REGISTER", .addr = A_RB_DW5_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW6_REGISTER", .addr = A_RB_DW6_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW7_REGISTER", .addr = A_RB_DW7_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW8_REGISTER", .addr = A_RB_DW8_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW9_REGISTER", .addr = A_RB_DW9_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW10_REGISTER", .addr = A_RB_DW10_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW11_REGISTER", .addr = A_RB_DW11_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW12_REGISTER", .addr = A_RB_DW12_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW13_REGISTER", .addr = A_RB_DW13_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW14_REGISTER", .addr = A_RB_DW14_REGISTER, - .ro = 0xffffffff, - },{ .name = "RB_DW15_REGISTER", .addr = A_RB_DW15_REGISTER, - .ro = 0xffffffff, - } -}; - -static const RegisterAccessInfo canfd_rx1_regs[] = { - { .name = "RB_ID_REGISTER_1", .addr = A_RB_ID_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DLC_REGISTER_1", .addr = A_RB_DLC_REGISTER_1, - .ro = 0xfe1fffff, - },{ .name = "RB0_DW0_REGISTER_1", .addr = A_RB0_DW0_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW1_REGISTER_1", .addr = A_RB_DW1_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW2_REGISTER_1", .addr = A_RB_DW2_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW3_REGISTER_1", .addr = A_RB_DW3_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW4_REGISTER_1", .addr = A_RB_DW4_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW5_REGISTER_1", .addr = A_RB_DW5_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW6_REGISTER_1", .addr = A_RB_DW6_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW7_REGISTER_1", .addr = A_RB_DW7_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW8_REGISTER_1", .addr = A_RB_DW8_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW9_REGISTER_1", .addr = A_RB_DW9_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW10_REGISTER_1", .addr = A_RB_DW10_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW11_REGISTER_1", .addr = A_RB_DW11_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW12_REGISTER_1", .addr = A_RB_DW12_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW13_REGISTER_1", .addr = A_RB_DW13_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW14_REGISTER_1", .addr = A_RB_DW14_REGISTER_1, - .ro = 0xffffffff, - },{ .name = "RB_DW15_REGISTER_1", .addr = A_RB_DW15_REGISTER_1, - .ro = 0xffffffff, - } -}; - -/* Acceptance filter registers. */ -static const RegisterAccessInfo canfd_af_regs[] = { - { .name = "AFMR_REGISTER", .addr = A_AFMR_REGISTER, - .pre_write = filter_mask, - },{ .name = "AFIR_REGISTER", .addr = A_AFIR_REGISTER, - .pre_write = filter_id, - } -}; - -static const RegisterAccessInfo canfd_txe_regs[] = { - { .name = "TXE_FIFO_TB_ID_REGISTER", .addr = A_TXE_FIFO_TB_ID_REGISTER, - .ro = 0xffffffff, - },{ .name = "TXE_FIFO_TB_DLC_REGISTER", .addr = A_TXE_FIFO_TB_DLC_REGISTER, - .ro = 0xffffffff, - } -}; - static const RegisterAccessInfo canfd_regs_info[] = { { .name = "SOFTWARE_RESET_REGISTER", .addr = A_SOFTWARE_RESET_REGISTER, .pre_write = canfd_srr_pre_write, @@ -1915,6 +1756,16 @@ static const MemoryRegionOps canfd_ops = { }, }; +static const MemoryRegionOps canfd_regs_ops = { + .read = register_read_memory, + .write = register_write_memory, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + static void canfd_reset(DeviceState *dev) { XlnxVersalCANFDState *s = XILINX_CANFD(dev); @@ -1994,140 +1845,16 @@ static int xlnx_canfd_connect_to_bus(XlnxVersalCANFDState *s, return can_bus_insert_client(bus, &s->bus_client); } -#define NUM_REG_PER_AF ARRAY_SIZE(canfd_af_regs) -#define NUM_AF 32 -#define NUM_REG_PER_TXE ARRAY_SIZE(canfd_txe_regs) -#define NUM_TXE 32 - -static int canfd_populate_regarray(XlnxVersalCANFDState *s, - RegisterInfoArray *r_array, int pos, - const RegisterAccessInfo *rae, - int num_rae) -{ - int i; - - for (i = 0; i < num_rae; i++) { - int index = rae[i].addr / 4; - RegisterInfo *r = &s->reg_info[index]; - - *r = (RegisterInfo) { - .data = &s->regs[index], - .data_size = sizeof(uint32_t), - .access = &rae[i], - .opaque = OBJECT(s), - }; - - r_array->r[i + pos] = r; - } - return i + pos; -} - -static void canfd_create_rai(RegisterAccessInfo *rai_array, - const RegisterAccessInfo *canfd_regs, - int template_rai_array_sz, - int num_template_to_copy) -{ - int i; - int reg_num; - - for (reg_num = 0; reg_num < num_template_to_copy; reg_num++) { - int pos = reg_num * template_rai_array_sz; - - memcpy(rai_array + pos, canfd_regs, - template_rai_array_sz * sizeof(RegisterAccessInfo)); - - for (i = 0; i < template_rai_array_sz; i++) { - const char *name = canfd_regs[i].name; - uint64_t addr = canfd_regs[i].addr; - rai_array[i + pos].name = g_strdup_printf("%s%d", name, reg_num); - rai_array[i + pos].addr = addr + pos * 4; - } - } -} - -static RegisterInfoArray *canfd_create_regarray(XlnxVersalCANFDState *s) -{ - const char *device_prefix = object_get_typename(OBJECT(s)); - uint64_t memory_size = XLNX_VERSAL_CANFD_R_MAX * 4; - int num_regs; - int pos = 0; - RegisterInfoArray *r_array; - - num_regs = ARRAY_SIZE(canfd_regs_info) + - s->cfg.tx_fifo * NUM_REGS_PER_MSG_SPACE + - s->cfg.rx0_fifo * NUM_REGS_PER_MSG_SPACE + - NUM_AF * NUM_REG_PER_AF + - NUM_TXE * NUM_REG_PER_TXE; - - s->tx_regs = g_new0(RegisterAccessInfo, - s->cfg.tx_fifo * ARRAY_SIZE(canfd_tx_regs)); - - canfd_create_rai(s->tx_regs, canfd_tx_regs, - ARRAY_SIZE(canfd_tx_regs), s->cfg.tx_fifo); - - s->rx0_regs = g_new0(RegisterAccessInfo, - s->cfg.rx0_fifo * ARRAY_SIZE(canfd_rx0_regs)); - - canfd_create_rai(s->rx0_regs, canfd_rx0_regs, - ARRAY_SIZE(canfd_rx0_regs), s->cfg.rx0_fifo); - - s->af_regs = g_new0(RegisterAccessInfo, - NUM_AF * ARRAY_SIZE(canfd_af_regs)); - - canfd_create_rai(s->af_regs, canfd_af_regs, - ARRAY_SIZE(canfd_af_regs), NUM_AF); - - s->txe_regs = g_new0(RegisterAccessInfo, - NUM_TXE * ARRAY_SIZE(canfd_txe_regs)); - - canfd_create_rai(s->txe_regs, canfd_txe_regs, - ARRAY_SIZE(canfd_txe_regs), NUM_TXE); - - if (s->cfg.enable_rx_fifo1) { - num_regs += s->cfg.rx1_fifo * NUM_REGS_PER_MSG_SPACE; - - s->rx1_regs = g_new0(RegisterAccessInfo, - s->cfg.rx1_fifo * ARRAY_SIZE(canfd_rx1_regs)); - - canfd_create_rai(s->rx1_regs, canfd_rx1_regs, - ARRAY_SIZE(canfd_rx1_regs), s->cfg.rx1_fifo); - } - - r_array = g_new0(RegisterInfoArray, 1); - r_array->r = g_new0(RegisterInfo * , num_regs); - r_array->num_elements = num_regs; - r_array->prefix = device_prefix; - - pos = canfd_populate_regarray(s, r_array, pos, - canfd_regs_info, - ARRAY_SIZE(canfd_regs_info)); - pos = canfd_populate_regarray(s, r_array, pos, - s->tx_regs, s->cfg.tx_fifo * - NUM_REGS_PER_MSG_SPACE); - pos = canfd_populate_regarray(s, r_array, pos, - s->rx0_regs, s->cfg.rx0_fifo * - NUM_REGS_PER_MSG_SPACE); - if (s->cfg.enable_rx_fifo1) { - pos = canfd_populate_regarray(s, r_array, pos, - s->rx1_regs, s->cfg.rx1_fifo * - NUM_REGS_PER_MSG_SPACE); - } - pos = canfd_populate_regarray(s, r_array, pos, - s->af_regs, NUM_AF * NUM_REG_PER_AF); - pos = canfd_populate_regarray(s, r_array, pos, - s->txe_regs, NUM_TXE * NUM_REG_PER_TXE); - - memory_region_init_io(&r_array->mem, OBJECT(s), &canfd_ops, r_array, - device_prefix, memory_size); - return r_array; -} - static void canfd_realize(DeviceState *dev, Error **errp) { XlnxVersalCANFDState *s = XILINX_CANFD(dev); RegisterInfoArray *reg_array; - reg_array = canfd_create_regarray(s); + reg_array = register_init_block32(dev, canfd_regs_info, + ARRAY_SIZE(canfd_regs_info), s->reg_info, + s->regs, &canfd_regs_ops, false, + A_RX_FIFO_WATERMARK_REGISTER + + sizeof(uint32_t)); memory_region_add_subregion(&s->iomem, 0x00, ®_array->mem); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq_canfd_int); diff --git a/include/hw/net/xlnx-versal-canfd.h b/include/hw/net/xlnx-versal-canfd.h index ad3104dd13..396f90d6dc 100644 --- a/include/hw/net/xlnx-versal-canfd.h +++ b/include/hw/net/xlnx-versal-canfd.h @@ -54,14 +54,6 @@ typedef struct XlnxVersalCANFDState { qemu_irq irq_addr_err; RegisterInfo reg_info[XLNX_VERSAL_CANFD_R_MAX]; - RegisterAccessInfo *tx_regs; - RegisterAccessInfo *rx0_regs; - RegisterAccessInfo *rx1_regs; - RegisterAccessInfo *af_regs; - RegisterAccessInfo *txe_regs; - RegisterAccessInfo *rx_mailbox_regs; - RegisterAccessInfo *af_mask_regs_mailbox; - uint32_t regs[XLNX_VERSAL_CANFD_R_MAX]; ptimer_state *canfd_timer;