hw/ssi: ibex_spi: fixup coverity issue

This patch addresses the coverity issues specified in [1],
as suggested, `FIELD_DP32()`/`FIELD_EX32()` macros have been
implemented to clean up the code.

[1] https://www.mail-archive.com/qemu-devel@nongnu.org/msg887713.html

Fixes: Coverity CID 1488107

Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-Id: <20220930033241.206581-2-wilfred.mallawa@opensource.wdc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Wilfred Mallawa 2022-09-30 13:32:42 +10:00 committed by Alistair Francis
parent 838f717b22
commit ff3809ef34
1 changed files with 68 additions and 64 deletions

View File

@ -108,18 +108,22 @@ static inline uint8_t div4_round_up(uint8_t dividend)
static void ibex_spi_rxfifo_reset(IbexSPIHostState *s) static void ibex_spi_rxfifo_reset(IbexSPIHostState *s)
{ {
uint32_t data = s->regs[IBEX_SPI_HOST_STATUS];
/* Empty the RX FIFO and assert RXEMPTY */ /* Empty the RX FIFO and assert RXEMPTY */
fifo8_reset(&s->rx_fifo); fifo8_reset(&s->rx_fifo);
s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXFULL_MASK; data = FIELD_DP32(data, STATUS, RXFULL, 0);
s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXEMPTY_MASK; data = FIELD_DP32(data, STATUS, RXEMPTY, 1);
s->regs[IBEX_SPI_HOST_STATUS] = data;
} }
static void ibex_spi_txfifo_reset(IbexSPIHostState *s) static void ibex_spi_txfifo_reset(IbexSPIHostState *s)
{ {
uint32_t data = s->regs[IBEX_SPI_HOST_STATUS];
/* Empty the TX FIFO and assert TXEMPTY */ /* Empty the TX FIFO and assert TXEMPTY */
fifo8_reset(&s->tx_fifo); fifo8_reset(&s->tx_fifo);
s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXFULL_MASK; data = FIELD_DP32(data, STATUS, TXFULL, 0);
s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_TXEMPTY_MASK; data = FIELD_DP32(data, STATUS, TXEMPTY, 1);
s->regs[IBEX_SPI_HOST_STATUS] = data;
} }
static void ibex_spi_host_reset(DeviceState *dev) static void ibex_spi_host_reset(DeviceState *dev)
@ -162,37 +166,38 @@ static void ibex_spi_host_reset(DeviceState *dev)
*/ */
static void ibex_spi_host_irq(IbexSPIHostState *s) static void ibex_spi_host_irq(IbexSPIHostState *s)
{ {
bool error_en = s->regs[IBEX_SPI_HOST_INTR_ENABLE] uint32_t intr_test_reg = s->regs[IBEX_SPI_HOST_INTR_TEST];
& R_INTR_ENABLE_ERROR_MASK; uint32_t intr_en_reg = s->regs[IBEX_SPI_HOST_INTR_ENABLE];
bool event_en = s->regs[IBEX_SPI_HOST_INTR_ENABLE] uint32_t intr_state_reg = s->regs[IBEX_SPI_HOST_INTR_STATE];
& R_INTR_ENABLE_SPI_EVENT_MASK;
bool err_pending = s->regs[IBEX_SPI_HOST_INTR_STATE] uint32_t err_en_reg = s->regs[IBEX_SPI_HOST_ERROR_ENABLE];
& R_INTR_STATE_ERROR_MASK; uint32_t event_en_reg = s->regs[IBEX_SPI_HOST_EVENT_ENABLE];
bool status_pending = s->regs[IBEX_SPI_HOST_INTR_STATE] uint32_t err_status_reg = s->regs[IBEX_SPI_HOST_ERROR_STATUS];
& R_INTR_STATE_SPI_EVENT_MASK; uint32_t status_reg = s->regs[IBEX_SPI_HOST_STATUS];
bool error_en = FIELD_EX32(intr_en_reg, INTR_ENABLE, ERROR);
bool event_en = FIELD_EX32(intr_en_reg, INTR_ENABLE, SPI_EVENT);
bool err_pending = FIELD_EX32(intr_state_reg, INTR_STATE, ERROR);
bool status_pending = FIELD_EX32(intr_state_reg, INTR_STATE, SPI_EVENT);
int err_irq = 0, event_irq = 0; int err_irq = 0, event_irq = 0;
/* Error IRQ enabled and Error IRQ Cleared */ /* Error IRQ enabled and Error IRQ Cleared */
if (error_en && !err_pending) { if (error_en && !err_pending) {
/* Event enabled, Interrupt Test Error */ /* Event enabled, Interrupt Test Error */
if (s->regs[IBEX_SPI_HOST_INTR_TEST] & R_INTR_TEST_ERROR_MASK) { if (FIELD_EX32(intr_test_reg, INTR_TEST, ERROR)) {
err_irq = 1; err_irq = 1;
} else if ((s->regs[IBEX_SPI_HOST_ERROR_ENABLE] } else if (FIELD_EX32(err_en_reg, ERROR_ENABLE, CMDBUSY) &&
& R_ERROR_ENABLE_CMDBUSY_MASK) && FIELD_EX32(err_status_reg, ERROR_STATUS, CMDBUSY)) {
s->regs[IBEX_SPI_HOST_ERROR_STATUS]
& R_ERROR_STATUS_CMDBUSY_MASK) {
/* Wrote to COMMAND when not READY */ /* Wrote to COMMAND when not READY */
err_irq = 1; err_irq = 1;
} else if ((s->regs[IBEX_SPI_HOST_ERROR_ENABLE] } else if (FIELD_EX32(err_en_reg, ERROR_ENABLE, CMDINVAL) &&
& R_ERROR_ENABLE_CMDINVAL_MASK) && FIELD_EX32(err_status_reg, ERROR_STATUS, CMDINVAL)) {
s->regs[IBEX_SPI_HOST_ERROR_STATUS]
& R_ERROR_STATUS_CMDINVAL_MASK) {
/* Invalid command segment */ /* Invalid command segment */
err_irq = 1; err_irq = 1;
} else if ((s->regs[IBEX_SPI_HOST_ERROR_ENABLE] } else if (FIELD_EX32(err_en_reg, ERROR_ENABLE, CSIDINVAL) &&
& R_ERROR_ENABLE_CSIDINVAL_MASK) && FIELD_EX32(err_status_reg, ERROR_STATUS, CSIDINVAL)) {
s->regs[IBEX_SPI_HOST_ERROR_STATUS]
& R_ERROR_STATUS_CSIDINVAL_MASK) {
/* Invalid value for CSID */ /* Invalid value for CSID */
err_irq = 1; err_irq = 1;
} }
@ -204,22 +209,19 @@ static void ibex_spi_host_irq(IbexSPIHostState *s)
/* Event IRQ Enabled and Event IRQ Cleared */ /* Event IRQ Enabled and Event IRQ Cleared */
if (event_en && !status_pending) { if (event_en && !status_pending) {
if (s->regs[IBEX_SPI_HOST_INTR_TEST] & R_INTR_TEST_SPI_EVENT_MASK) { if (FIELD_EX32(intr_test_reg, INTR_STATE, SPI_EVENT)) {
/* Event enabled, Interrupt Test Event */ /* Event enabled, Interrupt Test Event */
event_irq = 1; event_irq = 1;
} else if ((s->regs[IBEX_SPI_HOST_EVENT_ENABLE] } else if (FIELD_EX32(event_en_reg, EVENT_ENABLE, READY) &&
& R_EVENT_ENABLE_READY_MASK) && FIELD_EX32(status_reg, STATUS, READY)) {
(s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_READY_MASK)) {
/* SPI Host ready for next command */ /* SPI Host ready for next command */
event_irq = 1; event_irq = 1;
} else if ((s->regs[IBEX_SPI_HOST_EVENT_ENABLE] } else if (FIELD_EX32(event_en_reg, EVENT_ENABLE, TXEMPTY) &&
& R_EVENT_ENABLE_TXEMPTY_MASK) && FIELD_EX32(status_reg, STATUS, TXEMPTY)) {
(s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_TXEMPTY_MASK)) {
/* SPI TXEMPTY, TXFIFO drained */ /* SPI TXEMPTY, TXFIFO drained */
event_irq = 1; event_irq = 1;
} else if ((s->regs[IBEX_SPI_HOST_EVENT_ENABLE] } else if (FIELD_EX32(event_en_reg, EVENT_ENABLE, RXFULL) &&
& R_EVENT_ENABLE_RXFULL_MASK) && FIELD_EX32(status_reg, STATUS, RXFULL)) {
(s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_RXFULL_MASK)) {
/* SPI RXFULL, RXFIFO full */ /* SPI RXFULL, RXFIFO full */
event_irq = 1; event_irq = 1;
} }
@ -232,10 +234,11 @@ static void ibex_spi_host_irq(IbexSPIHostState *s)
static void ibex_spi_host_transfer(IbexSPIHostState *s) static void ibex_spi_host_transfer(IbexSPIHostState *s)
{ {
uint32_t rx, tx; uint32_t rx, tx, data;
/* Get num of one byte transfers */ /* Get num of one byte transfers */
uint8_t segment_len = ((s->regs[IBEX_SPI_HOST_COMMAND] & R_COMMAND_LEN_MASK) uint8_t segment_len = FIELD_EX32(s->regs[IBEX_SPI_HOST_COMMAND],
>> R_COMMAND_LEN_SHIFT); COMMAND, LEN);
while (segment_len > 0) { while (segment_len > 0) {
if (fifo8_is_empty(&s->tx_fifo)) { if (fifo8_is_empty(&s->tx_fifo)) {
/* Assert Stall */ /* Assert Stall */
@ -262,22 +265,21 @@ static void ibex_spi_host_transfer(IbexSPIHostState *s)
--segment_len; --segment_len;
} }
data = s->regs[IBEX_SPI_HOST_STATUS];
/* Assert Ready */ /* Assert Ready */
s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_READY_MASK; data = FIELD_DP32(data, STATUS, READY, 1);
/* Set RXQD */ /* Set RXQD */
s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXQD_MASK; data = FIELD_DP32(data, STATUS, RXQD, div4_round_up(segment_len));
s->regs[IBEX_SPI_HOST_STATUS] |= (R_STATUS_RXQD_MASK
& div4_round_up(segment_len));
/* Set TXQD */ /* Set TXQD */
s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXQD_MASK; data = FIELD_DP32(data, STATUS, TXQD, fifo8_num_used(&s->tx_fifo) / 4);
s->regs[IBEX_SPI_HOST_STATUS] |= (fifo8_num_used(&s->tx_fifo) / 4)
& R_STATUS_TXQD_MASK;
/* Clear TXFULL */ /* Clear TXFULL */
s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXFULL_MASK; data = FIELD_DP32(data, STATUS, TXFULL, 0);
/* Assert TXEMPTY and drop remaining bytes that exceed segment_len */
ibex_spi_txfifo_reset(s);
/* Reset RXEMPTY */ /* Reset RXEMPTY */
s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXEMPTY_MASK; data = FIELD_DP32(data, STATUS, RXEMPTY, 0);
/* Update register status */
s->regs[IBEX_SPI_HOST_STATUS] = data;
/* Drop remaining bytes that exceed segment_len */
ibex_spi_txfifo_reset(s);
ibex_spi_host_irq(s); ibex_spi_host_irq(s);
} }
@ -340,7 +342,7 @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
{ {
IbexSPIHostState *s = opaque; IbexSPIHostState *s = opaque;
uint32_t val32 = val64; uint32_t val32 = val64;
uint32_t shift_mask = 0xff; uint32_t shift_mask = 0xff, status = 0;
uint8_t txqd_len; uint8_t txqd_len;
trace_ibex_spi_host_write(addr, size, val64); trace_ibex_spi_host_write(addr, size, val64);
@ -397,21 +399,23 @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
s->regs[addr] = val32; s->regs[addr] = val32;
/* STALL, IP not enabled */ /* STALL, IP not enabled */
if (!(s->regs[IBEX_SPI_HOST_CONTROL] & R_CONTROL_SPIEN_MASK)) { if (!(FIELD_EX32(s->regs[IBEX_SPI_HOST_CONTROL],
CONTROL, SPIEN))) {
return; return;
} }
/* SPI not ready, IRQ Error */ /* SPI not ready, IRQ Error */
if (!(s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_READY_MASK)) { if (!(FIELD_EX32(s->regs[IBEX_SPI_HOST_STATUS],
STATUS, READY))) {
s->regs[IBEX_SPI_HOST_ERROR_STATUS] |= R_ERROR_STATUS_CMDBUSY_MASK; s->regs[IBEX_SPI_HOST_ERROR_STATUS] |= R_ERROR_STATUS_CMDBUSY_MASK;
ibex_spi_host_irq(s); ibex_spi_host_irq(s);
return; return;
} }
/* Assert Not Ready */ /* Assert Not Ready */
s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_READY_MASK; s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_READY_MASK;
if (((val32 & R_COMMAND_DIRECTION_MASK) >> R_COMMAND_DIRECTION_SHIFT) if (FIELD_EX32(val32, COMMAND, DIRECTION) != BIDIRECTIONAL_TRANSFER) {
!= BIDIRECTIONAL_TRANSFER) {
qemu_log_mask(LOG_UNIMP, qemu_log_mask(LOG_UNIMP,
"%s: Rx Only/Tx Only are not supported\n", __func__); "%s: Rx Only/Tx Only are not supported\n", __func__);
} }
@ -452,8 +456,8 @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
return; return;
} }
/* Byte ordering is set by the IP */ /* Byte ordering is set by the IP */
if ((s->regs[IBEX_SPI_HOST_STATUS] & status = s->regs[IBEX_SPI_HOST_STATUS];
R_STATUS_BYTEORDER_MASK) == 0) { if (FIELD_EX32(status, STATUS, BYTEORDER) == 0) {
/* LE: LSB transmitted first (default for ibex processor) */ /* LE: LSB transmitted first (default for ibex processor) */
shift_mask = 0xff << (i * 8); shift_mask = 0xff << (i * 8);
} else { } else {
@ -464,18 +468,18 @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
fifo8_push(&s->tx_fifo, (val32 & shift_mask) >> (i * 8)); fifo8_push(&s->tx_fifo, (val32 & shift_mask) >> (i * 8));
} }
status = s->regs[IBEX_SPI_HOST_STATUS];
/* Reset TXEMPTY */ /* Reset TXEMPTY */
s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXEMPTY_MASK; status = FIELD_DP32(status, STATUS, TXEMPTY, 0);
/* Update TXQD */ /* Update TXQD */
txqd_len = (s->regs[IBEX_SPI_HOST_STATUS] & txqd_len = FIELD_EX32(status, STATUS, TXQD);
R_STATUS_TXQD_MASK) >> R_STATUS_TXQD_SHIFT;
/* Partial bytes (size < 4) are padded, in words. */ /* Partial bytes (size < 4) are padded, in words. */
txqd_len += 1; txqd_len += 1;
s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXQD_MASK; status = FIELD_DP32(status, STATUS, TXQD, txqd_len);
s->regs[IBEX_SPI_HOST_STATUS] |= txqd_len;
/* Assert Ready */ /* Assert Ready */
s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_READY_MASK; status = FIELD_DP32(status, STATUS, READY, 1);
/* Update register status */
s->regs[IBEX_SPI_HOST_STATUS] = status;
break; break;
case IBEX_SPI_HOST_ERROR_ENABLE: case IBEX_SPI_HOST_ERROR_ENABLE:
s->regs[addr] = val32; s->regs[addr] = val32;