On Wed, Nov 22, 2023 at 08:45:56PM +0100, Francisco Iglesias wrote: > On Sun, Nov 19, 2023 at 11:51:02PM +0100, Philippe Mathieu-Daudé wrote: > > Per > > https://docs.xilinx.com/r/en-US/ug1085-zynq-ultrascale-trm/Message-Format > > > > Message Format > > > > The same message format is used for RXFIFO, TXFIFO, and TXHPB. > > Each message includes four words (16 bytes). Software must read > > and write all four words regardless of the actual number of data > > bytes and valid fields in the message. > > > > There is no mention in this reference manual about what the > > hardware does when not all four words are read. To fix the > > reported underflow behavior, I choose to fill the 4 frame data > > registers when the first register (ID) is accessed, which is how > > I expect hardware would do. > > > > Reported-by: Qiang Liu <cyruscy...@gmail.com> > > Fixes: 98e5d7a2b7 ("hw/net/can: Introduce Xilinx ZynqMP CAN controller") > > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1427 > > Signed-off-by: Philippe Mathieu-Daudé <phi...@linaro.org> > > Reviewed-by: Francisco Iglesias <francisco.igles...@amd.com> Reviewed-by: Vikram Garhwal <vikram.garh...@amd.com>
> > > > --- > > hw/net/can/xlnx-zynqmp-can.c | 17 +++++++++-------- > > 1 file changed, 9 insertions(+), 8 deletions(-) > > > > diff --git a/hw/net/can/xlnx-zynqmp-can.c b/hw/net/can/xlnx-zynqmp-can.c > > index 58938b574e..c63fb4a83c 100644 > > --- a/hw/net/can/xlnx-zynqmp-can.c > > +++ b/hw/net/can/xlnx-zynqmp-can.c > > @@ -777,14 +777,18 @@ static void update_rx_fifo(XlnxZynqMPCANState *s, > > const qemu_can_frame *frame) > > } > > } > > > > -static uint64_t can_rxfifo_pre_read(RegisterInfo *reg, uint64_t val) > > +static uint64_t can_rxfifo_post_read_id(RegisterInfo *reg, uint64_t val) > > { > > XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque); > > + unsigned used = fifo32_num_used(&s->rx_fifo); > > > > - if (!fifo32_is_empty(&s->rx_fifo)) { > > - val = fifo32_pop(&s->rx_fifo); > > - } else { > > + if (used < CAN_FRAME_SIZE) { > > ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXUFLW, 1); > > + } else { > > + val = s->regs[R_RXFIFO_ID] = fifo32_pop(&s->rx_fifo); > > + s->regs[R_RXFIFO_DLC] = fifo32_pop(&s->rx_fifo); > > + s->regs[R_RXFIFO_DATA1] = fifo32_pop(&s->rx_fifo); > > + s->regs[R_RXFIFO_DATA2] = fifo32_pop(&s->rx_fifo); > > } > > > > can_update_irq(s); > > @@ -945,14 +949,11 @@ static const RegisterAccessInfo can_regs_info[] = { > > .post_write = can_tx_post_write, > > },{ .name = "RXFIFO_ID", .addr = A_RXFIFO_ID, > > .ro = 0xffffffff, > > - .post_read = can_rxfifo_pre_read, > > + .post_read = can_rxfifo_post_read_id, > > },{ .name = "RXFIFO_DLC", .addr = A_RXFIFO_DLC, > > .rsvd = 0xfff0000, > > - .post_read = can_rxfifo_pre_read, > > },{ .name = "RXFIFO_DATA1", .addr = A_RXFIFO_DATA1, > > - .post_read = can_rxfifo_pre_read, > > },{ .name = "RXFIFO_DATA2", .addr = A_RXFIFO_DATA2, > > - .post_read = can_rxfifo_pre_read, > > },{ .name = "AFR", .addr = A_AFR, > > .rsvd = 0xfffffff0, > > .post_write = can_filter_enable_post_write, > > -- > > 2.41.0 > >