]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
dm: core: Support accessing core tags
authorSimon Glass <sjg@chromium.org>
Sun, 8 May 2022 10:39:24 +0000 (04:39 -0600)
committerSimon Glass <sjg@chromium.org>
Tue, 28 Jun 2022 02:09:52 +0000 (03:09 +0100)
At present tag numbers are only allocated for non-core data, meaning that
the 'core' data, like priv and plat, are accessed through dedicated
functions.

For debugging and consistency it is convenient to use tags for this 'core'
data too. Add support for this, with new tag numbers and functions to
access the pointer and size for each.

Update one of the test drivers so that the uclass-private data can be
tested here.

There is some code duplication with functions like device_alloc_priv() but
this is not addressed for now. At some point, some rationalisation may
help to reduce code size, but more thought it needed on that.

Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/core/device.c
drivers/misc/test_drv.c
include/dm/device.h
include/dm/tag.h
test/dm/core.c
tools/dtoc/test_dtoc.py

index 7f71570a940ab545384f3c145643513b18ec5dd9..d9ce546c0c440cb5ea481d2a3c8f94b2d52d5f41 100644 (file)
@@ -674,6 +674,71 @@ void *dev_get_parent_priv(const struct udevice *dev)
        return dm_priv_to_rw(dev->parent_priv_);
 }
 
+void *dev_get_attach_ptr(const struct udevice *dev, enum dm_tag_t tag)
+{
+       switch (tag) {
+       case DM_TAG_PLAT:
+               return dev_get_plat(dev);
+       case DM_TAG_PARENT_PLAT:
+               return dev_get_parent_plat(dev);
+       case DM_TAG_UC_PLAT:
+               return dev_get_uclass_plat(dev);
+       case DM_TAG_PRIV:
+               return dev_get_priv(dev);
+       case DM_TAG_PARENT_PRIV:
+               return dev_get_parent_priv(dev);
+       case DM_TAG_UC_PRIV:
+               return dev_get_uclass_priv(dev);
+       default:
+               return NULL;
+       }
+}
+
+int dev_get_attach_size(const struct udevice *dev, enum dm_tag_t tag)
+{
+       const struct udevice *parent = dev_get_parent(dev);
+       const struct uclass *uc = dev->uclass;
+       const struct uclass_driver *uc_drv = uc->uc_drv;
+       const struct driver *parent_drv = NULL;
+       int size = 0;
+
+       if (parent)
+               parent_drv = parent->driver;
+
+       switch (tag) {
+       case DM_TAG_PLAT:
+               size = dev->driver->plat_auto;
+               break;
+       case DM_TAG_PARENT_PLAT:
+               if (parent) {
+                       size = parent_drv->per_child_plat_auto;
+                       if (!size)
+                               size = parent->uclass->uc_drv->per_child_plat_auto;
+               }
+               break;
+       case DM_TAG_UC_PLAT:
+               size = uc_drv->per_device_plat_auto;
+               break;
+       case DM_TAG_PRIV:
+               size = dev->driver->priv_auto;
+               break;
+       case DM_TAG_PARENT_PRIV:
+               if (parent) {
+                       size = parent_drv->per_child_auto;
+                       if (!size)
+                               size = parent->uclass->uc_drv->per_child_auto;
+               }
+               break;
+       case DM_TAG_UC_PRIV:
+               size = uc_drv->per_device_auto;
+               break;
+       default:
+               break;
+       }
+
+       return size;
+}
+
 static int device_get_device_tail(struct udevice *dev, int ret,
                                  struct udevice **devp)
 {
index b6df118903229c5c5cb99b13413d2b5294fe7c90..927618256f0ac88d73cf6e1955a8412a7101a2d0 100644 (file)
@@ -108,7 +108,9 @@ UCLASS_DRIVER(testbus) = {
        .child_pre_probe = testbus_child_pre_probe_uclass,
        .child_post_probe = testbus_child_post_probe_uclass,
 
-       /* This is for dtoc testing only */
+       .per_device_auto   = sizeof(struct dm_test_uclass_priv),
+
+       /* Note: this is for dtoc testing as well as tags*/
        .per_device_plat_auto   = sizeof(struct dm_test_uclass_plat),
 };
 
index 5bdb10653f8e3725f55e6692da301f5171bf1ff1..12c6ba37ff37070ee5b2a0e05a6b0e972722419f 100644 (file)
@@ -11,6 +11,7 @@
 #define _DM_DEVICE_H
 
 #include <dm/ofnode.h>
+#include <dm/tag.h>
 #include <dm/uclass-id.h>
 #include <fdtdec.h>
 #include <linker_lists.h>
@@ -546,6 +547,30 @@ void *dev_get_parent_priv(const struct udevice *dev);
  */
 void *dev_get_uclass_priv(const struct udevice *dev);
 
+/**
+ * dev_get_attach_ptr() - Get the value of an attached pointed tag
+ *
+ * The tag is assumed to hold a pointer, if it exists
+ *
+ * @dev: Device to look at
+ * @tag: Tag to access
+ * @return value of tag, or NULL if there is no tag of this type
+ */
+void *dev_get_attach_ptr(const struct udevice *dev, enum dm_tag_t tag);
+
+/**
+ * dev_get_attach_size() - Get the size of an attached tag
+ *
+ * Core tags have an automatic-allocation mechanism where the allocated size is
+ * defined by the device, parent or uclass. This returns the size associated
+ * with a particular tag
+ *
+ * @dev: Device to look at
+ * @tag: Tag to access
+ * @return size of auto-allocated data, 0 if none
+ */
+int dev_get_attach_size(const struct udevice *dev, enum dm_tag_t tag);
+
 /**
  * dev_get_parent() - Get the parent of a device
  *
index 54fc31eb1539d00ed82d424876130a2ba267447b..9cb5d68f0a3791e43515d2e29c3be9101b0c57c4 100644 (file)
 struct udevice;
 
 enum dm_tag_t {
+       /* Types of core tags that can be attached to devices */
+       DM_TAG_PLAT,
+       DM_TAG_PARENT_PLAT,
+       DM_TAG_UC_PLAT,
+
+       DM_TAG_PRIV,
+       DM_TAG_PARENT_PRIV,
+       DM_TAG_UC_PRIV,
+       DM_TAG_DRIVER_DATA,
+       DM_TAG_ATTACH_COUNT,
+
        /* EFI_LOADER */
-       DM_TAG_EFI = 0,
+       DM_TAG_EFI = DM_TAG_ATTACH_COUNT,
 
        DM_TAG_COUNT,
 };
index ebd504427d13bfddae4f17b88c215015fa1bac32..26e2fd56619ab10225a51df7d283b359e02ffb5d 100644 (file)
@@ -1275,3 +1275,83 @@ static int dm_test_uclass_find_device(struct unit_test_state *uts)
        return 0;
 }
 DM_TEST(dm_test_uclass_find_device, UT_TESTF_SCAN_FDT);
+
+/* Test getting information about tags attached to devices */
+static int dm_test_dev_get_attach(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+
+       ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev));
+       ut_asserteq_str("a-test", dev->name);
+
+       ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_PLAT));
+       ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_PRIV));
+       ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_UC_PRIV));
+       ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_UC_PLAT));
+       ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_PARENT_PLAT));
+       ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_PARENT_PRIV));
+
+       ut_asserteq(sizeof(struct dm_test_pdata),
+                   dev_get_attach_size(dev, DM_TAG_PLAT));
+       ut_asserteq(sizeof(struct dm_test_priv),
+                   dev_get_attach_size(dev, DM_TAG_PRIV));
+       ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_UC_PRIV));
+       ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_UC_PLAT));
+       ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_PARENT_PLAT));
+       ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_PARENT_PRIV));
+
+       return 0;
+}
+DM_TEST(dm_test_dev_get_attach, UT_TESTF_SCAN_FDT);
+
+/* Test getting information about tags attached to bus devices */
+static int dm_test_dev_get_attach_bus(struct unit_test_state *uts)
+{
+       struct udevice *dev, *child;
+
+       ut_assertok(uclass_first_device_err(UCLASS_TEST_BUS, &dev));
+       ut_asserteq_str("some-bus", dev->name);
+
+       ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_PLAT));
+       ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_PRIV));
+       ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_UC_PRIV));
+       ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_UC_PLAT));
+       ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_PARENT_PLAT));
+       ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_PARENT_PRIV));
+
+       ut_asserteq(sizeof(struct dm_test_pdata),
+                   dev_get_attach_size(dev, DM_TAG_PLAT));
+       ut_asserteq(sizeof(struct dm_test_priv),
+                   dev_get_attach_size(dev, DM_TAG_PRIV));
+       ut_asserteq(sizeof(struct dm_test_uclass_priv),
+                   dev_get_attach_size(dev, DM_TAG_UC_PRIV));
+       ut_asserteq(sizeof(struct dm_test_uclass_plat),
+                   dev_get_attach_size(dev, DM_TAG_UC_PLAT));
+       ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_PARENT_PLAT));
+       ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_PARENT_PRIV));
+
+       /* Now try the child of the bus */
+       ut_assertok(device_first_child_err(dev, &child));
+       ut_asserteq_str("c-test@5", child->name);
+
+       ut_assertnonnull(dev_get_attach_ptr(child, DM_TAG_PLAT));
+       ut_assertnonnull(dev_get_attach_ptr(child, DM_TAG_PRIV));
+       ut_assertnull(dev_get_attach_ptr(child, DM_TAG_UC_PRIV));
+       ut_assertnull(dev_get_attach_ptr(child, DM_TAG_UC_PLAT));
+       ut_assertnonnull(dev_get_attach_ptr(child, DM_TAG_PARENT_PLAT));
+       ut_assertnonnull(dev_get_attach_ptr(child, DM_TAG_PARENT_PRIV));
+
+       ut_asserteq(sizeof(struct dm_test_pdata),
+                   dev_get_attach_size(child, DM_TAG_PLAT));
+       ut_asserteq(sizeof(struct dm_test_priv),
+                   dev_get_attach_size(child, DM_TAG_PRIV));
+       ut_asserteq(0, dev_get_attach_size(child, DM_TAG_UC_PRIV));
+       ut_asserteq(0, dev_get_attach_size(child, DM_TAG_UC_PLAT));
+       ut_asserteq(sizeof(struct dm_test_parent_plat),
+                   dev_get_attach_size(child, DM_TAG_PARENT_PLAT));
+       ut_asserteq(sizeof(struct dm_test_parent_data),
+                   dev_get_attach_size(child, DM_TAG_PARENT_PRIV));
+
+       return 0;
+}
+DM_TEST(dm_test_dev_get_attach_bus, UT_TESTF_SCAN_FDT);
index 8bac207621423af9c39574eb14132aab77b79f4e..879ca2ab2bfc9b00780f2ee2069c45548d555b3a 100755 (executable)
@@ -618,6 +618,9 @@ u8 _denx_u_boot_test_bus_priv_some_bus[sizeof(struct dm_test_priv)]
 #include <dm/test.h>
 u8 _denx_u_boot_test_bus_ucplat_some_bus[sizeof(struct dm_test_uclass_plat)]
 \t__attribute__ ((section (".priv_data")));
+#include <dm/test.h>
+u8 _denx_u_boot_test_bus_uc_priv_some_bus[sizeof(struct dm_test_uclass_priv)]
+       __attribute__ ((section (".priv_data")));
 #include <test.h>
 
 DM_DEVICE_INST(some_bus) = {
@@ -628,6 +631,7 @@ DM_DEVICE_INST(some_bus) = {
 \t.driver_data\t= DM_TEST_TYPE_FIRST,
 \t.priv_\t\t= _denx_u_boot_test_bus_priv_some_bus,
 \t.uclass\t\t= DM_UCLASS_REF(testbus),
+\t.uclass_priv_ = _denx_u_boot_test_bus_uc_priv_some_bus,
 \t.uclass_node\t= {
 \t\t.prev = &DM_UCLASS_REF(testbus)->dev_head,
 \t\t.next = &DM_UCLASS_REF(testbus)->dev_head,