diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/compression.c | 1 | ||||
-rw-r--r-- | test/dm/Makefile | 7 | ||||
-rw-r--r-- | test/dm/bus.c | 16 | ||||
-rw-r--r-- | test/dm/cmd_dm.c | 16 | ||||
-rw-r--r-- | test/dm/core.c | 9 | ||||
-rw-r--r-- | test/dm/eth.c | 156 | ||||
-rw-r--r-- | test/dm/pci.c | 59 | ||||
-rwxr-xr-x | test/dm/test-dm.sh | 3 | ||||
-rw-r--r-- | test/dm/test-main.c | 7 | ||||
-rw-r--r-- | test/dm/test-uclass.c | 17 | ||||
-rw-r--r-- | test/dm/test.dts | 78 | ||||
-rw-r--r-- | test/dm/usb.c | 50 |
12 files changed, 400 insertions, 19 deletions
diff --git a/test/compression.c b/test/compression.c index ea2e4ad22e..7ef3a8c9f5 100644 --- a/test/compression.c +++ b/test/compression.c @@ -10,6 +10,7 @@ #include <bootm.h> #include <command.h> #include <malloc.h> +#include <mapmem.h> #include <asm/io.h> #include <u-boot/zlib.h> diff --git a/test/dm/Makefile b/test/dm/Makefile index 612aa957fa..fd9e29f201 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -17,8 +17,11 @@ obj-$(CONFIG_DM_TEST) += ut.o obj-$(CONFIG_DM_TEST) += core.o obj-$(CONFIG_DM_TEST) += ut.o ifneq ($(CONFIG_SANDBOX),) +obj-$(CONFIG_DM_ETH) += eth.o obj-$(CONFIG_DM_GPIO) += gpio.o -obj-$(CONFIG_DM_SPI) += spi.o -obj-$(CONFIG_DM_SPI_FLASH) += sf.o obj-$(CONFIG_DM_I2C) += i2c.o +obj-$(CONFIG_DM_PCI) += pci.o +obj-$(CONFIG_DM_SPI_FLASH) += sf.o +obj-$(CONFIG_DM_SPI) += spi.o +obj-$(CONFIG_DM_USB) += usb.o endif diff --git a/test/dm/bus.c b/test/dm/bus.c index faffe6a385..116a52db59 100644 --- a/test/dm/bus.c +++ b/test/dm/bus.c @@ -273,20 +273,22 @@ DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); /* As above but the size is controlled by the uclass */ static int dm_test_bus_parent_data_uclass(struct dm_test_state *dms) { + struct driver *drv; struct udevice *bus; int size; int ret; /* Set the driver size to 0 so that the uclass size is used */ ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); - size = bus->driver->per_child_auto_alloc_size; + drv = (struct driver *)bus->driver; + size = drv->per_child_auto_alloc_size; bus->uclass->uc_drv->per_child_auto_alloc_size = size; - bus->driver->per_child_auto_alloc_size = 0; + drv->per_child_auto_alloc_size = 0; ret = test_bus_parent_data(dms); if (ret) return ret; bus->uclass->uc_drv->per_child_auto_alloc_size = 0; - bus->driver->per_child_auto_alloc_size = size; + drv->per_child_auto_alloc_size = size; return 0; } @@ -414,19 +416,21 @@ DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); static int dm_test_bus_parent_platdata_uclass(struct dm_test_state *dms) { struct udevice *bus; + struct driver *drv; int size; int ret; /* Set the driver size to 0 so that the uclass size is used */ ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); - size = bus->driver->per_child_platdata_auto_alloc_size; + drv = (struct driver *)bus->driver; + size = drv->per_child_platdata_auto_alloc_size; bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size; - bus->driver->per_child_platdata_auto_alloc_size = 0; + drv->per_child_platdata_auto_alloc_size = 0; ret = test_bus_parent_platdata(dms); if (ret) return ret; bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0; - bus->driver->per_child_platdata_auto_alloc_size = size; + drv->per_child_platdata_auto_alloc_size = size; return 0; } diff --git a/test/dm/cmd_dm.c b/test/dm/cmd_dm.c index 79a674efcc..2f527e959b 100644 --- a/test/dm/cmd_dm.c +++ b/test/dm/cmd_dm.c @@ -10,6 +10,7 @@ #include <common.h> #include <dm.h> #include <malloc.h> +#include <mapmem.h> #include <errno.h> #include <asm/io.h> #include <dm/root.h> @@ -77,8 +78,8 @@ static void dm_display_line(struct udevice *dev) printf("- %c %s @ %08lx", dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ', dev->name, (ulong)map_to_sysmem(dev)); - if (dev->req_seq != -1) - printf(", %d", dev->req_seq); + if (dev->seq != -1 || dev->req_seq != -1) + printf(", seq %d, (req %d)", dev->seq, dev->req_seq); puts("\n"); } @@ -112,7 +113,12 @@ static int do_dm_dump_uclass(cmd_tbl_t *cmdtp, int flag, int argc, static int do_dm_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - return dm_test_main(); + const char *test_name = NULL; + + if (argc > 0) + test_name = argv[0]; + + return dm_test_main(test_name); } #define TEST_HELP "\ndm test Run tests" #else @@ -132,7 +138,7 @@ static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) cmd_tbl_t *test_cmd; int ret; - if (argc != 2) + if (argc < 2) return CMD_RET_USAGE; test_cmd = find_cmd_tbl(argv[1], test_commands, ARRAY_SIZE(test_commands)); @@ -147,7 +153,7 @@ static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } U_BOOT_CMD( - dm, 2, 1, do_dm, + dm, 3, 1, do_dm, "Driver model low level access", "tree Dump driver model tree ('*' = activated)\n" "dm uclass Dump list of instances for each uclass" diff --git a/test/dm/core.c b/test/dm/core.c index eccda0974d..990d390d01 100644 --- a/test/dm/core.c +++ b/test/dm/core.c @@ -141,6 +141,7 @@ static int dm_test_autoprobe(struct dm_test_state *dms) ut_assert(uc); ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]); + ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]); ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]); /* The root device should not be activated until needed */ @@ -167,8 +168,12 @@ static int dm_test_autoprobe(struct dm_test_state *dms) ut_assert(dms->root->flags & DM_FLAG_ACTIVATED); } - /* Our 3 dm_test_infox children should be passed to post_probe */ + /* + * Our 3 dm_test_info children should be passed to pre_probe and + * post_probe + */ ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]); + ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]); /* Also we can check the per-device data */ expected_base_add = 0; @@ -179,7 +184,7 @@ static int dm_test_autoprobe(struct dm_test_state *dms) ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev)); ut_assert(dev); - priv = dev->uclass_priv; + priv = dev_get_uclass_priv(dev); ut_assert(priv); ut_asserteq(expected_base_add, priv->base_add); diff --git a/test/dm/eth.c b/test/dm/eth.c new file mode 100644 index 0000000000..4891f3ad34 --- /dev/null +++ b/test/dm/eth.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2015 National Instruments + * + * (C) Copyright 2015 + * Joe Hershberger <joe.hershberger@ni.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <dm/test.h> +#include <dm/ut.h> +#include <fdtdec.h> +#include <malloc.h> +#include <net.h> +#include <asm/eth.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int dm_test_eth(struct dm_test_state *dms) +{ + net_ping_ip = string_to_ip("1.1.2.2"); + + setenv("ethact", "eth@10002000"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10002000", getenv("ethact")); + + setenv("ethact", "eth@10003000"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10003000", getenv("ethact")); + + setenv("ethact", "eth@10004000"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10004000", getenv("ethact")); + + return 0; +} +DM_TEST(dm_test_eth, DM_TESTF_SCAN_FDT); + +static int dm_test_eth_alias(struct dm_test_state *dms) +{ + net_ping_ip = string_to_ip("1.1.2.2"); + setenv("ethact", "eth0"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10002000", getenv("ethact")); + + setenv("ethact", "eth1"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10004000", getenv("ethact")); + + /* Expected to fail since eth2 is not defined in the device tree */ + setenv("ethact", "eth2"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10002000", getenv("ethact")); + + setenv("ethact", "eth5"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10003000", getenv("ethact")); + + return 0; +} +DM_TEST(dm_test_eth_alias, DM_TESTF_SCAN_FDT); + +static int dm_test_eth_prime(struct dm_test_state *dms) +{ + net_ping_ip = string_to_ip("1.1.2.2"); + + /* Expected to be "eth@10003000" because of ethprime variable */ + setenv("ethact", NULL); + setenv("ethprime", "eth5"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10003000", getenv("ethact")); + + /* Expected to be "eth@10002000" because it is first */ + setenv("ethact", NULL); + setenv("ethprime", NULL); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10002000", getenv("ethact")); + + return 0; +} +DM_TEST(dm_test_eth_prime, DM_TESTF_SCAN_FDT); + +static int dm_test_eth_rotate(struct dm_test_state *dms) +{ + char ethaddr[18]; + + /* Invalidate eth1's MAC address */ + net_ping_ip = string_to_ip("1.1.2.2"); + strcpy(ethaddr, getenv("eth1addr")); + setenv("eth1addr", NULL); + + /* Make sure that the default is to rotate to the next interface */ + setenv("ethact", "eth@10004000"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10002000", getenv("ethact")); + + /* If ethrotate is no, then we should fail on a bad MAC */ + setenv("ethact", "eth@10004000"); + setenv("ethrotate", "no"); + ut_asserteq(-EINVAL, net_loop(PING)); + ut_asserteq_str("eth@10004000", getenv("ethact")); + + /* Restore the env */ + setenv("eth1addr", ethaddr); + setenv("ethrotate", NULL); + + /* Invalidate eth0's MAC address */ + strcpy(ethaddr, getenv("ethaddr")); + setenv(".flags", "ethaddr"); + setenv("ethaddr", NULL); + + /* Make sure we can skip invalid devices */ + setenv("ethact", "eth@10004000"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10004000", getenv("ethact")); + + /* Restore the env */ + setenv("ethaddr", ethaddr); + setenv(".flags", NULL); + + return 0; +} +DM_TEST(dm_test_eth_rotate, DM_TESTF_SCAN_FDT); + +static int dm_test_net_retry(struct dm_test_state *dms) +{ + net_ping_ip = string_to_ip("1.1.2.2"); + + /* + * eth1 is disabled and netretry is yes, so the ping should succeed and + * the active device should be eth0 + */ + sandbox_eth_disable_response(1, true); + setenv("ethact", "eth@10004000"); + setenv("netretry", "yes"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10002000", getenv("ethact")); + + /* + * eth1 is disabled and netretry is no, so the ping should fail and the + * active device should be eth1 + */ + setenv("ethact", "eth@10004000"); + setenv("netretry", "no"); + ut_asserteq(-ETIMEDOUT, net_loop(PING)); + ut_asserteq_str("eth@10004000", getenv("ethact")); + + /* Restore the env */ + setenv("netretry", NULL); + sandbox_eth_disable_response(1, false); + + return 0; +} +DM_TEST(dm_test_net_retry, DM_TESTF_SCAN_FDT); diff --git a/test/dm/pci.c b/test/dm/pci.c new file mode 100644 index 0000000000..6c63fa4c1f --- /dev/null +++ b/test/dm/pci.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <asm/io.h> +#include <dm/test.h> +#include <dm/ut.h> + +/* Test that sandbox PCI works correctly */ +static int dm_test_pci_base(struct dm_test_state *dms) +{ + struct udevice *bus; + + ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus)); + + return 0; +} +DM_TEST(dm_test_pci_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that we can use the swapcase device correctly */ +static int dm_test_pci_swapcase(struct dm_test_state *dms) +{ + pci_dev_t pci_dev = PCI_BDF(0, 0x1f, 0); + struct pci_controller *hose; + struct udevice *bus, *swap; + ulong io_addr, mem_addr; + char *ptr; + + /* Check that asking for the device automatically fires up PCI */ + ut_assertok(uclass_get_device(UCLASS_PCI_EMUL, 0, &swap)); + + ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus)); + hose = dev_get_uclass_priv(bus); + + /* First test I/O */ + io_addr = pci_read_bar32(hose, pci_dev, 0); + outb(2, io_addr); + ut_asserteq(2, inb(io_addr)); + + /* + * Now test memory mapping - note we must unmap and remap to cause + * the swapcase emulation to see our data and response. + */ + mem_addr = pci_read_bar32(hose, pci_dev, 1); + ptr = map_sysmem(mem_addr, 20); + strcpy(ptr, "This is a TesT"); + unmap_sysmem(ptr); + + ptr = map_sysmem(mem_addr, 20); + ut_asserteq_str("tHIS IS A tESt", ptr); + unmap_sysmem(ptr); + + return 0; +} +DM_TEST(dm_test_pci_swapcase, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/test-dm.sh b/test/dm/test-dm.sh index 8ebc39297c..6158f6833f 100755 --- a/test/dm/test-dm.sh +++ b/test/dm/test-dm.sh @@ -10,5 +10,8 @@ dtc -I dts -O dtb test/dm/test.dts -o test/dm/test.dtb make O=sandbox sandbox_config || die "Cannot configure U-Boot" make O=sandbox -s -j${NUM_CPUS} || die "Cannot build U-Boot" dd if=/dev/zero of=spi.bin bs=1M count=2 +echo -n "this is a test" > testflash.bin +dd if=/dev/zero bs=1M count=4 >>testflash.bin ./sandbox/u-boot -d test/dm/test.dtb -c "dm test" rm spi.bin +rm testflash.bin diff --git a/test/dm/test-main.c b/test/dm/test-main.c index 90ca81092f..a47bb37022 100644 --- a/test/dm/test-main.c +++ b/test/dm/test-main.c @@ -65,7 +65,7 @@ static int dm_test_destroy(struct dm_test_state *dms) return 0; } -int dm_test_main(void) +int dm_test_main(const char *test_name) { struct dm_test *tests = ll_entry_start(struct dm_test, dm_test); const int n_ents = ll_entry_count(struct dm_test, dm_test); @@ -83,9 +83,12 @@ int dm_test_main(void) ut_assert(gd->fdt_blob); } - printf("Running %d driver model tests\n", n_ents); + if (!test_name) + printf("Running %d driver model tests\n", n_ents); for (test = tests; test < tests + n_ents; test++) { + if (test_name && strcmp(test_name, test->name)) + continue; printf("Test: %s\n", test->name); ut_assertok(dm_test_init(dms)); diff --git a/test/dm/test-uclass.c b/test/dm/test-uclass.c index 017e097928..7cb37f70c7 100644 --- a/test/dm/test-uclass.c +++ b/test/dm/test-uclass.c @@ -31,6 +31,7 @@ int test_ping(struct udevice *dev, int pingval, int *pingret) static int test_post_bind(struct udevice *dev) { dm_testdrv_op_count[DM_TEST_OP_POST_BIND]++; + ut_assert(!device_active(dev)); return 0; } @@ -42,12 +43,23 @@ static int test_pre_unbind(struct udevice *dev) return 0; } +static int test_pre_probe(struct udevice *dev) +{ + struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev); + + dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]++; + ut_assert(priv); + ut_assert(device_active(dev)); + + return 0; +} + static int test_post_probe(struct udevice *dev) { struct udevice *prev = list_entry(dev->uclass_node.prev, struct udevice, uclass_node); - struct dm_test_uclass_perdev_priv *priv = dev->uclass_priv; + struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev); struct uclass *uc = dev->uclass; dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]++; @@ -58,7 +70,7 @@ static int test_post_probe(struct udevice *dev) return 0; if (&prev->uclass_node != &uc->dev_head) { struct dm_test_uclass_perdev_priv *prev_uc_priv - = prev->uclass_priv; + = dev_get_uclass_priv(prev); struct dm_test_pdata *pdata = prev->platdata; ut_assert(pdata); @@ -96,6 +108,7 @@ UCLASS_DRIVER(test) = { .id = UCLASS_TEST, .post_bind = test_post_bind, .pre_unbind = test_pre_unbind, + .pre_probe = test_pre_probe, .post_probe = test_post_probe, .pre_remove = test_pre_remove, .init = test_init, diff --git a/test/dm/test.dts b/test/dm/test.dts index 84024a44a3..d0c40be6b0 100644 --- a/test/dm/test.dts +++ b/test/dm/test.dts @@ -10,6 +10,7 @@ console = &uart0; i2c0 = "/i2c@0"; spi0 = "/spi@0"; + pci0 = &pci; testfdt6 = "/e-test"; testbus3 = "/some-bus"; testfdt0 = "/some-bus/c-test@0"; @@ -17,6 +18,11 @@ testfdt3 = "/b-test"; testfdt5 = "/some-bus/c-test@5"; testfdt8 = "/a-test"; + eth0 = "/eth@10002000"; + eth5 = ð_5; + usb0 = &usb_0; + usb1 = &usb_1; + usb2 = &usb_2; }; uart0: serial { @@ -135,6 +141,22 @@ }; }; + pci: pci-controller { + compatible = "sandbox,pci"; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000 + 0x01000000 0 0x20000000 0x20000000 0 0x2000>; + pci@1f,0 { + compatible = "pci-generic"; + reg = <0xf800 0 0 0 0>; + emul@1f,0 { + compatible = "sandbox,swap-case"; + }; + }; + }; + spi@0 { #address-cells = <1>; #size-cells = <0>; @@ -149,4 +171,60 @@ }; }; + eth@10002000 { + compatible = "sandbox,eth"; + reg = <0x10002000 0x1000>; + fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x00>; + }; + + eth_5: eth@10003000 { + compatible = "sandbox,eth"; + reg = <0x10003000 0x1000>; + fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x11>; + }; + + eth@10004000 { + compatible = "sandbox,eth"; + reg = <0x10004000 0x1000>; + fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x22>; + }; + + usb_0: usb@0 { + compatible = "sandbox,usb"; + status = "disabled"; + hub { + compatible = "sandbox,usb-hub"; + #address-cells = <1>; + #size-cells = <0>; + flash-stick { + reg = <0>; + compatible = "sandbox,usb-flash"; + }; + }; + }; + + usb_1: usb@1 { + compatible = "sandbox,usb"; + hub { + compatible = "usb-hub"; + usb,device-class = <9>; + hub-emul { + compatible = "sandbox,usb-hub"; + #address-cells = <1>; + #size-cells = <0>; + flash-stick { + reg = <0>; + compatible = "sandbox,usb-flash"; + sandbox,filepath = "testflash.bin"; + }; + + }; + }; + }; + + usb_2: usb@2 { + compatible = "sandbox,usb"; + status = "disabled"; + }; + }; diff --git a/test/dm/usb.c b/test/dm/usb.c new file mode 100644 index 0000000000..6ea86d7247 --- /dev/null +++ b/test/dm/usb.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <usb.h> +#include <asm/io.h> +#include <dm/test.h> +#include <dm/ut.h> + +/* Test that sandbox USB works correctly */ +static int dm_test_usb_base(struct dm_test_state *dms) +{ + struct udevice *bus; + + ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus)); + ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus)); + ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus)); + + return 0; +} +DM_TEST(dm_test_usb_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* + * Test that we can use the flash stick. This is more of a functional test. It + * covers scanning the bug, setting up a hub and a flash stick and reading + * data from the flash stick. + */ +static int dm_test_usb_flash(struct dm_test_state *dms) +{ + struct udevice *dev; + block_dev_desc_t *dev_desc; + char cmp[1024]; + + ut_assertok(usb_init()); + ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev)); + ut_assertok(get_device("usb", "0", &dev_desc)); + + /* Read a few blocks and look for the string we expect */ + ut_asserteq(512, dev_desc->blksz); + memset(cmp, '\0', sizeof(cmp)); + ut_asserteq(2, dev_desc->block_read(dev_desc->dev, 0, 2, cmp)); + ut_assertok(strcmp(cmp, "this is a test")); + + return 0; +} +DM_TEST(dm_test_usb_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); |