From 097dd3e0a9c4b07909dfa2d97d202f74856cfa81 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 3 Mar 2014 12:19:24 +0100 Subject: fdt: add "fdt checksign" command check if a fdt is correct signed pass an optional addr value. Contains the addr of the key blob Signed-off-by: Heiko Schocher Acked-by: Simon Glass --- common/cmd_fdt.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'common') diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 3a9edd6468..a6744ed9c2 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -570,7 +570,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) ft_board_setup(working_fdt, gd->bd); #endif /* Create a chosen node */ - else if (argv[1][0] == 'c') { + else if (strncmp(argv[1], "cho", 3) == 0) { unsigned long initrd_start = 0, initrd_end = 0; if ((argc != 2) && (argc != 4)) @@ -583,6 +583,41 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) fdt_chosen(working_fdt, 1); fdt_initrd(working_fdt, initrd_start, initrd_end, 1); + +#if defined(CONFIG_FIT_SIGNATURE) + } else if (strncmp(argv[1], "che", 3) == 0) { + int cfg_noffset; + int ret; + unsigned long addr; + struct fdt_header *blob; + + if (!working_fdt) + return CMD_RET_FAILURE; + + if (argc > 2) { + addr = simple_strtoul(argv[2], NULL, 16); + blob = map_sysmem(addr, 0); + } else { + blob = (struct fdt_header *)gd->fdt_blob; + } + if (!fdt_valid(&blob)) + return 1; + + gd->fdt_blob = blob; + cfg_noffset = fit_conf_get_node(working_fdt, NULL); + if (!cfg_noffset) { + printf("Could not find configuration node: %s\n", + fdt_strerror(cfg_noffset)); + return CMD_RET_FAILURE; + } + + ret = fit_config_verify(working_fdt, cfg_noffset); + if (ret == 1) + return CMD_RET_SUCCESS; + else + return CMD_RET_FAILURE; +#endif + } /* resize the fdt */ else if (strncmp(argv[1], "re", 2) == 0) { @@ -992,6 +1027,11 @@ static char fdt_help_text[] = "fdt rsvmem delete - Delete a mem reserves\n" "fdt chosen [ ] - Add/update the /chosen branch in the tree\n" " / - initrd start/end addr\n" +#if defined(CONFIG_FIT_SIGNATURE) + "fdt checksign [] - check FIT signature\n" + " - addr of key blob\n" + " default gd->fdt_blob\n" +#endif "NOTE: Dereference aliases by omiting the leading '/', " "e.g. fdt print ethernet0."; #endif -- cgit v1.2.1 From 2842c1c24269a05142802d25520e7cb9035e456c Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 3 Mar 2014 12:19:25 +0100 Subject: fit: add sha256 support add sha256 support to fit images Signed-off-by: Heiko Schocher Acked-by: Simon Glass --- common/image-fit.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'common') diff --git a/common/image-fit.c b/common/image-fit.c index b94a3fe86d..77f32bce31 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -22,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR; #include #include +#include #include #include @@ -882,6 +883,10 @@ int calculate_hash(const void *data, int data_len, const char *algo, sha1_csum_wd((unsigned char *)data, data_len, (unsigned char *)value, CHUNKSZ_SHA1); *value_len = 20; + } else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) { + sha256_csum_wd((unsigned char *)data, data_len, + (unsigned char *)value, CHUNKSZ_SHA256); + *value_len = SHA256_SUM_LEN; } else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) { md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5); *value_len = 16; -- cgit v1.2.1 From 646257d1f4004855d486024527a4784bf57c4c4d Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 3 Mar 2014 12:19:26 +0100 Subject: rsa: add sha256-rsa2048 algorithm based on patch from andreas@oetken.name: http://patchwork.ozlabs.org/patch/294318/ commit message: I currently need support for rsa-sha256 signatures in u-boot and found out that the code for signatures is not very generic. Thus adding of different hash-algorithms for rsa-signatures is not easy to do without copy-pasting the rsa-code. I attached a patch for how I think it could be better and included support for rsa-sha256. This is a fast first shot. aditionally work: - removed checkpatch warnings - removed compiler warnings - rebased against current head Signed-off-by: Heiko Schocher Cc: andreas@oetken.name Cc: Simon Glass --- common/image-sig.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'common') diff --git a/common/image-sig.c b/common/image-sig.c index 973b06d505..8b6f49bb38 100644 --- a/common/image-sig.c +++ b/common/image-sig.c @@ -14,15 +14,53 @@ DECLARE_GLOBAL_DATA_PTR; #endif /* !USE_HOSTCC*/ #include #include +#include #define IMAGE_MAX_HASHED_NODES 100 +#ifdef USE_HOSTCC +__attribute__((weak)) void *get_blob(void) +{ + return NULL; +} +#endif + +struct checksum_algo checksum_algos[] = { + { + "sha1", + SHA1_SUM_LEN, +#if IMAGE_ENABLE_SIGN + EVP_sha1, +#else + sha1_calculate, + padding_sha1_rsa2048, +#endif + }, + { + "sha256", + SHA256_SUM_LEN, +#if IMAGE_ENABLE_SIGN + EVP_sha256, +#else + sha256_calculate, + padding_sha256_rsa2048, +#endif + } +}; struct image_sig_algo image_sig_algos[] = { { "sha1,rsa2048", rsa_sign, rsa_add_verify_data, rsa_verify, + &checksum_algos[0], + }, + { + "sha256,rsa2048", + rsa_sign, + rsa_add_verify_data, + rsa_verify, + &checksum_algos[1], } }; -- cgit v1.2.1 From db1b5f3d20666ffd52d649a3bd6141989b596e3f Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 3 Mar 2014 12:19:27 +0100 Subject: rsa: add sha256,rsa4096 algorithm Add support for sha256,rsa4096 signatures in u-boot. Signed-off-by: Heiko Schocher Acked-by: Simon Glass Cc: andreas@oetken.name --- common/image-sig.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'common') diff --git a/common/image-sig.c b/common/image-sig.c index 8b6f49bb38..763960a45a 100644 --- a/common/image-sig.c +++ b/common/image-sig.c @@ -29,6 +29,7 @@ struct checksum_algo checksum_algos[] = { { "sha1", SHA1_SUM_LEN, + RSA2048_BYTES, #if IMAGE_ENABLE_SIGN EVP_sha1, #else @@ -39,14 +40,28 @@ struct checksum_algo checksum_algos[] = { { "sha256", SHA256_SUM_LEN, + RSA2048_BYTES, #if IMAGE_ENABLE_SIGN EVP_sha256, #else sha256_calculate, padding_sha256_rsa2048, +#endif + }, + { + "sha256", + SHA256_SUM_LEN, + RSA4096_BYTES, +#if IMAGE_ENABLE_SIGN + EVP_sha256, +#else + sha256_calculate, + padding_sha256_rsa4096, #endif } + }; + struct image_sig_algo image_sig_algos[] = { { "sha1,rsa2048", @@ -61,7 +76,15 @@ struct image_sig_algo image_sig_algos[] = { rsa_add_verify_data, rsa_verify, &checksum_algos[1], + }, + { + "sha256,rsa4096", + rsa_sign, + rsa_add_verify_data, + rsa_verify, + &checksum_algos[2], } + }; struct image_sig_algo *image_get_sig_algo(const char *name) -- cgit v1.2.1 From bf007ebb6f4b01af675782d23bacbddd17e1a627 Mon Sep 17 00:00:00 2001 From: Hung-ying Tyan Date: Mon, 3 Mar 2014 12:19:28 +0100 Subject: gen: Add progressive hash API Add hash_init(), hash_update() and hash_finish() to the hash_algo struct. Add hash_lookup_algo() to look up the struct given an algorithm name. Signed-off-by: Hung-ying Tyan Signed-off-by: Simon Glass Signed-off-by: Heiko Schocher Acked-by: Simon Glass --- common/hash.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 105 insertions(+), 11 deletions(-) (limited to 'common') diff --git a/common/hash.c b/common/hash.c index 872cd85428..7627b84b45 100644 --- a/common/hash.c +++ b/common/hash.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -19,6 +20,88 @@ #include #include +#ifdef CONFIG_CMD_SHA1SUM +static int hash_init_sha1(struct hash_algo *algo, void **ctxp) +{ + sha1_context *ctx = malloc(sizeof(sha1_context)); + sha1_starts(ctx); + *ctxp = ctx; + return 0; +} + +static int hash_update_sha1(struct hash_algo *algo, void *ctx, const void *buf, + unsigned int size, int is_last) +{ + sha1_update((sha1_context *)ctx, buf, size); + return 0; +} + +static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf, + int size) +{ + if (size < algo->digest_size) + return -1; + + sha1_finish((sha1_context *)ctx, dest_buf); + free(ctx); + return 0; +} +#endif + +#ifdef CONFIG_SHA256 +static int hash_init_sha256(struct hash_algo *algo, void **ctxp) +{ + sha256_context *ctx = malloc(sizeof(sha256_context)); + sha256_starts(ctx); + *ctxp = ctx; + return 0; +} + +static int hash_update_sha256(struct hash_algo *algo, void *ctx, + const void *buf, unsigned int size, int is_last) +{ + sha256_update((sha256_context *)ctx, buf, size); + return 0; +} + +static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void + *dest_buf, int size) +{ + if (size < algo->digest_size) + return -1; + + sha256_finish((sha256_context *)ctx, dest_buf); + free(ctx); + return 0; +} +#endif + +static int hash_init_crc32(struct hash_algo *algo, void **ctxp) +{ + uint32_t *ctx = malloc(sizeof(uint32_t)); + *ctx = 0; + *ctxp = ctx; + return 0; +} + +static int hash_update_crc32(struct hash_algo *algo, void *ctx, + const void *buf, unsigned int size, int is_last) +{ + *((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), buf, size); + return 0; +} + +static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf, + int size) +{ + if (size < algo->digest_size) + return -1; + + *((uint32_t *)dest_buf) = *((uint32_t *)ctx); + free(ctx); + return 0; +} + /* * These are the hash algorithms we support. Chips which support accelerated * crypto could perhaps add named version of these algorithms here. Note that @@ -53,6 +136,9 @@ static struct hash_algo hash_algo[] = { SHA1_SUM_LEN, sha1_csum_wd, CHUNKSZ_SHA1, + hash_init_sha1, + hash_update_sha1, + hash_finish_sha1, }, #define MULTI_HASH #endif @@ -62,6 +148,9 @@ static struct hash_algo hash_algo[] = { SHA256_SUM_LEN, sha256_csum_wd, CHUNKSZ_SHA256, + hash_init_sha256, + hash_update_sha256, + hash_finish_sha256, }, #define MULTI_HASH #endif @@ -70,6 +159,9 @@ static struct hash_algo hash_algo[] = { 4, crc32_wd_buf, CHUNKSZ_CRC32, + hash_init_crc32, + hash_update_crc32, + hash_finish_crc32, }, }; @@ -204,16 +296,19 @@ static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum, return 0; } -static struct hash_algo *find_hash_algo(const char *name) +int hash_lookup_algo(const char *algo_name, struct hash_algo **algop) { int i; for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { - if (!strcmp(name, hash_algo[i].name)) - return &hash_algo[i]; + if (!strcmp(algo_name, hash_algo[i].name)) { + *algop = &hash_algo[i]; + return 0; + } } - return NULL; + debug("Unknown hash algorithm '%s'\n", algo_name); + return -EPROTONOSUPPORT; } static void show_hash(struct hash_algo *algo, ulong addr, ulong len, @@ -230,12 +325,12 @@ int hash_block(const char *algo_name, const void *data, unsigned int len, uint8_t *output, int *output_size) { struct hash_algo *algo; + int ret; + + ret = hash_lookup_algo(algo_name, &algo); + if (ret) + return ret; - algo = find_hash_algo(algo_name); - if (!algo) { - debug("Unknown hash algorithm '%s'\n", algo_name); - return -EPROTONOSUPPORT; - } if (output_size && *output_size < algo->digest_size) { debug("Output buffer size %d too small (need %d bytes)", *output_size, algo->digest_size); @@ -265,8 +360,7 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, u8 vsum[HASH_MAX_DIGEST_SIZE]; void *buf; - algo = find_hash_algo(algo_name); - if (!algo) { + if (hash_lookup_algo(algo_name, &algo)) { printf("Unknown hash algorithm '%s'\n", algo_name); return CMD_RET_USAGE; } -- cgit v1.2.1 From 29a23f9d6c533f8371be3ae0268c4c75866291b2 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 3 Mar 2014 12:19:30 +0100 Subject: tools, fit_check_sign: verify a signed fit image add host tool "fit_check_sign" which verifies, if a fit image is signed correct. Signed-off-by: Heiko Schocher Cc: Simon Glass --- common/image-sig.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'common') diff --git a/common/image-sig.c b/common/image-sig.c index 763960a45a..72284eb1d1 100644 --- a/common/image-sig.c +++ b/common/image-sig.c @@ -19,9 +19,14 @@ DECLARE_GLOBAL_DATA_PTR; #define IMAGE_MAX_HASHED_NODES 100 #ifdef USE_HOSTCC -__attribute__((weak)) void *get_blob(void) +void *host_blob; +void image_set_host_blob(void *blob) { - return NULL; + host_blob = blob; +} +void *image_get_host_blob(void) +{ + return host_blob; } #endif @@ -32,10 +37,9 @@ struct checksum_algo checksum_algos[] = { RSA2048_BYTES, #if IMAGE_ENABLE_SIGN EVP_sha1, -#else +#endif sha1_calculate, padding_sha1_rsa2048, -#endif }, { "sha256", @@ -43,10 +47,9 @@ struct checksum_algo checksum_algos[] = { RSA2048_BYTES, #if IMAGE_ENABLE_SIGN EVP_sha256, -#else +#endif sha256_calculate, padding_sha256_rsa2048, -#endif }, { "sha256", @@ -54,10 +57,9 @@ struct checksum_algo checksum_algos[] = { RSA4096_BYTES, #if IMAGE_ENABLE_SIGN EVP_sha256, -#else +#endif sha256_calculate, padding_sha256_rsa4096, -#endif } }; -- cgit v1.2.1 From b401b73d02bb4f97197830e565f19a65577fecc6 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 5 Mar 2014 19:58:39 +0100 Subject: aes: Add 'aes' command to access AES-128-CBC Add simple 'aes' command, which allows using the AES-128-CBC encryption and decryption functions from U-Boot command line. Signed-off-by: Marek Vasut --- common/Makefile | 1 + common/cmd_aes.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 common/cmd_aes.c (limited to 'common') diff --git a/common/Makefile b/common/Makefile index e2ff0cb57d..c49a0af28d 100644 --- a/common/Makefile +++ b/common/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_ENV_IS_IN_UBI) += env_ubi.o obj-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o # command +obj-$(CONFIG_CMD_AES) += cmd_aes.o obj-$(CONFIG_CMD_AMBAPP) += cmd_ambapp.o obj-$(CONFIG_SOURCE) += cmd_source.o obj-$(CONFIG_CMD_SOURCE) += cmd_source.o diff --git a/common/cmd_aes.c b/common/cmd_aes.c new file mode 100644 index 0000000000..76da3efffe --- /dev/null +++ b/common/cmd_aes.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 Marek Vasut + * + * Command for en/de-crypting block of memory with AES-128-CBC cipher. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/** + * do_aes() - Handle the "aes" command-line command + * @cmdtp: Command data struct pointer + * @flag: Command flag + * @argc: Command-line argument count + * @argv: Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + */ +static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + uint32_t key_addr, src_addr, dst_addr, len; + uint8_t *key_ptr, *src_ptr, *dst_ptr; + uint8_t key_exp[AES_EXPAND_KEY_LENGTH]; + uint32_t aes_blocks; + int enc; + + if (argc != 6) + return CMD_RET_USAGE; + + if (!strncmp(argv[1], "enc", 3)) + enc = 1; + else if (!strncmp(argv[1], "dec", 3)) + enc = 0; + else + return CMD_RET_USAGE; + + key_addr = simple_strtoul(argv[2], NULL, 16); + src_addr = simple_strtoul(argv[3], NULL, 16); + dst_addr = simple_strtoul(argv[4], NULL, 16); + len = simple_strtoul(argv[5], NULL, 16); + + key_ptr = (uint8_t *)key_addr; + src_ptr = (uint8_t *)src_addr; + dst_ptr = (uint8_t *)dst_addr; + + /* First we expand the key. */ + aes_expand_key(key_ptr, key_exp); + + /* Calculate the number of AES blocks to encrypt. */ + aes_blocks = DIV_ROUND_UP(len, AES_KEY_LENGTH); + + if (enc) + aes_cbc_encrypt_blocks(key_exp, src_ptr, dst_ptr, aes_blocks); + else + aes_cbc_decrypt_blocks(key_exp, src_ptr, dst_ptr, aes_blocks); + + return 0; +} + +/***************************************************/ +#ifdef CONFIG_SYS_LONGHELP +static char aes_help_text[] = + "enc key src dst len - Encrypt block of data $len bytes long\n" + " at address $src using a key at address\n" + " $key and store the result at address\n" + " $dst. The $len size must be multiple of\n" + " 16 bytes and $key must be 16 bytes long.\n" + "aes dec key src dst len - Decrypt block of data $len bytes long\n" + " at address $src using a key at address\n" + " $key and store the result at address\n" + " $dst. The $len size must be multiple of\n" + " 16 bytes and $key must be 16 bytes long."; +#endif + +U_BOOT_CMD( + aes, 6, 1, do_aes, + "AES 128 CBC encryption", + aes_help_text +); -- cgit v1.2.1 From 7ce1526ed2bf7a7499a843d38b30095fa2894659 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 5 Mar 2014 19:59:50 +0100 Subject: env: Add env_export() wrapper Implement env_export() wrapper, so that all implementers of saveenv() don't have to call hexport_r(), crc32() etc. sequence . This trims down a bit of code duplication. Signed-off-by: Marek Vasut --- common/env_common.c | 17 +++++++++++++++++ common/env_dataflash.c | 17 ++++++----------- common/env_eeprom.c | 12 +++--------- common/env_fat.c | 12 +++--------- common/env_flash.c | 21 ++++++--------------- common/env_mmc.c | 12 ++---------- common/env_nand.c | 13 ++++--------- common/env_nvram.c | 12 +++--------- common/env_onenand.c | 13 ++++--------- common/env_sf.c | 24 +++++++----------------- common/env_ubi.c | 27 ++++++++------------------- 11 files changed, 63 insertions(+), 117 deletions(-) (limited to 'common') diff --git a/common/env_common.c b/common/env_common.c index c0bfc2f5db..fe35ff4360 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -172,6 +172,23 @@ int env_import(const char *buf, int check) return 0; } +/* Emport the environment and generate CRC for it. */ +int env_export(env_t *env_out) +{ + char *res; + ssize_t len; + + res = (char *)env_out->data; + len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + env_out->crc = crc32(0, env_out->data, ENV_SIZE); + + return 0; +} + void env_relocate(void) { #if defined(CONFIG_NEEDS_MANUAL_RELOC) diff --git a/common/env_dataflash.c b/common/env_dataflash.c index b53b87e958..034e323169 100644 --- a/common/env_dataflash.c +++ b/common/env_dataflash.c @@ -56,17 +56,12 @@ void env_relocate_spec(void) int saveenv(void) { - env_t env_new; - ssize_t len; - char *res; - - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_t env_new; + int ret; + + ret = env_export(&env_new); + if (ret) + return ret; return write_dataflash(CONFIG_ENV_ADDR, (unsigned long)&env_new, diff --git a/common/env_eeprom.c b/common/env_eeprom.c index 0db2bb63fe..490ac731b3 100644 --- a/common/env_eeprom.c +++ b/common/env_eeprom.c @@ -98,8 +98,6 @@ void env_relocate_spec(void) int saveenv(void) { env_t env_new; - ssize_t len; - char *res; int rc; unsigned int off = CONFIG_ENV_OFFSET; #ifdef CONFIG_ENV_OFFSET_REDUND @@ -109,13 +107,9 @@ int saveenv(void) BUG_ON(env_ptr != NULL); - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + rc = env_export(&env_new); + if (rc) + return rc; #ifdef CONFIG_ENV_OFFSET_REDUND if (gd->env_valid == 1) { diff --git a/common/env_fat.c b/common/env_fat.c index 708fd13dc7..aad0487c32 100644 --- a/common/env_fat.c +++ b/common/env_fat.c @@ -37,19 +37,14 @@ int env_init(void) int saveenv(void) { env_t env_new; - ssize_t len; - char *res; block_dev_desc_t *dev_desc = NULL; int dev = FAT_ENV_DEVICE; int part = FAT_ENV_PART; int err; - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } + err = env_export(&env_new); + if (err) + return err; #ifdef CONFIG_MMC if (strcmp(FAT_ENV_INTERFACE, "mmc") == 0) { @@ -79,7 +74,6 @@ int saveenv(void) return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); err = file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)); if (err == -1) { printf("\n** Unable to write \"%s\" from %s%d:%d **\n", diff --git a/common/env_flash.c b/common/env_flash.c index 7d5a4cfc8a..b3ad908894 100644 --- a/common/env_flash.c +++ b/common/env_flash.c @@ -106,8 +106,7 @@ int env_init(void) int saveenv(void) { env_t env_new; - ssize_t len; - char *res, *saved_data = NULL; + char *saved_data = NULL; char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG; int rc = 1; #if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE @@ -125,13 +124,9 @@ int saveenv(void) if (flash_sect_protect(0, (ulong)flash_addr_new, end_addr_new)) goto done; - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - goto done; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + rc = env_export(&env_new); + if (rc) + return rc; env_new.flags = new_flag; #if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE @@ -258,13 +253,9 @@ int saveenv(void) if (flash_sect_protect(0, (long)flash_addr, end_addr)) goto done; - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); + rc = env_export(&env_new); + if (rc) goto done; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); puts("Erasing Flash..."); if (flash_sect_erase((long)flash_addr, end_addr)) diff --git a/common/env_mmc.c b/common/env_mmc.c index 045428c6ec..c99fc750fa 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -118,8 +118,6 @@ static unsigned char env_flags; int saveenv(void) { ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); - ssize_t len; - char *res; struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); u32 offset; int ret, copy = 0; @@ -127,15 +125,9 @@ int saveenv(void) if (init_mmc_for_env(mmc)) return 1; - res = (char *)&env_new->data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - ret = 1; + ret = env_export(env_new); + if (ret) goto fini; - } - - env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE); #ifdef CONFIG_ENV_OFFSET_REDUND env_new->flags = ++env_flags; /* increase the serial */ diff --git a/common/env_nand.c b/common/env_nand.c index 695a9eebb0..5a734a9321 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -181,8 +181,6 @@ int saveenv(void) { int ret = 0; ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); - ssize_t len; - char *res; int env_idx = 0; static const struct env_location location[] = { { @@ -207,13 +205,10 @@ int saveenv(void) if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) return 1; - res = (char *)&env_new->data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); + ret = env_export(env_new); + if (ret) + return ret; + #ifdef CONFIG_ENV_OFFSET_REDUND env_new->flags = ++env_flags; /* increase the serial */ env_idx = (gd->env_valid == 1); diff --git a/common/env_nvram.c b/common/env_nvram.c index 0866cde924..524f07d5f8 100644 --- a/common/env_nvram.c +++ b/common/env_nvram.c @@ -69,17 +69,11 @@ void env_relocate_spec(void) int saveenv(void) { env_t env_new; - ssize_t len; - char *res; int rcode = 0; - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + rcode = env_export(&env_new); + if (rcode) + return rcode; #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE nvram_write(CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE); diff --git a/common/env_onenand.c b/common/env_onenand.c index 4b44632180..cc3d670de8 100644 --- a/common/env_onenand.c +++ b/common/env_onenand.c @@ -66,8 +66,7 @@ void env_relocate_spec(void) int saveenv(void) { env_t env_new; - ssize_t len; - char *res; + int ret; struct mtd_info *mtd = &onenand_mtd; #ifdef CONFIG_ENV_ADDR_FLEX struct onenand_chip *this = &onenand_chip; @@ -78,13 +77,9 @@ int saveenv(void) .callback = NULL, }; - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + ret = env_export(&env_new); + if (ret) + return ret; instr.len = CONFIG_ENV_SIZE; #ifdef CONFIG_ENV_ADDR_FLEX diff --git a/common/env_sf.c b/common/env_sf.c index be270f21bc..37ab13ae17 100644 --- a/common/env_sf.c +++ b/common/env_sf.c @@ -47,8 +47,7 @@ static struct spi_flash *env_flash; int saveenv(void) { env_t env_new; - ssize_t len; - char *res, *saved_buffer = NULL, flag = OBSOLETE_FLAG; + char *saved_buffer = NULL, flag = OBSOLETE_FLAG; u32 saved_size, saved_offset, sector = 1; int ret; @@ -62,13 +61,9 @@ int saveenv(void) } } - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + ret = env_export(&env_new); + if (ret) + return ret; env_new.flags = ACTIVE_FLAG; if (gd->env_valid == 1) { @@ -225,10 +220,9 @@ out: int saveenv(void) { u32 saved_size, saved_offset, sector = 1; - char *res, *saved_buffer = NULL; + char *saved_buffer = NULL; int ret = 1; env_t env_new; - ssize_t len; if (!env_flash) { env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, @@ -260,13 +254,9 @@ int saveenv(void) sector++; } - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); + ret = env_export(&env_new); + if (ret) goto done; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, diff --git a/common/env_ubi.c b/common/env_ubi.c index c0828a47d3..77bbfa6ef4 100644 --- a/common/env_ubi.c +++ b/common/env_ubi.c @@ -37,15 +37,11 @@ static unsigned char env_flags; int saveenv(void) { ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); - ssize_t len; - char *res; + int ret; - res = (char *)&env_new->data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } + ret = env_export(env_new); + if (ret) + return ret; if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { printf("\n** Cannot find mtd partition \"%s\"\n", @@ -53,7 +49,6 @@ int saveenv(void) return 1; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); env_new->flags = ++env_flags; /* increase the serial */ if (gd->env_valid == 1) { @@ -86,15 +81,11 @@ int saveenv(void) int saveenv(void) { ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); - ssize_t len; - char *res; + int ret; - res = (char *)&env_new->data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } + ret = env_export(env_new); + if (ret) + return ret; if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { printf("\n** Cannot find mtd partition \"%s\"\n", @@ -102,8 +93,6 @@ int saveenv(void) return 1; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); - if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new, CONFIG_ENV_SIZE)) { printf("\n** Unable to write env to %s:%s **\n", -- cgit v1.2.1 From a4223b746db5c2db2e1a1d4f0bb20e30484b1667 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 5 Mar 2014 19:59:51 +0100 Subject: env: Implement support for encrypting environment Add function which allows encrypting the whole environment block with AES-128-CBC. The key for the environment is retrieved by env_aes_cbc_get_key() function, which must be implemented on a per-board basis. Signed-off-by: Marek Vasut --- common/env_common.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'common') diff --git a/common/env_common.c b/common/env_common.c index fe35ff4360..cd7b4cd1df 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -140,6 +140,52 @@ int set_default_vars(int nvars, char * const vars[]) H_NOCLEAR | H_INTERACTIVE, nvars, vars); } +#ifdef CONFIG_ENV_AES +#include +/** + * env_aes_cbc_get_key() - Get AES-128-CBC key for the environment + * + * This function shall return 16-byte array containing AES-128 key used + * to encrypt and decrypt the environment. This function must be overriden + * by the implementer as otherwise the environment encryption will not + * work. + */ +__weak uint8_t *env_aes_cbc_get_key(void) +{ + return NULL; +} + +static int env_aes_cbc_crypt(env_t *env, const int enc) +{ + unsigned char *data = env->data; + uint8_t *key; + uint8_t key_exp[AES_EXPAND_KEY_LENGTH]; + uint32_t aes_blocks; + + key = env_aes_cbc_get_key(); + if (!key) + return -EINVAL; + + /* First we expand the key. */ + aes_expand_key(key, key_exp); + + /* Calculate the number of AES blocks to encrypt. */ + aes_blocks = ENV_SIZE / AES_KEY_LENGTH; + + if (enc) + aes_cbc_encrypt_blocks(key_exp, data, data, aes_blocks); + else + aes_cbc_decrypt_blocks(key_exp, data, data, aes_blocks); + + return 0; +} +#else +static inline int env_aes_cbc_crypt(env_t *env, const int enc) +{ + return 0; +} +#endif + /* * Check if CRC is valid and (if yes) import the environment. * Note that "buf" may or may not be aligned. @@ -147,6 +193,7 @@ int set_default_vars(int nvars, char * const vars[]) int env_import(const char *buf, int check) { env_t *ep = (env_t *)buf; + int ret; if (check) { uint32_t crc; @@ -159,6 +206,14 @@ int env_import(const char *buf, int check) } } + /* Decrypt the env if desired. */ + ret = env_aes_cbc_crypt(ep, 0); + if (ret) { + error("Failed to decrypt env!\n"); + set_default_env("!import failed"); + return ret; + } + if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, 0, NULL)) { gd->flags |= GD_FLG_ENV_READY; @@ -177,6 +232,7 @@ int env_export(env_t *env_out) { char *res; ssize_t len; + int ret; res = (char *)env_out->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); @@ -184,6 +240,12 @@ int env_export(env_t *env_out) error("Cannot export environment: errno = %d\n", errno); return 1; } + + /* Encrypt the env if desired. */ + ret = env_aes_cbc_crypt(env_out, 1); + if (ret) + return ret; + env_out->crc = crc32(0, env_out->data, ENV_SIZE); return 0; -- cgit v1.2.1 From 0f605c1501f6e82553e9affc6e17876a85db408c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 22 Mar 2014 17:14:51 -0600 Subject: Start the deprecation process for generic board We should move forward to remove the old board init code. Add a prominent message to encourage maintainers to get started on this work. Signed-off-by: Simon Glass --- common/main.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'common') diff --git a/common/main.c b/common/main.c index 8b6f274fa2..e54f63b956 100644 --- a/common/main.c +++ b/common/main.c @@ -427,6 +427,12 @@ void main_loop(void) bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); +#ifndef CONFIG_SYS_GENERIC_BOARD + puts("Warning: Your board does not use generic board. Please read\n"); + puts("doc/README.generic-board and take action. Boards not\n"); + puts("upgraded by the late 2014 may break or be removed.\n"); +#endif + #ifdef CONFIG_MODEM_SUPPORT debug("DEBUG: main_loop: do_mdm_init=%d\n", do_mdm_init); if (do_mdm_init) { -- cgit v1.2.1 From 9f661504367fce188d7838865f922f7edc5e7743 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 31 Mar 2014 13:02:51 +0900 Subject: floppy: delete unused files Signed-off-by: Masahiro Yamada --- common/cmd_fdos.c | 124 ------------------------------------------------------ 1 file changed, 124 deletions(-) delete mode 100644 common/cmd_fdos.c (limited to 'common') diff --git a/common/cmd_fdos.c b/common/cmd_fdos.c deleted file mode 100644 index 69303255ff..0000000000 --- a/common/cmd_fdos.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - - * Pierre AUBERT p.aubert@staubli.com - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Dos floppy support - */ - -#include -#include -#include -#include - -/*----------------------------------------------------------------------------- - * do_fdosboot -- - *----------------------------------------------------------------------------- - */ -int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - char *name; - char *ep; - int size; - int drive = CONFIG_SYS_FDC_DRIVE_NUMBER; - - /* pre-set load_addr */ - if ((ep = getenv("loadaddr")) != NULL) { - load_addr = simple_strtoul(ep, NULL, 16); - } - - /* pre-set Boot file name */ - if ((name = getenv("bootfile")) == NULL) { - name = "uImage"; - } - - switch (argc) { - case 1: - break; - case 2: - /* only one arg - accept two forms: - * just load address, or just boot file name. - * The latter form must be written "filename" here. - */ - if (argv[1][0] == '"') { /* just boot filename */ - name = argv [1]; - } else { /* load address */ - load_addr = simple_strtoul(argv[1], NULL, 16); - } - break; - case 3: - load_addr = simple_strtoul(argv[1], NULL, 16); - name = argv [2]; - break; - default: - return CMD_RET_USAGE; - } - - /* Init physical layer */ - if (!fdc_fdos_init (drive)) { - return (-1); - } - - /* Open file */ - if (dos_open (name) < 0) { - printf ("Unable to open %s\n", name); - return 1; - } - if ((size = dos_read (load_addr)) < 0) { - printf ("boot error\n"); - return 1; - } - flush_cache (load_addr, size); - - setenv_hex("filesize", size); - - printf("Floppy DOS load complete: %d bytes loaded to 0x%lx\n", - size, load_addr); - - return bootm_maybe_autostart(cmdtp, argv[0]); -} - -/*----------------------------------------------------------------------------- - * do_fdosls -- - *----------------------------------------------------------------------------- - */ -int do_fdosls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - char *path = ""; - int drive = CONFIG_SYS_FDC_DRIVE_NUMBER; - - switch (argc) { - case 1: - break; - case 2: - path = argv [1]; - break; - } - - /* Init physical layer */ - if (!fdc_fdos_init (drive)) { - return (-1); - } - /* Open directory */ - if (dos_open (path) < 0) { - printf ("Unable to open %s\n", path); - return 1; - } - return (dos_dir ()); -} - -U_BOOT_CMD( - fdosboot, 3, 0, do_fdosboot, - "boot from a dos floppy file", - "[loadAddr] [filename]" -); - -U_BOOT_CMD( - fdosls, 2, 0, do_fdosls, - "list files in a directory", - "[directory]" -); -- cgit v1.2.1 From 3fa1981e243cbe8f4a31139740600eddde5a4da4 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 17 Apr 2014 16:20:39 -0400 Subject: env_flash.c: Drop unused variables With 7ce1526 we no longer need 'len' or 'res', so drop these variables. Signed-off-by: Tom Rini --- common/env_flash.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'common') diff --git a/common/env_flash.c b/common/env_flash.c index b3ad908894..004e8849a7 100644 --- a/common/env_flash.c +++ b/common/env_flash.c @@ -224,9 +224,8 @@ int env_init(void) int saveenv(void) { env_t env_new; - ssize_t len; int rc = 1; - char *res, *saved_data = NULL; + char *saved_data = NULL; #if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE ulong up_data = 0; -- cgit v1.2.1 From fd11bea2ccb97909f421e20e6a5ba770dbf39d0b Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 27 Mar 2014 20:34:13 +0000 Subject: blackfin: make name_to_gpio be a weak symbol This required moving it into a C file from the header. The only user of a non-default name_to_gpio is blackfin, therefore build tested with the blackfin bct-brettl2 build, which is one I picked at random. Also tested with a build for the ARM tec board which uses the default/fallback implementation. Inspection with objdump shows that both have done the right thing. This change was requested by Marek during review of the sunxi patch series. Signed-off-by: Ian Campbell Cc: Marek Vasut Cc: Wolfgang Denk Cc: Sonic Zhang --- common/cmd_gpio.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'common') diff --git a/common/cmd_gpio.c b/common/cmd_gpio.c index 778aa5f098..aff044518f 100644 --- a/common/cmd_gpio.c +++ b/common/cmd_gpio.c @@ -11,9 +11,10 @@ #include #include -#ifndef name_to_gpio -#define name_to_gpio(name) simple_strtoul(name, NULL, 10) -#endif +int __weak name_to_gpio(const char *name) +{ + return simple_strtoul(name, NULL, 10); +} enum gpio_cmd { GPIO_INPUT, -- cgit v1.2.1 From c4474fc88047ac91292930ae906585934df59015 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 4 Apr 2014 12:23:24 +0100 Subject: board_r: return 0 from show_model_r The show_model_r function should return an int but didn't. Return 0 to indicate inevitable success and avoid the following if it is used: common/board_r.c: In function 'show_model_r': common/board_r.c:531:1: warning: no return statement in function returning non-void [-Wreturn-type] } ^ Cc: Simon Glass Signed-off-by: Paul Burton Acked-by: Simon Glass --- common/board_r.c | 1 + 1 file changed, 1 insertion(+) (limited to 'common') diff --git a/common/board_r.c b/common/board_r.c index 8629a656c2..d1f0aa9b1a 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -528,6 +528,7 @@ static int show_model_r(void) # else checkboard(); # endif + return 0; } #endif -- cgit v1.2.1 From 77cc8902e98f4b4a36688f454a07ad7bc82793a2 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 15 Apr 2014 10:28:12 -0700 Subject: bootm: set max decompression size for LZO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LZO decompressor wasn't initializing the maximum output size, which meant it would fail to decompress most of the time. Reported-by: Matthias Weißer Signed-off-by: Kees Cook Tested-by: Matthias Weißer Acked-by: Simon Glass --- common/cmd_bootm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common') diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 9751edc907..c243a5bd78 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -453,7 +453,7 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, #endif /* CONFIG_LZMA */ #ifdef CONFIG_LZO case IH_COMP_LZO: { - size_t size; + size_t size = unc_len; printf(" Uncompressing %s ... ", type_name); -- cgit v1.2.1 From 3da7e5a50be7ca8deeac822787c7ee3bcd465c07 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 7 Apr 2014 10:11:20 +0100 Subject: board_f: call init_func_ram on MIPS Assigning gd->ram_size the return value of initdram matches the existing MIPS board behaviour. Suggested-by: Daniel Schwierzeck Signed-off-by: Paul Burton --- common/board_f.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'common') diff --git a/common/board_f.c b/common/board_f.c index f285bad538..2ece9e26aa 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -173,7 +173,7 @@ static int announce_dram_init(void) return 0; } -#ifdef CONFIG_PPC +#if defined(CONFIG_MIPS) || defined(CONFIG_PPC) static int init_func_ram(void) { #ifdef CONFIG_BOARD_TYPES @@ -889,7 +889,7 @@ static init_fnc_t init_sequence_f[] = { #ifdef CONFIG_ARM dram_init, /* configure available RAM banks */ #endif -#ifdef CONFIG_PPC +#if defined(CONFIG_MIPS) || defined(CONFIG_PPC) init_func_ram, #endif #ifdef CONFIG_POST -- cgit v1.2.1 From 6dc9bacea58db97e55bcb3ed2e00d5ca66a615d9 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 7 Apr 2014 10:11:21 +0100 Subject: board_f: call timer_init on MIPS MIPS needs a call to timer_init to preserve its current behaviour ensuring that the cop0 compare register is initialised appropriately. Reported-by: Daniel Schwierzeck Signed-off-by: Paul Burton --- common/board_f.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common') diff --git a/common/board_f.c b/common/board_f.c index 2ece9e26aa..cbdf06f812 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -819,7 +819,7 @@ static init_fnc_t init_sequence_f[] = { /* TODO: can we rename this to timer_init()? */ init_timebase, #endif -#ifdef CONFIG_ARM +#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) timer_init, /* initialize timer */ #endif #ifdef CONFIG_SYS_ALLOC_DPRAM -- cgit v1.2.1 From 94fb182cdf5f39befc822cd5a1110a1ca3b6631d Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 11 Apr 2014 17:09:40 +0200 Subject: fdt_support: split fdt_getprop_u32_default We already have a nice helper to give us a property cell value with default fall back from a path. Split that into two helpers - one for the old path based lookup and one to give us a value based on a node offset. Signed-off-by: Alexander Graf Acked-by: Scott Wood Reviewed-by: York Sun --- common/fdt_support.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'common') diff --git a/common/fdt_support.c b/common/fdt_support.c index f9f358e7e8..cc0bf76595 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -49,6 +49,37 @@ static void write_cell(u8 *addr, u64 val, int size) } } +/** + * fdt_getprop_u32_default_node - Return a node's property or a default + * + * @fdt: ptr to device tree + * @off: offset of node + * @cell: cell offset in property + * @prop: property name + * @dflt: default value if the property isn't found + * + * Convenience function to return a node's property or a default value if + * the property doesn't exist. + */ +u32 fdt_getprop_u32_default_node(const void *fdt, int off, int cell, + const char *prop, const u32 dflt) +{ + const fdt32_t *val; + int len; + + val = fdt_getprop(fdt, off, prop, &len); + + /* Check if property exists */ + if (!val) + return dflt; + + /* Check if property is long enough */ + if (len < ((cell + 1) * sizeof(uint32_t))) + return dflt; + + return fdt32_to_cpu(*val); +} + /** * fdt_getprop_u32_default - Find a node and return it's property or a default * @@ -63,18 +94,13 @@ static void write_cell(u8 *addr, u64 val, int size) u32 fdt_getprop_u32_default(const void *fdt, const char *path, const char *prop, const u32 dflt) { - const fdt32_t *val; int off; off = fdt_path_offset(fdt, path); if (off < 0) return dflt; - val = fdt_getprop(fdt, off, prop, NULL); - if (val) - return fdt32_to_cpu(*val); - else - return dflt; + return fdt_getprop_u32_default_node(fdt, off, 0, prop, dflt); } /** -- cgit v1.2.1 From c48e686889395ee6d33c7a7d76f8399839b699d1 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 11 Apr 2014 17:09:41 +0200 Subject: fdt_support: Add helper function to read "ranges" property This patch adds a helper function that can be used to interpret most "ranges" properties in the device tree. It reads the n'th range out of a "ranges" array and returns the node's virtual address of the range, the physical address that range starts at and the size of the range. Signed-off-by: Alexander Graf Acked-by: Scott Wood Reviewed-by: York Sun --- common/fdt_support.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) (limited to 'common') diff --git a/common/fdt_support.c b/common/fdt_support.c index cc0bf76595..fcd252336c 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -1435,3 +1435,97 @@ u64 fdt_get_base_address(void *fdt, int node) return prop ? fdt_translate_address(fdt, node, prop + naddr) : 0; } + +/* + * Read a property of size . Currently only supports 1 or 2 cells. + */ +static int fdt_read_prop(const fdt32_t *prop, int prop_len, int cell_off, + uint64_t *val, int cells) +{ + const fdt32_t *prop32 = &prop[cell_off]; + const fdt64_t *prop64 = (const fdt64_t *)&prop[cell_off]; + + if ((cell_off + cells) > prop_len) + return -FDT_ERR_NOSPACE; + + switch (cells) { + case 1: + *val = fdt32_to_cpu(*prop32); + break; + case 2: + *val = fdt64_to_cpu(*prop64); + break; + default: + return -FDT_ERR_NOSPACE; + } + + return 0; +} + +/** + * fdt_read_range - Read a node's n'th range property + * + * @fdt: ptr to device tree + * @node: offset of node + * @n: range index + * @child_addr: pointer to storage for the "child address" field + * @addr: pointer to storage for the CPU view translated physical start + * @len: pointer to storage for the range length + * + * Convenience function that reads and interprets a specific range out of + * a number of the "ranges" property array. + */ +int fdt_read_range(void *fdt, int node, int n, uint64_t *child_addr, + uint64_t *addr, uint64_t *len) +{ + int pnode = fdt_parent_offset(fdt, node); + const fdt32_t *ranges; + int pacells; + int acells; + int scells; + int ranges_len; + int cell = 0; + int r = 0; + + /* + * The "ranges" property is an array of + * { } + * + * All 3 elements can span a diffent number of cells. Fetch their size. + */ + pacells = fdt_getprop_u32_default_node(fdt, pnode, 0, "#address-cells", 1); + acells = fdt_getprop_u32_default_node(fdt, node, 0, "#address-cells", 1); + scells = fdt_getprop_u32_default_node(fdt, node, 0, "#size-cells", 1); + + /* Now try to get the ranges property */ + ranges = fdt_getprop(fdt, node, "ranges", &ranges_len); + if (!ranges) + return -FDT_ERR_NOTFOUND; + ranges_len /= sizeof(uint32_t); + + /* Jump to the n'th entry */ + cell = n * (pacells + acells + scells); + + /* Read */ + if (child_addr) { + r = fdt_read_prop(ranges, ranges_len, cell, child_addr, + acells); + if (r) + return r; + } + cell += acells; + + /* Read */ + if (addr) + *addr = fdt_translate_address(fdt, node, ranges + cell); + cell += pacells; + + /* Read */ + if (len) { + r = fdt_read_prop(ranges, ranges_len, cell, len, scells); + if (r) + return r; + } + + return 0; +} -- cgit v1.2.1 From 34e026f9b1eb3bcffb38e7787c2e6eac0e88ba85 Mon Sep 17 00:00:00 2001 From: York Sun Date: Thu, 27 Mar 2014 17:54:47 -0700 Subject: driver/ddr/fsl: Add DDR4 support to Freescale DDR driver Mostly reusing DDR3 driver, this patch adds DDR4 SPD handling, register calculation and programming. Signed-off-by: York Sun --- common/ddr_spd.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'common') diff --git a/common/ddr_spd.c b/common/ddr_spd.c index 7a388bb9fa..438e71afd2 100644 --- a/common/ddr_spd.c +++ b/common/ddr_spd.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Freescale Semiconductor, Inc. + * Copyright 2008-2014 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -116,3 +116,46 @@ ddr3_spd_check(const ddr3_spd_eeprom_t *spd) return 1; } } + +unsigned int ddr4_spd_check(const struct ddr4_spd_eeprom_s *spd) +{ + char *p = (char *)spd; + int csum16; + int len; + char crc_lsb; /* byte 126 */ + char crc_msb; /* byte 127 */ + + len = 126; + csum16 = crc16(p, len); + + crc_lsb = (char) (csum16 & 0xff); + crc_msb = (char) (csum16 >> 8); + + if (spd->crc[0] != crc_lsb || spd->crc[1] != crc_msb) { + printf("SPD checksum unexpected.\n" + "Checksum lsb in SPD = %02X, computed SPD = %02X\n" + "Checksum msb in SPD = %02X, computed SPD = %02X\n", + spd->crc[0], crc_lsb, spd->crc[1], crc_msb); + return 1; + } + + p = (char *)((ulong)spd + 128); + len = 126; + csum16 = crc16(p, len); + + crc_lsb = (char) (csum16 & 0xff); + crc_msb = (char) (csum16 >> 8); + + if (spd->mod_section.uc[126] != crc_lsb || + spd->mod_section.uc[127] != crc_msb) { + printf("SPD checksum unexpected.\n" + "Checksum lsb in SPD = %02X, computed SPD = %02X\n" + "Checksum msb in SPD = %02X, computed SPD = %02X\n", + spd->mod_section.uc[126], + crc_lsb, spd->mod_section.uc[127], + crc_msb); + return 1; + } + + return 0; +} -- cgit v1.2.1 From 08a98b89df39d25a1260f390c19be4649dfd303d Mon Sep 17 00:00:00 2001 From: Adrian Cox Date: Thu, 10 Apr 2014 14:02:44 +0100 Subject: usb: Fix USB keyboard polling via control endpoint USB keyboard polling failed for some keyboards on PowerPC 5020. This was caused by requesting only 4 bytes of data from keyboards that produce an 8 byte HID report. Signed-off-by: Adrian Cox Signed-off-by: Wolfgang Denk Cc: Marek Vasut --- common/usb_kbd.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'common') diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 1ad67caf13..0b77c16c5f 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -91,6 +91,12 @@ static const unsigned char usb_kbd_arrow[] = { #define USB_KBD_LEDMASK \ (USB_KBD_NUMLOCK | USB_KBD_CAPSLOCK | USB_KBD_SCROLLLOCK) +/* + * USB Keyboard reports are 8 bytes in boot protocol. + * Appendix B of HID Device Class Definition 1.11 + */ +#define USB_KBD_BOOT_REPORT_SIZE 8 + struct usb_kbd_pdata { uint32_t repeat_delay; @@ -99,7 +105,7 @@ struct usb_kbd_pdata { uint8_t usb_kbd_buffer[USB_KBD_BUFFER_LEN]; uint8_t *new; - uint8_t old[8]; + uint8_t old[USB_KBD_BOOT_REPORT_SIZE]; uint8_t flags; }; @@ -131,7 +137,8 @@ void usb_kbd_generic_poll(void) /* Submit a interrupt transfer request */ maxp = usb_maxpacket(usb_kbd_dev, pipe); usb_submit_int_msg(usb_kbd_dev, pipe, data->new, - maxp > 8 ? 8 : maxp, ep->bInterval); + min(maxp, USB_KBD_BOOT_REPORT_SIZE), + ep->bInterval); } /* Puts character in the queue and sets up the in and out pointer. */ @@ -266,8 +273,11 @@ static uint32_t usb_kbd_service_key(struct usb_device *dev, int i, int up) old = data->old; } - if ((old[i] > 3) && (memscan(new + 2, old[i], 6) == new + 8)) + if ((old[i] > 3) && + (memscan(new + 2, old[i], USB_KBD_BOOT_REPORT_SIZE - 2) == + new + USB_KBD_BOOT_REPORT_SIZE)) { res |= usb_kbd_translate(data, old[i], data->new[0], up); + } return res; } @@ -285,7 +295,7 @@ static int usb_kbd_irq_worker(struct usb_device *dev) else if ((data->new[0] == LEFT_CNTR) || (data->new[0] == RIGHT_CNTR)) data->flags |= USB_KBD_CTRL; - for (i = 2; i < 8; i++) { + for (i = 2; i < USB_KBD_BOOT_REPORT_SIZE; i++) { res |= usb_kbd_service_key(dev, i, 0); res |= usb_kbd_service_key(dev, i, 1); } @@ -297,7 +307,7 @@ static int usb_kbd_irq_worker(struct usb_device *dev) if (res == 1) usb_kbd_setled(dev); - memcpy(data->old, data->new, 8); + memcpy(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE); return 1; } @@ -305,7 +315,8 @@ static int usb_kbd_irq_worker(struct usb_device *dev) /* Keyboard interrupt handler */ static int usb_kbd_irq(struct usb_device *dev) { - if ((dev->irq_status != 0) || (dev->irq_act_len != 8)) { + if ((dev->irq_status != 0) || + (dev->irq_act_len != USB_KBD_BOOT_REPORT_SIZE)) { debug("USB KBD: Error %lX, len %d\n", dev->irq_status, dev->irq_act_len); return 1; @@ -333,7 +344,8 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev) /* Submit a interrupt transfer request */ maxp = usb_maxpacket(dev, pipe); usb_submit_int_msg(dev, pipe, &data->new[0], - maxp > 8 ? 8 : maxp, ep->bInterval); + min(maxp, USB_KBD_BOOT_REPORT_SIZE), + ep->bInterval); usb_kbd_irq_worker(dev); #elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) @@ -341,8 +353,8 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev) struct usb_kbd_pdata *data = dev->privptr; iface = &dev->config.if_desc[0]; usb_get_report(dev, iface->desc.bInterfaceNumber, - 1, 0, data->new, sizeof(data->new)); - if (memcmp(data->old, data->new, sizeof(data->new))) + 1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE); + if (memcmp(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE)) usb_kbd_irq_worker(dev); #endif } @@ -441,7 +453,8 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) memset(data, 0, sizeof(struct usb_kbd_pdata)); /* allocate input buffer aligned and sized to USB DMA alignment */ - data->new = memalign(USB_DMA_MINALIGN, roundup(8, USB_DMA_MINALIGN)); + data->new = memalign(USB_DMA_MINALIGN, + roundup(USB_KBD_BOOT_REPORT_SIZE, USB_DMA_MINALIGN)); /* Insert private data into USB device structure */ dev->privptr = data; @@ -459,7 +472,8 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE, 0); debug("USB KBD: enable interrupt pipe...\n"); - if (usb_submit_int_msg(dev, pipe, data->new, maxp > 8 ? 8 : maxp, + if (usb_submit_int_msg(dev, pipe, data->new, + min(maxp, USB_KBD_BOOT_REPORT_SIZE), ep->bInterval) < 0) { printf("Failed to get keyboard state from device %04x:%04x\n", dev->descriptor.idVendor, dev->descriptor.idProduct); -- cgit v1.2.1 From 75504e9592745021006cb8905b5ff5a51d9d1cb3 Mon Sep 17 00:00:00 2001 From: Mateusz Zalega Date: Wed, 30 Apr 2014 13:07:48 +0200 Subject: usb: dfu: fix boards wo USB cable detection Former usb_cable_connected() patch broke compilation of boards which do not support this feature. I've renamed usb_cable_connected() to g_dnl_usb_cable_connected() and added its default implementation to gadget downloader driver code. There's only one driver of this kind and it's unlikely there'll be another, so there's no point in keeping it in /common. Previously this function was declared in usb.h. I've moved it, since it's more appropriate to keep it in g_dnl.h - usb.h seems to be intended for USB host implementation. Existing code, confronted with default -EOPNOTSUPP return value, continues as if the cable was connected. CONFIG_USB_CABLE_CHECK was removed. Change-Id: Ib9198621adee2811b391c64512f14646cefd0369 Signed-off-by: Mateusz Zalega Acked-by: Marek Vasut Acked-by: Lukasz Majewski --- common/cmd_usb_mass_storage.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'common') diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c index 5f557d5f85..14a5b6ae5e 100644 --- a/common/cmd_usb_mass_storage.c +++ b/common/cmd_usb_mass_storage.c @@ -45,10 +45,14 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, /* Timeout unit: seconds */ int cable_ready_timeout = UMS_CABLE_READY_TIMEOUT; - if (!usb_cable_connected()) { + if (!g_dnl_board_usb_cable_connected()) { + /* + * Won't execute if we don't know whether the cable is + * connected. + */ puts("Please connect USB cable.\n"); - while (!usb_cable_connected()) { + while (!g_dnl_board_usb_cable_connected()) { if (ctrlc()) { puts("\rCTRL+C - Operation aborted.\n"); goto exit; -- cgit v1.2.1 From c4d0e856047f2689278ffea63a562c4f22a35ee3 Mon Sep 17 00:00:00 2001 From: Mateusz Zalega Date: Mon, 28 Apr 2014 21:13:28 +0200 Subject: USB: gadget: added a saner gadget downloader registration API Preprocessor definitions and hardcoded implementation selection in g_dnl core were replaced by a linker list made of (usb_function_name, bind_callback) pairs. Signed-off-by: Mateusz Zalega Acked-by: Lukasz Majewski Acked-by: Marek Vasut --- common/cmd_dfu.c | 3 +-- common/cmd_thordown.c | 3 +-- common/cmd_usb_mass_storage.c | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'common') diff --git a/common/cmd_dfu.c b/common/cmd_dfu.c index 5547678208..a03538dabb 100644 --- a/common/cmd_dfu.c +++ b/common/cmd_dfu.c @@ -22,7 +22,6 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char *interface = argv[2]; char *devstring = argv[3]; - char *s = "dfu"; int ret, i = 0; ret = dfu_init_env_entities(interface, simple_strtoul(devstring, @@ -38,7 +37,7 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int controller_index = simple_strtoul(usb_controller, NULL, 0); board_usb_init(controller_index, USB_INIT_DEVICE); - g_dnl_register(s); + g_dnl_register("usb_dnl_dfu"); while (1) { if (dfu_reset()) /* diff --git a/common/cmd_thordown.c b/common/cmd_thordown.c index c4b3511458..2dd750928e 100644 --- a/common/cmd_thordown.c +++ b/common/cmd_thordown.c @@ -22,7 +22,6 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char *interface = argv[2]; char *devstring = argv[3]; - const char *s = "thor"; int ret; puts("TIZEN \"THOR\" Downloader\n"); @@ -40,7 +39,7 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) goto exit; } - g_dnl_register(s); + g_dnl_register("usb_dnl_thor"); ret = thor_init(); if (ret) { diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c index 14a5b6ae5e..d8d9efd4f6 100644 --- a/common/cmd_usb_mass_storage.c +++ b/common/cmd_usb_mass_storage.c @@ -40,7 +40,7 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, return CMD_RET_FAILURE; } - g_dnl_register("ums"); + g_dnl_register("usb_dnl_ums"); /* Timeout unit: seconds */ int cable_ready_timeout = UMS_CABLE_READY_TIMEOUT; -- cgit v1.2.1