diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/dm/Makefile | 1 | ||||
-rw-r--r-- | test/dm/blk.c | 27 | ||||
-rw-r--r-- | test/dm/bus.c | 47 | ||||
-rw-r--r-- | test/dm/pci.c | 20 | ||||
-rw-r--r-- | test/dm/regmap.c | 30 | ||||
-rw-r--r-- | test/dm/test-fdt.c | 36 | ||||
-rw-r--r-- | test/dm/virtio.c | 122 |
7 files changed, 260 insertions, 23 deletions
diff --git a/test/dm/Makefile b/test/dm/Makefile index b490cf2862..213e0fda94 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -53,4 +53,5 @@ obj-$(CONFIG_MISC) += misc.o obj-$(CONFIG_DM_SERIAL) += serial.o obj-$(CONFIG_CPU) += cpu.o obj-$(CONFIG_TEE) += tee.o +obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o endif diff --git a/test/dm/blk.c b/test/dm/blk.c index 4de477bafa..9c71adc69d 100644 --- a/test/dm/blk.c +++ b/test/dm/blk.c @@ -15,34 +15,29 @@ DECLARE_GLOBAL_DATA_PTR; /* Test that block devices can be created */ static int dm_test_blk_base(struct unit_test_state *uts) { - struct udevice *blk, *usb_blk, *dev; + struct udevice *blk1, *blk3, *dev; /* Make sure there are no block devices */ - ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_BLK, 0, &blk)); + ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_BLK, 0, &dev)); /* Create two, one the parent of the other */ ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test", - IF_TYPE_HOST, 1, 512, 2, &blk)); - ut_assertok(blk_create_device(blk, "usb_storage_blk", "test", - IF_TYPE_USB, 3, 512, 2, &usb_blk)); + IF_TYPE_HOST, 1, 512, 2, &blk1)); + ut_assertok(blk_create_device(blk1, "sandbox_host_blk", "test", + IF_TYPE_HOST, 3, 512, 2, &blk3)); /* Check we can find them */ ut_asserteq(-ENODEV, blk_get_device(IF_TYPE_HOST, 0, &dev)); ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev)); - ut_asserteq_ptr(blk, dev); - - ut_asserteq(-ENODEV, blk_get_device(IF_TYPE_USB, 0, &dev)); - ut_assertok(blk_get_device(IF_TYPE_USB, 3, &dev)); - ut_asserteq_ptr(usb_blk, dev); + ut_asserteq_ptr(blk1, dev); + ut_assertok(blk_get_device(IF_TYPE_HOST, 3, &dev)); + ut_asserteq_ptr(blk3, dev); /* Check we can iterate */ ut_assertok(blk_first_device(IF_TYPE_HOST, &dev)); - ut_asserteq_ptr(blk, dev); - ut_asserteq(-ENODEV, blk_next_device(&dev)); - - ut_assertok(blk_first_device(IF_TYPE_USB, &dev)); - ut_asserteq_ptr(usb_blk, dev); - ut_asserteq(-ENODEV, blk_next_device(&dev)); + ut_asserteq_ptr(blk1, dev); + ut_assertok(blk_next_device(&dev)); + ut_asserteq_ptr(blk3, dev); return 0; } diff --git a/test/dm/bus.c b/test/dm/bus.c index 08137a2216..93f3acd430 100644 --- a/test/dm/bus.c +++ b/test/dm/bus.c @@ -63,6 +63,15 @@ static int testbus_child_pre_probe_uclass(struct udevice *dev) return 0; } +static int testbus_child_post_probe_uclass(struct udevice *dev) +{ + struct dm_test_priv *priv = dev_get_priv(dev); + + priv->uclass_postp++; + + return 0; +} + static int testbus_child_post_remove(struct udevice *dev) { struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev); @@ -102,12 +111,13 @@ UCLASS_DRIVER(testbus) = { .id = UCLASS_TEST_BUS, .flags = DM_UC_FLAG_SEQ_ALIAS, .child_pre_probe = testbus_child_pre_probe_uclass, + .child_post_probe = testbus_child_post_probe_uclass, }; /* Test that we can probe for children */ static int dm_test_bus_children(struct unit_test_state *uts) { - int num_devices = 7; + int num_devices = 8; struct udevice *bus; struct uclass *uc; @@ -547,3 +557,38 @@ static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts) } DM_TEST(dm_test_bus_child_pre_probe_uclass, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* + * Test that the bus' uclass' child_post_probe() is called after the + * device's probe() method + */ +static int dm_test_bus_child_post_probe_uclass(struct unit_test_state *uts) +{ + struct udevice *bus, *dev; + int child_count; + + /* + * See testfdt_drv_probe() which effectively initializes that + * the uclass postp flag is set to a value + */ + ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); + for (device_find_first_child(bus, &dev), child_count = 0; + dev; + device_find_next_child(&dev)) { + struct dm_test_priv *priv = dev_get_priv(dev); + + /* Check that things happened in the right order */ + ut_asserteq_ptr(NULL, priv); + ut_assertok(device_probe(dev)); + + priv = dev_get_priv(dev); + ut_assert(priv != NULL); + ut_asserteq(0, priv->uclass_postp); + child_count++; + } + ut_asserteq(3, child_count); + + return 0; +} +DM_TEST(dm_test_bus_child_post_probe_uclass, + DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/pci.c b/test/dm/pci.c index a1dedd84a7..a1febd54b7 100644 --- a/test/dm/pci.c +++ b/test/dm/pci.c @@ -211,6 +211,16 @@ static int dm_test_pci_cap(struct unit_test_state *uts) cap = dm_pci_find_capability(swap, PCI_CAP_ID_PCIX); ut_asserteq(0, cap); + /* look up PCI_CAP_ID_MSIX starting from PCI_CAP_ID_PM_OFFSET */ + cap = dm_pci_find_next_capability(swap, PCI_CAP_ID_PM_OFFSET, + PCI_CAP_ID_MSIX); + ut_asserteq(PCI_CAP_ID_MSIX_OFFSET, cap); + + /* look up PCI_CAP_ID_VNDR starting from PCI_CAP_ID_EXP_OFFSET */ + cap = dm_pci_find_next_capability(swap, PCI_CAP_ID_EXP_OFFSET, + PCI_CAP_ID_VNDR); + ut_asserteq(0, cap); + ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 1, &bus)); ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &swap)); @@ -222,6 +232,16 @@ static int dm_test_pci_cap(struct unit_test_state *uts) cap = dm_pci_find_ext_capability(swap, PCI_EXT_CAP_ID_SRIOV); ut_asserteq(0, cap); + /* look up PCI_EXT_CAP_ID_DSN starting from PCI_EXT_CAP_ID_ERR_OFFSET */ + cap = dm_pci_find_next_ext_capability(swap, PCI_EXT_CAP_ID_ERR_OFFSET, + PCI_EXT_CAP_ID_DSN); + ut_asserteq(PCI_EXT_CAP_ID_DSN_OFFSET, cap); + + /* look up PCI_EXT_CAP_ID_RCRB starting from PCI_EXT_CAP_ID_VC_OFFSET */ + cap = dm_pci_find_next_ext_capability(swap, PCI_EXT_CAP_ID_VC_OFFSET, + PCI_EXT_CAP_ID_RCRB); + ut_asserteq(0, cap); + return 0; } DM_TEST(dm_test_pci_cap, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/regmap.c b/test/dm/regmap.c index d4b86b3b03..a8d7e6829e 100644 --- a/test/dm/regmap.c +++ b/test/dm/regmap.c @@ -25,7 +25,7 @@ static int dm_test_regmap_base(struct unit_test_state *uts) ut_assertok_ptr(map); ut_asserteq(1, map->range_count); ut_asserteq(0x10, map->ranges[0].start); - ut_asserteq(4, map->ranges[0].size); + ut_asserteq(16, map->ranges[0].size); ut_asserteq(0x10, map_to_sysmem(regmap_get_range(map, 0))); ut_assertok(uclass_get_device(UCLASS_SYSCON, 1, &dev)); @@ -116,3 +116,31 @@ static int dm_test_regmap_rw(struct unit_test_state *uts) } DM_TEST(dm_test_regmap_rw, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Get/Set test */ +static int dm_test_regmap_getset(struct unit_test_state *uts) +{ + struct udevice *dev; + struct regmap *map; + uint reg; + struct layout { + u32 val0; + u32 val1; + u32 val2; + u32 val3; + }; + + ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev)); + map = syscon_get_regmap(dev); + ut_assertok_ptr(map); + + regmap_set(map, struct layout, val0, 0xcacafafa); + regmap_set(map, struct layout, val3, 0x55aa2211); + + ut_assertok(regmap_get(map, struct layout, val0, ®)); + ut_assertok(regmap_get(map, struct layout, val3, ®)); + + return 0; +} + +DM_TEST(dm_test_regmap_getset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 79b1f1de45..e43acb21d5 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -55,10 +55,13 @@ static int testfdt_drv_probe(struct udevice *dev) /* * If this device is on a bus, the uclass_flag will be set before - * calling this function. This is used by - * dm_test_bus_child_pre_probe_uclass(). + * calling this function. In the meantime the uclass_postp is + * initlized to a value -1. These are used respectively by + * dm_test_bus_child_pre_probe_uclass() and + * dm_test_bus_child_post_probe_uclass(). */ priv->uclass_total += priv->uclass_flag; + priv->uclass_postp = -1; return 0; } @@ -84,6 +87,25 @@ U_BOOT_DRIVER(testfdt_drv) = { .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), }; +static const struct udevice_id testfdt1_ids[] = { + { + .compatible = "denx,u-boot-fdt-test1", + .data = DM_TEST_TYPE_FIRST }, + { } +}; + +U_BOOT_DRIVER(testfdt1_drv) = { + .name = "testfdt1_drv", + .of_match = testfdt1_ids, + .id = UCLASS_TEST_FDT, + .ofdata_to_platdata = testfdt_ofdata_to_platdata, + .probe = testfdt_drv_probe, + .ops = &test_ops, + .priv_auto_alloc_size = sizeof(struct dm_test_priv), + .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), + .flags = DM_FLAG_PRE_RELOC, +}; + /* From here is the testfdt uclass code */ int testfdt_ping(struct udevice *dev, int pingval, int *pingret) { @@ -168,7 +190,7 @@ int dm_check_devices(struct unit_test_state *uts, int num_devices) /* Test that FDT-based binding works correctly */ static int dm_test_fdt(struct unit_test_state *uts) { - const int num_devices = 7; + const int num_devices = 8; struct udevice *dev; struct uclass *uc; int ret; @@ -208,8 +230,12 @@ static int dm_test_fdt_pre_reloc(struct unit_test_state *uts) ret = uclass_get(UCLASS_TEST_FDT, &uc); ut_assert(!ret); - /* These is only one pre-reloc device */ - ut_asserteq(1, list_count_items(&uc->dev_head)); + /* + * These are 2 pre-reloc devices: + * one with "u-boot,dm-pre-reloc" property (a-test node), and the other + * one whose driver marked with DM_FLAG_PRE_RELOC flag (h-test node). + */ + ut_asserteq(2, list_count_items(&uc->dev_head)); return 0; } diff --git a/test/dm/virtio.c b/test/dm/virtio.c new file mode 100644 index 0000000000..4b317d2ec3 --- /dev/null +++ b/test/dm/virtio.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <common.h> +#include <dm.h> +#include <virtio_types.h> +#include <virtio.h> +#include <virtio_ring.h> +#include <dm/device-internal.h> +#include <dm/uclass-internal.h> +#include <dm/root.h> +#include <dm/test.h> +#include <test/ut.h> + +/* Basic test of the virtio uclass */ +static int dm_test_virtio_base(struct unit_test_state *uts) +{ + struct udevice *bus, *dev; + u8 status; + + /* check probe success */ + ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus)); + + /* check the child virtio-blk device is bound */ + ut_assertok(device_find_first_child(bus, &dev)); + ut_assertok(strcmp(dev->name, "virtio-blk#0")); + + /* check driver status */ + ut_assertok(virtio_get_status(dev, &status)); + ut_asserteq(VIRTIO_CONFIG_S_ACKNOWLEDGE, status); + + return 0; +} +DM_TEST(dm_test_virtio_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test all of the virtio uclass ops */ +static int dm_test_virtio_all_ops(struct unit_test_state *uts) +{ + struct udevice *bus, *dev; + struct virtio_dev_priv *uc_priv; + uint offset = 0, len = 0, nvqs = 1; + void *buffer = NULL; + u8 status; + u32 counter; + u64 features; + struct virtqueue *vqs[2]; + + /* check probe success */ + ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus)); + + /* check the child virtio-blk device is bound */ + ut_assertok(device_find_first_child(bus, &dev)); + + /* + * fake the virtio device probe by filling in uc_priv->vdev + * which is used by virtio_find_vqs/virtio_del_vqs. + */ + uc_priv = dev_get_uclass_priv(bus); + uc_priv->vdev = dev; + + /* test virtio_xxx APIs */ + ut_assertok(virtio_get_config(dev, offset, buffer, len)); + ut_assertok(virtio_set_config(dev, offset, buffer, len)); + ut_asserteq(-ENOSYS, virtio_generation(dev, &counter)); + ut_assertok(virtio_set_status(dev, VIRTIO_CONFIG_S_DRIVER_OK)); + ut_assertok(virtio_get_status(dev, &status)); + ut_asserteq(VIRTIO_CONFIG_S_DRIVER_OK, status); + ut_assertok(virtio_reset(dev)); + ut_assertok(virtio_get_status(dev, &status)); + ut_asserteq(0, status); + ut_assertok(virtio_get_features(dev, &features)); + ut_asserteq(VIRTIO_F_VERSION_1, features); + ut_assertok(virtio_set_features(dev)); + ut_assertok(virtio_find_vqs(dev, nvqs, vqs)); + ut_assertok(virtio_del_vqs(dev)); + ut_assertok(virtio_notify(dev, vqs[0])); + + return 0; +} +DM_TEST(dm_test_virtio_all_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test of the virtio driver that does not have required driver ops */ +static int dm_test_virtio_missing_ops(struct unit_test_state *uts) +{ + struct udevice *bus; + + /* find the virtio device */ + ut_assertok(uclass_find_device(UCLASS_VIRTIO, 1, &bus)); + + /* + * Probe the device should fail with error -ENOENT. + * See ops check in virtio_uclass_pre_probe(). + */ + ut_asserteq(-ENOENT, device_probe(bus)); + + return 0; +} +DM_TEST(dm_test_virtio_missing_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test removal of virtio device driver */ +static int dm_test_virtio_remove(struct unit_test_state *uts) +{ + struct udevice *bus, *dev; + + /* check probe success */ + ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus)); + + /* check the child virtio-blk device is bound */ + ut_assertok(device_find_first_child(bus, &dev)); + + /* set driver status to VIRTIO_CONFIG_S_DRIVER_OK */ + ut_assertok(virtio_set_status(dev, VIRTIO_CONFIG_S_DRIVER_OK)); + + /* check the device can be successfully removed */ + dev->flags |= DM_FLAG_ACTIVATED; + ut_assertok(device_remove(bus, DM_REMOVE_ACTIVE_ALL)); + + return 0; +} +DM_TEST(dm_test_virtio_remove, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); |