[Top][All Lists]
[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
>