qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 2/2] tests: Add tmp105 unit test


From: Blue Swirl
Subject: Re: [Qemu-devel] [PATCH 2/2] tests: Add tmp105 unit test
Date: Wed, 12 Dec 2012 19:43:55 +0000

On Wed, Dec 12, 2012 at 6:29 AM, Andreas Färber <address@hidden> wrote:
> Exercise all four commands of the TMP105, testing for an issue in the
> I2C TX path. The test case is specific to the n800's OMAP I2C for now
> and is the first test case for arm.
>
> Signed-off-by: Andreas Färber <address@hidden>
> ---
>  tests/Makefile      |    2 +
>  tests/tmp105-test.c |  205 
> +++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 Dateien geändert, 207 Zeilen hinzugefügt(+)
>  create mode 100644 tests/tmp105-test.c
>
> diff --git a/tests/Makefile b/tests/Makefile
> index b60f0fb..69eff45 100644
> --- a/tests/Makefile
> +++ b/tests/Makefile
> @@ -28,6 +28,7 @@ check-qtest-i386-y += tests/rtc-test$(EXESUF)
>  check-qtest-x86_64-y = $(check-qtest-i386-y)
>  check-qtest-sparc-y = tests/m48t59-test$(EXESUF)
>  check-qtest-sparc64-y = tests/m48t59-test$(EXESUF)
> +check-qtest-arm-y = tests/tmp105-test$(EXESUF)
>
>  GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h 
> tests/test-qmp-commands.h
>
> @@ -78,6 +79,7 @@ tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y)
>  tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y)
>  tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y)
>  tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o 
> $(trace-obj-y)
> +tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(trace-obj-y)
>
>  # QTest rules
>
> diff --git a/tests/tmp105-test.c b/tests/tmp105-test.c
> new file mode 100644
> index 0000000..26d51f7
> --- /dev/null
> +++ b/tests/tmp105-test.c
> @@ -0,0 +1,205 @@
> +/*
> + * QTest testcase for the TMP105 temperature sensor
> + *
> + * Copyright (c) 2012 Andreas Färber
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +#include "libqtest.h"
> +
> +#include <glib.h>
> +#include <string.h>
> +
> +enum OMAPI2CRegisters {
> +    OMAP_I2C_REV  = 0x00,
> +    OMAP_I2C_STAT = 0x08,
> +    OMAP_I2C_CNT  = 0x18,
> +    OMAP_I2C_DATA = 0x1c,
> +    OMAP_I2C_CON  = 0x24,
> +    OMAP_I2C_SA   = 0x2c,
> +};
> +
> +enum OMAPI2CSTATBits {
> +    OMAP_I2C_STAT_NACK = 1 << 1,
> +    OMAP_I2C_STAT_ARDY = 1 << 2,
> +    OMAP_I2C_STAT_RRDY = 1 << 3,
> +    OMAP_I2C_STAT_XRDY = 1 << 4,
> +    OMAP_I2C_STAT_ROVR = 1 << 11,
> +    OMAP_I2C_STAT_SBD  = 1 << 15,
> +};
> +
> +enum OMAPI2CCONBits {
> +    OMAP_I2C_CON_STT    = 1 << 0,
> +    OMAP_I2C_CON_STP    = 1 << 1,
> +    OMAP_I2C_CON_TRX    = 1 << 9,
> +    OMAP_I2C_CON_MST    = 1 << 10,
> +    OMAP_I2C_CON_BE     = 1 << 14,
> +    OMAP_I2C_CON_I2C_EN = 1 << 15,
> +};
> +
> +#define OMAP2_I2C_1_BASE 0x48070000
> +
> +#define N8X0_ADDR 0x48
> +
> +static const uint32_t i2c_base = OMAP2_I2C_1_BASE;
> +
> +static void omap_i2c_init(void)
> +{
> +    uint16_t data;
> +
> +    /* verify the mmio address by looking for a known signature */
> +    memread(i2c_base + OMAP_I2C_REV, &data, 2);
> +    g_assert_cmphex(data, ==, 0x34);
> +}
> +
> +static void omap_i2c_set_slave_addr(uint8_t addr)
> +{
> +    uint16_t data = addr;
> +
> +    memwrite(i2c_base + OMAP_I2C_SA, &data, 2);
> +    memread(i2c_base + OMAP_I2C_SA, &data, 2);
> +    g_assert_cmphex(data, ==, addr);
> +}
> +
> +static void omap_i2c_send(uint8_t addr, const void *buf, uint16_t len)

With const uint8_t *buf you could avoid a few casts below.

> +{
> +    uint16_t data;
> +
> +    omap_i2c_set_slave_addr(addr);
> +
> +    data = len;
> +    memwrite(i2c_base + OMAP_I2C_CNT, &data, 2);
> +
> +    data = OMAP_I2C_CON_I2C_EN |
> +           OMAP_I2C_CON_TRX |
> +           OMAP_I2C_CON_MST |
> +           OMAP_I2C_CON_STT |
> +           OMAP_I2C_CON_STP;
> +    memwrite(i2c_base + OMAP_I2C_CON, &data, 2);
> +    memread(i2c_base + OMAP_I2C_CON, &data, 2);
> +    g_assert((data & OMAP_I2C_CON_STP) != 0);
> +
> +    memread(i2c_base + OMAP_I2C_STAT, &data, 2);
> +    g_assert((data & OMAP_I2C_STAT_NACK) == 0);
> +
> +    while (len > 1) {
> +        memread(i2c_base + OMAP_I2C_STAT, &data, 2);
> +        g_assert((data & OMAP_I2C_STAT_XRDY) != 0);
> +
> +        memwrite(i2c_base + OMAP_I2C_DATA, buf, 2);
> +        buf = (uint8_t *)buf + 2;
> +        len -= 2;
> +    }
> +    if (len == 1) {
> +        memread(i2c_base + OMAP_I2C_STAT, &data, 2);
> +        g_assert((data & OMAP_I2C_STAT_XRDY) != 0);
> +
> +        memwrite(i2c_base + OMAP_I2C_DATA, buf, 1);
> +    }
> +
> +    memread(i2c_base + OMAP_I2C_CON, &data, 2);
> +    g_assert((data & OMAP_I2C_CON_STP) == 0);
> +}
> +
> +static void omap_i2c_recv(uint8_t addr, void *buf, uint16_t len)
> +{
> +    uint16_t data, stat;
> +
> +    omap_i2c_set_slave_addr(addr);
> +
> +    data = len;
> +    memwrite(i2c_base + OMAP_I2C_CNT, &data, 2);
> +
> +    data = OMAP_I2C_CON_I2C_EN |
> +           OMAP_I2C_CON_MST |
> +           OMAP_I2C_CON_STT |
> +           OMAP_I2C_CON_STP;
> +    memwrite(i2c_base + OMAP_I2C_CON, &data, 2);
> +    memread(i2c_base + OMAP_I2C_CON, &data, 2);
> +    g_assert((data & OMAP_I2C_CON_STP) == 0);
> +
> +    memread(i2c_base + OMAP_I2C_STAT, &data, 2);
> +    g_assert((data & OMAP_I2C_STAT_NACK) == 0);
> +
> +    memread(i2c_base + OMAP_I2C_CNT, &data, 2);
> +    g_assert_cmpuint(data, ==, len);
> +
> +    while (len > 0) {
> +        memread(i2c_base + OMAP_I2C_STAT, &data, 2);
> +        g_assert((data & OMAP_I2C_STAT_RRDY) != 0);
> +        g_assert((data & OMAP_I2C_STAT_ROVR) == 0);
> +
> +        memread(i2c_base + OMAP_I2C_DATA, &data, 2);
> +
> +        memread(i2c_base + OMAP_I2C_STAT, &stat, 2);
> +        if ((stat & OMAP_I2C_STAT_SBD) != 0) {
> +            *(uint8_t *)buf = data & 0xf;
> +            buf = (uint8_t *)buf + 1;
> +            len--;
> +        } else {
> +            memcpy(buf, &data, 2);
> +            buf = (uint8_t *)buf + 2;
> +            len -= 2;
> +        }
> +    }
> +
> +    memread(i2c_base + OMAP_I2C_CON, &data, 2);
> +    g_assert((data & OMAP_I2C_CON_STP) == 0);
> +}
> +
> +static void send_and_receive(void)
> +{
> +    const uint8_t addr = N8X0_ADDR;
> +    uint8_t cmd[3];
> +    uint8_t resp[2];
> +
> +    omap_i2c_init();
> +
> +    cmd[0] = 0;
> +    omap_i2c_send(addr, cmd, 1);
> +    omap_i2c_recv(addr, resp, 2);
> +    g_assert_cmpuint(((uint16_t)resp[0] << 8) | resp[1], ==, 0);
> +
> +    cmd[0] = 1;
> +    cmd[1] = 0x0;
> +    omap_i2c_send(addr, cmd, 2);
> +    omap_i2c_recv(addr, resp, 1);
> +    g_assert_cmphex(resp[0], ==, cmd[1]);
> +
> +    cmd[0] = 2;
> +    cmd[1] = 0x12;
> +    cmd[2] = 0x34;
> +    omap_i2c_send(addr, cmd, 3);
> +    omap_i2c_recv(addr, resp, 2);
> +    g_assert_cmphex(resp[0], ==, cmd[1]);
> +    g_assert_cmphex(resp[1], ==, cmd[2]);
> +
> +    cmd[0] = 3;
> +    cmd[1] = 0x42;
> +    cmd[2] = 0x31;
> +    omap_i2c_send(addr, cmd, 3);
> +    omap_i2c_recv(addr, resp, 2);
> +    g_assert_cmphex(resp[0], ==, cmd[1]);
> +    g_assert_cmphex(resp[1], ==, cmd[2]);
> +}
> +
> +int main(int argc, char **argv)
> +{
> +    QTestState *s = NULL;
> +    int ret;
> +
> +    g_test_init(&argc, &argv, NULL);
> +
> +    s = qtest_start("-display none -machine n800");
> +
> +    qtest_add_func("/tmp105/tx-rx", send_and_receive);

A register fuzzing test (like rtc-test.c) would be nice too.

> +
> +    ret = g_test_run();
> +
> +    if (s) {
> +        qtest_quit(s);
> +    }
> +
> +    return ret;
> +}
> --
> 1.7.10.4
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]