From 7262ff7e564c8b7d81f940af242c20f832ee7511 Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Mon, 7 Mar 2022 14:55:51 +0530 Subject: [PATCH 01/14] ARM: dts: k3-j721s2: Correct timer frequency MCU Timer0 runs at 250MHz, and the clock-frequency defined in DT appears incorrect. Without this delays in R5 SPL are 10x off. Signed-off-by: Vignesh Raghavendra --- arch/arm/dts/k3-j721s2-common-proc-board-u-boot.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/dts/k3-j721s2-common-proc-board-u-boot.dtsi b/arch/arm/dts/k3-j721s2-common-proc-board-u-boot.dtsi index 749bc717f3..a17e61eccf 100644 --- a/arch/arm/dts/k3-j721s2-common-proc-board-u-boot.dtsi +++ b/arch/arm/dts/k3-j721s2-common-proc-board-u-boot.dtsi @@ -40,7 +40,7 @@ compatible = "ti,omap5430-timer"; reg = <0x0 0x40400000 0x0 0x80>; ti,timer-alwon; - clock-frequency = <25000000>; + clock-frequency = <250000000>; u-boot,dm-spl; }; From c755aa8a1dc2f2b819ce36148248ebe93bbc7f86 Mon Sep 17 00:00:00 2001 From: SESA644425 Date: Wed, 9 Mar 2022 01:27:15 -0800 Subject: [PATCH 02/14] lib: rsa: Fix const-correctness of rsassa_pss functions Prior to introduction of modifications in rsassa_pss functions related to padding verification, doing a pass to update const-correctness in targeted functions to comply with coding-rules and avoid const-cast Signed-off-by: SESA644425 Reviewed-by: Simon Glass --- include/image.h | 2 +- include/u-boot/rsa.h | 4 ++-- lib/rsa/rsa-verify.c | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/image.h b/include/image.h index 673b5f55ec..e4c6a50b88 100644 --- a/include/image.h +++ b/include/image.h @@ -1309,7 +1309,7 @@ ll_entry_declare(struct crypto_algo, __name, cryptos) struct padding_algo { const char *name; int (*verify)(struct image_sign_info *info, - uint8_t *pad, int pad_len, + const uint8_t *pad, int pad_len, const uint8_t *hash, int hash_len); }; diff --git a/include/u-boot/rsa.h b/include/u-boot/rsa.h index b9634e38d9..085363eb1e 100644 --- a/include/u-boot/rsa.h +++ b/include/u-boot/rsa.h @@ -101,11 +101,11 @@ int rsa_verify_with_pkey(struct image_sign_info *info, const void *hash, uint8_t *sig, uint sig_len); int padding_pkcs_15_verify(struct image_sign_info *info, - uint8_t *msg, int msg_len, + const uint8_t *msg, int msg_len, const uint8_t *hash, int hash_len); int padding_pss_verify(struct image_sign_info *info, - uint8_t *msg, int msg_len, + const uint8_t *msg, int msg_len, const uint8_t *hash, int hash_len); #define RSA_DEFAULT_PADDING_NAME "pkcs-1.5" diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 112664059c..c2c7248f90 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -73,7 +73,7 @@ static int rsa_verify_padding(const uint8_t *msg, const int pad_len, } int padding_pkcs_15_verify(struct image_sign_info *info, - uint8_t *msg, int msg_len, + const uint8_t *msg, int msg_len, const uint8_t *hash, int hash_len) { struct checksum_algo *checksum = info->checksum; @@ -125,7 +125,7 @@ static void u32_i2osp(uint32_t val, uint8_t *buf) * Return: 0 if the octet string was correctly generated, others on error */ static int mask_generation_function1(struct checksum_algo *checksum, - uint8_t *seed, int seed_len, + const uint8_t *seed, int seed_len, uint8_t *output, int output_len) { struct image_region region[2]; @@ -176,9 +176,9 @@ out: } static int compute_hash_prime(struct checksum_algo *checksum, - uint8_t *pad, int pad_len, - uint8_t *hash, int hash_len, - uint8_t *salt, int salt_len, + const uint8_t *pad, int pad_len, + const uint8_t *hash, int hash_len, + const uint8_t *salt, int salt_len, uint8_t *hprime) { struct image_region region[3]; @@ -215,7 +215,7 @@ out: * @hash_len: Length of the hash */ int padding_pss_verify(struct image_sign_info *info, - uint8_t *msg, int msg_len, + const uint8_t *msg, int msg_len, const uint8_t *hash, int hash_len) { uint8_t *masked_db = NULL; @@ -287,7 +287,7 @@ int padding_pss_verify(struct image_sign_info *info, /* step 12 & 13 */ compute_hash_prime(checksum, pad_zero, 8, - (uint8_t *)hash, hash_len, + hash, hash_len, salt, salt_len, hprime); /* step 14 */ From fb7330545e08876e26dae155f6f6d6788e4a102e Mon Sep 17 00:00:00 2001 From: SESA644425 Date: Wed, 9 Mar 2022 01:27:16 -0800 Subject: [PATCH 03/14] lib: rsa: Leverage existing data buffer instead of systematic copy Prior to introduction of modifications in rsassa_pss functions related to padding verification, doing a pass to reduce memory consumption of function by replacing memory copies of parts of const buffer by pointers to the original buffer (masked_db and h are subparts of msg buffer which is declared const, salt is a subpart of db which is a working buffer, unmodified after being filled). New pointers scope is limited to the function where they are declared (not returned to caller by any mean), zeroing risk of memory fault related to the change. Signed-off-by: SESA644425 Reviewed-by: Simon Glass --- lib/rsa/rsa-verify.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index c2c7248f90..de71234cfb 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -208,6 +208,10 @@ out: * saltlen:-1 "set the salt length to the digest length" is currently * not supported. * + * msg is a concatenation of : masked_db + h + 0xbc + * Once unmasked, db is a concatenation of : [0x00]* + 0x01 + salt + * Length of 0-padding at begin of db depends on salt length. + * * @info: Specifies key and FIT information * @msg: byte array of message, len equal to msg_len * @msg_len: Message length @@ -218,27 +222,25 @@ int padding_pss_verify(struct image_sign_info *info, const uint8_t *msg, int msg_len, const uint8_t *hash, int hash_len) { - uint8_t *masked_db = NULL; - int masked_db_len = msg_len - hash_len - 1; - uint8_t *h = NULL, *hprime = NULL; - int h_len = hash_len; + const uint8_t *masked_db = NULL; uint8_t *db_mask = NULL; - int db_mask_len = masked_db_len; - uint8_t *db = NULL, *salt = NULL; - int db_len = masked_db_len, salt_len = msg_len - hash_len - 2; + uint8_t *db = NULL; + int db_len = msg_len - hash_len - 1; + const uint8_t *h = NULL; + uint8_t *hprime = NULL; + int h_len = hash_len; + uint8_t *salt = NULL; + int salt_len = msg_len - hash_len - 2; uint8_t pad_zero[8] = { 0 }; int ret, i, leftmost_bits = 1; uint8_t leftmost_mask; struct checksum_algo *checksum = info->checksum; /* first, allocate everything */ - masked_db = malloc(masked_db_len); - h = malloc(h_len); - db_mask = malloc(db_mask_len); + db_mask = malloc(db_len); db = malloc(db_len); - salt = malloc(salt_len); hprime = malloc(hash_len); - if (!masked_db || !h || !db_mask || !db || !salt || !hprime) { + if (!db_mask || !db || !hprime) { printf("%s: can't allocate some buffer\n", __func__); ret = -ENOMEM; goto out; @@ -252,8 +254,8 @@ int padding_pss_verify(struct image_sign_info *info, } /* step 5 */ - memcpy(masked_db, msg, masked_db_len); - memcpy(h, msg + masked_db_len, h_len); + masked_db = &msg[0]; + h = &msg[db_len]; /* step 6 */ leftmost_mask = (0xff >> (8 - leftmost_bits)) << (8 - leftmost_bits); @@ -265,7 +267,7 @@ int padding_pss_verify(struct image_sign_info *info, } /* step 7 */ - mask_generation_function1(checksum, h, h_len, db_mask, db_mask_len); + mask_generation_function1(checksum, h, h_len, db_mask, db_len); /* step 8 */ for (i = 0; i < db_len; i++) @@ -283,7 +285,7 @@ int padding_pss_verify(struct image_sign_info *info, } /* step 11 */ - memcpy(salt, &db[1], salt_len); + salt = &db[1]; /* step 12 & 13 */ compute_hash_prime(checksum, pad_zero, 8, @@ -295,11 +297,8 @@ int padding_pss_verify(struct image_sign_info *info, out: free(hprime); - free(salt); free(db); free(db_mask); - free(h); - free(masked_db); return ret; } From 81eff51047e2fb29f518f8a3721f539a68a11b6d Mon Sep 17 00:00:00 2001 From: SESA644425 Date: Wed, 9 Mar 2022 01:27:17 -0800 Subject: [PATCH 04/14] lib: rsa: Update function padding_pss_verify (any-salt) Modify function to support any salt length instead of max length only. Function now detects salt length by parsing the content of db buffer. Note that it works with (but is not limited to) zero-length, digest-length and max-length Signed-off-by: SESA644425 Reviewed-by: Simon Glass --- lib/rsa/rsa-verify.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index de71234cfb..1d95cfbdee 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -204,9 +204,7 @@ out: /* * padding_pss_verify() - verify the pss padding of a signature * - * Only works with a rsa_pss_saltlen:-2 (default value) right now - * saltlen:-1 "set the salt length to the digest length" is currently - * not supported. + * Works with any salt length * * msg is a concatenation of : masked_db + h + 0xbc * Once unmasked, db is a concatenation of : [0x00]* + 0x01 + salt @@ -229,8 +227,8 @@ int padding_pss_verify(struct image_sign_info *info, const uint8_t *h = NULL; uint8_t *hprime = NULL; int h_len = hash_len; - uint8_t *salt = NULL; - int salt_len = msg_len - hash_len - 2; + uint8_t *db_nopad = NULL, *salt = NULL; + int db_padlen, salt_len; uint8_t pad_zero[8] = { 0 }; int ret, i, leftmost_bits = 1; uint8_t leftmost_mask; @@ -277,15 +275,20 @@ int padding_pss_verify(struct image_sign_info *info, db[0] &= 0xff >> leftmost_bits; /* step 10 */ - if (db[0] != 0x01) { + db_padlen = 0; + while (db[db_padlen] == 0x00 && db_padlen < (db_len - 1)) + db_padlen++; + db_nopad = &db[db_padlen]; + if (db_nopad[0] != 0x01) { printf("%s: invalid pss padding ", __func__); - printf("(leftmost byte of db isn't 0x01)\n"); + printf("(leftmost byte of db after 0-padding isn't 0x01)\n"); ret = EINVAL; goto out; } /* step 11 */ - salt = &db[1]; + salt_len = db_len - db_padlen - 1; + salt = &db_nopad[1]; /* step 12 & 13 */ compute_hash_prime(checksum, pad_zero, 8, From 067cfc1c2ea382b0820d995f476e2a26713a3200 Mon Sep 17 00:00:00 2001 From: Ivan Vozvakhov Date: Sat, 12 Mar 2022 13:03:14 +0300 Subject: [PATCH 05/14] led: led_pwm: Add a driver for LEDs connected to PWM Add a driver which allows to use of LEDs connected to PWM (Linux compatible). MAINTAINERS: add i.vozvakhov as a maintainer of leds-pwm C(required during new functionality adding). Signed-off-by: Ivan Vozvakhov --- MAINTAINERS | 6 + doc/device-tree-bindings/leds/leds-pwm.txt | 47 +++++ drivers/led/Kconfig | 6 + drivers/led/Makefile | 1 + drivers/led/led_pwm.c | 192 +++++++++++++++++++++ 5 files changed, 252 insertions(+) create mode 100644 doc/device-tree-bindings/leds/leds-pwm.txt create mode 100644 drivers/led/led_pwm.c diff --git a/MAINTAINERS b/MAINTAINERS index 6142504284..7a9e3156f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -899,6 +899,12 @@ F: doc/README.kwbimage F: doc/kwboot.1 F: tools/kwb* +LED +M: Ivan Vozvakhov +S: Supported +F: doc/device-tree-bindings/leds/leds-pwm.txt +F: drivers/led/led_pwm.c + LOGGING M: Simon Glass S: Maintained diff --git a/doc/device-tree-bindings/leds/leds-pwm.txt b/doc/device-tree-bindings/leds/leds-pwm.txt new file mode 100644 index 0000000000..186e8a848f --- /dev/null +++ b/doc/device-tree-bindings/leds/leds-pwm.txt @@ -0,0 +1,47 @@ +LEDs connected to PWM (Linux compatible) + +Required properties: +- compatible : should be "pwm-leds". + +Each LED is represented as a sub-node of the pwm-leds device. Each +node's name represents the name of the corresponding LED. + +LED sub-node properties: +- pwms : (required) LED pwm channel, see "pwms property" in + doc/device-tree-bindings/pwm/pwm.txt +- label : (optional) LED label, see "label property" in + doc/device-tree-bindings/led/common.txt +- max-brightness : (optional, unsigned, default 255) Maximum brightness possible + for the LED +- active-low : (optional, boolean, default false) For PWMs where the LED is + wired to supply rather than ground +- u-boot,default-brightness : (optional, unsigned, default 0) Initial state + of pwm-leds + +Example: + +leds { + compatible = "pwm-leds"; + status = "okay"; + + blue { + label = "led-blue"; + pwms = <&pwm1 0 100000 0>; + max-brightness = <255>; + u-boot,default-brightness = <127>; + }; + + green { + label = "led-green"; + pwms = <&pwm2 0 100000 0>; + max-brightness = <255>; + u-boot,default-brightness = <127>; + }; + + red { + label = "led-red"; + pwms = <&pwm3 0 100000 0>; + max-brightness = <255>; + u-boot,default-brightness = <127>; + }; +} diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig index 430d0760ba..418ed215c5 100644 --- a/drivers/led/Kconfig +++ b/drivers/led/Kconfig @@ -49,6 +49,12 @@ config LED_CORTINA This option enables support for LEDs connected to the Cortina Access CAxxxx SOCs. +config LED_PWM + bool "LED PWM" + depends on LED && DM_PWM + help + Enable support for LEDs connected to PWM. + Linux compatible ofdata. config LED_BLINK bool "Support LED blinking" diff --git a/drivers/led/Makefile b/drivers/led/Makefile index 2aa2c2173a..49ae91961d 100644 --- a/drivers/led/Makefile +++ b/drivers/led/Makefile @@ -8,5 +8,6 @@ obj-$(CONFIG_LED_BCM6328) += led_bcm6328.o obj-$(CONFIG_LED_BCM6358) += led_bcm6358.o obj-$(CONFIG_LED_BCM6753) += led_bcm6753.o obj-$(CONFIG_LED_BCM6858) += led_bcm6858.o +obj-$(CONFIG_LED_PWM) += led_pwm.o obj-$(CONFIG_$(SPL_)LED_GPIO) += led_gpio.o obj-$(CONFIG_LED_CORTINA) += led_cortina.o diff --git a/drivers/led/led_pwm.c b/drivers/led/led_pwm.c new file mode 100644 index 0000000000..4e50272258 --- /dev/null +++ b/drivers/led/led_pwm.c @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 VK + * Author: Ivan Vozvakhov + */ + +#include +#include +#include +#include +#include +#include +#include + +#define LEDS_PWM_DRIVER_NAME "led_pwm" + +struct led_pwm_priv { + struct udevice *pwm; + uint period; /* period in ns */ + uint duty; /* duty cycle in ns */ + uint channel; /* pwm channel number */ + bool active_low; /* pwm polarity */ + bool enabled; +}; + +static int led_pwm_enable(struct udevice *dev) +{ + struct led_pwm_priv *priv = dev_get_priv(dev); + int ret; + + ret = pwm_set_invert(priv->pwm, priv->channel, priv->active_low); + if (ret) + return ret; + + ret = pwm_set_config(priv->pwm, priv->channel, priv->period, priv->duty); + if (ret) + return ret; + + ret = pwm_set_enable(priv->pwm, priv->channel, true); + if (ret) + return ret; + + priv->enabled = true; + + return 0; +} + +static int led_pwm_disable(struct udevice *dev) +{ + struct led_pwm_priv *priv = dev_get_priv(dev); + int ret; + + ret = pwm_set_config(priv->pwm, priv->channel, priv->period, 0); + if (ret) + return ret; + + ret = pwm_set_enable(priv->pwm, priv->channel, false); + if (ret) + return ret; + + priv->enabled = false; + + return 0; +} + +static int led_pwm_set_state(struct udevice *dev, enum led_state_t state) +{ + struct led_pwm_priv *priv = dev_get_priv(dev); + int ret; + + switch (state) { + case LEDST_OFF: + ret = led_pwm_disable(dev); + break; + case LEDST_ON: + ret = led_pwm_enable(dev); + break; + case LEDST_TOGGLE: + ret = (priv->enabled) ? led_pwm_disable(dev) : led_pwm_enable(dev); + break; + default: + ret = -ENOSYS; + } + + return ret; +} + +static enum led_state_t led_pwm_get_state(struct udevice *dev) +{ + struct led_pwm_priv *priv = dev_get_priv(dev); + + return (priv->enabled) ? LEDST_ON : LEDST_OFF; +} + +static int led_pwm_probe(struct udevice *dev) +{ + struct led_pwm_priv *priv = dev_get_priv(dev); + struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev); + + /* Ignore the top-level LED node */ + if (!uc_plat->label) + return 0; + + return led_pwm_set_state(dev, (priv->enabled) ? LEDST_ON : LEDST_OFF); +} + +static int led_pwm_of_to_plat(struct udevice *dev) +{ + struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev); + struct led_pwm_priv *priv = dev_get_priv(dev); + struct ofnode_phandle_args args; + uint def_brightness, max_brightness; + int ret; + + /* Ignore the top-level LED node */ + if (!uc_plat->label) + return 0; + + ret = dev_read_phandle_with_args(dev, "pwms", "#pwm-cells", 0, 0, &args); + if (ret) + return ret; + + ret = uclass_get_device_by_ofnode(UCLASS_PWM, args.node, &priv->pwm); + if (ret) + return ret; + + priv->channel = args.args[0]; + priv->period = args.args[1]; + priv->active_low = dev_read_bool(dev, "active-low"); + + def_brightness = dev_read_u32_default(dev, "u-boot,default-brightness", 0); + max_brightness = dev_read_u32_default(dev, "max-brightness", 255); + priv->enabled = !!def_brightness; + + /* + * No need to handle pwm iverted case (active_low) + * because of pwm_set_invert function + */ + if (def_brightness < max_brightness) + priv->duty = priv->period * def_brightness / max_brightness; + else + priv->duty = priv->period; + + return 0; +} + +static int led_pwm_bind(struct udevice *parent) +{ + struct udevice *dev; + ofnode node; + int ret; + + dev_for_each_subnode(node, parent) { + struct led_uc_plat *uc_plat; + const char *label; + + label = ofnode_read_string(node, "label"); + if (!label) + label = ofnode_get_name(node); + + ret = device_bind_driver_to_node(parent, LEDS_PWM_DRIVER_NAME, + ofnode_get_name(node), + node, &dev); + if (ret) + return ret; + + uc_plat = dev_get_uclass_plat(dev); + uc_plat->label = label; + } + return 0; +} + +static const struct led_ops led_pwm_ops = { + .set_state = led_pwm_set_state, + .get_state = led_pwm_get_state, +}; + +static const struct udevice_id led_pwm_ids[] = { + { .compatible = "pwm-leds" }, + { } +}; + +U_BOOT_DRIVER(led_pwm) = { + .name = LEDS_PWM_DRIVER_NAME, + .id = UCLASS_LED, + .of_match = led_pwm_ids, + .ops = &led_pwm_ops, + .priv_auto = sizeof(struct led_pwm_priv), + .bind = led_pwm_bind, + .probe = led_pwm_probe, + .of_to_plat = led_pwm_of_to_plat, +}; From e146a2c12ff1e9138f564ae6815a131bd850d8ef Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 15 Mar 2022 10:19:32 -0700 Subject: [PATCH 06/14] lib/crypto: support sha384/sha512 in x509/pkcs7 Set digest_size SHA384 and SHA512 algorithms in pkcs7 and x509, (not set by ported linux code, but needed by __UBOOT__ part). EFI_CAPSULE_AUTHENTICATE doesn't select these algos but required for correctness if certificates contain sha384WithRSAEncryption or sha512WithRSAEncryption OIDs. Signed-off-by: Dhananjay Phadke Reviewed-by: Ilias Apalodimas --- lib/crypto/pkcs7_verify.c | 4 ++++ lib/crypto/x509_public_key.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/lib/crypto/pkcs7_verify.c b/lib/crypto/pkcs7_verify.c index 82c5c745d4..b832f01356 100644 --- a/lib/crypto/pkcs7_verify.c +++ b/lib/crypto/pkcs7_verify.c @@ -65,6 +65,10 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7, return -ENOPKG; if (!strcmp(sinfo->sig->hash_algo, "sha256")) sig->digest_size = SHA256_SUM_LEN; + else if (!strcmp(sinfo->sig->hash_algo, "sha384")) + sig->digest_size = SHA384_SUM_LEN; + else if (!strcmp(sinfo->sig->hash_algo, "sha512")) + sig->digest_size = SHA512_SUM_LEN; else if (!strcmp(sinfo->sig->hash_algo, "sha1")) sig->digest_size = SHA1_SUM_LEN; else diff --git a/lib/crypto/x509_public_key.c b/lib/crypto/x509_public_key.c index d557ab27ae..5c0e2b622d 100644 --- a/lib/crypto/x509_public_key.c +++ b/lib/crypto/x509_public_key.c @@ -71,6 +71,10 @@ int x509_get_sig_params(struct x509_certificate *cert) return -ENOPKG; if (!strcmp(sig->hash_algo, "sha256")) sig->digest_size = SHA256_SUM_LEN; + else if (!strcmp(sig->hash_algo, "sha384")) + sig->digest_size = SHA384_SUM_LEN; + else if (!strcmp(sig->hash_algo, "sha512")) + sig->digest_size = SHA512_SUM_LEN; else if (!strcmp(sig->hash_algo, "sha1")) sig->digest_size = SHA1_SUM_LEN; else From 5fa973eb2880d8173f99ae68e015e10ab8f89c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Carretero?= Date: Tue, 15 Mar 2022 16:34:51 -0400 Subject: [PATCH 07/14] spl: allow boot from first bootable partition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was implemented in order to get dual-slot bootloader partitions on the BeagleBone Black, whose MLO boots from the first bootable partition: MLO chainloads u-boot in the same way. Signed-off-by: Jérôme Carretero Reviewed-by: Tom Rini --- common/spl/Kconfig | 3 ++- common/spl/spl_mmc.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index a3a6f31aad..ac61b25a06 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -668,7 +668,8 @@ config SYS_MMCSD_FS_BOOT_PARTITION default 1 help Partition on the MMC to load U-Boot from when the MMC is being - used in fs mode + used in fs mode. + Use -1 as a special value to use the first bootable partition. config SPL_MMC_TINY bool "Tiny MMC framework in SPL" diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 1bb785a80f..6116a68371 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -280,16 +280,40 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, { int err = -ENOSYS; + __maybe_unused int partition = CONFIG_SYS_MMCSD_FS_BOOT_PARTITION; + +#if CONFIG_SYS_MMCSD_FS_BOOT_PARTITION == -1 + { + struct disk_partition info; + debug("Checking for the first MBR bootable partition\n"); + for (int type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) { + err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info); + if (err) + continue; + debug("Partition %d is of type %d and bootable=%d\n", type_part, info.sys_ind, info.bootable); + if (info.bootable != 0) { + debug("Partition %d is bootable, using it\n", type_part); + partition = type_part; + break; + } + } + printf("Using first bootable partition: %d\n", partition); + if (partition == CONFIG_SYS_MMCSD_FS_BOOT_PARTITION) { + return -ENOSYS; + } + } +#endif + #ifdef CONFIG_SPL_FS_FAT if (!spl_start_uboot()) { err = spl_load_image_fat_os(spl_image, bootdev, mmc_get_blk_desc(mmc), - CONFIG_SYS_MMCSD_FS_BOOT_PARTITION); + partition); if (!err) return err; } #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME err = spl_load_image_fat(spl_image, bootdev, mmc_get_blk_desc(mmc), - CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, + partition, filename); if (!err) return err; @@ -298,13 +322,13 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, #ifdef CONFIG_SPL_FS_EXT4 if (!spl_start_uboot()) { err = spl_load_image_ext_os(spl_image, bootdev, mmc_get_blk_desc(mmc), - CONFIG_SYS_MMCSD_FS_BOOT_PARTITION); + partition); if (!err) return err; } #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME err = spl_load_image_ext(spl_image, bootdev, mmc_get_blk_desc(mmc), - CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, + partition, filename); if (!err) return err; From 877de2a369aaeebe7fb0a2f8f1438255d249c6c0 Mon Sep 17 00:00:00 2001 From: Paul HENRYS Date: Thu, 17 Mar 2022 10:29:47 +0100 Subject: [PATCH 08/14] drivers: led: bcm6858: Set a default brightness when probing LEDs When probing the LEDs, a default brightness is set based on settings from the U-Boot device tree, i.e. the 'default-brightness' property of the LED nodes. If that property is not present, the default maximum brightness is set. This should make sure the LED controller's registers affecting the brightness are correctly initialized and should give a consistent behaviour. Signed-off-by: Paul HENRYS --- drivers/led/led_bcm6858.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/led/led_bcm6858.c b/drivers/led/led_bcm6858.c index fbf46a114c..3ca6c5b8a9 100644 --- a/drivers/led/led_bcm6858.c +++ b/drivers/led/led_bcm6858.c @@ -18,6 +18,7 @@ #define LEDS_MAX 32 #define LEDS_WAIT 100 +#define LEDS_MAX_BRIGHTNESS 7 /* LED Mode register */ #define LED_MODE_REG 0x0 @@ -38,6 +39,8 @@ #define LED_HW_LED_EN_REG 0x08 /* LED Flash control register0 */ #define LED_FLASH_RATE_CONTROL_REG0 0x10 +/* LED Brightness control register0 */ +#define LED_BRIGHTNESS_CONTROL_REG0 0x20 /* Soft LED input register */ #define LED_SW_LED_IP_REG 0xb8 /* Parallel LED Output Polarity Register */ @@ -96,6 +99,27 @@ static int bcm6858_led_set_period(struct udevice *dev, int period_ms) } #endif +static int led_set_brightness(struct udevice *dev, unsigned int brightness) +{ + struct bcm6858_led_priv *priv = dev_get_priv(dev); + u32 offset, shift, mask, value; + + offset = (priv->pin / 8) * 4; + shift = (priv->pin % 8) * 4; + mask = 0xf << shift; + + /* 8 levels of brightness achieved through PWM */ + value = (brightness > LEDS_MAX_BRIGHTNESS ? + LEDS_MAX_BRIGHTNESS : brightness) << shift; + + debug("%s: %s brightness set to %u\n", __func__, dev->name, value >> shift); + + clrbits_32(priv->regs + LED_BRIGHTNESS_CONTROL_REG0 + offset, mask); + setbits_32(priv->regs + LED_BRIGHTNESS_CONTROL_REG0 + offset, value); + + return 0; +} + static enum led_state_t bcm6858_led_get_state(struct udevice *dev) { struct bcm6858_led_priv *priv = dev_get_priv(dev); @@ -113,6 +137,8 @@ static int bcm6858_led_set_state(struct udevice *dev, enum led_state_t state) { struct bcm6858_led_priv *priv = dev_get_priv(dev); + debug("%s: Set led %s to %d\n", __func__, dev->name, state); + switch (state) { case LEDST_OFF: clrbits_32(priv->regs + LED_SW_LED_IP_REG, (1 << priv->pin)); @@ -180,7 +206,7 @@ static int bcm6858_led_probe(struct udevice *dev) } else { struct bcm6858_led_priv *priv = dev_get_priv(dev); void __iomem *regs; - unsigned int pin; + unsigned int pin, brightness; regs = dev_remap_addr(dev_get_parent(dev)); if (!regs) @@ -201,6 +227,10 @@ static int bcm6858_led_probe(struct udevice *dev) clrbits_32(regs + LED_PLED_OP_PPOL_REG, 1 << pin); else setbits_32(regs + LED_PLED_OP_PPOL_REG, 1 << pin); + + brightness = dev_read_u32_default(dev, "default-brightness", + LEDS_MAX_BRIGHTNESS); + led_set_brightness(dev, brightness); } return 0; From c86a4de8df611b58ec41ae6c42c6fec58e5ab54f Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Mon, 21 Mar 2022 09:13:36 +0100 Subject: [PATCH 09/14] mtd: Add flash_node in struct mtd_info Currently, add_mtd_partitions_of() can be used only if dev field of mtd_info struct is populated. It's the case, for example, for a spi nor flash, which has a DT compatible "jedec,spi-nor" and an associated device. mtd->dev is populated in spi_nor_scan(). But in case of a raw nand node, mtd_info's dev field can't be populated as flash node has no compatible, so no associated device. add_mtd_partitions_of() can't be used to parse "partitions" subnode. To remove this constraint, add an ofnode field in mtd_info struct which reference the DT flash node. This new field is populated by nand_scan_tail(). This new field will be used by add_mtd_partitions_of() to parse the flash node for "partitions" defined in DT. Signed-off-by: Patrice Chotard Cc: Farhan Ali Cc: Heinrich Schuchardt Cc: Jagan Teki Cc: Marek Behun Cc: Miquel Raynal Cc: Simon Glass Cc: Wolfgang Denk --- drivers/mtd/nand/raw/nand_base.c | 1 + include/linux/mtd/mtd.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index f7616985d9..a007603df1 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -5257,6 +5257,7 @@ int nand_scan_tail(struct mtd_info *mtd) break; } + mtd->flash_node = chip->flash_node; /* Fill in remaining MTD driver data */ mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH; mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM : diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 7455400981..af45e63bf9 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -305,6 +305,7 @@ struct mtd_info { struct device dev; #else struct udevice *dev; + ofnode flash_node; #endif int usecount; From 7ab3364c6d1c17b8ee6da523d5729b0248ba63bf Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Mon, 21 Mar 2022 09:13:37 +0100 Subject: [PATCH 10/14] mtd: Update the way partitions are parsed In case mtd_info's dev field is not populated (raw nand's case), use the flash_node new field which reference the DT flash node where can be found "partitions" node with "fixed-partitions" compatible. Signed-off-by: Patrice Chotard Cc: Farhan Ali Cc: Heinrich Schuchardt Cc: Jagan Teki Cc: Marek Behun Cc: Miquel Raynal Cc: Simon Glass Cc: Wolfgang Denk --- drivers/mtd/mtdpart.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 4119ea4ff6..d077897e4a 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -887,10 +887,14 @@ int add_mtd_partitions_of(struct mtd_info *master) ofnode parts, child; int i = 0; - if (!master->dev) + if (!master->dev && !ofnode_valid(master->flash_node)) return 0; - parts = ofnode_find_subnode(mtd_get_ofnode(master), "partitions"); + if (master->dev) + parts = ofnode_find_subnode(mtd_get_ofnode(master), "partitions"); + else + parts = ofnode_find_subnode(master->flash_node, "partitions"); + if (!ofnode_valid(parts) || !ofnode_is_available(parts) || !ofnode_device_is_compatible(parts, "fixed-partitions")) return 0; From e6fe02a5715b3dc02fe4041c4f5a59099a711d70 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 22 Mar 2022 17:08:43 +0100 Subject: [PATCH 11/14] cmd: pxe_utils: sysboot: replace cls command by video_clear in PXE parser Since the commit bfaa51dd4adf ("cmd: add serial console support for the cls command") the cls command is not enough to clear the video display when ANSI console is activated. This patch clears the video device with the video_clear() API before to display the bitmap used for the PXE background. This patch avoids to display the LOGO, activated by default with commit 7a8555d87136 ("video: Show the U-Boot logo by default"). Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- boot/pxe_utils.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index 0c24becae3..b08aee9896 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -14,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +23,6 @@ #include #ifdef CONFIG_DM_RNG -#include #include #endif @@ -1516,8 +1517,13 @@ void handle_pxe_menu(struct pxe_context *ctx, struct pxe_menu *cfg) /* display BMP if available */ if (cfg->bmp) { if (get_relfile(ctx, cfg->bmp, image_load_addr, NULL)) { - if (CONFIG_IS_ENABLED(CMD_CLS)) - run_command("cls", 0); +#if defined(CONFIG_DM_VIDEO) + struct udevice *dev; + + err = uclass_first_device_err(UCLASS_VIDEO, &dev); + if (!err) + video_clear(dev); +#endif bmp_display(image_load_addr, BMP_ALIGN_CENTER, BMP_ALIGN_CENTER); } else { From b583348ca8c8ce74d5dd665446d20f4c6c6e3f06 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Thu, 24 Mar 2022 11:26:11 -0400 Subject: [PATCH 12/14] image: fit: Align hash output buffers Hardware-accelerated hash functions require that the input and output buffers be aligned to the minimum DMA alignment. memalign.h helpfully provides a macro just for this purpose. It doesn't exist on the host, but we don't need to be aligned there either. Fixes: 5dfb521386 ("[new uImage] New uImage low-level API") Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- boot/image-fit.c | 4 +++- tools/mkimage.h | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/boot/image-fit.c b/boot/image-fit.c index f01cafe4e2..6610035d0a 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #ifdef CONFIG_DM_HASH #include @@ -1263,7 +1264,8 @@ int calculate_hash(const void *data, int data_len, const char *name, static int fit_image_check_hash(const void *fit, int noffset, const void *data, size_t size, char **err_msgp) { - uint8_t value[FIT_MAX_HASH_LEN]; + DEFINE_ALIGN_BUFFER(uint8_t, value, FIT_MAX_HASH_LEN, + ARCH_DMA_MINALIGN); int value_len; const char *algo; uint8_t *fit_value; diff --git a/tools/mkimage.h b/tools/mkimage.h index 0d3148444c..7652c8b001 100644 --- a/tools/mkimage.h +++ b/tools/mkimage.h @@ -41,6 +41,9 @@ static inline ulong map_to_sysmem(void *ptr) return (ulong)(uintptr_t)ptr; } +#define ARCH_DMA_MINALIGN 1 +#define DEFINE_ALIGN_BUFFER(type, name, size, alugn) type name[size] + #define MKIMAGE_TMPFILE_SUFFIX ".tmp" #define MKIMAGE_MAX_TMPFILE_LEN 256 #define MKIMAGE_DEFAULT_DTC_OPTIONS "-I dts -O dtb -p 500" From 749c6a6275a201007d7fd53de63b21cdf108eebf Mon Sep 17 00:00:00 2001 From: Ville Baillie Date: Mon, 28 Mar 2022 09:13:43 +0000 Subject: [PATCH 13/14] ubifs: Fix journal replay wrt. xattr nodes Backport commit 1cb51a15b576 ("ubifs: Fix journal replay wrt. xattr nodes") from the Linux Kernel, which has the following Signed-off-by line: Signed-off-by: Richard Weinberger For U-Boot, after comapring with the upstream commit: Signed-off-by: Tom Rini --- fs/ubifs/tnc.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index e8b8f16838..4fb10045ff 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -50,6 +50,11 @@ enum { NOT_ON_MEDIA = 3, }; +static int try_read_node(const struct ubifs_info *c, void *buf, int type, + int len, int lnum, int offs); +static int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key, + struct ubifs_zbranch *zbr, void *node); + /** * insert_old_idx - record an index node obsoleted since the last commit start. * @c: UBIFS file-system description object @@ -402,7 +407,19 @@ static int tnc_read_node_nm(struct ubifs_info *c, struct ubifs_zbranch *zbr, return 0; } - err = ubifs_tnc_read_node(c, zbr, node); + if (c->replaying) { + err = fallible_read_node(c, &zbr->key, zbr, node); + /* + * When the node was not found, return -ENOENT, 0 otherwise. + * Negative return codes stay as-is. + */ + if (err == 0) + err = -ENOENT; + else if (err == 1) + err = 0; + } else { + err = ubifs_tnc_read_node(c, zbr, node); + } if (err) return err; @@ -2770,7 +2787,11 @@ struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c, if (nm->name) { if (err) { /* Handle collisions */ - err = resolve_collision(c, key, &znode, &n, nm); + if (c->replaying) + err = fallible_resolve_collision(c, key, &znode, &n, + nm, 0); + else + err = resolve_collision(c, key, &znode, &n, nm); dbg_tnc("rc returned %d, znode %p, n %d", err, znode, n); if (unlikely(err < 0)) From c3322a53f34f986ad9818df72707ebb59c9c8725 Mon Sep 17 00:00:00 2001 From: Hajo Noerenberg Date: Mon, 28 Mar 2022 15:49:08 +0200 Subject: [PATCH 14/14] ahci: add PCI bindings for Marvell 88SE6121/45 SATA controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add AHCI PCI bindings for Marvell 88SE6121/45 SATA controllers. The 88SE6121 controller is used, for example, in the Seagate Blackarmor NAS440 or the Iomega ix4-200d NAS. As Pali Rohár explained [1], these controllers do not match the standard AHCI class code and therefore require an explizit PCI binding. The Linux kernel also uses this approach [2]. [1] https://lists.denx.de/pipermail/u-boot/2022-March/479197.html [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/ata/ahci.c?h=v5.17#n557 Signed-off-by: Hajo Noerenberg Reviewed-by: Pali Rohár --- drivers/ata/ahci-pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/ahci-pci.c b/drivers/ata/ahci-pci.c index b1d231e0f9..797e0d570e 100644 --- a/drivers/ata/ahci-pci.c +++ b/drivers/ata/ahci-pci.c @@ -38,6 +38,8 @@ U_BOOT_DRIVER(ahci_pci) = { static struct pci_device_id ahci_pci_supported[] = { { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_SATA_AHCI, ~0) }, { PCI_DEVICE(0x1b21, 0x0611) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6121) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6145) }, {}, };