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();
>   }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.