summaryrefslogtreecommitdiff
path: root/hw/i2c
diff options
context:
space:
mode:
authorHao Wu <wuhaotsh@google.com>2021-02-10 14:04:26 -0800
committerPeter Maydell <peter.maydell@linaro.org>2021-02-16 14:12:54 +0000
commit6b6e7570d6ebc8bc6d9bc1356ae46708f02d3eeb (patch)
tree004d6c0c3d9aa9b5ee5835608fe7b5f467b2fc73 /hw/i2c
parentd986bf729c3cfc8672cfc6f3ab99c2d5c2eb11f1 (diff)
downloadqemu-6b6e7570d6ebc8bc6d9bc1356ae46708f02d3eeb.zip
hw/i2c: Implement NPCM7XX SMBus Module FIFO Mode
This patch implements the FIFO mode of the SMBus module. In FIFO, the user transmits or receives at most 16 bytes at a time. The FIFO mode allows the module to transmit large amount of data faster than single byte mode. Since we only added the device in a patch that is only a few commits away in the same patch set. We do not increase the VMstate version number in this special case. Reviewed-by: Doug Evans<dje@google.com> Reviewed-by: Tyrong Ting<kfting@nuvoton.com> Signed-off-by: Hao Wu <wuhaotsh@google.com> Reviewed-by: Corey Minyard <cminyard@mvista.com> Message-id: 20210210220426.3577804-6-wuhaotsh@google.com Acked-by: Corey Minyard <cminyard@mvista.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/i2c')
-rw-r--r--hw/i2c/npcm7xx_smbus.c342
-rw-r--r--hw/i2c/trace-events1
2 files changed, 330 insertions, 13 deletions
diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
index a465740623..6b2f9e1aaa 100644
--- a/hw/i2c/npcm7xx_smbus.c
+++ b/hw/i2c/npcm7xx_smbus.c
@@ -129,14 +129,45 @@ enum NPCM7xxSMBusBank1Register {
#define NPCM7XX_ADDR_EN BIT(7)
#define NPCM7XX_ADDR_A(rv) extract8((rv), 0, 6)
+/* FIFO Mode Register Fields */
+/* FIF_CTL fields */
+#define NPCM7XX_SMBFIF_CTL_FIFO_EN BIT(4)
+#define NPCM7XX_SMBFIF_CTL_FAIR_RDY_IE BIT(2)
+#define NPCM7XX_SMBFIF_CTL_FAIR_RDY BIT(1)
+#define NPCM7XX_SMBFIF_CTL_FAIR_BUSY BIT(0)
+/* FIF_CTS fields */
+#define NPCM7XX_SMBFIF_CTS_STR BIT(7)
+#define NPCM7XX_SMBFIF_CTS_CLR_FIFO BIT(6)
+#define NPCM7XX_SMBFIF_CTS_RFTE_IE BIT(3)
+#define NPCM7XX_SMBFIF_CTS_RXF_TXE BIT(1)
+/* TXF_CTL fields */
+#define NPCM7XX_SMBTXF_CTL_THR_TXIE BIT(6)
+#define NPCM7XX_SMBTXF_CTL_TX_THR(rv) extract8((rv), 0, 5)
+/* T_OUT fields */
+#define NPCM7XX_SMBT_OUT_ST BIT(7)
+#define NPCM7XX_SMBT_OUT_IE BIT(6)
+#define NPCM7XX_SMBT_OUT_CLKDIV(rv) extract8((rv), 0, 6)
+/* TXF_STS fields */
+#define NPCM7XX_SMBTXF_STS_TX_THST BIT(6)
+#define NPCM7XX_SMBTXF_STS_TX_BYTES(rv) extract8((rv), 0, 5)
+/* RXF_STS fields */
+#define NPCM7XX_SMBRXF_STS_RX_THST BIT(6)
+#define NPCM7XX_SMBRXF_STS_RX_BYTES(rv) extract8((rv), 0, 5)
+/* RXF_CTL fields */
+#define NPCM7XX_SMBRXF_CTL_THR_RXIE BIT(6)
+#define NPCM7XX_SMBRXF_CTL_LAST BIT(5)
+#define NPCM7XX_SMBRXF_CTL_RX_THR(rv) extract8((rv), 0, 5)
+
#define KEEP_OLD_BIT(o, n, b) (((n) & (~(b))) | ((o) & (b)))
#define WRITE_ONE_CLEAR(o, n, b) ((n) & (b) ? (o) & (~(b)) : (o))
#define NPCM7XX_SMBUS_ENABLED(s) ((s)->ctl2 & NPCM7XX_SMBCTL2_ENABLE)
+#define NPCM7XX_SMBUS_FIFO_ENABLED(s) ((s)->fif_ctl & \
+ NPCM7XX_SMBFIF_CTL_FIFO_EN)
/* VERSION fields values, read-only. */
#define NPCM7XX_SMBUS_VERSION_NUMBER 1
-#define NPCM7XX_SMBUS_VERSION_FIFO_SUPPORTED 0
+#define NPCM7XX_SMBUS_VERSION_FIFO_SUPPORTED 1
/* Reset values */
#define NPCM7XX_SMB_ST_INIT_VAL 0x00
@@ -151,6 +182,14 @@ enum NPCM7xxSMBusBank1Register {
#define NPCM7XX_SMB_ADDR_INIT_VAL 0x00
#define NPCM7XX_SMB_SCLLT_INIT_VAL 0x00
#define NPCM7XX_SMB_SCLHT_INIT_VAL 0x00
+#define NPCM7XX_SMB_FIF_CTL_INIT_VAL 0x00
+#define NPCM7XX_SMB_FIF_CTS_INIT_VAL 0x00
+#define NPCM7XX_SMB_FAIR_PER_INIT_VAL 0x00
+#define NPCM7XX_SMB_TXF_CTL_INIT_VAL 0x00
+#define NPCM7XX_SMB_T_OUT_INIT_VAL 0x3f
+#define NPCM7XX_SMB_TXF_STS_INIT_VAL 0x00
+#define NPCM7XX_SMB_RXF_STS_INIT_VAL 0x00
+#define NPCM7XX_SMB_RXF_CTL_INIT_VAL 0x01
static uint8_t npcm7xx_smbus_get_version(void)
{
@@ -171,7 +210,13 @@ static void npcm7xx_smbus_update_irq(NPCM7xxSMBusState *s)
(s->ctl1 & NPCM7XX_SMBCTL1_STASTRE &&
s->st & NPCM7XX_SMBST_SDAST) ||
(s->ctl1 & NPCM7XX_SMBCTL1_EOBINTE &&
- s->cst3 & NPCM7XX_SMBCST3_EO_BUSY));
+ s->cst3 & NPCM7XX_SMBCST3_EO_BUSY) ||
+ (s->rxf_ctl & NPCM7XX_SMBRXF_CTL_THR_RXIE &&
+ s->rxf_sts & NPCM7XX_SMBRXF_STS_RX_THST) ||
+ (s->txf_ctl & NPCM7XX_SMBTXF_CTL_THR_TXIE &&
+ s->txf_sts & NPCM7XX_SMBTXF_STS_TX_THST) ||
+ (s->fif_cts & NPCM7XX_SMBFIF_CTS_RFTE_IE &&
+ s->fif_cts & NPCM7XX_SMBFIF_CTS_RXF_TXE));
if (level) {
s->cst2 |= NPCM7XX_SMBCST2_INTSTS;
@@ -189,6 +234,13 @@ static void npcm7xx_smbus_nack(NPCM7xxSMBusState *s)
s->status = NPCM7XX_SMBUS_STATUS_NEGACK;
}
+static void npcm7xx_smbus_clear_buffer(NPCM7xxSMBusState *s)
+{
+ s->fif_cts &= ~NPCM7XX_SMBFIF_CTS_RXF_TXE;
+ s->txf_sts = 0;
+ s->rxf_sts = 0;
+}
+
static void npcm7xx_smbus_send_byte(NPCM7xxSMBusState *s, uint8_t value)
{
int rv = i2c_send(s->bus, value);
@@ -197,6 +249,15 @@ static void npcm7xx_smbus_send_byte(NPCM7xxSMBusState *s, uint8_t value)
npcm7xx_smbus_nack(s);
} else {
s->st |= NPCM7XX_SMBST_SDAST;
+ if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
+ s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
+ if (NPCM7XX_SMBTXF_STS_TX_BYTES(s->txf_sts) ==
+ NPCM7XX_SMBTXF_CTL_TX_THR(s->txf_ctl)) {
+ s->txf_sts = NPCM7XX_SMBTXF_STS_TX_THST;
+ } else {
+ s->txf_sts = 0;
+ }
+ }
}
trace_npcm7xx_smbus_send_byte((DEVICE(s)->canonical_path), value, !rv);
npcm7xx_smbus_update_irq(s);
@@ -215,6 +276,67 @@ static void npcm7xx_smbus_recv_byte(NPCM7xxSMBusState *s)
npcm7xx_smbus_update_irq(s);
}
+static void npcm7xx_smbus_recv_fifo(NPCM7xxSMBusState *s)
+{
+ uint8_t expected_bytes = NPCM7XX_SMBRXF_CTL_RX_THR(s->rxf_ctl);
+ uint8_t received_bytes = NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts);
+ uint8_t pos;
+
+ if (received_bytes == expected_bytes) {
+ return;
+ }
+
+ while (received_bytes < expected_bytes &&
+ received_bytes < NPCM7XX_SMBUS_FIFO_SIZE) {
+ pos = (s->rx_cur + received_bytes) % NPCM7XX_SMBUS_FIFO_SIZE;
+ s->rx_fifo[pos] = i2c_recv(s->bus);
+ trace_npcm7xx_smbus_recv_byte((DEVICE(s)->canonical_path),
+ s->rx_fifo[pos]);
+ ++received_bytes;
+ }
+
+ trace_npcm7xx_smbus_recv_fifo((DEVICE(s)->canonical_path),
+ received_bytes, expected_bytes);
+ s->rxf_sts = received_bytes;
+ if (unlikely(received_bytes < expected_bytes)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: invalid rx_thr value: 0x%02x\n",
+ DEVICE(s)->canonical_path, expected_bytes);
+ return;
+ }
+
+ s->rxf_sts |= NPCM7XX_SMBRXF_STS_RX_THST;
+ if (s->rxf_ctl & NPCM7XX_SMBRXF_CTL_LAST) {
+ trace_npcm7xx_smbus_nack(DEVICE(s)->canonical_path);
+ i2c_nack(s->bus);
+ s->rxf_ctl &= ~NPCM7XX_SMBRXF_CTL_LAST;
+ }
+ if (received_bytes == NPCM7XX_SMBUS_FIFO_SIZE) {
+ s->st |= NPCM7XX_SMBST_SDAST;
+ s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
+ } else if (!(s->rxf_ctl & NPCM7XX_SMBRXF_CTL_THR_RXIE)) {
+ s->st |= NPCM7XX_SMBST_SDAST;
+ } else {
+ s->st &= ~NPCM7XX_SMBST_SDAST;
+ }
+ npcm7xx_smbus_update_irq(s);
+}
+
+static void npcm7xx_smbus_read_byte_fifo(NPCM7xxSMBusState *s)
+{
+ uint8_t received_bytes = NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts);
+
+ if (received_bytes == 0) {
+ npcm7xx_smbus_recv_fifo(s);
+ return;
+ }
+
+ s->sda = s->rx_fifo[s->rx_cur];
+ s->rx_cur = (s->rx_cur + 1u) % NPCM7XX_SMBUS_FIFO_SIZE;
+ --s->rxf_sts;
+ npcm7xx_smbus_update_irq(s);
+}
+
static void npcm7xx_smbus_start(NPCM7xxSMBusState *s)
{
/*
@@ -228,6 +350,9 @@ static void npcm7xx_smbus_start(NPCM7xxSMBusState *s)
if (available) {
s->st |= NPCM7XX_SMBST_MODE | NPCM7XX_SMBST_XMIT | NPCM7XX_SMBST_SDAST;
s->cst |= NPCM7XX_SMBCST_BUSY;
+ if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
+ s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
+ }
} else {
s->st &= ~NPCM7XX_SMBST_MODE;
s->cst &= ~NPCM7XX_SMBCST_BUSY;
@@ -279,7 +404,15 @@ static void npcm7xx_smbus_send_address(NPCM7xxSMBusState *s, uint8_t value)
s->st |= NPCM7XX_SMBST_SDAST;
}
} else if (recv) {
- npcm7xx_smbus_recv_byte(s);
+ s->st |= NPCM7XX_SMBST_SDAST;
+ if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
+ npcm7xx_smbus_recv_fifo(s);
+ } else {
+ npcm7xx_smbus_recv_byte(s);
+ }
+ } else if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
+ s->st |= NPCM7XX_SMBST_SDAST;
+ s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
}
npcm7xx_smbus_update_irq(s);
}
@@ -322,11 +455,31 @@ static uint8_t npcm7xx_smbus_read_sda(NPCM7xxSMBusState *s)
switch (s->status) {
case NPCM7XX_SMBUS_STATUS_STOPPING_LAST_RECEIVE:
- npcm7xx_smbus_execute_stop(s);
+ if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
+ if (NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts) <= 1) {
+ npcm7xx_smbus_execute_stop(s);
+ }
+ if (NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts) == 0) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: read to SDA with an empty rx-fifo buffer, "
+ "result undefined: %u\n",
+ DEVICE(s)->canonical_path, s->sda);
+ break;
+ }
+ npcm7xx_smbus_read_byte_fifo(s);
+ value = s->sda;
+ } else {
+ npcm7xx_smbus_execute_stop(s);
+ }
break;
case NPCM7XX_SMBUS_STATUS_RECEIVING:
- npcm7xx_smbus_recv_byte(s);
+ if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
+ npcm7xx_smbus_read_byte_fifo(s);
+ value = s->sda;
+ } else {
+ npcm7xx_smbus_recv_byte(s);
+ }
break;
default:
@@ -372,8 +525,12 @@ static void npcm7xx_smbus_write_st(NPCM7xxSMBusState *s, uint8_t value)
}
if (value & NPCM7XX_SMBST_STASTR &&
- s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
- npcm7xx_smbus_recv_byte(s);
+ s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
+ if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
+ npcm7xx_smbus_recv_fifo(s);
+ } else {
+ npcm7xx_smbus_recv_byte(s);
+ }
}
npcm7xx_smbus_update_irq(s);
@@ -419,6 +576,7 @@ static void npcm7xx_smbus_write_ctl2(NPCM7xxSMBusState *s, uint8_t value)
s->st = 0;
s->cst3 = s->cst3 & (~NPCM7XX_SMBCST3_EO_BUSY);
s->cst = 0;
+ npcm7xx_smbus_clear_buffer(s);
}
}
@@ -431,6 +589,70 @@ static void npcm7xx_smbus_write_ctl3(NPCM7xxSMBusState *s, uint8_t value)
NPCM7XX_SMBCTL3_SCL_LVL | NPCM7XX_SMBCTL3_SDA_LVL);
}
+static void npcm7xx_smbus_write_fif_ctl(NPCM7xxSMBusState *s, uint8_t value)
+{
+ uint8_t new_ctl = value;
+
+ new_ctl = KEEP_OLD_BIT(s->fif_ctl, new_ctl, NPCM7XX_SMBFIF_CTL_FAIR_RDY);
+ new_ctl = WRITE_ONE_CLEAR(new_ctl, value, NPCM7XX_SMBFIF_CTL_FAIR_RDY);
+ new_ctl = KEEP_OLD_BIT(s->fif_ctl, new_ctl, NPCM7XX_SMBFIF_CTL_FAIR_BUSY);
+ s->fif_ctl = new_ctl;
+}
+
+static void npcm7xx_smbus_write_fif_cts(NPCM7xxSMBusState *s, uint8_t value)
+{
+ s->fif_cts = WRITE_ONE_CLEAR(s->fif_cts, value, NPCM7XX_SMBFIF_CTS_STR);
+ s->fif_cts = WRITE_ONE_CLEAR(s->fif_cts, value, NPCM7XX_SMBFIF_CTS_RXF_TXE);
+ s->fif_cts = KEEP_OLD_BIT(value, s->fif_cts, NPCM7XX_SMBFIF_CTS_RFTE_IE);
+
+ if (value & NPCM7XX_SMBFIF_CTS_CLR_FIFO) {
+ npcm7xx_smbus_clear_buffer(s);
+ }
+}
+
+static void npcm7xx_smbus_write_txf_ctl(NPCM7xxSMBusState *s, uint8_t value)
+{
+ s->txf_ctl = value;
+}
+
+static void npcm7xx_smbus_write_t_out(NPCM7xxSMBusState *s, uint8_t value)
+{
+ uint8_t new_t_out = value;
+
+ if ((value & NPCM7XX_SMBT_OUT_ST) || (!(s->t_out & NPCM7XX_SMBT_OUT_ST))) {
+ new_t_out &= ~NPCM7XX_SMBT_OUT_ST;
+ } else {
+ new_t_out |= NPCM7XX_SMBT_OUT_ST;
+ }
+
+ s->t_out = new_t_out;
+}
+
+static void npcm7xx_smbus_write_txf_sts(NPCM7xxSMBusState *s, uint8_t value)
+{
+ s->txf_sts = WRITE_ONE_CLEAR(s->txf_sts, value, NPCM7XX_SMBTXF_STS_TX_THST);
+}
+
+static void npcm7xx_smbus_write_rxf_sts(NPCM7xxSMBusState *s, uint8_t value)
+{
+ if (value & NPCM7XX_SMBRXF_STS_RX_THST) {
+ s->rxf_sts &= ~NPCM7XX_SMBRXF_STS_RX_THST;
+ if (s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
+ npcm7xx_smbus_recv_fifo(s);
+ }
+ }
+}
+
+static void npcm7xx_smbus_write_rxf_ctl(NPCM7xxSMBusState *s, uint8_t value)
+{
+ uint8_t new_ctl = value;
+
+ if (!(value & NPCM7XX_SMBRXF_CTL_LAST)) {
+ new_ctl = KEEP_OLD_BIT(s->rxf_ctl, new_ctl, NPCM7XX_SMBRXF_CTL_LAST);
+ }
+ s->rxf_ctl = new_ctl;
+}
+
static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned size)
{
NPCM7xxSMBusState *s = opaque;
@@ -487,9 +709,41 @@ static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned size)
default:
if (bank) {
/* Bank 1 */
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: read from invalid offset 0x%" HWADDR_PRIx "\n",
- DEVICE(s)->canonical_path, offset);
+ switch (offset) {
+ case NPCM7XX_SMB_FIF_CTS:
+ value = s->fif_cts;
+ break;
+
+ case NPCM7XX_SMB_FAIR_PER:
+ value = s->fair_per;
+ break;
+
+ case NPCM7XX_SMB_TXF_CTL:
+ value = s->txf_ctl;
+ break;
+
+ case NPCM7XX_SMB_T_OUT:
+ value = s->t_out;
+ break;
+
+ case NPCM7XX_SMB_TXF_STS:
+ value = s->txf_sts;
+ break;
+
+ case NPCM7XX_SMB_RXF_STS:
+ value = s->rxf_sts;
+ break;
+
+ case NPCM7XX_SMB_RXF_CTL:
+ value = s->rxf_ctl;
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: read from invalid offset 0x%" HWADDR_PRIx "\n",
+ DEVICE(s)->canonical_path, offset);
+ break;
+ }
} else {
/* Bank 0 */
switch (offset) {
@@ -537,6 +791,10 @@ static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned size)
value = s->scllt;
break;
+ case NPCM7XX_SMB_FIF_CTL:
+ value = s->fif_ctl;
+ break;
+
case NPCM7XX_SMB_SCLHT:
value = s->sclht;
break;
@@ -618,9 +876,41 @@ static void npcm7xx_smbus_write(void *opaque, hwaddr offset, uint64_t value,
default:
if (bank) {
/* Bank 1 */
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: write to invalid offset 0x%" HWADDR_PRIx "\n",
- DEVICE(s)->canonical_path, offset);
+ switch (offset) {
+ case NPCM7XX_SMB_FIF_CTS:
+ npcm7xx_smbus_write_fif_cts(s, value);
+ break;
+
+ case NPCM7XX_SMB_FAIR_PER:
+ s->fair_per = value;
+ break;
+
+ case NPCM7XX_SMB_TXF_CTL:
+ npcm7xx_smbus_write_txf_ctl(s, value);
+ break;
+
+ case NPCM7XX_SMB_T_OUT:
+ npcm7xx_smbus_write_t_out(s, value);
+ break;
+
+ case NPCM7XX_SMB_TXF_STS:
+ npcm7xx_smbus_write_txf_sts(s, value);
+ break;
+
+ case NPCM7XX_SMB_RXF_STS:
+ npcm7xx_smbus_write_rxf_sts(s, value);
+ break;
+
+ case NPCM7XX_SMB_RXF_CTL:
+ npcm7xx_smbus_write_rxf_ctl(s, value);
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: write to invalid offset 0x%" HWADDR_PRIx "\n",
+ DEVICE(s)->canonical_path, offset);
+ break;
+ }
} else {
/* Bank 0 */
switch (offset) {
@@ -668,6 +958,10 @@ static void npcm7xx_smbus_write(void *opaque, hwaddr offset, uint64_t value,
s->scllt = value;
break;
+ case NPCM7XX_SMB_FIF_CTL:
+ npcm7xx_smbus_write_fif_ctl(s, value);
+ break;
+
case NPCM7XX_SMB_SCLHT:
s->sclht = value;
break;
@@ -714,7 +1008,18 @@ static void npcm7xx_smbus_enter_reset(Object *obj, ResetType type)
s->scllt = NPCM7XX_SMB_SCLLT_INIT_VAL;
s->sclht = NPCM7XX_SMB_SCLHT_INIT_VAL;
+ s->fif_ctl = NPCM7XX_SMB_FIF_CTL_INIT_VAL;
+ s->fif_cts = NPCM7XX_SMB_FIF_CTS_INIT_VAL;
+ s->fair_per = NPCM7XX_SMB_FAIR_PER_INIT_VAL;
+ s->txf_ctl = NPCM7XX_SMB_TXF_CTL_INIT_VAL;
+ s->t_out = NPCM7XX_SMB_T_OUT_INIT_VAL;
+ s->txf_sts = NPCM7XX_SMB_TXF_STS_INIT_VAL;
+ s->rxf_sts = NPCM7XX_SMB_RXF_STS_INIT_VAL;
+ s->rxf_ctl = NPCM7XX_SMB_RXF_CTL_INIT_VAL;
+
+ npcm7xx_smbus_clear_buffer(s);
s->status = NPCM7XX_SMBUS_STATUS_IDLE;
+ s->rx_cur = 0;
}
static void npcm7xx_smbus_hold_reset(Object *obj)
@@ -756,6 +1061,17 @@ static const VMStateDescription vmstate_npcm7xx_smbus = {
VMSTATE_UINT8_ARRAY(addr, NPCM7xxSMBusState, NPCM7XX_SMBUS_NR_ADDRS),
VMSTATE_UINT8(scllt, NPCM7xxSMBusState),
VMSTATE_UINT8(sclht, NPCM7xxSMBusState),
+ VMSTATE_UINT8(fif_ctl, NPCM7xxSMBusState),
+ VMSTATE_UINT8(fif_cts, NPCM7xxSMBusState),
+ VMSTATE_UINT8(fair_per, NPCM7xxSMBusState),
+ VMSTATE_UINT8(txf_ctl, NPCM7xxSMBusState),
+ VMSTATE_UINT8(t_out, NPCM7xxSMBusState),
+ VMSTATE_UINT8(txf_sts, NPCM7xxSMBusState),
+ VMSTATE_UINT8(rxf_sts, NPCM7xxSMBusState),
+ VMSTATE_UINT8(rxf_ctl, NPCM7xxSMBusState),
+ VMSTATE_UINT8_ARRAY(rx_fifo, NPCM7xxSMBusState,
+ NPCM7XX_SMBUS_FIFO_SIZE),
+ VMSTATE_UINT8(rx_cur, NPCM7xxSMBusState),
VMSTATE_END_OF_LIST(),
},
};
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
index c3bb70ad04..82fe6f965f 100644
--- a/hw/i2c/trace-events
+++ b/hw/i2c/trace-events
@@ -25,3 +25,4 @@ npcm7xx_smbus_send_byte(const char *id, uint8_t value, int success) "%s send byt
npcm7xx_smbus_recv_byte(const char *id, uint8_t value) "%s recv byte: 0x%02x"
npcm7xx_smbus_stop(const char *id) "%s stopping"
npcm7xx_smbus_nack(const char *id) "%s nacking"
+npcm7xx_smbus_recv_fifo(const char *id, uint8_t received, uint8_t expected) "%s recv fifo: received %u, expected %u"