From 7a0d88076b9cd8ccc88d41383f92ac2494d4168e Mon Sep 17 00:00:00 2001 From: Nathan Barrett-Morrison Date: Wed, 2 Feb 2022 15:05:18 -0500 Subject: Add in the ability to load and boot an uncompressed kernel image during the Falcon Mode boot sequence. This is required for architectures which do not support compressed kernel images (i.e. ARM64). This is only used while not booting via FIT image. Signed-off-by: Nathan Barrett-Morrison Cc: Tom Rini Reviewed-by: Tom Rini --- arch/arm/lib/Makefile | 5 ++++- common/spl/spl.c | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index d137b4b..62cf80f 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -35,7 +35,10 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o else obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o -obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o +ifdef CONFIG_SPL_FRAMEWORK +obj-$(CONFIG_CMD_BOOTI) += image.o +obj-$(CONFIG_CMD_BOOTZ) += zimage.o +endif obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o endif ifdef CONFIG_ARM64 diff --git a/common/spl/spl.c b/common/spl/spl.c index 29e0898..828f72f 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -116,6 +116,11 @@ int __weak bootz_setup(ulong image, ulong *start, ulong *end) { return 1; } + +int __weak booti_setup(ulong image, ulong *relocated_addr, ulong *size, bool force_reloc) +{ + return 1; +} #endif /* Weak default function for arch/board-specific fixups to the spl_image_info */ @@ -391,6 +396,21 @@ int spl_parse_image_header(struct spl_image_info *spl_image, #endif #if CONFIG_IS_ENABLED(OS_BOOT) +#if defined(CMD_BOOTI) + ulong start, size; + + if (!booti_setup((ulong)header, &start, &size, 0)) { + spl_image->name = "Linux"; + spl_image->os = IH_OS_LINUX; + spl_image->load_addr = start; + spl_image->entry_point = start; + spl_image->size = size; + debug(SPL_TPL_PROMPT + "payload Image, load addr: 0x%lx size: %d\n", + spl_image->load_addr, spl_image->size); + return 0; + } +#elif defined(CMD_BOOTZ) ulong start, end; if (!bootz_setup((ulong)header, &start, &end)) { @@ -405,6 +425,7 @@ int spl_parse_image_header(struct spl_image_info *spl_image, return 0; } #endif +#endif if (!spl_parse_board_header(spl_image, bootdev, (const void *)header, sizeof(*header))) return 0; -- cgit v1.1 From b471bdc47b2acabe0b5fcb0fb40a0b1c0602d3b3 Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Tue, 14 Jun 2022 15:21:30 +0200 Subject: dm: core: Add functions to read 8/16-bit integers Add functions to read 8/16-bit integers like the existing functions for 32/64-bit to simplify read of 8/16-bit integers from device tree properties. Signed-off-by: Stefan Herbrechtsmeier Reviewed-by: Marek Vasut Reviewed-by: Simon Glass Reviewed-by: Simon Glass --- arch/sandbox/dts/test.dts | 2 ++ drivers/core/of_access.c | 38 +++++++++++++++++++++++++++ drivers/core/ofnode.c | 62 ++++++++++++++++++++++++++++++++++++++++++++ drivers/core/read.c | 21 +++++++++++++++ include/dm/of_access.h | 32 +++++++++++++++++++++++ include/dm/ofnode.h | 40 +++++++++++++++++++++++++++++ include/dm/read.h | 65 +++++++++++++++++++++++++++++++++++++++++++++++ test/dm/test-fdt.c | 19 ++++++++++++++ 8 files changed, 279 insertions(+) diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 2761588..c7fffa2 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -233,6 +233,8 @@ test5-gpios = <&gpio_a 19>; bool-value; + int8-value = /bits/ 8 <0x12>; + int16-value = /bits/ 16 <0x1234>; int-value = <1234>; uint-value = <(-1234)>; int64-value = /bits/ 64 <0x1111222233334444>; diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index a52f5a6..df007e6 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -488,6 +488,44 @@ static void *of_find_property_value_of_size(const struct device_node *np, return prop->value; } +int of_read_u8(const struct device_node *np, const char *propname, u8 *outp) +{ + const u8 *val; + + debug("%s: %s: ", __func__, propname); + if (!np) + return -EINVAL; + val = of_find_property_value_of_size(np, propname, sizeof(*outp)); + if (IS_ERR(val)) { + debug("(not found)\n"); + return PTR_ERR(val); + } + + *outp = *val; + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + +int of_read_u16(const struct device_node *np, const char *propname, u16 *outp) +{ + const __be16 *val; + + debug("%s: %s: ", __func__, propname); + if (!np) + return -EINVAL; + val = of_find_property_value_of_size(np, propname, sizeof(*outp)); + if (IS_ERR(val)) { + debug("(not found)\n"); + return PTR_ERR(val); + } + + *outp = be16_to_cpup(val); + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + int of_read_u32(const struct device_node *np, const char *propname, u32 *outp) { return of_read_u32_index(np, propname, 0, outp); diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 45ea84e..42f3c09 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -31,6 +31,68 @@ bool ofnode_name_eq(ofnode node, const char *name) return (strlen(name) == len) && !strncmp(node_name, name, len); } +int ofnode_read_u8(ofnode node, const char *propname, u8 *outp) +{ + const u8 *cell; + int len; + + assert(ofnode_valid(node)); + debug("%s: %s: ", __func__, propname); + + if (ofnode_is_np(node)) + return of_read_u8(ofnode_to_np(node), propname, outp); + + cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, + &len); + if (!cell || len < sizeof(*cell)) { + debug("(not found)\n"); + return -EINVAL; + } + *outp = *cell; + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + +u8 ofnode_read_u8_default(ofnode node, const char *propname, u8 def) +{ + assert(ofnode_valid(node)); + ofnode_read_u8(node, propname, &def); + + return def; +} + +int ofnode_read_u16(ofnode node, const char *propname, u16 *outp) +{ + const fdt16_t *cell; + int len; + + assert(ofnode_valid(node)); + debug("%s: %s: ", __func__, propname); + + if (ofnode_is_np(node)) + return of_read_u16(ofnode_to_np(node), propname, outp); + + cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, + &len); + if (!cell || len < sizeof(*cell)) { + debug("(not found)\n"); + return -EINVAL; + } + *outp = be16_to_cpup(cell); + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + +u16 ofnode_read_u16_default(ofnode node, const char *propname, u16 def) +{ + assert(ofnode_valid(node)); + ofnode_read_u16(node, propname, &def); + + return def; +} + int ofnode_read_u32(ofnode node, const char *propname, u32 *outp) { return ofnode_read_u32_index(node, propname, 0, outp); diff --git a/drivers/core/read.c b/drivers/core/read.c index c73508d..07ab8ab 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -13,6 +13,27 @@ #include #include +int dev_read_u8(const struct udevice *dev, const char *propname, u8 *outp) +{ + return ofnode_read_u8(dev_ofnode(dev), propname, outp); +} + +u8 dev_read_u8_default(const struct udevice *dev, const char *propname, u8 def) +{ + return ofnode_read_u8_default(dev_ofnode(dev), propname, def); +} + +int dev_read_u16(const struct udevice *dev, const char *propname, u16 *outp) +{ + return ofnode_read_u16(dev_ofnode(dev), propname, outp); +} + +u16 dev_read_u16_default(const struct udevice *dev, const char *propname, + u16 def) +{ + return ofnode_read_u16_default(dev_ofnode(dev), propname, def); +} + int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp) { return ofnode_read_u32(dev_ofnode(dev), propname, outp); diff --git a/include/dm/of_access.h b/include/dm/of_access.h index 5b7821d..83f34f0 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -265,6 +265,38 @@ struct device_node *of_find_node_by_prop_value(struct device_node *from, struct device_node *of_find_node_by_phandle(phandle handle); /** + * of_read_u8() - Find and read a 8-bit integer from a property + * + * Search for a property in a device node and read a 8-bit value from + * it. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @outp: pointer to return value, modified only if return value is 0. + * + * Return: 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + */ +int of_read_u8(const struct device_node *np, const char *propname, u8 *outp); + +/** + * of_read_u16() - Find and read a 16-bit integer from a property + * + * Search for a property in a device node and read a 16-bit value from + * it. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @outp: pointer to return value, modified only if return value is 0. + * + * Return: 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + */ +int of_read_u16(const struct device_node *np, const char *propname, u16 *outp); + +/** * of_read_u32() - Find and read a 32-bit integer from a property * * Search for a property in a device node and read a 32-bit value from diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 7ce1e4c..f608523 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -222,6 +222,46 @@ static inline oftree oftree_default(void) bool ofnode_name_eq(ofnode node, const char *name); /** + * ofnode_read_u8() - Read a 8-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * Return: 0 if OK, -ve on error + */ +int ofnode_read_u8(ofnode node, const char *propname, u8 *outp); + +/** + * ofnode_read_u8_default() - Read a 8-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * Return: property value, or @def if not found + */ +u8 ofnode_read_u8_default(ofnode node, const char *propname, u8 def); + +/** + * ofnode_read_u16() - Read a 16-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * Return: 0 if OK, -ve on error + */ +int ofnode_read_u16(ofnode node, const char *propname, u16 *outp); + +/** + * ofnode_read_u16_default() - Read a 16-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * Return: property value, or @def if not found + */ +u16 ofnode_read_u16_default(ofnode node, const char *propname, u16 def); + +/** * ofnode_read_u32() - Read a 32-bit integer from a property * * @node: valid node reference to read property from diff --git a/include/dm/read.h b/include/dm/read.h index 1b54b69..122b9cd 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -32,6 +32,47 @@ static inline const struct device_node *dev_np(const struct udevice *dev) #if !defined(CONFIG_DM_DEV_READ_INLINE) || CONFIG_IS_ENABLED(OF_PLATDATA) /** + * dev_read_u8() - read a 8-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * Return: 0 if OK, -ve on error + */ +int dev_read_u8(const struct udevice *dev, const char *propname, u8 *outp); + +/** + * dev_read_u8_default() - read a 8-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * Return: property value, or @def if not found + */ +u8 dev_read_u8_default(const struct udevice *dev, const char *propname, u8 def); + +/** + * dev_read_u16() - read a 16-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * Return: 0 if OK, -ve on error + */ +int dev_read_u16(const struct udevice *dev, const char *propname, u16 *outp); + +/** + * dev_read_u16_default() - read a 16-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * Return: property value, or @def if not found + */ +u16 dev_read_u16_default(const struct udevice *dev, const char *propname, + u16 def); + +/** * dev_read_u32() - read a 32-bit integer from a device's DT property * * @dev: device to read DT property from @@ -772,6 +813,30 @@ phy_interface_t dev_read_phy_mode(const struct udevice *dev); #else /* CONFIG_DM_DEV_READ_INLINE is enabled */ #include +static inline int dev_read_u8(const struct udevice *dev, + const char *propname, u8 *outp) +{ + return ofnode_read_u8(dev_ofnode(dev), propname, outp); +} + +static inline int dev_read_u8_default(const struct udevice *dev, + const char *propname, u8 def) +{ + return ofnode_read_u8_default(dev_ofnode(dev), propname, def); +} + +static inline int dev_read_u16(const struct udevice *dev, + const char *propname, u16 *outp) +{ + return ofnode_read_u16(dev_ofnode(dev), propname, outp); +} + +static inline int dev_read_u16_default(const struct udevice *dev, + const char *propname, u16 def) +{ + return ofnode_read_u16_default(dev_ofnode(dev), propname, def); +} + static inline int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp) { diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 6118ad4..012f2f4 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -815,6 +815,8 @@ DM_TEST(dm_test_first_child, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); static int dm_test_read_int(struct unit_test_state *uts) { struct udevice *dev; + u8 val8; + u16 val16; u32 val32; s32 sval; uint val; @@ -822,6 +824,23 @@ static int dm_test_read_int(struct unit_test_state *uts) ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev)); ut_asserteq_str("a-test", dev->name); + + ut_assertok(dev_read_u8(dev, "int8-value", &val8)); + ut_asserteq(0x12, val8); + + ut_asserteq(-EINVAL, dev_read_u8(dev, "missing", &val8)); + ut_asserteq(6, dev_read_u8_default(dev, "missing", 6)); + + ut_asserteq(0x12, dev_read_u8_default(dev, "int8-value", 6)); + + ut_assertok(dev_read_u16(dev, "int16-value", &val16)); + ut_asserteq(0x1234, val16); + + ut_asserteq(-EINVAL, dev_read_u16(dev, "missing", &val16)); + ut_asserteq(6, dev_read_u16_default(dev, "missing", 6)); + + ut_asserteq(0x1234, dev_read_u16_default(dev, "int16-value", 6)); + ut_assertok(dev_read_u32(dev, "int-value", &val32)); ut_asserteq(1234, val32); -- cgit v1.1 From c0facda1976f7990ad9edbaecb6802369867c1d6 Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Tue, 14 Jun 2022 15:21:31 +0200 Subject: misc: usb251xb: Support 8/16 bit device tree values The device tree binding [1] specify the vendor-id, product-id, device-id and language-id as 16 bit values and the linux driver reads the boost-up value as 8 bit value. [1] https://www.kernel.org/doc/Documentation/devicetree/bindings/usb/usb251xb.txt Signed-off-by: Stefan Herbrechtsmeier Reviewed-by: Marek Vasut --- drivers/misc/usb251xb.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/misc/usb251xb.c b/drivers/misc/usb251xb.c index 077edc2..a78ad18 100644 --- a/drivers/misc/usb251xb.c +++ b/drivers/misc/usb251xb.c @@ -400,14 +400,14 @@ static int usb251xb_of_to_plat(struct udevice *dev) } } - if (dev_read_u32(dev, "vendor-id", &hub->vendor_id)) - hub->vendor_id = USB251XB_DEF_VENDOR_ID; + hub->vendor_id = dev_read_u16_default(dev, "vendor-id", + USB251XB_DEF_VENDOR_ID); - if (dev_read_u32(dev, "product-id", &hub->product_id)) - hub->product_id = data->product_id; + hub->product_id = dev_read_u16_default(dev, "product-id", + data->product_id); - if (dev_read_u32(dev, "device-id", &hub->device_id)) - hub->device_id = USB251XB_DEF_DEVICE_ID; + hub->device_id = dev_read_u16_default(dev, "device-id", + USB251XB_DEF_DEVICE_ID); hub->conf_data1 = USB251XB_DEF_CONFIG_DATA_1; if (dev_read_bool(dev, "self-powered")) { @@ -513,11 +513,11 @@ static int usb251xb_of_to_plat(struct udevice *dev) if (!dev_read_u32(dev, "power-on-time-ms", &property_u32)) hub->power_on_time = min_t(u8, property_u32 / 2, 255); - if (dev_read_u32(dev, "language-id", &hub->lang_id)) - hub->lang_id = USB251XB_DEF_LANGUAGE_ID; + hub->lang_id = dev_read_u16_default(dev, "language-id", + USB251XB_DEF_LANGUAGE_ID); - if (!dev_read_u32(dev, "boost-up", &hub->boost_up)) - hub->boost_up = USB251XB_DEF_BOOST_UP; + hub->boost_up = dev_read_u8_default(dev, "boost-up", + USB251XB_DEF_BOOST_UP); cproperty_char = dev_read_string(dev, "manufacturer"); strlcpy(str, cproperty_char ? : USB251XB_DEF_MANUFACTURER_STRING, -- cgit v1.1 From 77253c50ab5910bf72e1e868c86940c5a2bc7bb9 Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Tue, 14 Jun 2022 16:12:00 +0200 Subject: spl: fit: Allocate buffers aligned to cache line size Allocate memory for buffers at a cache-line boundary to avoid misaligned buffer address for subsequent reads. This avoids an additional sector-based memory copy in the fat file system driver: FAT: Misaligned buffer address (...) Signed-off-by: Stefan Herbrechtsmeier --- common/spl/spl_fit.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index a35be52..c1ed31e 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -429,7 +429,9 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image, * depending on how the overlay is stored, so * don't fail yet if the allocation failed. */ - tmpbuffer = malloc(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ); + size_t size = CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ; + + tmpbuffer = malloc_cache_aligned(size); if (!tmpbuffer) debug("%s: unable to allocate space for overlays\n", __func__); @@ -537,7 +539,7 @@ static void *spl_get_fit_load_buffer(size_t size) { void *buf; - buf = malloc(size); + buf = malloc_cache_aligned(size); if (!buf) { pr_err("Could not get FIT buffer of %lu bytes\n", (ulong)size); pr_err("\tcheck CONFIG_SYS_SPL_MALLOC_SIZE\n"); -- cgit v1.1 From fd0d7a6c88fe0ae16dda95eba52c598b9fa9db2a Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 26 Jul 2022 16:21:41 +0200 Subject: drivers: tee: optee: remove unused probe local variable Removes local variable child in optee_probe() that is not used. Cc: Patrick Delaunay Reviewed-by: Patrick Delaunay Signed-off-by: Etienne Carriere --- drivers/tee/optee/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index a89d62a..c1f5fc4 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -642,7 +642,6 @@ static int optee_probe(struct udevice *dev) { struct optee_pdata *pdata = dev_get_plat(dev); u32 sec_caps; - struct udevice *child; int ret; if (!is_optee_api(pdata->invoke_fn)) { @@ -673,7 +672,7 @@ static int optee_probe(struct udevice *dev) * only bind the drivers associated to the supported OP-TEE TA */ if (IS_ENABLED(CONFIG_RNG_OPTEE)) { - ret = device_bind_driver(dev, "optee-rng", "optee-rng", &child); + ret = device_bind_driver(dev, "optee-rng", "optee-rng", NULL); if (ret) return ret; } -- cgit v1.1 From 94ccfb78a4d61cac7cbc78f23751ec1db949d29e Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 26 Jul 2022 16:21:42 +0200 Subject: drivers: tee: optee: discover OP-TEE services This change defines resources for OP-TEE service drivers to register themselves for being bound to when OP-TEE firmware reports the related service is supported. OP-TEE services are discovered during optee driver probe sequence which mandates optee driver is always probe once bound. Discovery of optee services and binding to related U-Boot drivers is embedded upon configuration switch CONFIG_OPTEE_SERVICE_DISCOVERY. Cc: Jens Wiklander Cc: Patrick Delaunay Signed-off-by: Etienne Carriere Reviewed-by: Patrick Delaunay --- drivers/tee/optee/Kconfig | 8 +++ drivers/tee/optee/core.c | 171 ++++++++++++++++++++++++++++++++++++++++++-- include/tee/optee_service.h | 34 +++++++++ 3 files changed, 208 insertions(+), 5 deletions(-) create mode 100644 include/tee/optee_service.h diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig index d030280..9dc65b0 100644 --- a/drivers/tee/optee/Kconfig +++ b/drivers/tee/optee/Kconfig @@ -37,6 +37,14 @@ config OPTEE_TA_SCP03 help Enables support for controlling (enabling, provisioning) the Secure Channel Protocol 03 operation in the OP-TEE SCP03 TA. + +config OPTEE_SERVICE_DISCOVERY + bool "OP-TEE service discovery" + default y + help + This implements automated driver binding of OP-TEE service drivers by + requesting OP-TEE firmware to enumerate its hosted services. + endmenu endif diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index c1f5fc4..9240277 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "optee_smc.h" #include "optee_msg.h" @@ -22,6 +23,25 @@ #define PAGELIST_ENTRIES_PER_PAGE \ ((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1) +/* + * PTA_DEVICE_ENUM interface exposed by OP-TEE to discover enumerated services + */ +#define PTA_DEVICE_ENUM { 0x7011a688, 0xddde, 0x4053, \ + { 0xa5, 0xa9, 0x7b, 0x3c, 0x4d, 0xdf, 0x13, 0xb8 } } +/* + * PTA_CMD_GET_DEVICES - List services without supplicant dependencies + * + * [out] memref[0]: List of the UUIDs of service enumerated by OP-TEE + */ +#define PTA_CMD_GET_DEVICES 0x0 + +/* + * PTA_CMD_GET_DEVICES_SUPP - List services depending on tee supplicant + * + * [out] memref[0]: List of the UUIDs of service enumerated by OP-TEE + */ +#define PTA_CMD_GET_DEVICES_SUPP 0x1 + typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, @@ -42,6 +62,134 @@ struct rpc_param { u32 a7; }; +static struct optee_service *find_service_driver(const struct tee_optee_ta_uuid *uuid) +{ + struct optee_service *service; + u8 loc_uuid[TEE_UUID_LEN]; + size_t service_cnt, idx; + + service_cnt = ll_entry_count(struct optee_service, optee_service); + service = ll_entry_start(struct optee_service, optee_service); + + for (idx = 0; idx < service_cnt; idx++, service++) { + tee_optee_ta_uuid_to_octets(loc_uuid, &service->uuid); + if (!memcmp(uuid, loc_uuid, sizeof(uuid))) + return service; + } + + return NULL; +} + +static int bind_service_list(struct udevice *dev, struct tee_shm *service_list, size_t count) +{ + const struct tee_optee_ta_uuid *service_uuid = (const void *)service_list->addr; + struct optee_service *service; + size_t idx; + int ret; + + for (idx = 0; idx < count; idx++) { + service = find_service_driver(service_uuid + idx); + if (!service) + continue; + + ret = device_bind_driver(dev, service->driver_name, service->driver_name, NULL); + if (ret) { + dev_warn(dev, "%s was not bound: %d, ignored\n", service->driver_name, ret); + continue; + } + } + + return 0; +} + +static int __enum_services(struct udevice *dev, struct tee_shm *shm, size_t *shm_size, u32 tee_sess) +{ + struct tee_invoke_arg arg = { }; + struct tee_param param = { }; + int ret = 0; + + arg.func = PTA_CMD_GET_DEVICES; + arg.session = tee_sess; + + /* Fill invoke cmd params */ + param.attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT; + param.u.memref.shm = shm; + param.u.memref.size = *shm_size; + + ret = tee_invoke_func(dev, &arg, 1, ¶m); + if (ret || (arg.ret && arg.ret != TEE_ERROR_SHORT_BUFFER)) { + dev_err(dev, "PTA_CMD_GET_DEVICES invoke function err: 0x%x\n", arg.ret); + return -EINVAL; + } + + *shm_size = param.u.memref.size; + + return 0; +} + +static int enum_services(struct udevice *dev, struct tee_shm **shm, size_t *count, u32 tee_sess) +{ + size_t shm_size = 0; + int ret; + + ret = __enum_services(dev, NULL, &shm_size, tee_sess); + if (ret) + return ret; + + ret = tee_shm_alloc(dev, shm_size, 0, shm); + if (ret) { + dev_err(dev, "Failed to allocated shared memory: %d\n", ret); + return ret; + } + + ret = __enum_services(dev, *shm, &shm_size, tee_sess); + if (!ret) + *count = shm_size / sizeof(struct tee_optee_ta_uuid); + + return ret; +} + +static int open_enum_session(struct udevice *dev, u32 *tee_sess) +{ + const struct tee_optee_ta_uuid pta_uuid = PTA_DEVICE_ENUM; + struct tee_open_session_arg arg = { }; + int ret; + + tee_optee_ta_uuid_to_octets(arg.uuid, &pta_uuid); + + ret = tee_open_session(dev, &arg, 0, NULL); + if (ret || arg.ret) { + if (!ret) + ret = -EIO; + return ret; + } + + *tee_sess = arg.session; + + return 0; +} + +static int bind_service_drivers(struct udevice *dev) +{ + struct tee_shm *service_list = NULL; + size_t service_count; + u32 tee_sess; + int ret; + + ret = open_enum_session(dev, &tee_sess); + if (ret) + return ret; + + ret = enum_services(dev, &service_list, &service_count, tee_sess); + if (!ret) + ret = bind_service_list(dev, service_list, service_count); + + tee_shm_free(service_list); + tee_close_session(dev, tee_sess); + + return ret; +} + /** * reg_pair_to_ptr() - Make a pointer of 2 32-bit values * @reg0: High bits of the pointer @@ -638,6 +786,14 @@ static int optee_of_to_plat(struct udevice *dev) return 0; } +static int optee_bind(struct udevice *dev) +{ + if (IS_ENABLED(CONFIG_OPTEE_SERVICE_DISCOVERY)) + dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND); + + return 0; +} + static int optee_probe(struct udevice *dev) { struct optee_pdata *pdata = dev_get_plat(dev); @@ -667,11 +823,15 @@ static int optee_probe(struct udevice *dev) return -ENOENT; } - /* - * in U-Boot, the discovery of TA on the TEE bus is not supported: - * only bind the drivers associated to the supported OP-TEE TA - */ - if (IS_ENABLED(CONFIG_RNG_OPTEE)) { + if (IS_ENABLED(CONFIG_OPTEE_SERVICE_DISCOVERY)) { + ret = bind_service_drivers(dev); + if (ret) + return ret; + } else if (IS_ENABLED(CONFIG_RNG_OPTEE)) { + /* + * Discovery of TAs on the TEE bus is not supported in U-Boot: + * only bind the drivers associated to the supported OP-TEE TA + */ ret = device_bind_driver(dev, "optee-rng", "optee-rng", NULL); if (ret) return ret; @@ -691,6 +851,7 @@ U_BOOT_DRIVER(optee) = { .of_match = optee_match, .of_to_plat = optee_of_to_plat, .probe = optee_probe, + .bind = optee_bind, .ops = &optee_ops, .plat_auto = sizeof(struct optee_pdata), .priv_auto = sizeof(struct optee_private), diff --git a/include/tee/optee_service.h b/include/tee/optee_service.h new file mode 100644 index 0000000..fca468a --- /dev/null +++ b/include/tee/optee_service.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * (C) Copyright 2022 Linaro Limited + */ + +#ifndef _OPTEE_SERVICE_H +#define _OPTEE_SERVICE_H + +/* + * struct optee_service - Discoverable OP-TEE service + * + * @driver_name - Name of the related driver + * @uuid - UUID of the OP-TEE service related to the driver + * + * Use macro OPTEE_SERVICE_DRIVER() to register a driver related to an + * OP-TEE service discovered when driver asks OP-TEE services enumaration. + */ +struct optee_service { + const char *driver_name; + const struct tee_optee_ta_uuid uuid; +}; + +#ifdef CONFIG_OPTEE_SERVICE_DISCOVERY +#define OPTEE_SERVICE_DRIVER(__name, __uuid, __drv_name) \ + ll_entry_declare(struct optee_service, __name, optee_service) = { \ + .uuid = __uuid, \ + .driver_name = __drv_name, \ + } +#else +#define OPTEE_SERVICE_DRIVER(__name, __uuid, __drv_name) \ + static int __name##__COUNTER__ __always_unused +#endif + +#endif /* _OPTEE_SERVICE_H */ -- cgit v1.1 From 57fb86a97d75dbf9898bce50813cf63106da08ac Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 26 Jul 2022 16:21:43 +0200 Subject: drivers: rng: optee_rng: register to CONFIG_OPTEE_SERVICE_DISCOVERY Changes optee_rng driver to register itself has a OP-TEE service so that a device is bound for the driver when OP-TEE enumerates the PTA RNG service. Cc: Sughosh Ganu Cc: Patrick Delaunay Signed-off-by: Etienne Carriere Reviewed-by: Patrick Delaunay --- drivers/rng/Kconfig | 1 + drivers/rng/optee_rng.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig index 1614368..5dcf681 100644 --- a/drivers/rng/Kconfig +++ b/drivers/rng/Kconfig @@ -41,6 +41,7 @@ config RNG_NPCM config RNG_OPTEE bool "OP-TEE based Random Number Generator support" depends on DM_RNG && OPTEE + default y if OPTEE_SERVICE_DISCOVERY help This driver provides support for the OP-TEE based Random Number Generator on ARM SoCs where hardware entropy sources are not diff --git a/drivers/rng/optee_rng.c b/drivers/rng/optee_rng.c index aa8ce86..410dfc0 100644 --- a/drivers/rng/optee_rng.c +++ b/drivers/rng/optee_rng.c @@ -11,6 +11,9 @@ #include #include #include +#include + +#define DRIVER_NAME "optee-rng" #define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 @@ -35,6 +38,8 @@ #define TA_HWRNG_UUID { 0xab7a617c, 0xb8e7, 0x4d8f, \ { 0x83, 0x01, 0xd0, 0x9b, 0x61, 0x03, 0x6b, 0x64 } } +OPTEE_SERVICE_DRIVER(optee_rng, TA_HWRNG_UUID, DRIVER_NAME); + /** open_session_ta_hwrng() - Open session with hwrng Trusted App * * @dev: device @@ -177,7 +182,7 @@ static const struct dm_rng_ops optee_rng_ops = { }; U_BOOT_DRIVER(optee_rng) = { - .name = "optee-rng", + .name = DRIVER_NAME, .id = UCLASS_RNG, .ops = &optee_rng_ops, .probe = optee_rng_probe, -- cgit v1.1 From 56ce22c0cd5a9cea09044f62d5f641f38e41f909 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Tue, 23 Aug 2022 15:10:39 -0400 Subject: post: memory: Fix format strings This fixes numerous cases of format strings not matching their arguments. Also keep the format strings on one line for easier grepping. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- post/drivers/memory.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/post/drivers/memory.c b/post/drivers/memory.c index 281989d..4fb9355 100644 --- a/post/drivers/memory.c +++ b/post/drivers/memory.c @@ -228,9 +228,8 @@ static int memory_post_dataline(unsigned long long * pmem) hi = (temp64>>32) & 0xffffffff; lo = temp64 & 0xffffffff; - post_log("Memory (data line) error at %08x, " - "wrote %08x%08x, read %08x%08x !\n", - pmem, pathi, patlo, hi, lo); + post_log("Memory (data line) error at %p, wrote %08x%08x, read %08x%08x !\n", + pmem, pathi, patlo, hi, lo); ret = -1; } } @@ -259,9 +258,8 @@ static int memory_post_addrline(ulong *testaddr, ulong *base, ulong size) } #endif if(readback == *testaddr) { - post_log("Memory (address line) error at %08x<->%08x, " - "XOR value %08x !\n", - testaddr, target, xor); + post_log("Memory (address line) error at %p<->%p, XOR value %08lx !\n", + testaddr, target, xor); ret = -1; } } @@ -287,9 +285,8 @@ static int memory_post_test1(unsigned long start, for (i = 0; i < size / sizeof (ulong) && !ret; i++) { readback = mem[i]; if (readback != val) { - post_log("Memory error at %08x, " - "wrote %08x, read %08x !\n", - mem + i, val, readback); + post_log("Memory error at %p, wrote %08lx, read %08lx !\n", + mem + i, val, readback); ret = -1; break; @@ -317,9 +314,8 @@ static int memory_post_test2(unsigned long start, unsigned long size) for (i = 0; i < size / sizeof (ulong) && !ret; i++) { readback = mem[i]; if (readback != (1 << (i % 32))) { - post_log("Memory error at %08x, " - "wrote %08x, read %08x !\n", - mem + i, 1 << (i % 32), readback); + post_log("Memory error at %p, wrote %08lx, read %08lx !\n", + mem + i, 1UL << (i % 32), readback); ret = -1; break; @@ -347,9 +343,8 @@ static int memory_post_test3(unsigned long start, unsigned long size) for (i = 0; i < size / sizeof (ulong) && !ret; i++) { readback = mem[i]; if (readback != i) { - post_log("Memory error at %08x, " - "wrote %08x, read %08x !\n", - mem + i, i, readback); + post_log("Memory error at %p, wrote %08lx, read %08lx !\n", + mem + i, i, readback); ret = -1; break; @@ -377,9 +372,8 @@ static int memory_post_test4(unsigned long start, unsigned long size) for (i = 0; i < size / sizeof (ulong) && !ret; i++) { readback = mem[i]; if (readback != ~i) { - post_log("Memory error at %08x, " - "wrote %08x, read %08x !\n", - mem + i, ~i, readback); + post_log("Memory error at %p, wrote %08lx, read %08lx !\n", + mem + i, ~i, readback); ret = -1; break; -- cgit v1.1 From 1b3e68203cab4dfdd90d0934ec08762be723f3b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 27 Aug 2022 16:37:55 +0200 Subject: xyz-modem: Allow to configure initial timeout for loadx and loady MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now when loadx and loady commands could be aborted / cancelled by CTRL+C, allow to configure timeout for initial x/y-modem packet via env variable $loadxy_timeout and by default use value from new compile-time config option CONFIG_CMD_LOADXY_TIMEOUT. Value is in seconds and zero value means infinite timeout. Default value is 90s which is the value used before this change for loadx command. Other load commands loadb and loads already waits infinitely. Same behavior for loadx and loady commands can be achieved by setting $loadxy_timeout or CONFIG_CMD_LOADXY_TIMEOUT to 0. Signed-off-by: Pali Rohár --- cmd/Kconfig | 7 +++++++ common/xyzModem.c | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 37bc64d..08821b0 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1194,6 +1194,13 @@ config CMD_LOADS help Load an S-Record file over serial line +config CMD_LOADXY_TIMEOUT + int "loadxy_timeout" + range 0 2000 + default 90 + help + Initial timeout for loadx and loady commands. Zero means infinity. + config CMD_LSBLK depends on BLK bool "lsblk - list block drivers and devices" diff --git a/common/xyzModem.c b/common/xyzModem.c index ece25ac..a68d392 100644 --- a/common/xyzModem.c +++ b/common/xyzModem.c @@ -26,6 +26,7 @@ #include #include #include +#include /* Assumption - run xyzModem protocol over the console port */ @@ -50,6 +51,8 @@ static struct int len, mode, total_retries; int total_SOH, total_STX, total_CAN; bool crc_mode, at_eof, tx_ack; + bool first_xmodem_packet; + ulong initial_time, timeout; unsigned long file_length, read_length; } xyz; @@ -409,6 +412,19 @@ xyzModem_get_hdr (void) return 0; } +static +ulong +xyzModem_get_initial_timeout (void) +{ + /* timeout is in seconds, non-positive timeout value is infinity */ +#if CONFIG_IS_ENABLED(ENV_SUPPORT) + const char *timeout_str = env_get("loadxy_timeout"); + if (timeout_str) + return 1000 * simple_strtol(timeout_str, NULL, 10); +#endif + return 1000 * CONFIG_CMD_LOADXY_TIMEOUT; +} + int xyzModem_stream_open (connection_info_t * info, int *err) { @@ -439,18 +455,28 @@ xyzModem_stream_open (connection_info_t * info, int *err) xyz.total_CAN = 0; xyz.read_length = 0; xyz.file_length = 0; + xyz.first_xmodem_packet = false; + xyz.initial_time = get_timer(0); + xyz.timeout = xyzModem_get_initial_timeout(); CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); if (xyz.mode == xyzModem_xmodem) { /* X-modem doesn't have an information header - exit here */ + xyz.first_xmodem_packet = true; xyz.next_blk = 1; return 0; } - while (retries-- > 0) + while (!(xyz.timeout && get_timer(xyz.initial_time) > xyz.timeout)) { + if (--retries <= 0) + { + retries = xyzModem_MAX_RETRIES; + crc_retries = xyzModem_MAX_RETRIES_WITH_CRC; + xyz.crc_mode = true; + } stat = xyzModem_get_hdr (); if (stat == 0) { @@ -503,9 +529,19 @@ xyzModem_stream_read (char *buf, int size, int *err) retries = xyzModem_MAX_RETRIES; while (retries-- > 0) { + if (xyz.first_xmodem_packet && xyz.timeout && + get_timer(xyz.initial_time) > xyz.timeout) + { + *err = xyzModem_timeout; + xyz.len = -1; + return total; + } + stat = xyzModem_get_hdr (); if (stat == 0) { + if (xyz.mode == xyzModem_xmodem && xyz.first_xmodem_packet) + xyz.first_xmodem_packet = false; if (xyz.blk == xyz.next_blk) { xyz.tx_ack = true; @@ -583,7 +619,7 @@ xyzModem_stream_read (char *buf, int size, int *err) xyz.total_retries++; ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__)); } - if (stat < 0) + if (stat < 0 && (!xyz.first_xmodem_packet || stat != xyzModem_timeout)) { *err = stat; xyz.len = -1; -- cgit v1.1 From 9895bda2ed09fe6b38f553022c263d5aa975cf99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 29 Aug 2022 17:36:23 +0200 Subject: doc: cmd: loady: Document new configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár --- doc/usage/cmd/loady.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/usage/cmd/loady.rst b/doc/usage/cmd/loady.rst index 2819cc7..718af6e 100644 --- a/doc/usage/cmd/loady.rst +++ b/doc/usage/cmd/loady.rst @@ -61,6 +61,13 @@ Configuration The command is only available if CONFIG_CMD_LOADB=y. +Initial timeout in seconds while waiting for transfer is configured by +config option CMD_LOADXY_TIMEOUT or by env variable $loadxy_timeout. +Setting it to 0 means infinite timeout. + +Transfer can be cancelled by pressing 3 times after two seconds +of inactivity on terminal. + Return value ------------ -- cgit v1.1 From 4ca8d95ce1e71995052e81f1854a23803ca48b73 Mon Sep 17 00:00:00 2001 From: Alexander Sowarka Date: Sun, 28 Aug 2022 21:30:20 +0200 Subject: nvme: Fix multipage prp-list The nvme driver falsely assumed that the last entry on a page of the prp-list always points to the next page of the prp-list. This potentially can lead to the illegal creation of pages on the prp-list with only a single entry. This change now ensures that splitting the prp-list into multiple pages, behaves now as required by the NVME-Spec. Related to this, also the size of the memory allocation is adjusted accordingly. Signed-off-by: Alexander Sowarka --- drivers/nvme/nvme.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index a305305..31cf700 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -72,7 +72,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, } nprps = DIV_ROUND_UP(length, page_size); - num_pages = DIV_ROUND_UP(nprps, prps_per_page); + num_pages = DIV_ROUND_UP(nprps - 1, prps_per_page - 1); if (nprps > dev->prp_entry_num) { free(dev->prp_pool); @@ -85,13 +85,13 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, printf("Error: malloc prp_pool fail\n"); return -ENOMEM; } - dev->prp_entry_num = prps_per_page * num_pages; + dev->prp_entry_num = num_pages * (prps_per_page - 1) + 1; } prp_pool = dev->prp_pool; i = 0; while (nprps) { - if (i == ((page_size >> 3) - 1)) { + if ((i == (prps_per_page - 1)) && nprps > 1) { *(prp_pool + i) = cpu_to_le64((ulong)prp_pool + page_size); i = 0; @@ -104,7 +104,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, *prp2 = (ulong)dev->prp_pool; flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool + - dev->prp_entry_num * sizeof(u64)); + num_pages * page_size); return 0; } -- cgit v1.1 From 04dd7c8e5624ee971004a6b310c2e7d958a0018c Mon Sep 17 00:00:00 2001 From: Xiang W Date: Mon, 29 Aug 2022 07:53:15 +0800 Subject: virtio: pci: fix bug of virtio_pci_map_capability The bar of the structure virtio_pci_cap is the index, and each base address occupies 4 bytes, so it needs to be multiplied by 4. This patch fixes a bug reported by Felix Yan https://lists.denx.de/pipermail/u-boot/2022-August/492779.html Signed-off-by: Xiang W Tested-by: Felix Yan --- drivers/virtio/virtio_pci_modern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c index 880a12c..cfde400 100644 --- a/drivers/virtio/virtio_pci_modern.c +++ b/drivers/virtio/virtio_pci_modern.c @@ -466,7 +466,7 @@ static void __iomem *virtio_pci_map_capability(struct udevice *udev, unsigned long mask = PCI_REGION_TYPE | PCI_REGION_SYS_MEMORY | PCI_REGION_RO; unsigned long flags = PCI_REGION_MEM; - u8 *p = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0 + cap->bar, cap->offset, + u8 *p = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0 + 4 * cap->bar, cap->offset, cap->length, mask, flags); return (void __iomem *)p; -- cgit v1.1 From d7124f0ba42263e6a24a829ca523861650bfec65 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 30 Aug 2022 14:09:11 +0200 Subject: gpio: Allow to print pin's label even for pin with GPIOF_FUNC function Currently, if pin's function is GPIOF_FUNC, only "func" if displayed without any other information. It would be interesting, if information is available, to indicate which pinmuxing's name is used. For example, for STM32 SoC's based platform, "gpio status" command output : before Bank GPIOZ: GPIOZ0: unused : 0 [ ] GPIOZ1: unused : 0 [ ] GPIOZ2: unused : 0 [ ] GPIOZ3: unused : 0 [ ] GPIOZ4: func GPIOZ5: func GPIOZ6: unused : 0 [ ] GPIOZ7: unused : 0 [ ] GPIOZ8: unknown GPIOZ9: unknown GPIOZ10: unknown GPIOZ11: unknown GPIOZ12: unknown GPIOZ13: unknown GPIOZ14: unknown GPIOZ15: unknown After Bank GPIOZ: GPIOZ0: unused : 0 [ ] GPIOZ1: unused : 0 [ ] GPIOZ2: unused : 0 [ ] GPIOZ3: unused : 0 [ ] GPIOZ4: func i2c4-0 GPIOZ5: func i2c4-0 GPIOZ6: unused : 0 [ ] GPIOZ7: unused : 0 [ ] GPIOZ8: unknown GPIOZ9: unknown GPIOZ10: unknown GPIOZ11: unknown GPIOZ12: unknown GPIOZ13: unknown GPIOZ14: unknown GPIOZ15: unknown Signed-off-by: Patrice Chotard Reviewed-by: Simon Glass Reviewed-by: Patrick Delaunay --- drivers/gpio/gpio-uclass.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 0ed32b7..d60e461 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -884,26 +884,31 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize) const struct dm_gpio_ops *ops = gpio_get_ops(dev); struct gpio_dev_priv *priv; char *str = buf; + const char *label; int func; int ret; int len; + bool used; BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); *buf = 0; priv = dev_get_uclass_priv(dev); - ret = gpio_get_raw_function(dev, offset, NULL); + ret = gpio_get_raw_function(dev, offset, &label); if (ret < 0) return ret; func = ret; len = snprintf(str, buffsize, "%s%d: %s", priv->bank_name ? priv->bank_name : "", offset, gpio_function[func]); - if (func == GPIOF_INPUT || func == GPIOF_OUTPUT || - func == GPIOF_UNUSED) { - const char *label; - bool used; + switch (func) { + case GPIOF_FUNC: + snprintf(str + len, buffsize - len, " %s", label ? label : ""); + break; + case GPIOF_INPUT: + case GPIOF_OUTPUT: + case GPIOF_UNUSED: ret = ops->get_value(dev, offset); if (ret < 0) return ret; @@ -913,6 +918,7 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize) used ? 'x' : ' ', used ? " " : "", label ? label : ""); + break; } return 0; -- cgit v1.1 From a32920897a205c53717d864ae6c44fb6703094c9 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 30 Aug 2022 14:09:12 +0200 Subject: gpio: Fix pin's status display for pin with GPIOF_UNUSED function Even pin with GPIOF_UNUSED function can have a label. The criteria to add or not a space character is linked to label not to the used/unused status. Signed-off-by: Patrice Chotard Reviewed-by: Simon Glass Reviewed-by: Patrick Delaunay --- drivers/gpio/gpio-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index d60e461..a00880e 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -916,7 +916,7 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize) snprintf(str + len, buffsize - len, ": %d [%c]%s%s", ret, used ? 'x' : ' ', - used ? " " : "", + label ? " " : "", label ? label : ""); break; } -- cgit v1.1 From 2c38f7c31806c5724a2f9c58a47cf76979fd6f0a Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 30 Aug 2022 14:09:13 +0200 Subject: pinctrl: pinctrl_stm32: Populate uc_priv->name[] with pinmux node's name Populate uc_priv->name[] with pinmux node's name in order to indicate the pinmuxing's name in case GPIO is configured in alternate. For example, for STM32 SoC's based platform, "gpio status" command output : before Bank GPIOZ: GPIOZ0: unused : 0 [ ] GPIOZ1: unused : 0 [ ] GPIOZ2: unused : 0 [ ] GPIOZ3: unused : 0 [ ] GPIOZ4: func GPIOZ5: func GPIOZ6: unused : 0 [ ] GPIOZ7: unused : 0 [ ] GPIOZ8: unknown GPIOZ9: unknown GPIOZ10: unknown GPIOZ11: unknown GPIOZ12: unknown GPIOZ13: unknown GPIOZ14: unknown GPIOZ15: unknown After Bank GPIOZ: GPIOZ0: unused : 0 [ ] GPIOZ1: unused : 0 [ ] GPIOZ2: unused : 0 [ ] GPIOZ3: unused : 0 [ ] GPIOZ4: func i2c4-0 GPIOZ5: func i2c4-0 GPIOZ6: unused : 0 [ ] GPIOZ7: unused : 0 [ ] GPIOZ8: unknown GPIOZ9: unknown GPIOZ10: unknown GPIOZ11: unknown GPIOZ12: unknown GPIOZ13: unknown GPIOZ14: unknown GPIOZ15: unknown Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- drivers/pinctrl/pinctrl_stm32.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index 990cd19..b755fa4 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -257,10 +257,12 @@ static int stm32_pinctrl_probe(struct udevice *dev) return 0; } -static int stm32_gpio_config(struct gpio_desc *desc, +static int stm32_gpio_config(ofnode node, + struct gpio_desc *desc, const struct stm32_gpio_ctl *ctl) { struct stm32_gpio_priv *priv = dev_get_priv(desc->dev); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc->dev); struct stm32_gpio_regs *regs = priv->regs; struct stm32_pinctrl_priv *ctrl_priv; int ret; @@ -291,6 +293,8 @@ static int stm32_gpio_config(struct gpio_desc *desc, index = desc->offset; clrsetbits_le32(®s->otyper, OTYPE_MSK << index, ctl->otype << index); + uc_priv->name[desc->offset] = strdup(ofnode_get_name(node)); + hwspinlock_unlock(&ctrl_priv->hws); return 0; @@ -385,7 +389,7 @@ static int stm32_pinctrl_config(ofnode node) if (rv) return rv; desc.offset = gpio_dsc.pin; - rv = stm32_gpio_config(&desc, &gpio_ctl); + rv = stm32_gpio_config(node, &desc, &gpio_ctl); log_debug("rv = %d\n\n", rv); if (rv) return rv; -- cgit v1.1 From f6f681642f0d730887bfe944b029cb6f76a35fb6 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 30 Aug 2022 14:09:14 +0200 Subject: gpio: sandbox: Add GPIOD_IS_AF for gpio configured in alternate function This allows to test if a pin's label if displayed using gpio_get_status() when this pin is configured in alternate function. Signed-off-by: Patrice Chotard Reviewed-by: Simon Glass Reviewed-by: Patrick Delaunay --- drivers/gpio/sandbox.c | 5 +++++ include/asm-generic/gpio.h | 1 + include/dt-bindings/gpio/sandbox-gpio.h | 3 +++ test/dm/gpio.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c index 106b2a7..305f9a6 100644 --- a/drivers/gpio/sandbox.c +++ b/drivers/gpio/sandbox.c @@ -196,6 +196,8 @@ static int sb_gpio_get_function(struct udevice *dev, unsigned offset) return GPIOF_OUTPUT; if (get_gpio_flag(dev, offset, GPIOD_IS_IN)) return GPIOF_INPUT; + if (get_gpio_flag(dev, offset, GPIOD_IS_AF)) + return GPIOF_FUNC; return GPIOF_INPUT; /*GPIO is not configurated */ } @@ -219,6 +221,9 @@ static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, if (args->args[1] & GPIO_OUT_ACTIVE) desc->flags |= GPIOD_IS_OUT_ACTIVE; + if (args->args[1] & GPIO_AF) + desc->flags |= GPIOD_IS_AF; + return 0; } diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 81f63f0..0fcf709 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -127,6 +127,7 @@ struct gpio_desc { #define GPIOD_OPEN_SOURCE BIT(6) /* GPIO is open source type */ #define GPIOD_PULL_UP BIT(7) /* GPIO has pull-up enabled */ #define GPIOD_PULL_DOWN BIT(8) /* GPIO has pull-down enabled */ +#define GPIOD_IS_AF BIT(9) /* GPIO is an alternate function */ /* Flags for updating the above */ #define GPIOD_MASK_DIR (GPIOD_IS_OUT | GPIOD_IS_IN | \ diff --git a/include/dt-bindings/gpio/sandbox-gpio.h b/include/dt-bindings/gpio/sandbox-gpio.h index e4bfdb3..05f9836 100644 --- a/include/dt-bindings/gpio/sandbox-gpio.h +++ b/include/dt-bindings/gpio/sandbox-gpio.h @@ -21,4 +21,7 @@ /* Bit 18 express GPIO output is active */ #define GPIO_OUT_ACTIVE 0x40000 +/* Bit 19 express GPIO set as alternate function */ +#define GPIO_AF 0x80000 + #endif diff --git a/test/dm/gpio.c b/test/dm/gpio.c index 33ae987..a8c35d4 100644 --- a/test/dm/gpio.c +++ b/test/dm/gpio.c @@ -778,3 +778,33 @@ static int dm_test_gpio_get_values_as_int_base3(struct unit_test_state *uts) } DM_TEST(dm_test_gpio_get_values_as_int_base3, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* Check that gpio_get_status return the label of a GPIO configured as GPIOD_AF */ +static int dm_test_gpio_function(struct unit_test_state *uts) +{ + struct gpio_desc desc; + struct udevice *dev; + ulong flags; + unsigned int offset, gpio; + char buf[80]; + + ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); + ut_asserteq_str("a-test", dev->name); + + /* request gpio_b 5 */ + ut_assertok(gpio_request_by_name(dev, "test-gpios", 2, &desc, 0)); + /* update gpio_b 5 function to GPIO_AF */ + ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_IS_AF, GPIOD_IS_AF)); + ut_assertok(dm_gpio_get_flags(&desc, &flags)); + ut_asserteq(GPIOD_IS_AF, flags); + /* check using gpio_get_status that label is displayed for a pin with GPIO_AF function */ + ut_assertok(gpio_lookup_name("b5", &dev, &offset, &gpio)); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b5: func a-test.test-gpios2", buf); + + ut_assertok(dm_gpio_free(dev, &desc)); + + return 0; +} +DM_TEST(dm_test_gpio_function, + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); -- cgit v1.1 From 069f0d7506f6e256f9e2ade82e315ef976dfb9ba Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Tue, 30 Aug 2022 16:40:37 -0400 Subject: cli: Reduce size of readline buffers in SPL Normally, readline is not used int SPL. However, it may be useful to enable the Freescale DDR interactive mode in SPL, while U-Boot is still executing from SRAM. The default settings for readline result in a large buffer being allocated. Reduce the size of the maximum input line, and the number of lines of scrollback when building for SPL. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- common/cli_readline.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common/cli_readline.c b/common/cli_readline.c index e86ee73..f883b7f 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -72,8 +72,13 @@ static char *delete_char (char *buffer, char *p, int *colp, int *np, int plen) #define getcmd_getch() getchar() #define getcmd_cbeep() getcmd_putch('\a') +#ifdef CONFIG_SPL_BUILD +#define HIST_MAX 3 +#define HIST_SIZE 32 +#else #define HIST_MAX 20 #define HIST_SIZE CONFIG_SYS_CBSIZE +#endif static int hist_max; static int hist_add_idx; -- cgit v1.1 From 0cd933bb4bd74084d942c42098ebf9e07d9e0f63 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 31 Aug 2022 21:13:40 +0200 Subject: lib: rsa: fix padding_pss_verify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check the that the hash length is shorter than the message length. This avoids: ./tools/../lib/rsa/rsa-verify.c:275:11: warning: ‘*db’ may be used uninitialized [-Wmaybe-uninitialized] 275 | db[0] &= 0xff >> leftmost_bits; Fixes: 061daa0b61f0 ("rsa: add support of padding pss") Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- lib/rsa/rsa-verify.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 1d95cfb..9605c37 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -215,6 +215,8 @@ out: * @msg_len: Message length * @hash: Pointer to the expected hash * @hash_len: Length of the hash + * + * Return: 0 if padding is correct, non-zero otherwise */ int padding_pss_verify(struct image_sign_info *info, const uint8_t *msg, int msg_len, @@ -234,6 +236,9 @@ int padding_pss_verify(struct image_sign_info *info, uint8_t leftmost_mask; struct checksum_algo *checksum = info->checksum; + if (db_len <= 0) + return -EINVAL; + /* first, allocate everything */ db_mask = malloc(db_len); db = malloc(db_len); -- cgit v1.1