Re: [PATCH 4/5] tests/qtest: expand K230 I2C controller tests
Daniel Henrique Barboza <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
On 8/7/2026 12:28 PM, Wang Zhongyu wrote: > Expand the K230 I2C qtests to cover instance isolation, read-only > registers, system reset, read-to-clear interrupts, abort source > reporting, and START BYTE abort handling. > > Signed-off-by: Wang Zhongyu <[email protected]> > --- Reviewed-by: Daniel Henrique Barboza <[email protected]> > tests/qtest/k230-i2c-test.c | 532 +++++++++++++++++++++++++++++++++++- > 1 file changed, 529 insertions(+), 3 deletions(-) > > diff --git a/tests/qtest/k230-i2c-test.c b/tests/qtest/k230-i2c-test.c > index cc8dd54153..1d134de5d0 100644 > --- a/tests/qtest/k230-i2c-test.c > +++ b/tests/qtest/k230-i2c-test.c > @@ -25,11 +25,18 @@ > #define K230_IC_SAR 0x08 > #define K230_IC_HS_MADDR 0x0c > #define K230_IC_DATA_CMD 0x10 > +#define K230_IC_SS_SCL_HCNT 0x14 > +#define K230_IC_SS_SCL_LCNT 0x18 > +#define K230_IC_FS_SCL_HCNT 0x1c > +#define K230_IC_FS_SCL_LCNT 0x20 > +#define K230_IC_HS_SCL_HCNT 0x24 > +#define K230_IC_HS_SCL_LCNT 0x28 > #define K230_IC_INTR_STAT 0x2c > #define K230_IC_INTR_MASK 0x30 > #define K230_IC_RAW_INTR_STAT 0x34 > #define K230_IC_RX_TL 0x38 > #define K230_IC_TX_TL 0x3c > +#define K230_IC_CLR_INTR 0x40 > #define K230_IC_CLR_RX_UNDER 0x44 > #define K230_IC_CLR_TX_ABRT 0x54 > #define K230_IC_ENABLE 0x6c > @@ -37,20 +44,32 @@ > #define K230_IC_TXFLR 0x74 > #define K230_IC_RXFLR 0x78 > #define K230_IC_TX_ABRT_SOURCE 0x80 > +#define K230_IC_SDA_SETUP 0x94 > +#define K230_IC_ACK_GENERAL_CALL 0x98 > #define K230_IC_ENABLE_STATUS 0x9c > #define K230_IC_COMP_PARAM_1 0xf4 > #define K230_IC_COMP_VERSION 0xf8 > #define K230_IC_COMP_TYPE 0xfc > > +/* IC_CON */ > +#define IC_CON_MASTER_MODE BIT(0) > #define IC_CON_10BITADDR_MASTER BIT(4) > +#define IC_CON_RESTART_EN BIT(5) > + > +/* IC_TAR */ > +#define IC_TAR_GC_OR_START BIT(10) > +#define IC_TAR_SPECIAL BIT(11) > > /* IC_DATA_CMD */ > +#define IC_DATA_CMD_READ BIT(8) > #define IC_DATA_CMD_STOP BIT(9) > > /* IC_INTR_STAT and IC_RAW_INTR_STAT */ > #define IC_INTR_RX_UNDER BIT(0) > #define IC_INTR_TX_EMPTY BIT(4) > #define IC_INTR_TX_ABRT BIT(6) > +#define IC_INTR_ACTIVITY BIT(8) > +#define IC_INTR_START_DET BIT(10) > > /* IC_STATUS */ > #define IC_STATUS_TFNF BIT(1) > @@ -58,6 +77,10 @@ > > /* IC_TX_ABRT_SOURCE */ > #define IC_ABRT_7B_ADDR_NOACK BIT(0) > +#define IC_ABRT_GCALL_NOACK BIT(4) > +#define IC_ABRT_GCALL_READ BIT(5) > +#define IC_ABRT_SBYTE_NORSTRT BIT(9) > +#define IC_ABRT_MASTER_DIS BIT(11) > > #define K230_IC_COMP_PARAM_1_VALUE 0x001f3fae > #define K230_IC_COMP_VERSION_VALUE 0x3132302a > @@ -131,6 +154,38 @@ static void test_all_instances(void) > qtest_quit(qts); > } > > +static void test_instance_isolation(void) > +{ > + QTestState *qts = qtest_init("-machine k230"); > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_TAR, 0x2a); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_RX_TL, 17); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_INTR_MASK, 0x41); > + > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_TAR), > + ==, 0x2a); > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_RX_TL), > + ==, 17); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_INTR_MASK), > + ==, 0x41); > + > + for (int i = 1; i < K230_I2C_COUNT; i++) { > + g_assert_cmphex(qtest_readl(qts, > + k230_i2c_base[i] + K230_IC_TAR), > + ==, 0x55); > + g_assert_cmphex(qtest_readl(qts, > + k230_i2c_base[i] + K230_IC_RX_TL), > + ==, 0); > + g_assert_cmphex(qtest_readl(qts, > + k230_i2c_base[i] + > + K230_IC_INTR_MASK), > + ==, 0x8ff); > + } > + > + qtest_quit(qts); > +} > + > static void test_register_access(void) > { > QTestState *qts = qtest_init("-machine k230"); > @@ -163,6 +218,82 @@ static void test_register_access(void) > g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_TX_TL), > ==, 32); > > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_INTR_MASK, > + UINT32_MAX); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_INTR_MASK), > + ==, 0xfff); > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_SDA_SETUP, > + UINT32_MAX); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_SDA_SETUP), > + ==, 0xff); > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_ACK_GENERAL_CALL, > + UINT32_MAX); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + > + K230_IC_ACK_GENERAL_CALL), > + ==, 1); > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_TX_ABRT_SOURCE, > + UINT32_MAX); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + > + K230_IC_TX_ABRT_SOURCE), > + ==, 0xffff); > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_SS_SCL_HCNT, > + 65525); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + > + K230_IC_SS_SCL_HCNT), > + ==, 65525); > + > + /* > + * Values greater than 65525 are rejected. The previous valid > + * value must be preserved. > + */ > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_SS_SCL_HCNT, > + 65526); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + > + K230_IC_SS_SCL_HCNT), > + ==, 65525); > + > + qtest_quit(qts); > +} > + > +static void test_readonly_registers(void) > +{ > + static const struct { > + uint32_t offset; > + uint32_t expected; > + } registers[] = { > + { K230_IC_INTR_STAT, 0 }, > + { K230_IC_RAW_INTR_STAT, 0 }, > + { K230_IC_STATUS, IC_STATUS_TFNF | IC_STATUS_TFE }, > + { K230_IC_TXFLR, 0 }, > + { K230_IC_RXFLR, 0 }, > + { K230_IC_ENABLE_STATUS, 0 }, > + { K230_IC_COMP_PARAM_1, K230_IC_COMP_PARAM_1_VALUE }, > + { K230_IC_COMP_VERSION, K230_IC_COMP_VERSION_VALUE }, > + { K230_IC_COMP_TYPE, K230_IC_COMP_TYPE_VALUE }, > + }; > + QTestState *qts = qtest_init("-machine k230"); > + > + for (size_t i = 0; i < G_N_ELEMENTS(registers); i++) { > + qtest_writel(qts, > + K230_I2C0_BASE + registers[i].offset, > + UINT32_MAX); > + > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + > + registers[i].offset), > + ==, registers[i].expected); > + } > + > qtest_quit(qts); > } > > @@ -171,15 +302,78 @@ static void test_register_lock_while_enabled(void) > QTestState *qts = qtest_init("-machine k230"); > > qtest_writel(qts, K230_I2C0_BASE + K230_IC_TAR, 0x22); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_SAR, 0x155); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_HS_MADDR, 0x3); > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_SS_SCL_HCNT, 20); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_SS_SCL_LCNT, 21); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_FS_SCL_HCNT, 22); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_FS_SCL_LCNT, 23); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_HS_SCL_HCNT, 24); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_HS_SCL_LCNT, 25); > + > qtest_writel(qts, K230_I2C0_BASE + K230_IC_ENABLE, 1); > > - qtest_writel(qts, K230_I2C0_BASE + K230_IC_TAR, 0x33); > + /* > + * Configuration registers cannot be changed while the > + * controller is enabled. > + */ > qtest_writel(qts, K230_I2C0_BASE + K230_IC_CON, 0); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_TAR, 0x33); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_SAR, 0x222); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_HS_MADDR, 0x7); > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_SS_SCL_HCNT, 30); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_SS_SCL_LCNT, 31); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_FS_SCL_HCNT, 32); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_FS_SCL_LCNT, 33); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_HS_SCL_HCNT, 34); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_HS_SCL_LCNT, 35); > > - g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_TAR), > - ==, 0x22); > g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_CON), > ==, 0x7f); > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_TAR), > + ==, 0x22); > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_SAR), > + ==, 0x155); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_HS_MADDR), > + ==, 0x3); > + > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + > + K230_IC_SS_SCL_HCNT), > + ==, 20); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + > + K230_IC_SS_SCL_LCNT), > + ==, 21); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + > + K230_IC_FS_SCL_HCNT), > + ==, 22); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + > + K230_IC_FS_SCL_LCNT), > + ==, 23); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + > + K230_IC_HS_SCL_HCNT), > + ==, 24); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + > + K230_IC_HS_SCL_LCNT), > + ==, 25); > + > + /* > + * Configuration registers become writable again after the > + * controller is disabled. > + */ > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_ENABLE, 0); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_TAR, 0x33); > + > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_TAR), > + ==, 0x33); > > qtest_quit(qts); > } > @@ -281,6 +475,7 @@ static void test_address_nack(void) > */ > con = qtest_readl(qts, K230_I2C0_BASE + K230_IC_CON); > con &= ~IC_CON_10BITADDR_MASTER; > + > qtest_writel(qts, K230_I2C0_BASE + K230_IC_CON, con); > qtest_writel(qts, K230_I2C0_BASE + K230_IC_TAR, 0x7f); > qtest_writel(qts, K230_I2C0_BASE + K230_IC_ENABLE, 1); > @@ -310,6 +505,325 @@ static void test_address_nack(void) > qtest_quit(qts); > } > > +static void test_system_reset(void) > +{ > + QTestState *qts = qtest_init("-machine k230"); > + uint32_t raw; > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_TAR, 0x2a); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_SAR, 0x123); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_RX_TL, 10); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_TX_TL, 12); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_INTR_MASK, 0); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_ENABLE, 1); > + > + /* > + * Reading an empty RX FIFO produces RX_UNDER. > + */ > + qtest_readl(qts, K230_I2C0_BASE + K230_IC_DATA_CMD); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + g_assert_cmphex(raw & IC_INTR_RX_UNDER, ==, IC_INTR_RX_UNDER); > + > + qtest_system_reset(qts); > + > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_CON), > + ==, 0x7f); > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_TAR), > + ==, 0x55); > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_SAR), > + ==, 0x55); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_HS_MADDR), > + ==, 0x1); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_INTR_MASK), > + ==, 0x8ff); > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_RX_TL), > + ==, 0); > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_TX_TL), > + ==, 0); > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_ENABLE), > + ==, 0); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_ENABLE_STATUS), > + ==, 0); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT), > + ==, 0); > + g_assert_cmphex(qtest_readl(qts, > + K230_I2C0_BASE + > + K230_IC_TX_ABRT_SOURCE), > + ==, 0); > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_TXFLR), > + ==, 0); > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_RXFLR), > + ==, 0); > + g_assert_cmphex(qtest_readl(qts, K230_I2C0_BASE + K230_IC_STATUS), > + ==, IC_STATUS_TFNF | IC_STATUS_TFE); > + > + qtest_quit(qts); > +} > + > +static void test_clear_on_read(void) > +{ > + QTestState *qts = qtest_init("-machine k230"); > + uint32_t con; > + uint32_t raw; > + uint32_t source; > + > + /* > + * Produce RX_UNDER. > + */ > + qtest_readl(qts, K230_I2C0_BASE + K230_IC_DATA_CMD); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + g_assert_cmphex(raw & IC_INTR_RX_UNDER, ==, IC_INTR_RX_UNDER); > + > + /* > + * Writing a clear register must not clear the interrupt. > + */ > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_CLR_RX_UNDER, 1); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + g_assert_cmphex(raw & IC_INTR_RX_UNDER, ==, IC_INTR_RX_UNDER); > + > + /* > + * Produce an independent TX_ABRT interrupt. > + */ > + con = qtest_readl(qts, K230_I2C0_BASE + K230_IC_CON); > + con &= ~IC_CON_10BITADDR_MASTER; > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_CON, con); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_TAR, 0x7f); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_ENABLE, 1); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_DATA_CMD, > + IC_DATA_CMD_STOP | 0x55); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + source = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_TX_ABRT_SOURCE); > + > + g_assert_cmphex(raw & IC_INTR_RX_UNDER, ==, IC_INTR_RX_UNDER); > + g_assert_cmphex(raw & IC_INTR_TX_ABRT, ==, IC_INTR_TX_ABRT); > + g_assert_cmphex(source & IC_ABRT_7B_ADDR_NOACK, > + ==, IC_ABRT_7B_ADDR_NOACK); > + > + /* > + * Reading CLR_RX_UNDER clears only RX_UNDER. > + */ > + qtest_readl(qts, K230_I2C0_BASE + K230_IC_CLR_RX_UNDER); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + > + g_assert_cmphex(raw & IC_INTR_RX_UNDER, ==, 0); > + g_assert_cmphex(raw & IC_INTR_TX_ABRT, ==, IC_INTR_TX_ABRT); > + > + /* > + * Writing CLR_TX_ABRT must not clear TX_ABRT. > + */ > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_CLR_TX_ABRT, 1); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + g_assert_cmphex(raw & IC_INTR_TX_ABRT, ==, IC_INTR_TX_ABRT); > + > + /* > + * Reading CLR_TX_ABRT clears TX_ABRT and its source. > + */ > + qtest_readl(qts, K230_I2C0_BASE + K230_IC_CLR_TX_ABRT); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + source = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_TX_ABRT_SOURCE); > + > + g_assert_cmphex(raw & IC_INTR_TX_ABRT, ==, 0); > + g_assert_cmphex(source, ==, 0); > + > + /* > + * CLR_INTR clears latched interrupts. TX_EMPTY remains asserted > + * because it is recalculated from the empty TX FIFO. > + */ > + qtest_readl(qts, K230_I2C0_BASE + K230_IC_CLR_INTR); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + > + g_assert_cmphex(raw & IC_INTR_RX_UNDER, ==, 0); > + g_assert_cmphex(raw & IC_INTR_TX_ABRT, ==, 0); > + g_assert_cmphex(raw & IC_INTR_ACTIVITY, ==, 0); > + g_assert_cmphex(raw & IC_INTR_START_DET, ==, 0); > + g_assert_cmphex(raw & IC_INTR_TX_EMPTY, ==, IC_INTR_TX_EMPTY); > + > + qtest_quit(qts); > +} > + > +static void test_abort_sources(void) > +{ > + QTestState *qts = qtest_init("-machine k230"); > + uint32_t con; > + uint32_t raw; > + uint32_t source; > + > + /* > + * Master mode disabled. > + */ > + con = qtest_readl(qts, K230_I2C0_BASE + K230_IC_CON); > + con &= ~(IC_CON_MASTER_MODE | IC_CON_10BITADDR_MASTER); > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_CON, con); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_TAR, 0x7f); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_ENABLE, 1); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_DATA_CMD, > + IC_DATA_CMD_STOP | 0x55); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + source = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_TX_ABRT_SOURCE); > + > + g_assert_cmphex(raw & IC_INTR_TX_ABRT, ==, IC_INTR_TX_ABRT); > + g_assert_cmphex(source & IC_ABRT_MASTER_DIS, > + ==, IC_ABRT_MASTER_DIS); > + > + qtest_system_reset(qts); > + > + /* > + * A read command cannot target the General Call address. > + */ > + con = qtest_readl(qts, K230_I2C0_BASE + K230_IC_CON); > + con &= ~IC_CON_10BITADDR_MASTER; > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_CON, con); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_TAR, > + IC_TAR_SPECIAL); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_ENABLE, 1); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_DATA_CMD, > + IC_DATA_CMD_READ | IC_DATA_CMD_STOP); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + source = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_TX_ABRT_SOURCE); > + > + g_assert_cmphex(raw & IC_INTR_TX_ABRT, ==, IC_INTR_TX_ABRT); > + g_assert_cmphex(source & IC_ABRT_GCALL_READ, > + ==, IC_ABRT_GCALL_READ); > + > + qtest_system_reset(qts); > + > + /* > + * No slave is attached to acknowledge the General Call. > + */ > + con = qtest_readl(qts, K230_I2C0_BASE + K230_IC_CON); > + con &= ~IC_CON_10BITADDR_MASTER; > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_CON, con); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_TAR, > + IC_TAR_SPECIAL); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_ENABLE, 1); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_DATA_CMD, > + IC_DATA_CMD_STOP | 0x55); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + source = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_TX_ABRT_SOURCE); > + > + g_assert_cmphex(raw & IC_INTR_TX_ABRT, ==, IC_INTR_TX_ABRT); > + g_assert_cmphex(source & IC_ABRT_GCALL_NOACK, > + ==, IC_ABRT_GCALL_NOACK); > + > + qtest_system_reset(qts); > + > + /* > + * 10-bit master addressing is deliberately unsupported. > + */ > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_ENABLE, 1); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_DATA_CMD, > + IC_DATA_CMD_STOP | 0x55); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + source = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_TX_ABRT_SOURCE); > + > + g_assert_cmphex(raw & IC_INTR_TX_ABRT, ==, IC_INTR_TX_ABRT); > + g_assert_cmphex(source, ==, 0); > + > + qtest_quit(qts); > +} > + > +static void test_start_byte_abort(void) > +{ > + QTestState *qts = qtest_init("-machine k230"); > + uint32_t con; > + uint32_t raw; > + uint32_t source; > + > + /* > + * START BYTE requires RESTART_EN. > + */ > + con = qtest_readl(qts, K230_I2C0_BASE + K230_IC_CON); > + con &= ~(IC_CON_10BITADDR_MASTER | IC_CON_RESTART_EN); > + > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_CON, con); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_TAR, > + IC_TAR_SPECIAL | IC_TAR_GC_OR_START); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_ENABLE, 1); > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_DATA_CMD, > + IC_DATA_CMD_STOP | 0x55); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + source = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_TX_ABRT_SOURCE); > + > + g_assert_cmphex(raw & IC_INTR_TX_ABRT, ==, IC_INTR_TX_ABRT); > + g_assert_cmphex(source & IC_ABRT_SBYTE_NORSTRT, > + ==, IC_ABRT_SBYTE_NORSTRT); > + > + /* > + * Bit 9 remains set while the invalid configuration remains. > + */ > + qtest_readl(qts, K230_I2C0_BASE + K230_IC_CLR_TX_ABRT); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + source = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_TX_ABRT_SOURCE); > + > + g_assert_cmphex(raw & IC_INTR_TX_ABRT, ==, IC_INTR_TX_ABRT); > + g_assert_cmphex(source & IC_ABRT_SBYTE_NORSTRT, > + ==, IC_ABRT_SBYTE_NORSTRT); > + > + /* > + * Remove the cause by enabling RESTART_EN, then clear again. > + */ > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_ENABLE, 0); > + > + con |= IC_CON_RESTART_EN; > + qtest_writel(qts, K230_I2C0_BASE + K230_IC_CON, con); > + > + qtest_readl(qts, K230_I2C0_BASE + K230_IC_CLR_TX_ABRT); > + > + raw = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_RAW_INTR_STAT); > + source = qtest_readl(qts, > + K230_I2C0_BASE + K230_IC_TX_ABRT_SOURCE); > + > + g_assert_cmphex(raw & IC_INTR_TX_ABRT, ==, 0); > + g_assert_cmphex(source, ==, 0); > + > + qtest_quit(qts); > +} > + > int main(int argc, char **argv) > { > g_test_init(&argc, &argv, NULL); > @@ -318,8 +832,12 @@ int main(int argc, char **argv) > test_reset_values); > qtest_add_func("/k230-i2c/all-instances", > test_all_instances); > + qtest_add_func("/k230-i2c/instance-isolation", > + test_instance_isolation); > qtest_add_func("/k230-i2c/register-access", > test_register_access); > + qtest_add_func("/k230-i2c/readonly-registers", > + test_readonly_registers); > qtest_add_func("/k230-i2c/register-lock-while-enabled", > test_register_lock_while_enabled); > qtest_add_func("/k230-i2c/enable-disable", > @@ -330,6 +848,14 @@ int main(int argc, char **argv) > test_rx_underflow); > qtest_add_func("/k230-i2c/address-nack", > test_address_nack); > + qtest_add_func("/k230-i2c/system-reset", > + test_system_reset); > + qtest_add_func("/k230-i2c/clear-on-read", > + test_clear_on_read); > + qtest_add_func("/k230-i2c/abort-sources", > + test_abort_sources); > + qtest_add_func("/k230-i2c/start-byte-abort", > + test_start_byte_abort); > > return g_test_run(); > }