[U-Boot] [PATCH v3 0/20] Various patches in common/

This collection of patches to common/ adds the following:
- EDID support for LCD displays - TPM stress test - gettime command to find out the time since boot - Adds coreboot information to the 'version' command - Fixes LMB on x86 - SHA256 hashing using a new hashing framework created in response to list feedback - Reading raw data from a partition of a block device
Some patches have been dropped from v2 in response to list feedback.
Also fixes a few minor bugs and tidy-ups.
Changes in v3: - Rename stricmp() to strcasecmp() to match Linux / POSIX - Bracket strcasecmp() declarations with __HAVE_ARCH_... - Rename stricmp() to strcasecmp() to match Linux / POSIX - Correct hash error message to show the algorithm name, not always SHA1 - Fix ordering of hash.o in Makefile - Correct hash command help to say 'hash' instead of 'sha1sum' - Drop meminfo from this series - Drop patch 'Update time command to avoid using get_timer_masked()'
Changes in v2: - Remove arm: tag from bootstage step patch - Convert space to tab in README - Update gettime commit message to include boards without CONFIG_SYS_HZ - Add more comments to the stdio strncpy commit message - Add new patch to adjust sha1 functions to use const/unsigned - Add new patch to adjust sha256 functions to const and watchdog - Add stricmp() patch again since it is used in this series - Add generic hash API to allow SHA256 command to be added without duplication - Add new patch to change sha1sum to use generic hash API - Add new hash command to support generic hash API - Add patch to enable hashing and EDID on smdk5250 - Add x86 patch to enable io command for coreboot - Add x86 tag to version command patch
Anton Staaf (1): Add gettime command
Kenneth Waters (1): Add a command to read raw blocks from a partition
Luigi Semenzato (1): tpm: Add TPM stress test
Simon Glass (11): Add new bootstage step for the main loop Fix use of conditional LMB sha1: Use const where possible, and unsigned for input len sha256: Use const where possible and add watchdog function Add strcasecmp() and strncasecmp() Add generic hash API sha1sum: Use generic hash layer Add hash command to perform hashing using various algorithms console: Enable function to display console info exynos: Enable hashing functions and EDID for smdk5250 x86: coreboot: Enable io command
Stefan Reinauer (1): x86: Add coreboot version to u-boot's version command
Tom Wai-Hong Tam (3): edid: Library of EDID decode and print edid: Add I2C command for printing the EDID fdt: edid: Enable fdt_add_edid() function when CONFIG_LCD defined
Vadim Bendebury (1): Add console command to access io space registers
Vincent Palatin (1): stdio: remove useless strncpy
README | 25 +++ arch/m68k/include/asm/string.h | 2 +- arch/powerpc/include/asm/string.h | 2 +- arch/sparc/include/asm/string.h | 2 +- common/Makefile | 6 + common/cmd_bootm.c | 2 +- common/cmd_gettime.c | 56 +++++++ common/cmd_hash.c | 63 ++++++++ common/cmd_i2c.c | 39 +++++ common/cmd_io.c | 93 +++++++++++ common/cmd_read.c | 81 ++++++++++ common/cmd_sha1sum.c | 129 +--------------- common/cmd_tpm.c | 93 +++++++++++- common/cmd_version.c | 7 +- common/console.c | 6 +- common/edid.c | 307 +++++++++++++++++++++++++++++++++++++ common/fdt_support.c | 2 +- common/hash.c | 221 ++++++++++++++++++++++++++ common/main.c | 2 + common/stdio.c | 1 - include/command.h | 8 +- include/config_cmd_all.h | 4 + include/configs/coreboot.h | 1 + include/configs/smdk5250.h | 7 + include/edid.h | 275 +++++++++++++++++++++++++++++++++ include/hash.h | 69 +++++++++ include/linux/string.h | 7 +- include/sha1.h | 26 +-- include/sha256.h | 8 +- lib/sha1.c | 19 ++- lib/sha256.c | 37 +++++- lib/string.c | 16 ++- 32 files changed, 1438 insertions(+), 178 deletions(-) create mode 100644 common/cmd_gettime.c create mode 100644 common/cmd_hash.c create mode 100644 common/cmd_io.c create mode 100644 common/cmd_read.c create mode 100644 common/edid.c create mode 100644 common/hash.c create mode 100644 include/edid.h create mode 100644 include/hash.h

Mark when we get to the main loop.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: - Remove arm: tag from bootstage step patch
common/main.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/common/main.c b/common/main.c index 5362781..b145f85 100644 --- a/common/main.c +++ b/common/main.c @@ -376,6 +376,8 @@ void main_loop (void) char bcs_set[16]; #endif /* CONFIG_BOOTCOUNT_LIMIT */
+ bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); + #ifdef CONFIG_BOOTCOUNT_LIMIT bootcount = bootcount_load(); bootcount++;

From: Anton Staaf robotboy@chromium.org
Gettime returns the current timer value. If CONFIG_SYS_HZ is defined then the timer value is also converted to seconds.
Tegra20 (SeaBoard) # gettime Timer val: 7754 Seconds : 7 Remainder : 754 sys_hz = 1000
There has been some discussion about whether this is useful enough to be included in U-Boot. The following boards do not have CONFIG_SYS_HZ defined:
M52277EVB M52277EVB_stmicro M53017EVB M54418TWR M54418TWR_nand_mii M54418TWR_nand_rmii M54418TWR_nand_rmii_lowfreq M54418TWR_serial_mii M54418TWR_serial_rmii
Signed-off-by: Anton Staaf robotboy@chromium.org Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: - Convert space to tab in README - Update gettime commit message to include boards without CONFIG_SYS_HZ
README | 1 + common/Makefile | 1 + common/cmd_gettime.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ include/config_cmd_all.h | 1 + 4 files changed, 59 insertions(+), 0 deletions(-) create mode 100644 common/cmd_gettime.c
diff --git a/README b/README index ed7d270..089d7a4 100644 --- a/README +++ b/README @@ -819,6 +819,7 @@ The following options need to be configured: CONFIG_CMD_FDOS * Dos diskette Support CONFIG_CMD_FLASH flinfo, erase, protect CONFIG_CMD_FPGA FPGA device initialization support + CONFIG_CMD_GETTIME * Get time since boot CONFIG_CMD_GO * the 'go' command (exec code) CONFIG_CMD_GREPENV * search environment CONFIG_CMD_HWFLOW * RTS/CTS hw flow control diff --git a/common/Makefile b/common/Makefile index 9e43322..0fb79ed 100644 --- a/common/Makefile +++ b/common/Makefile @@ -100,6 +100,7 @@ ifdef CONFIG_FPGA COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o endif COBJS-$(CONFIG_CMD_FS_GENERIC) += cmd_fs.o +COBJS-$(CONFIG_CMD_GETTIME) += cmd_gettime.o COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o diff --git a/common/cmd_gettime.c b/common/cmd_gettime.c new file mode 100644 index 0000000..d7d36a9 --- /dev/null +++ b/common/cmd_gettime.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. + * + * Copyright (c) 2009, Code Aurora Forum. All rights reserved. + * + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Get Timer overflows after 2^32 / CONFIG_SYS_HZ (32Khz) = 131072 sec + */ +#include <common.h> +#include <command.h> + +static int do_gettime(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + unsigned long int val = get_timer(0); + +#ifdef CONFIG_SYS_HZ + printf("Timer val: %lu\n", val); + printf("Seconds : %lu\n", val / CONFIG_SYS_HZ); + printf("Remainder : %lu\n", val % CONFIG_SYS_HZ); + printf("sys_hz = %lu\n", (unsigned long int)CONFIG_SYS_HZ); +#else + printf("CONFIG_SYS_HZ not defined"); + printf("Timer Val %lu", val); +#endif + + return 0; +} + +U_BOOT_CMD( + gettime, 1, 1, do_gettime, + "get timer val elapsed,\n", + "get time elapsed from uboot start\n" +); diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h index f434cd0..b87967e 100644 --- a/include/config_cmd_all.h +++ b/include/config_cmd_all.h @@ -40,6 +40,7 @@ #define CONFIG_CMD_FDOS /* Floppy DOS support */ #define CONFIG_CMD_FLASH /* flinfo, erase, protect */ #define CONFIG_CMD_FPGA /* FPGA configuration Support */ +#define CONFIG_CMD_GETTIME /* Get time since boot */ #define CONFIG_CMD_HWFLOW /* RTS/CTS hw flow control */ #define CONFIG_CMD_I2C /* I2C serial bus support */ #define CONFIG_CMD_IDE /* IDE harddisk support */

From: Kenneth Waters kwaters@chromium.org
Sometimes data is on a block device and within a partition, but not in a particular filesystem.
This commands permits reading raw data from a partition.
Signed-off-by: Kenneth Waters kwaters@chromium.org Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: None
README | 1 + common/Makefile | 1 + common/cmd_read.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++ include/config_cmd_all.h | 1 + 4 files changed, 84 insertions(+), 0 deletions(-) create mode 100644 common/cmd_read.c
diff --git a/README b/README index 089d7a4..027fa46 100644 --- a/README +++ b/README @@ -856,6 +856,7 @@ The following options need to be configured: CONFIG_CMD_PING * send ICMP ECHO_REQUEST to network host CONFIG_CMD_PORTIO * Port I/O + CONFIG_CMD_READ * Read raw data from partition CONFIG_CMD_REGINFO * Register dump CONFIG_CMD_RUN run command in env variable CONFIG_CMD_SAVES * save S record dump diff --git a/common/Makefile b/common/Makefile index 0fb79ed..84968f8 100644 --- a/common/Makefile +++ b/common/Makefile @@ -142,6 +142,7 @@ endif COBJS-y += cmd_pcmcia.o COBJS-$(CONFIG_CMD_PORTIO) += cmd_portio.o COBJS-$(CONFIG_CMD_PXE) += cmd_pxe.o +COBJS-$(CONFIG_CMD_READ) += cmd_read.o COBJS-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o COBJS-$(CONFIG_CMD_REISER) += cmd_reiser.o COBJS-$(CONFIG_CMD_SATA) += cmd_sata.o diff --git a/common/cmd_read.c b/common/cmd_read.c new file mode 100644 index 0000000..f0fc9bf --- /dev/null +++ b/common/cmd_read.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + */ + +#include <common.h> +#include <command.h> +#include <part.h> + +int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + char *ep; + block_dev_desc_t *dev_desc = NULL; + int dev; + int part = 0; + disk_partition_t part_info; + ulong offset = 0u; + ulong limit = 0u; + void *addr; + uint blk; + uint cnt; + + if (argc != 6) { + cmd_usage(cmdtp); + return 1; + } + + dev = (int)simple_strtoul(argv[2], &ep, 16); + if (*ep) { + if (*ep != ':') { + printf("Invalid block device %s\n", argv[2]); + return 1; + } + part = (int)simple_strtoul(++ep, NULL, 16); + } + + dev_desc = get_dev(argv[1], dev); + if (dev_desc == NULL) { + printf("Block device %s %d not supported\n", argv[1], dev); + return 1; + } + + addr = (void *)simple_strtoul(argv[3], NULL, 16); + blk = simple_strtoul(argv[4], NULL, 16); + cnt = simple_strtoul(argv[5], NULL, 16); + + if (part != 0) { + if (get_partition_info(dev_desc, part, &part_info)) { + printf("Cannot find partition %d\n", part); + return 1; + } + offset = part_info.start; + limit = part_info.size; + } else { + /* Largest address not available in block_dev_desc_t. */ + limit = ~0; + } + + if (cnt + blk > limit) { + printf("Read out of range\n"); + return 1; + } + + if (dev_desc->block_read(dev, offset + blk, cnt, addr) < 0) { + printf("Error reading blocks\n"); + return 1; + } + + return 0; +} + +U_BOOT_CMD( + read, 6, 0, do_read, + "Load binary data from a partition", + "<interface> <dev[:part]> addr blk# cnt" +); diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h index b87967e..148d676 100644 --- a/include/config_cmd_all.h +++ b/include/config_cmd_all.h @@ -71,6 +71,7 @@ #define CONFIG_CMD_REGINFO /* Register dump */ #define CONFIG_CMD_REISER /* Reiserfs support */ #define CONFIG_CMD_RARP /* rarpboot support */ +#define CONFIG_CMD_READ /* Read data from partition */ #define CONFIG_CMD_RUN /* run command in env variable */ #define CONFIG_CMD_SAVEENV /* saveenv */ #define CONFIG_CMD_SAVES /* save S record dump */

This code was not guarded with CONFIG_LMB so failed to build on x86.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: None
common/cmd_bootm.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 4dbe952..f7595c0 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -537,7 +537,7 @@ static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc, } break; #endif -#if defined(CONFIG_OF_LIBFDT) +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB) case BOOTM_STATE_FDT: { boot_fdt_add_mem_rsv_regions(&images.lmb,

From: Vincent Palatin vpalatin@chromium.org
The name is already copied when we memcpy() the whole structure.
This is because struct stdio_dev has this field:
char name[16]; /* Device name */
So the data is inline, rather than being a pointer.
Signed-off-by: Vincent Palatin vpalatin@chromium.org
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: - Add more comments to the stdio strncpy commit message
common/stdio.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/common/stdio.c b/common/stdio.c index 9f48e5f..97ff9cf 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -135,7 +135,6 @@ struct stdio_dev* stdio_clone(struct stdio_dev *dev) return NULL;
memcpy(_dev, dev, sizeof(struct stdio_dev)); - strncpy(_dev->name, dev->name, 16);
return _dev; }

In preparation for making the hash function common, we may as well use const where we can. Also the input length cannot be negative, but may be very large, so use unsigned.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: - Add new patch to adjust sha1 functions to use const/unsigned
include/sha1.h | 26 +++++++++----------------- lib/sha1.c | 19 +++++++++++-------- 2 files changed, 20 insertions(+), 25 deletions(-)
diff --git a/include/sha1.h b/include/sha1.h index 734d1fb..da09dab 100644 --- a/include/sha1.h +++ b/include/sha1.h @@ -59,7 +59,8 @@ void sha1_starts( sha1_context *ctx ); * \param input buffer holding the data * \param ilen length of the input data */ -void sha1_update( sha1_context *ctx, unsigned char *input, int ilen ); +void sha1_update(sha1_context *ctx, const unsigned char *input, + unsigned int ilen);
/** * \brief SHA-1 final digest @@ -76,8 +77,8 @@ void sha1_finish( sha1_context *ctx, unsigned char output[20] ); * \param ilen length of the input data * \param output SHA-1 checksum result */ -void sha1_csum( unsigned char *input, int ilen, - unsigned char output[20] ); +void sha1_csum(const unsigned char *input, unsigned int ilen, + unsigned char *output);
/** * \brief Output = SHA-1( input buffer ), with watchdog triggering @@ -87,17 +88,8 @@ void sha1_csum( unsigned char *input, int ilen, * \param output SHA-1 checksum result * \param chunk_sz watchdog triggering period (in bytes of input processed) */ -void sha1_csum_wd (unsigned char *input, int ilen, - unsigned char output[20], unsigned int chunk_sz); - -/** - * \brief Output = SHA-1( file contents ) - * - * \param path input file name - * \param output SHA-1 checksum result - * \return 0 if successful, or 1 if fopen failed - */ -int sha1_file( char *path, unsigned char output[20] ); +void sha1_csum_wd(const unsigned char *input, unsigned int ilen, + unsigned char *output, unsigned int chunk_sz);
/** * \brief Output = HMAC-SHA-1( input buffer, hmac key ) @@ -108,9 +100,9 @@ int sha1_file( char *path, unsigned char output[20] ); * \param ilen length of the input data * \param output HMAC-SHA-1 result */ -void sha1_hmac( unsigned char *key, int keylen, - unsigned char *input, int ilen, - unsigned char output[20] ); +void sha1_hmac(const unsigned char *key, int keylen, + const unsigned char *input, unsigned int ilen, + unsigned char *output);
/** * \brief Checkup routine diff --git a/lib/sha1.c b/lib/sha1.c index da5bc16..a121224 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -73,7 +73,7 @@ void sha1_starts (sha1_context * ctx) ctx->state[4] = 0xC3D2E1F0; }
-static void sha1_process (sha1_context * ctx, unsigned char data[64]) +static void sha1_process(sha1_context *ctx, const unsigned char data[64]) { unsigned long temp, W[16], A, B, C, D, E;
@@ -230,7 +230,8 @@ static void sha1_process (sha1_context * ctx, unsigned char data[64]) /* * SHA-1 process buffer */ -void sha1_update (sha1_context * ctx, unsigned char *input, int ilen) +void sha1_update(sha1_context *ctx, const unsigned char *input, + unsigned int ilen) { int fill; unsigned long left; @@ -305,7 +306,8 @@ void sha1_finish (sha1_context * ctx, unsigned char output[20]) /* * Output = SHA-1( input buffer ) */ -void sha1_csum (unsigned char *input, int ilen, unsigned char output[20]) +void sha1_csum(const unsigned char *input, unsigned int ilen, + unsigned char *output) { sha1_context ctx;
@@ -318,12 +320,12 @@ void sha1_csum (unsigned char *input, int ilen, unsigned char output[20]) * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz' * bytes of input processed. */ -void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20], - unsigned int chunk_sz) +void sha1_csum_wd(const unsigned char *input, unsigned int ilen, + unsigned char *output, unsigned int chunk_sz) { sha1_context ctx; #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - unsigned char *end, *curr; + const unsigned char *end, *curr; int chunk; #endif
@@ -350,8 +352,9 @@ void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20], /* * Output = HMAC-SHA-1( input buffer, hmac key ) */ -void sha1_hmac (unsigned char *key, int keylen, - unsigned char *input, int ilen, unsigned char output[20]) +void sha1_hmac(const unsigned char *key, int keylen, + const unsigned char *input, unsigned int ilen, + unsigned char *output) { int i; sha1_context ctx;

In preparation for making the hash function common, we may as well use const where we can.
Also add a watchdog version of the hashing function.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: - Add new patch to adjust sha256 functions to const and watchdog
include/sha256.h | 8 +++++++- lib/sha256.c | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/include/sha256.h b/include/sha256.h index e38ea89..beadab3 100644 --- a/include/sha256.h +++ b/include/sha256.h @@ -3,6 +3,9 @@
#define SHA256_SUM_LEN 32
+/* Reset watchdog each time we process this many bytes */ +#define CHUNKSZ_SHA256 (64 * 1024) + typedef struct { uint32_t total[2]; uint32_t state[8]; @@ -10,7 +13,10 @@ typedef struct { } sha256_context;
void sha256_starts(sha256_context * ctx); -void sha256_update(sha256_context * ctx, uint8_t * input, uint32_t length); +void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length); void sha256_finish(sha256_context * ctx, uint8_t digest[SHA256_SUM_LEN]);
+void sha256_csum_wd(const unsigned char *input, unsigned int ilen, + unsigned char *output, unsigned int chunk_sz); + #endif /* _SHA256_H */ diff --git a/lib/sha256.c b/lib/sha256.c index deb63a4..ab2db48 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -60,7 +60,7 @@ void sha256_starts(sha256_context * ctx) ctx->state[7] = 0x5BE0CD19; }
-void sha256_process(sha256_context * ctx, uint8_t data[64]) +static void sha256_process(sha256_context *ctx, const uint8_t data[64]) { uint32_t temp1, temp2; uint32_t W[64]; @@ -191,7 +191,7 @@ void sha256_process(sha256_context * ctx, uint8_t data[64]) ctx->state[7] += H; }
-void sha256_update(sha256_context * ctx, uint8_t * input, uint32_t length) +void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length) { uint32_t left, fill;
@@ -260,3 +260,36 @@ void sha256_finish(sha256_context * ctx, uint8_t digest[32]) PUT_UINT32_BE(ctx->state[6], digest, 24); PUT_UINT32_BE(ctx->state[7], digest, 28); } + +/* + * Output = SHA-256( input buffer ). Trigger the watchdog every 'chunk_sz' + * bytes of input processed. + */ +void sha256_csum_wd(const unsigned char *input, unsigned int ilen, + unsigned char *output, unsigned int chunk_sz) +{ + sha256_context ctx; +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + unsigned char *end, *curr; + int chunk; +#endif + + sha256_starts(&ctx); + +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + curr = input; + end = input + ilen; + while (curr < end) { + chunk = end - curr; + if (chunk > chunk_sz) + chunk = chunk_sz; + sha256_update(&ctx, curr, chunk); + curr += chunk; + WATCHDOG_RESET(); + } +#else + sha256_update(&ctx, input, ilen); +#endif + + sha256_finish(&ctx, output); +}

strncasecmp() is present as strnicmp() but disabled. Make it available and define strcasecmp() also. There is a only a small performance penalty to having strcasecmp() call strncasecmp(), so do this instead of a standalone function, to save code space.
Update the prototype in arch-specific headers as needed to avoid warnings.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: - Rename stricmp() to strcasecmp() to match Linux / POSIX - Bracket strcasecmp() declarations with __HAVE_ARCH_...
Changes in v2: - Add stricmp() patch again since it is used in this series
arch/m68k/include/asm/string.h | 2 +- arch/powerpc/include/asm/string.h | 2 +- arch/sparc/include/asm/string.h | 2 +- include/linux/string.h | 7 +++++-- lib/string.c | 16 ++++++++++++---- 5 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/arch/m68k/include/asm/string.h b/arch/m68k/include/asm/string.h index e0773a8..ecf5e56 100644 --- a/arch/m68k/include/asm/string.h +++ b/arch/m68k/include/asm/string.h @@ -16,7 +16,7 @@ #endif
extern int strcasecmp(const char *, const char *); -extern int strncasecmp(const char *, const char *, int); +extern int strncasecmp(const char *, const char *, __kernel_size_t); extern char * strcpy(char *,const char *); extern char * strncpy(char *,const char *, __kernel_size_t); extern __kernel_size_t strlen(const char *); diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h index d912a6b..036805e 100644 --- a/arch/powerpc/include/asm/string.h +++ b/arch/powerpc/include/asm/string.h @@ -14,7 +14,7 @@ #define __HAVE_ARCH_MEMCHR
extern int strcasecmp(const char *, const char *); -extern int strncasecmp(const char *, const char *, int); +extern int strncasecmp(const char *, const char *, __kernel_size_t); extern char * strcpy(char *,const char *); extern char * strncpy(char *,const char *, __kernel_size_t); extern __kernel_size_t strlen(const char *); diff --git a/arch/sparc/include/asm/string.h b/arch/sparc/include/asm/string.h index c6bbc20..af6faea 100644 --- a/arch/sparc/include/asm/string.h +++ b/arch/sparc/include/asm/string.h @@ -40,7 +40,7 @@ */
extern int strcasecmp(const char *, const char *); -extern int strncasecmp(const char *, const char *, int); +extern int strncasecmp(const char *, const char *, __kernel_size_t); extern char *strcpy(char *, const char *); extern char *strncpy(char *, const char *, __kernel_size_t); extern __kernel_size_t strlen(const char *); diff --git a/include/linux/string.h b/include/linux/string.h index 9a8cbc2..de83355 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -38,8 +38,11 @@ extern int strcmp(const char *,const char *); #ifndef __HAVE_ARCH_STRNCMP extern int strncmp(const char *,const char *,__kernel_size_t); #endif -#if 0 /* not used - was: #ifndef __HAVE_ARCH_STRNICMP */ -extern int strnicmp(const char *, const char *, __kernel_size_t); +#ifndef __HAVE_ARCH_STRCASECMP +int strcasecmp(const char *s1, const char *s2); +#endif +#ifndef __HAVE_ARCH_STRNCASECMP +extern int strncasecmp(const char *s1, const char *s2, __kernel_size_t len); #endif #ifndef __HAVE_ARCH_STRCHR extern char * strchr(const char *,int); diff --git a/lib/string.c b/lib/string.c index c3ad055..68f60be 100644 --- a/lib/string.c +++ b/lib/string.c @@ -21,14 +21,13 @@ #include <malloc.h>
-#if 0 /* not used - was: #ifndef __HAVE_ARCH_STRNICMP */ /** - * strnicmp - Case insensitive, length-limited string comparison + * strncasecmp - Case insensitive, length-limited string comparison * @s1: One string * @s2: The other string * @len: the maximum number of characters to compare */ -int strnicmp(const char *s1, const char *s2, size_t len) +int strncasecmp(const char *s1, const char *s2, size_t len) { /* Yes, Virginia, it had better be unsigned */ unsigned char c1, c2; @@ -52,7 +51,16 @@ int strnicmp(const char *s1, const char *s2, size_t len) } return (int)c1 - (int)c2; } -#endif + +/** + * strcasecmp - Case insensitive string comparison + * @s1: One string + * @s2: The other string + */ +int strcasecmp(const char *s1, const char *s2) +{ + return strncasecmp(s1, s2, -1U); +}
char * ___strtok;

We have a SHA1 command and want to add a SHA256 command also. Instead of duplicating the code, create a generic hash API which can process commands for different algorithms.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: - Rename stricmp() to strcasecmp() to match Linux / POSIX - Correct hash error message to show the algorithm name, not always SHA1 - Fix ordering of hash.o in Makefile
Changes in v2: - Add generic hash API to allow SHA256 command to be added without duplication
common/Makefile | 1 + common/hash.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/hash.h | 69 +++++++++++++++++ 3 files changed, 291 insertions(+), 0 deletions(-) create mode 100644 common/hash.c create mode 100644 include/hash.h
diff --git a/common/Makefile b/common/Makefile index 84968f8..c451c3d 100644 --- a/common/Makefile +++ b/common/Makefile @@ -30,6 +30,7 @@ ifndef CONFIG_SPL_BUILD COBJS-y += main.o COBJS-y += command.o COBJS-y += exports.o +COBJS-y += hash.o COBJS-$(CONFIG_SYS_HUSH_PARSER) += hush.o COBJS-y += s_record.o COBJS-y += xyzModem.o diff --git a/common/hash.c b/common/hash.c new file mode 100644 index 0000000..e3a6e43 --- /dev/null +++ b/common/hash.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * (C) Copyright 2011 + * Joe Hershberger, National Instruments, joe.hershberger@ni.com + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <hash.h> +#include <sha1.h> +#include <sha256.h> + +/* + * These are the hash algorithms we support. Chips which support accelerated + * crypto could perhaps add named version of these algorithms here. + */ +static struct hash_algo hash_algo[] = { +#ifdef CONFIG_SHA1 + { + "SHA1", + SHA1_SUM_LEN, + sha1_csum_wd, + CHUNKSZ_SHA1, + }, +#endif +#ifdef CONFIG_SHA256 + { + "SHA256", + SHA256_SUM_LEN, + sha256_csum_wd, + CHUNKSZ_SHA256, + }, +#endif +}; + +/** + * store_result: Store the resulting sum to an address or variable + * + * @algo: Hash algorithm being used + * @sum: Hash digest (algo->digest_size bytes) + * @dest: Destination, interpreted as a hex address if it starts + * with * or otherwise as an environment variable. + */ +static void store_result(struct hash_algo *algo, const u8 *sum, + const char *dest) +{ + unsigned int i; + + if (*dest == '*') { + u8 *ptr; + + ptr = (u8 *)simple_strtoul(dest + 1, NULL, 16); + memcpy(ptr, sum, algo->digest_size); + } else { + char str_output[HASH_MAX_DIGEST_SIZE * 2 + 1]; + char *str_ptr = str_output; + + for (i = 0; i < algo->digest_size; i++) { + sprintf(str_ptr, "%02x", sum[i]); + str_ptr += 2; + } + str_ptr = '\0'; + setenv(dest, str_output); + } +} + +/** + * parse_verify_sum: Parse a hash verification parameter + * + * @algo: Hash algorithm being used + * @verify_str: Argument to parse. If it starts with * then it is + * interpreted as a hex address containing the hash. + * If the length is exactly the right number of hex digits + * for the digest size, then we assume it is a hex digest. + * Otherwise we assume it is an environment variable, and + * look up its value (it must contain a hex digest). + * @vsum: Returns binary digest value (algo->digest_size bytes) + * @return 0 if ok, non-zero on error + */ +static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum) +{ + if (*verify_str == '*') { + u8 *ptr; + + ptr = (u8 *)simple_strtoul(verify_str + 1, NULL, 16); + memcpy(vsum, ptr, algo->digest_size); + } else { + unsigned int i; + char *vsum_str; + int digits = algo->digest_size * 2; + + /* + * As with the original code from sha1sum.c, we assume that a + * string which matches the digest size exactly is a hex + * string and not an environment variable. + */ + if (strlen(verify_str) == digits) + vsum_str = verify_str; + else { + vsum_str = getenv(verify_str); + if (vsum_str == NULL || strlen(vsum_str) != digits) { + printf("Expected %d hex digits in env var\n", + digits); + return 1; + } + } + + for (i = 0; i < algo->digest_size; i++) { + char *nullp = vsum_str + (i + 1) * 2; + char end = *nullp; + + *nullp = '\0'; + vsum[i] = simple_strtoul(vsum_str + (i * 2), NULL, 16); + *nullp = end; + } + } + return 0; +} + +static struct hash_algo *find_hash_algo(const char *name) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { + if (!strcasecmp(name, hash_algo[i].name)) + return &hash_algo[i]; + } + + return NULL; +} + +static void show_hash(struct hash_algo *algo, ulong addr, ulong len, + u8 *output) +{ + int i; + + printf("%s for %08lx ... %08lx ==> ", algo->name, addr, addr + len - 1); + for (i = 0; i < algo->digest_size; i++) + printf("%02x", output[i]); +} + +int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + struct hash_algo *algo; + ulong addr, len; + u8 output[HASH_MAX_DIGEST_SIZE]; + u8 vsum[HASH_MAX_DIGEST_SIZE]; + + if (argc < 2) + return CMD_RET_USAGE; + + algo = find_hash_algo(algo_name); + if (!algo) { + printf("Unknown hash algorithm '%s'\n", algo_name); + return CMD_RET_USAGE; + } + addr = simple_strtoul(*argv++, NULL, 16); + len = simple_strtoul(*argv++, NULL, 16); + argc -= 2; + + if (algo->digest_size > HASH_MAX_DIGEST_SIZE) { + puts("HASH_MAX_DIGEST_SIZE exceeded\n"); + return 1; + } + + algo->hash_func_ws((const unsigned char *)addr, len, output, + algo->chunk_size); + + /* Try to avoid code bloat when verify is not needed */ +#ifdef CONFIG_HASH_VERIFY + if (verify) { +#else + if (0) { +#endif + if (!argc) + return CMD_RET_USAGE; + if (parse_verify_sum(algo, *argv, vsum)) { + printf("ERROR: %s does not contain a valid %s sum\n", + *argv, algo->name); + return 1; + } + if (memcmp(output, vsum, algo->digest_size) != 0) { + int i; + + show_hash(algo, addr, len, output); + printf(" != "); + for (i = 0; i < algo->digest_size; i++) + printf("%02x", vsum[i]); + puts(" ** ERROR **\n"); + return 1; + } + } else { + show_hash(algo, addr, len, output); + printf("\n"); + + if (argc) + store_result(algo, output, *argv); + } + + return 0; +} diff --git a/include/hash.h b/include/hash.h new file mode 100644 index 0000000..34ba558 --- /dev/null +++ b/include/hash.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _HASH_H +#define _HASH_H + +#ifdef CONFIG_SHA1SUM_VERIFY +#define CONFIG_HASH_VERIFY +#endif + +struct hash_algo { + const char *name; /* Name of algorithm */ + int digest_size; /* Length of digest */ + /** + * hash_func_ws: Generic hashing function + * + * This is the generic prototype for a hashing function. We only + * have the watchdog version at present. + * + * @input: Input buffer + * @ilen: Input buffer length + * @output: Checksum result (length depends on algorithm) + * @chunk_sz: Trigger watchdog after processing this many bytes + */ + void (*hash_func_ws)(const unsigned char *input, unsigned int ilen, + unsigned char *output, unsigned int chunk_sz); + int chunk_size; /* Watchdog chunk size */ +}; + +/* + * Maximum digest size for all algorithms we support. Having this value + * avoids a malloc() or C99 local declaration in common/cmd_hash.c. + */ +#define HASH_MAX_DIGEST_SIZE 32 + +/** + * hash_command: Process a hash command for a particular algorithm + * + * This common function is used to implement specific hash commands. + * + * @algo_name: Hash algorithm being used + * @verify: Non-zero to enable verify mode + * @cmdtp: Pointer to command table entry + * @flag: Some flags normally 0 (see CMD_FLAG_.. above) + * @argc: Number of arguments (arg 0 must be the command text) + * @argv: Arguments + */ +int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]); + +#endif

Update the code to use the hash layer instead of local code.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: - Add new patch to change sha1sum to use generic hash API
common/cmd_sha1sum.c | 129 ++------------------------------------------------ 1 files changed, 4 insertions(+), 125 deletions(-)
diff --git a/common/cmd_sha1sum.c b/common/cmd_sha1sum.c index 8db5456..fe927ab 100644 --- a/common/cmd_sha1sum.c +++ b/common/cmd_sha1sum.c @@ -26,73 +26,11 @@
#include <common.h> #include <command.h> +#include <hash.h> #include <sha1.h>
-/* - * Store the resulting sum to an address or variable - */ -static void store_result(const u8 *sum, const char *dest) -{ - unsigned int i; - - if (*dest == '*') { - u8 *ptr; - - ptr = (u8 *)simple_strtoul(dest + 1, NULL, 16); - for (i = 0; i < 20; i++) - *ptr++ = sum[i]; - } else { - char str_output[41]; - char *str_ptr = str_output; - - for (i = 0; i < 20; i++) { - sprintf(str_ptr, "%02x", sum[i]); - str_ptr += 2; - } - str_ptr = '\0'; - setenv(dest, str_output); - } -} - -#ifdef CONFIG_SHA1SUM_VERIFY -static int parse_verify_sum(char *verify_str, u8 *vsum) -{ - if (*verify_str == '*') { - u8 *ptr; - - ptr = (u8 *)simple_strtoul(verify_str + 1, NULL, 16); - memcpy(vsum, ptr, 20); - } else { - unsigned int i; - char *vsum_str; - - if (strlen(verify_str) == 40) - vsum_str = verify_str; - else { - vsum_str = getenv(verify_str); - if (vsum_str == NULL || strlen(vsum_str) != 40) - return 1; - } - - for (i = 0; i < 20; i++) { - char *nullp = vsum_str + (i + 1) * 2; - char end = *nullp; - - *nullp = '\0'; - *(u8 *)(vsum + i) = - simple_strtoul(vsum_str + (i * 2), NULL, 16); - *nullp = end; - } - } - return 0; -} - int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - ulong addr, len; - unsigned int i; - u8 output[20]; - u8 vsum[20]; int verify = 0; int ac; char * const *av; @@ -102,75 +40,16 @@ int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
av = argv + 1; ac = argc - 1; +#ifdef CONFIG_SHA1SUM_VERIFY if (strcmp(*av, "-v") == 0) { verify = 1; av++; ac--; - if (ac < 3) - return CMD_RET_USAGE; } +#endif
- addr = simple_strtoul(*av++, NULL, 16); - len = simple_strtoul(*av++, NULL, 16); - - sha1_csum_wd((unsigned char *) addr, len, output, CHUNKSZ_SHA1); - - if (!verify) { - printf("SHA1 for %08lx ... %08lx ==> ", addr, addr + len - 1); - for (i = 0; i < 20; i++) - printf("%02x", output[i]); - printf("\n"); - - if (ac > 2) - store_result(output, *av); - } else { - char *verify_str = *av++; - - if (parse_verify_sum(verify_str, vsum)) { - printf("ERROR: %s does not contain a valid SHA1 sum\n", - verify_str); - return 1; - } - if (memcmp(output, vsum, 20) != 0) { - printf("SHA1 for %08lx ... %08lx ==> ", addr, - addr + len - 1); - for (i = 0; i < 20; i++) - printf("%02x", output[i]); - printf(" != "); - for (i = 0; i < 20; i++) - printf("%02x", vsum[i]); - printf(" ** ERROR **\n"); - return 1; - } - } - - return 0; -} -#else -static int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - unsigned long addr, len; - unsigned int i; - u8 output[20]; - - if (argc < 3) - return CMD_RET_USAGE; - - addr = simple_strtoul(argv[1], NULL, 16); - len = simple_strtoul(argv[2], NULL, 16); - - sha1_csum_wd((unsigned char *) addr, len, output, CHUNKSZ_SHA1); - printf("SHA1 for %08lx ... %08lx ==> ", addr, addr + len - 1); - for (i = 0; i < 20; i++) - printf("%02x", output[i]); - printf("\n"); - - if (argc > 3) - store_result(output, argv[3]); - - return 0; + return hash_command("sha1", verify, cmdtp, flag, ac, av); } -#endif
#ifdef CONFIG_SHA1SUM_VERIFY U_BOOT_CMD(

This new command supports hashing SHA1 and SHA256. It could be extended to others such as MD5 and the CRC algorithms. The syntax is modeled on those:
hash <algorithm> <address> <length> [*<dest_addr> | <dest_envvar>]
to calculate a hash, and:
hash -v <algorithm> <address> <length> [*<verify_addr> | <verify_envvar>]
to verify a hash.
Use CONFIG_CMD_HASH to enable the command, CONFIG_SHA1 to enable SHA1 and CONFIG_SHA256 to enable SHA256.
The existing sha1sum command remains.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: - Correct hash command help to say 'hash' instead of 'sha1sum'
Changes in v2: - Add new hash command to support generic hash API
README | 18 +++++++++++++ common/Makefile | 1 + common/cmd_hash.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ include/config_cmd_all.h | 1 + 4 files changed, 83 insertions(+), 0 deletions(-) create mode 100644 common/cmd_hash.c
diff --git a/README b/README index 027fa46..40158bb 100644 --- a/README +++ b/README @@ -822,6 +822,7 @@ The following options need to be configured: CONFIG_CMD_GETTIME * Get time since boot CONFIG_CMD_GO * the 'go' command (exec code) CONFIG_CMD_GREPENV * search environment + CONFIG_CMD_HASH * calculate hash / digest CONFIG_CMD_HWFLOW * RTS/CTS hw flow control CONFIG_CMD_I2C * I2C serial bus support CONFIG_CMD_IDE * IDE harddisk support @@ -2391,6 +2392,23 @@ CBFS (Coreboot Filesystem) support A better solution is to properly configure the firewall, but sometimes that is not allowed.
+- Hashing support: + CONFIG_CMD_HASH + + This enables a generic 'hash' command which can produce + hashes / digests from a few algorithms (e.g. SHA1, SHA256). + + CONFIG_HASH_VERIFY + + Enable the hash verify command (hash -v). This adds to code + size a little. + + CONFIG_SHA1 - support SHA1 hashing + CONFIG_SHA256 - support SHA256 hashing + + Note: There is also a sha1sum command, which should perhaps + be deprecated in favour of 'hash sha1'. + - Show boot progress: CONFIG_SHOW_BOOT_PROGRESS
diff --git a/common/Makefile b/common/Makefile index c451c3d..2c28e93 100644 --- a/common/Makefile +++ b/common/Makefile @@ -104,6 +104,7 @@ COBJS-$(CONFIG_CMD_FS_GENERIC) += cmd_fs.o COBJS-$(CONFIG_CMD_GETTIME) += cmd_gettime.o COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o +COBJS-$(CONFIG_CMD_HASH) += cmd_hash.o COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o COBJS-$(CONFIG_CMD_IMMAP) += cmd_immap.o COBJS-$(CONFIG_CMD_INI) += cmd_ini.o diff --git a/common/cmd_hash.c b/common/cmd_hash.c new file mode 100644 index 0000000..689c608 --- /dev/null +++ b/common/cmd_hash.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * (C) Copyright 2011 + * Joe Hershberger, National Instruments, joe.hershberger@ni.com + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <hash.h> + +static int do_hash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +#ifdef CONFIG_HASH_VERIFY + int verify = 0; + + if (!strcmp(argv[1], "-v")) { + verify = 1; + argc--; + argv++; + } +#endif + /* Move forward to 'algorithm' parameter */ + argc--; + argv++; + return hash_command(*argv, verify, cmdtp, flag, argc - 1, argv + 1); +} + +#ifdef CONFIG_HASH_VERIFY +U_BOOT_CMD( + hash, 6, 1, do_hash, + "compute hash message digest", + "algorithm address count [[*]sum_dest]\n" + " - compute message digest [save to env var / *address]\n" + "hash -v algorithm address count [*]sum\n" + " - verify hash of memory area with env var / *address" +); +#else +U_BOOT_CMD( + hash, 5, 1, do_hash, + "compute message digest", + "algorithm address count [[*]sum_dest]\n" + " - compute message digest [save to env var / *address]" +); +#endif diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h index 148d676..124d51f 100644 --- a/include/config_cmd_all.h +++ b/include/config_cmd_all.h @@ -41,6 +41,7 @@ #define CONFIG_CMD_FLASH /* flinfo, erase, protect */ #define CONFIG_CMD_FPGA /* FPGA configuration Support */ #define CONFIG_CMD_GETTIME /* Get time since boot */ +#define CONFIG_CMD_HASH /* calculate hash / digest */ #define CONFIG_CMD_HWFLOW /* RTS/CTS hw flow control */ #define CONFIG_CMD_I2C /* I2C serial bus support */ #define CONFIG_CMD_IDE /* IDE harddisk support */

From: Tom Wai-Hong Tam waihong@chromium.org
This implements a library for accessing EDID data from an LCD panel. This is used to obtain information about the panel such as its resolution and type.
This is a tidied-up version of the original code pulled from https://github.com/ynezz/u-boot-edid.
The changes we made are: - removed bit fields in the struct; - removed endianness cases in the struct; - fixed some wrong definitions; - fixed to fit 80 columns; - fixed some code styles.
Signed-off-by: Tom Wai-Hong Tam waihong@chromium.org Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: None
common/Makefile | 1 + common/edid.c | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/edid.h | 275 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 583 insertions(+), 0 deletions(-) create mode 100644 common/edid.c create mode 100644 include/edid.h
diff --git a/common/Makefile b/common/Makefile index 2c28e93..dcab027 100644 --- a/common/Makefile +++ b/common/Makefile @@ -188,6 +188,7 @@ COBJS-$(CONFIG_BOOTSTAGE) += bootstage.o COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o COBJS-y += flash.o COBJS-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o +COBJS-$(CONFIG_I2C_EDID) += edid.o COBJS-$(CONFIG_KALLSYMS) += kallsyms.o COBJS-$(CONFIG_LCD) += lcd.o COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o diff --git a/common/edid.c b/common/edid.c new file mode 100644 index 0000000..c82c298 --- /dev/null +++ b/common/edid.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * (C) Copyright 2010 + * Petr Stetiar ynezz@true.cz + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Contains stolen code from ddcprobe project which is: + * Copyright (C) Nalin Dahyabhai bigfun@pobox.com + * + */ + +#include <common.h> +#include <edid.h> +#include <linux/ctype.h> +#include <linux/string.h> + +int edid_check_info(struct edid1_info *edid_info) +{ + if ((edid_info == NULL) || (edid_info->version == 0)) + return -1; + + if (memcmp(edid_info->header, "\x0\xff\xff\xff\xff\xff\xff\x0", 8)) + return -1; + + if (edid_info->version == 0xff && edid_info->revision == 0xff) + return -1; + + return 0; +} + +int edid_get_ranges(struct edid1_info *edid, unsigned int *hmin, + unsigned int *hmax, unsigned int *vmin, + unsigned int *vmax) +{ + int i; + struct edid_monitor_descriptor *monitor; + + *hmin = *hmax = *vmin = *vmax = 0; + if (edid_check_info(edid)) + return -1; + + for (i = 0; i < ARRAY_SIZE(edid->monitor_details.descriptor); i++) { + monitor = &edid->monitor_details.descriptor[i]; + if (monitor->type == EDID_MONITOR_DESCRIPTOR_RANGE) { + *hmin = monitor->data.range_data.horizontal_min; + *hmax = monitor->data.range_data.horizontal_max; + *vmin = monitor->data.range_data.vertical_min; + *vmax = monitor->data.range_data.vertical_max; + return 0; + } + } + return -1; +} + +/** + * Snip the tailing whitespace/return of a string. + * + * @param string The string to be snipped + * @return the snipped string + */ +static char *snip(char *string) +{ + char *s; + + /* + * This is always a 13 character buffer + * and it's not always terminated. + */ + string[12] = '\0'; + s = &string[strlen(string) - 1]; + + while (s >= string && (isspace(*s) || *s == '\n' || *s == '\r' || + *s == '\0')) + *(s--) = '\0'; + + return string; +} + +/** + * Print an EDID monitor descriptor block + * + * @param monitor The EDID monitor descriptor block + * @have_timing Modifies to 1 if the desciptor contains timing info + */ +static void edid_print_dtd(struct edid_monitor_descriptor *monitor, + unsigned int *have_timing) +{ + unsigned char *bytes = (unsigned char *)monitor; + struct edid_detailed_timing *timing = + (struct edid_detailed_timing *)monitor; + + if (bytes[0] == 0 && bytes[1] == 0) { + if (monitor->type == EDID_MONITOR_DESCRIPTOR_SERIAL) + printf("Monitor serial number: %s\n", + snip(monitor->data.string)); + else if (monitor->type == EDID_MONITOR_DESCRIPTOR_ASCII) + printf("Monitor ID: %s\n", + snip(monitor->data.string)); + else if (monitor->type == EDID_MONITOR_DESCRIPTOR_NAME) + printf("Monitor name: %s\n", + snip(monitor->data.string)); + else if (monitor->type == EDID_MONITOR_DESCRIPTOR_RANGE) + printf("Monitor range limits, horizontal sync: " + "%d-%d kHz, vertical refresh: " + "%d-%d Hz, max pixel clock: " + "%d MHz\n", + monitor->data.range_data.horizontal_min, + monitor->data.range_data.horizontal_max, + monitor->data.range_data.vertical_min, + monitor->data.range_data.vertical_max, + monitor->data.range_data.pixel_clock_max * 10); + } else { + uint32_t pixclock, h_active, h_blanking, v_active, v_blanking; + uint32_t h_total, v_total, vfreq; + + pixclock = EDID_DETAILED_TIMING_PIXEL_CLOCK(*timing); + h_active = EDID_DETAILED_TIMING_HORIZONTAL_ACTIVE(*timing); + h_blanking = EDID_DETAILED_TIMING_HORIZONTAL_BLANKING(*timing); + v_active = EDID_DETAILED_TIMING_VERTICAL_ACTIVE(*timing); + v_blanking = EDID_DETAILED_TIMING_VERTICAL_BLANKING(*timing); + + h_total = h_active + h_blanking; + v_total = v_active + v_blanking; + if (v_total * h_total) + vfreq = pixclock / (v_total * h_total); + else + vfreq = 1; /* Error case */ + printf("\t%dx%d%c\t%d Hz (detailed)\n", h_active, + v_active, h_active > 1000 ? ' ' : '\t', vfreq); + *have_timing = 1; + } +} + +/** + * Get the manufacturer name from an EDID info. + * + * @param edid_info The EDID info to be printed + * @param name Returns the string of the manufacturer name + */ +static void edid_get_manufacturer_name(struct edid1_info *edid, char *name) +{ + name[0] = EDID1_INFO_MANUFACTURER_NAME_CHAR1(*edid) + 'A' - 1; + name[1] = EDID1_INFO_MANUFACTURER_NAME_CHAR2(*edid) + 'A' - 1; + name[2] = EDID1_INFO_MANUFACTURER_NAME_CHAR3(*edid) + 'A' - 1; + name[3] = '\0'; +} + +void edid_print_info(struct edid1_info *edid_info) +{ + int i; + char manufacturer[4]; + unsigned int have_timing = 0; + uint32_t serial_number; + + if (edid_check_info(edid_info)) { + printf("Not a valid EDID\n"); + return; + } + + printf("EDID version: %d.%d\n", + edid_info->version, edid_info->revision); + + printf("Product ID code: %04x\n", EDID1_INFO_PRODUCT_CODE(*edid_info)); + + edid_get_manufacturer_name(edid_info, manufacturer); + printf("Manufacturer: %s\n", manufacturer); + + serial_number = EDID1_INFO_SERIAL_NUMBER(*edid_info); + if (serial_number != 0xffffffff) { + if (strcmp(manufacturer, "MAG") == 0) + serial_number -= 0x7000000; + if (strcmp(manufacturer, "OQI") == 0) + serial_number -= 456150000; + if (strcmp(manufacturer, "VSC") == 0) + serial_number -= 640000000; + } + printf("Serial number: %08x\n", serial_number); + printf("Manufactured in week: %d year: %d\n", + edid_info->week, edid_info->year + 1990); + + printf("Video input definition: %svoltage level %d%s%s%s%s%s\n", + EDID1_INFO_VIDEO_INPUT_DIGITAL(*edid_info) ? + "digital signal, " : "analog signal, ", + EDID1_INFO_VIDEO_INPUT_VOLTAGE_LEVEL(*edid_info), + EDID1_INFO_VIDEO_INPUT_BLANK_TO_BLACK(*edid_info) ? + ", blank to black" : "", + EDID1_INFO_VIDEO_INPUT_SEPARATE_SYNC(*edid_info) ? + ", separate sync" : "", + EDID1_INFO_VIDEO_INPUT_COMPOSITE_SYNC(*edid_info) ? + ", composite sync" : "", + EDID1_INFO_VIDEO_INPUT_SYNC_ON_GREEN(*edid_info) ? + ", sync on green" : "", + EDID1_INFO_VIDEO_INPUT_SERRATION_V(*edid_info) ? + ", serration v" : ""); + + printf("Monitor is %s\n", + EDID1_INFO_FEATURE_RGB(*edid_info) ? "RGB" : "non-RGB"); + + printf("Maximum visible display size: %d cm x %d cm\n", + edid_info->max_size_horizontal, + edid_info->max_size_vertical); + + printf("Power management features: %s%s, %s%s, %s%s\n", + EDID1_INFO_FEATURE_ACTIVE_OFF(*edid_info) ? + "" : "no ", "active off", + EDID1_INFO_FEATURE_SUSPEND(*edid_info) ? "" : "no ", "suspend", + EDID1_INFO_FEATURE_STANDBY(*edid_info) ? "" : "no ", "standby"); + + printf("Estabilished timings:\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_720X400_70(*edid_info)) + printf("\t720x400\t\t70 Hz (VGA 640x400, IBM)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_720X400_88(*edid_info)) + printf("\t720x400\t\t88 Hz (XGA2)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_640X480_60(*edid_info)) + printf("\t640x480\t\t60 Hz (VGA)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_640X480_67(*edid_info)) + printf("\t640x480\t\t67 Hz (Mac II, Apple)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_640X480_72(*edid_info)) + printf("\t640x480\t\t72 Hz (VESA)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_640X480_75(*edid_info)) + printf("\t640x480\t\t75 Hz (VESA)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_800X600_56(*edid_info)) + printf("\t800x600\t\t56 Hz (VESA)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_800X600_60(*edid_info)) + printf("\t800x600\t\t60 Hz (VESA)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_800X600_72(*edid_info)) + printf("\t800x600\t\t72 Hz (VESA)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_800X600_75(*edid_info)) + printf("\t800x600\t\t75 Hz (VESA)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_832X624_75(*edid_info)) + printf("\t832x624\t\t75 Hz (Mac II)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_1024X768_87I(*edid_info)) + printf("\t1024x768\t87 Hz Interlaced (8514A)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_1024X768_60(*edid_info)) + printf("\t1024x768\t60 Hz (VESA)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_1024X768_70(*edid_info)) + printf("\t1024x768\t70 Hz (VESA)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_1024X768_75(*edid_info)) + printf("\t1024x768\t75 Hz (VESA)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_1280X1024_75(*edid_info)) + printf("\t1280x1024\t75 (VESA)\n"); + if (EDID1_INFO_ESTABLISHED_TIMING_1152X870_75(*edid_info)) + printf("\t1152x870\t75 (Mac II)\n"); + + /* Standard timings. */ + printf("Standard timings:\n"); + for (i = 0; i < ARRAY_SIZE(edid_info->standard_timings); i++) { + unsigned int aspect = 10000; + unsigned int x, y; + unsigned char xres, vfreq; + + xres = EDID1_INFO_STANDARD_TIMING_XRESOLUTION(*edid_info, i); + vfreq = EDID1_INFO_STANDARD_TIMING_VFREQ(*edid_info, i); + if ((xres != vfreq) || + ((xres != 0) && (xres != 1)) || + ((vfreq != 0) && (vfreq != 1))) { + switch (EDID1_INFO_STANDARD_TIMING_ASPECT(*edid_info, + i)) { + case ASPECT_625: + aspect = 6250; + break; + case ASPECT_75: + aspect = 7500; + break; + case ASPECT_8: + aspect = 8000; + break; + case ASPECT_5625: + aspect = 5625; + break; + } + x = (xres + 31) * 8; + y = x * aspect / 10000; + printf("\t%dx%d%c\t%d Hz\n", x, y, + x > 1000 ? ' ' : '\t', (vfreq & 0x3f) + 60); + have_timing = 1; + } + } + + /* Detailed timing information. */ + for (i = 0; i < ARRAY_SIZE(edid_info->monitor_details.descriptor); + i++) { + edid_print_dtd(&edid_info->monitor_details.descriptor[i], + &have_timing); + } + + if (!have_timing) + printf("\tNone\n"); +} diff --git a/include/edid.h b/include/edid.h new file mode 100644 index 0000000..4788de9 --- /dev/null +++ b/include/edid.h @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * (C) Copyright 2010 + * Petr Stetiar ynezz@true.cz + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Contains stolen code from ddcprobe project which is: + * Copyright (C) Nalin Dahyabhai bigfun@pobox.com + * + */ + +#ifndef __EDID_H_ +#define __EDID_H_ + +#include <linux/types.h> + +#define GET_BIT(_x, _pos) \ + (((_x) >> (_pos)) & 1) +#define GET_BITS(_x, _pos_msb, _pos_lsb) \ + (((_x) >> (_pos_lsb)) & ((1 << ((_pos_msb) - (_pos_lsb) + 1)) - 1)) + +/* Aspect ratios used in EDID info. */ +enum edid_aspect { + ASPECT_625 = 0, + ASPECT_75, + ASPECT_8, + ASPECT_5625, +}; + +/* Detailed timing information used in EDID v1.x */ +struct edid_detailed_timing { + unsigned char pixel_clock[2]; +#define EDID_DETAILED_TIMING_PIXEL_CLOCK(_x) \ + (((((uint32_t)(_x).pixel_clock[1]) << 8) + \ + (_x).pixel_clock[0]) * 10000) + unsigned char horizontal_active; + unsigned char horizontal_blanking; + unsigned char horizontal_active_blanking_hi; +#define EDID_DETAILED_TIMING_HORIZONTAL_ACTIVE(_x) \ + ((GET_BITS((_x).horizontal_active_blanking_hi, 7, 4) << 8) + \ + (_x).horizontal_active) +#define EDID_DETAILED_TIMING_HORIZONTAL_BLANKING(_x) \ + ((GET_BITS((_x).horizontal_active_blanking_hi, 3, 0) << 8) + \ + (_x).horizontal_blanking) + unsigned char vertical_active; + unsigned char vertical_blanking; + unsigned char vertical_active_blanking_hi; +#define EDID_DETAILED_TIMING_VERTICAL_ACTIVE(_x) \ + ((GET_BITS((_x).vertical_active_blanking_hi, 7, 4) << 8) + \ + (_x).vertical_active) +#define EDID_DETAILED_TIMING_VERTICAL_BLANKING(_x) \ + ((GET_BITS((_x).vertical_active_blanking_hi, 3, 0) << 8) + \ + (_x).vertical_blanking) + unsigned char hsync_offset; + unsigned char hsync_pulse_width; + unsigned char sync_offset_pulse_width; + unsigned char hsync_vsync_offset_pulse_width_hi; +#define EDID_DETAILED_TIMING_HSYNC_OFFSET(_x) \ + ((GET_BITS((_x).hsync_vsync_offset_pulse_width_hi, 7, 6) << 8) + \ + (_x).hsync_offset) +#define EDID_DETAILED_TIMING_HSYNC_PULSE_WIDTH(_x) \ + ((GET_BITS((_x).hsync_vsync_offset_pulse_width_hi, 5, 4) << 8) + \ + (_x).hsync_pulse_width) +#define EDID_DETAILED_TIMING_VSYNC_OFFSET(_x) \ + ((GET_BITS((_x).hsync_vsync_offset_pulse_width_hi, 3, 2) << 4) + \ + GET_BITS((_x).vsync_offset_pulse_width, 7, 4)) +#define EDID_DETAILED_TIMING_VSYNC_PULSE_WIDTH(_x) \ + ((GET_BITS((_x).hsync_vsync_offset_pulse_width_hi, 1, 0) << 4) + \ + GET_BITS((_x).vsync_offset_pulse_width, 3, 0)) + unsigned char himage_size; + unsigned char vimage_size; + unsigned char himage_vimage_size_hi; +#define EDID_DETAILED_TIMING_HIMAGE_SIZE(_x) \ + ((GET_BITS((_x).himage_vimage_size_hi, 7, 4) << 8) + (_x).himage_size) +#define EDID_DETAILED_TIMING_VIMAGE_SIZE(_x) \ + ((GET_BITS((_x).himage_vimage_size_hi, 3, 0) << 8) + (_x).vimage_size) + unsigned char hborder; + unsigned char vborder; + unsigned char flags; +#define EDID_DETAILED_TIMING_FLAG_INTERLACED(_x) \ + GET_BIT((_x).flags, 7) +#define EDID_DETAILED_TIMING_FLAG_STEREO(_x) \ + GET_BITS((_x).flags, 6, 5) +#define EDID_DETAILED_TIMING_FLAG_DIGITAL_COMPOSITE(_x) \ + GET_BITS((_x).flags, 4, 3) +#define EDID_DETAILED_TIMING_FLAG_POLARITY(_x) \ + GET_BITS((_x).flags, 2, 1) +#define EDID_DETAILED_TIMING_FLAG_INTERLEAVED(_x) \ + GET_BIT((_x).flags, 0) +} __attribute__ ((__packed__)); + +enum edid_monitor_descriptor_types { + EDID_MONITOR_DESCRIPTOR_SERIAL = 0xff, + EDID_MONITOR_DESCRIPTOR_ASCII = 0xfe, + EDID_MONITOR_DESCRIPTOR_RANGE = 0xfd, + EDID_MONITOR_DESCRIPTOR_NAME = 0xfc, +}; + +struct edid_monitor_descriptor { + uint16_t zero_flag_1; + unsigned char zero_flag_2; + unsigned char type; + unsigned char zero_flag_3; + union { + char string[13]; + struct { + unsigned char vertical_min; + unsigned char vertical_max; + unsigned char horizontal_min; + unsigned char horizontal_max; + unsigned char pixel_clock_max; + unsigned char gtf_data[8]; + } range_data; + } data; +} __attribute__ ((__packed__)); + +struct edid1_info { + unsigned char header[8]; + unsigned char manufacturer_name[2]; +#define EDID1_INFO_MANUFACTURER_NAME_ZERO(_x) \ + GET_BIT(((_x).manufacturer_name[0]), 7) +#define EDID1_INFO_MANUFACTURER_NAME_CHAR1(_x) \ + GET_BITS(((_x).manufacturer_name[0]), 6, 2) +#define EDID1_INFO_MANUFACTURER_NAME_CHAR2(_x) \ + ((GET_BITS(((_x).manufacturer_name[0]), 1, 0) << 3) + \ + GET_BITS(((_x).manufacturer_name[1]), 7, 5)) +#define EDID1_INFO_MANUFACTURER_NAME_CHAR3(_x) \ + GET_BITS(((_x).manufacturer_name[1]), 4, 0) + unsigned char product_code[2]; +#define EDID1_INFO_PRODUCT_CODE(_x) \ + (((uint16_t)(_x).product_code[1] << 8) + (_x).product_code[0]) + unsigned char serial_number[4]; +#define EDID1_INFO_SERIAL_NUMBER(_x) \ + (((uint32_t)(_x).serial_number[3] << 24) + \ + ((_x).serial_number[2] << 16) + ((_x).serial_number[1] << 8) + \ + (_x).serial_number[0]) + unsigned char week; + unsigned char year; + unsigned char version; + unsigned char revision; + unsigned char video_input_definition; +#define EDID1_INFO_VIDEO_INPUT_DIGITAL(_x) \ + GET_BIT(((_x).video_input_definition), 7) +#define EDID1_INFO_VIDEO_INPUT_VOLTAGE_LEVEL(_x) \ + GET_BITS(((_x).video_input_definition), 6, 5) +#define EDID1_INFO_VIDEO_INPUT_BLANK_TO_BLACK(_x) \ + GET_BIT(((_x).video_input_definition), 4) +#define EDID1_INFO_VIDEO_INPUT_SEPARATE_SYNC(_x) \ + GET_BIT(((_x).video_input_definition), 3) +#define EDID1_INFO_VIDEO_INPUT_COMPOSITE_SYNC(_x) \ + GET_BIT(((_x).video_input_definition), 2) +#define EDID1_INFO_VIDEO_INPUT_SYNC_ON_GREEN(_x) \ + GET_BIT(((_x).video_input_definition), 1) +#define EDID1_INFO_VIDEO_INPUT_SERRATION_V(_x) \ + GET_BIT(((_x).video_input_definition), 0) + unsigned char max_size_horizontal; + unsigned char max_size_vertical; + unsigned char gamma; + unsigned char feature_support; +#define EDID1_INFO_FEATURE_STANDBY(_x) \ + GET_BIT(((_x).feature_support), 7) +#define EDID1_INFO_FEATURE_SUSPEND(_x) \ + GET_BIT(((_x).feature_support), 6) +#define EDID1_INFO_FEATURE_ACTIVE_OFF(_x) \ + GET_BIT(((_x).feature_support), 5) +#define EDID1_INFO_FEATURE_DISPLAY_TYPE(_x) \ + GET_BITS(((_x).feature_support), 4, 3) +#define EDID1_INFO_FEATURE_RGB(_x) \ + GET_BIT(((_x).feature_support), 2) +#define EDID1_INFO_FEATURE_PREFERRED_TIMING_MODE(_x) \ + GET_BIT(((_x).feature_support), 1) +#define EDID1_INFO_FEATURE_DEFAULT_GTF_SUPPORT(_x) \ + GET_BIT(((_x).feature_support), 0) + unsigned char color_characteristics[10]; + unsigned char established_timings[3]; +#define EDID1_INFO_ESTABLISHED_TIMING_720X400_70(_x) \ + GET_BIT(((_x).established_timings[0]), 7) +#define EDID1_INFO_ESTABLISHED_TIMING_720X400_88(_x) \ + GET_BIT(((_x).established_timings[0]), 6) +#define EDID1_INFO_ESTABLISHED_TIMING_640X480_60(_x) \ + GET_BIT(((_x).established_timings[0]), 5) +#define EDID1_INFO_ESTABLISHED_TIMING_640X480_67(_x) \ + GET_BIT(((_x).established_timings[0]), 4) +#define EDID1_INFO_ESTABLISHED_TIMING_640X480_72(_x) \ + GET_BIT(((_x).established_timings[0]), 3) +#define EDID1_INFO_ESTABLISHED_TIMING_640X480_75(_x) \ + GET_BIT(((_x).established_timings[0]), 2) +#define EDID1_INFO_ESTABLISHED_TIMING_800X600_56(_x) \ + GET_BIT(((_x).established_timings[0]), 1) +#define EDID1_INFO_ESTABLISHED_TIMING_800X600_60(_x) \ + GET_BIT(((_x).established_timings[0]), 0) +#define EDID1_INFO_ESTABLISHED_TIMING_800X600_72(_x) \ + GET_BIT(((_x).established_timings[1]), 7) +#define EDID1_INFO_ESTABLISHED_TIMING_800X600_75(_x) \ + GET_BIT(((_x).established_timings[1]), 6) +#define EDID1_INFO_ESTABLISHED_TIMING_832X624_75(_x) \ + GET_BIT(((_x).established_timings[1]), 5) +#define EDID1_INFO_ESTABLISHED_TIMING_1024X768_87I(_x) \ + GET_BIT(((_x).established_timings[1]), 4) +#define EDID1_INFO_ESTABLISHED_TIMING_1024X768_60(_x) \ + GET_BIT(((_x).established_timings[1]), 3) +#define EDID1_INFO_ESTABLISHED_TIMING_1024X768_70(_x) \ + GET_BIT(((_x).established_timings[1]), 2) +#define EDID1_INFO_ESTABLISHED_TIMING_1024X768_75(_x) \ + GET_BIT(((_x).established_timings[1]), 1) +#define EDID1_INFO_ESTABLISHED_TIMING_1280X1024_75(_x) \ + GET_BIT(((_x).established_timings[1]), 0) +#define EDID1_INFO_ESTABLISHED_TIMING_1152X870_75(_x) \ + GET_BIT(((_x).established_timings[2]), 7) + struct { + unsigned char xresolution; + unsigned char aspect_vfreq; + } __attribute__((__packed__)) standard_timings[8]; +#define EDID1_INFO_STANDARD_TIMING_XRESOLUTION(_x, _i) \ + (((_x).standard_timings[_i]).xresolution) +#define EDID1_INFO_STANDARD_TIMING_ASPECT(_x, _i) \ + GET_BITS(((_x).standard_timings[_i].aspect_vfreq), 7, 6) +#define EDID1_INFO_STANDARD_TIMING_VFREQ(_x, _i) \ + GET_BITS(((_x).standard_timings[_i].aspect_vfreq), 5, 0) + union { + unsigned char timing[72]; + struct edid_monitor_descriptor descriptor[4]; + } monitor_details; + unsigned char extension_flag; + unsigned char checksum; +} __attribute__ ((__packed__)); + +/** + * Print the EDID info. + * + * @param edid_info The EDID info to be printed + */ +void edid_print_info(struct edid1_info *edid_info); + +/** + * Check the EDID info. + * + * @param info The EDID info to be checked + * @return 0 on valid, or -1 on invalid + */ +int edid_check_info(struct edid1_info *info); + +/** + * Get the horizontal and vertical rate ranges of the monitor. + * + * @param edid The EDID info + * @param hmin Returns the minimum horizontal rate + * @param hmax Returns the maxium horizontal rate + * @param vmin Returns the minimum vertical rate + * @param vmax Returns the maxium vertical rate + * @return 0 on success, or -1 on error + */ +int edid_get_ranges(struct edid1_info *edid, unsigned int *hmin, + unsigned int *hmax, unsigned int *vmin, + unsigned int *vmax); + +#endif /* __EDID_H_ */

From: Tom Wai-Hong Tam waihong@chromium.org
Add a single command to read the EDID information over I2C.
For example:
SMDK5250 # i2c dev 7 Setting bus to 7 SMDK5250 # i2c edid 50 EDID version: 1.4 Product ID code: 305c Manufacturer: AUO Serial number: 00000000 Manufactured in week: 0 year: 2011 Video input definition: digital signal, voltage level 0, blank to black Monitor is non-RGB Maximum visible display size: 26 cm x 14 cm Power management features: no active off, no suspend, no standby Estabilished timings: Standard timings: 1366x768 60 Hz (detailed) 1366x768 60 Hz (detailed) Monitor ID: 2VD2K.B116XW
Signed-off-by: Tom Wai-Hong Tam waihong@chromium.org Signed-off-by: Sean Paul seanpaul@chromium.org Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: None
README | 5 +++++ common/cmd_i2c.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/README b/README index 40158bb..c36b808 100644 --- a/README +++ b/README @@ -1476,6 +1476,11 @@ CBFS (Coreboot Filesystem) support
Support drawing of RLE8-compressed bitmaps on the LCD.
+ CONFIG_I2C_EDID + + Enables an 'i2c edid' command which can read EDID + information over I2C from an attached LCD display. +
- Splash Screen Support: CONFIG_SPLASH_SCREEN
diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 4438db5..11cbded 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -78,6 +78,7 @@
#include <common.h> #include <command.h> +#include <edid.h> #include <environment.h> #include <i2c.h> #include <malloc.h> @@ -1246,6 +1247,38 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) } #endif
+/* + * Syntax: + * i2c edid {i2c_chip} + */ +#if defined(CONFIG_I2C_EDID) +int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + u_char chip; + struct edid1_info edid; + + if (argc < 2) { + cmd_usage(cmdtp); + return 1; + } + + chip = simple_strtoul(argv[1], NULL, 16); + if (i2c_read(chip, 0, 1, (uchar *)&edid, sizeof(edid)) != 0) { + puts("Error reading EDID content.\n"); + return 1; + } + + if (edid_check_info(&edid)) { + puts("Content isn't valid EDID.\n"); + return 1; + } + + edid_print_info(&edid); + return 0; + +} +#endif /* CONFIG_I2C_EDID */ + #if defined(CONFIG_I2C_MUX) static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { @@ -1335,6 +1368,9 @@ static cmd_tbl_t cmd_i2c_sub[] = { #if defined(CONFIG_I2C_MULTI_BUS) U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""), #endif /* CONFIG_I2C_MULTI_BUS */ +#if defined(CONFIG_I2C_EDID) + U_BOOT_CMD_MKENT(edid, 1, 1, do_edid, "", ""), +#endif /* CONFIG_I2C_EDID */ U_BOOT_CMD_MKENT(loop, 3, 1, do_i2c_loop, "", ""), U_BOOT_CMD_MKENT(md, 3, 1, do_i2c_md, "", ""), U_BOOT_CMD_MKENT(mm, 2, 1, do_i2c_mm, "", ""), @@ -1385,6 +1421,9 @@ static char i2c_help_text[] = #if defined(CONFIG_I2C_MULTI_BUS) "i2c dev [dev] - show or set current I2C bus\n" #endif /* CONFIG_I2C_MULTI_BUS */ +#if defined(CONFIG_I2C_EDID) + "i2c edid chip - print EDID configuration information\n" +#endif /* CONFIG_I2C_EDID */ "i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n" "i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n" "i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n"

From: Tom Wai-Hong Tam waihong@chromium.org
This function can be used for LCDs as well as monitors.
Signed-off-by: Tom Wai-Hong Tam waihong@chromium.org Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: None
common/fdt_support.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/common/fdt_support.c b/common/fdt_support.c index 963ea90..6b9fa05 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -1315,7 +1315,7 @@ int fdt_set_status_by_alias(void *fdt, const char* alias, return fdt_set_node_status(fdt, offset, status, error_code); }
-#if defined(CONFIG_VIDEO) +#if defined(CONFIG_VIDEO) || defined(CONFIG_LCD) int fdt_add_edid(void *blob, const char *compat, unsigned char *edid_buf) { int noff;

From: Vadim Bendebury vbendeb@chromium.org
Provide u-boot console functions to access IO space registers. A no thrills implementation, accessing one register at a time.
For example: boot > iod 80 0080: 00000094 boot > iod.w 80 0080: 0094 boot > iod.b 80 0080: 94 boot > iow.b 0x80 12 boot > iod 0x80 0080: 00000012
Signed-off-by: Vadim Bendebury vbendeb@chromium.org Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: None
common/Makefile | 1 + common/cmd_io.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++ include/command.h | 8 ++-- include/config_cmd_all.h | 1 + 4 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 common/cmd_io.c
diff --git a/common/Makefile b/common/Makefile index dcab027..1c5d623 100644 --- a/common/Makefile +++ b/common/Makefile @@ -120,6 +120,7 @@ COBJS-$(CONFIG_LOGBUFFER) += cmd_log.o COBJS-$(CONFIG_ID_EEPROM) += cmd_mac.o COBJS-$(CONFIG_CMD_MD5SUM) += cmd_md5sum.o COBJS-$(CONFIG_CMD_MEMORY) += cmd_mem.o +COBJS-$(CONFIG_CMD_IO) += cmd_io.o COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o COBJS-$(CONFIG_MII) += miiphyutil.o COBJS-$(CONFIG_CMD_MII) += miiphyutil.o diff --git a/common/cmd_io.c b/common/cmd_io.c new file mode 100644 index 0000000..6450cb5 --- /dev/null +++ b/common/cmd_io.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * IO space access commands. + */ + +#include <common.h> +#include <command.h> +#include <asm/io.h> + +/* + * IO Display + * + * Syntax: + * iod{.b, .w, .l} {addr} + */ +int do_io_iod(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + ulong addr; + int size; + + if (argc != 2) + return CMD_RET_USAGE; + + size = cmd_get_data_size(argv[0], 4); + if (size < 0) + return 1; + + addr = simple_strtoul(argv[1], NULL, 16); + + printf("%04x: ", (u16) addr); + + if (size == 4) + printf("%08x\n", inl(addr)); + else if (size == 2) + printf("%04x\n", inw(addr)); + else + printf("%02x\n", inb(addr)); + + return 0; +} + +int do_io_iow(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + ulong addr, size, val; + + if (argc != 3) + return CMD_RET_USAGE; + + size = cmd_get_data_size(argv[0], 4); + if (size < 0) + return 1; + + addr = simple_strtoul(argv[1], NULL, 16); + val = simple_strtoul(argv[2], NULL, 16); + + if (size == 4) + outl((u32) val, addr); + else if (size == 2) + outw((u16) val, addr); + else + outb((u8) val, addr); + + return 0; +} + +/**************************************************/ +U_BOOT_CMD(iod, 2, 0, do_io_iod, + "IO space display", "[.b, .w, .l] address [# of objects]"); + +U_BOOT_CMD(iow, 3, 0, do_io_iow, + "IO space modify (auto-incrementing address)", + "[.b, .w, .l] address"); diff --git a/include/command.h b/include/command.h index 10bc260..476e7cf 100644 --- a/include/command.h +++ b/include/command.h @@ -89,10 +89,10 @@ extern int cmd_auto_complete(const char *const prompt, char *buf, int *np, int * */
#if defined(CONFIG_CMD_MEMORY) \ - || defined(CONFIG_CMD_I2C) \ - || defined(CONFIG_CMD_ITEST) \ - || defined(CONFIG_CMD_PCI) \ - || defined(CONFIG_CMD_PORTIO) + || defined(CONFIG_CMD_I2C) \ + || defined(CONFIG_CMD_ITEST) \ + || defined(CONFIG_CMD_PCI) \ + || defined(CONFIG_CMD_PORTIO) #define CMD_DATA_SIZE extern int cmd_get_data_size(char* arg, int default_size); #endif diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h index 124d51f..e82f642 100644 --- a/include/config_cmd_all.h +++ b/include/config_cmd_all.h @@ -48,6 +48,7 @@ #define CONFIG_CMD_IMI /* iminfo */ #define CONFIG_CMD_IMLS /* List all found images */ #define CONFIG_CMD_IMMAP /* IMMR dump support */ +#define CONFIG_CMD_IO /* Access to X86 IO space */ #define CONFIG_CMD_IRQ /* irqinfo */ #define CONFIG_CMD_ITEST /* Integer (and string) test */ #define CONFIG_CMD_JFFS2 /* JFFS2 Support */

On Wed, Dec 5, 2012 at 10:46 PM, Simon Glass sjg@chromium.org wrote:
From: Vadim Bendebury vbendeb@chromium.org
Provide u-boot console functions to access IO space registers. A no thrills implementation, accessing one register at a time.
For example: boot > iod 80 0080: 00000094 boot > iod.w 80 0080: 0094 boot > iod.b 80 0080: 94 boot > iow.b 0x80 12 boot > iod 0x80 0080: 00000012
Doesn't md/mw accomplish the same?
Regards,
Fabio Estevam

On Wed, Dec 5, 2012 at 5:23 PM, Fabio Estevam festevam@gmail.com wrote:
On Wed, Dec 5, 2012 at 10:46 PM, Simon Glass sjg@chromium.org wrote:
From: Vadim Bendebury vbendeb@chromium.org
Provide u-boot console functions to access IO space registers. A no thrills implementation, accessing one register at a time.
For example: boot > iod 80 0080: 00000094 boot > iod.w 80 0080: 0094 boot > iod.b 80 0080: 94 boot > iow.b 0x80 12 boot > iod 0x80 0080: 00000012
Doesn't md/mw accomplish the same?
No - md/mw access memory, the new commands access the IO space (which is an x86 architecture property).
cheers, /vb
Regards,
Fabio Estevam

On Wed, Dec 5, 2012 at 11:25 PM, Vadim Bendebury vbendeb@chromium.org wrote:
No - md/mw access memory, the new commands access the IO space (which is an x86 architecture property).
Ok, understood. On ARM we are able to access registers via md/mw.
Maybe it would be better to put a note in the commit message that this is x86 specific.
Regards,
Fabio Estevam

Hi Fabio,
On Wed, Dec 5, 2012 at 5:30 PM, Fabio Estevam festevam@gmail.com wrote:
On Wed, Dec 5, 2012 at 11:25 PM, Vadim Bendebury vbendeb@chromium.org wrote:
No - md/mw access memory, the new commands access the IO space (which is an x86 architecture property).
Ok, understood. On ARM we are able to access registers via md/mw.
Maybe it would be better to put a note in the commit message that this is x86 specific.
Yes I put it an x86: tag on it for the next version. I have not added any x86 note in the README - in fact this is sadly missing a README comment.
Regards, Simon
Regards,
Fabio Estevam

On Sat, Dec 08, 2012 at 11:54:13AM -0800, Simon Glass wrote:
Hi Fabio,
On Wed, Dec 5, 2012 at 5:30 PM, Fabio Estevam festevam@gmail.com wrote:
On Wed, Dec 5, 2012 at 11:25 PM, Vadim Bendebury vbendeb@chromium.org wrote:
No - md/mw access memory, the new commands access the IO space (which is an x86 architecture property).
Ok, understood. On ARM we are able to access registers via md/mw.
Maybe it would be better to put a note in the commit message that this is x86 specific.
Yes I put it an x86: tag on it for the next version. I have not added any x86 note in the README - in fact this is sadly missing a README comment.
Please address adding to the README in another patch, thanks!

The CONFIG_SYS_CONSOLE_INFO_QUIET option should suppress the console information, but allow boards to display it later if required. Adjust the code to support this.
This is used to avoid printing the information while the LCD display is not ready, since it only becomes ready when stdio init is complete.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: None
common/console.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/common/console.c b/common/console.c index 1177f7d..25b141a 100644 --- a/common/console.c +++ b/common/console.c @@ -591,7 +591,6 @@ int console_init_f(void)
void stdio_print_current_devices(void) { -#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET /* Print information */ puts("In: "); if (stdio_devices[stdin] == NULL) { @@ -613,7 +612,6 @@ void stdio_print_current_devices(void) } else { printf ("%s\n", stdio_devices[stderr]->name); } -#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ }
#ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV @@ -685,7 +683,9 @@ done:
gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
+#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET stdio_print_current_devices(); +#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE /* set the environment variables (will overwrite previous env settings) */ @@ -760,7 +760,9 @@ int console_init_r(void)
gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
+#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET stdio_print_current_devices(); +#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
/* Setting environment variables */ for (i = 0; i < 3; i++) {

From: Luigi Semenzato semenzato@chromium.org
Add a simple command to stress-test a TPM (Trusted Platform Module).
Signed-off-by: Luigi Semenzato semenzato@chromium.org
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: - Drop meminfo from this series - Drop patch 'Update time command to avoid using get_timer_masked()'
Changes in v2: None
common/cmd_tpm.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 87 insertions(+), 6 deletions(-)
diff --git a/common/cmd_tpm.c b/common/cmd_tpm.c index 6f5cd48..0970a6f 100644 --- a/common/cmd_tpm.c +++ b/common/cmd_tpm.c @@ -63,19 +63,68 @@ static int tpm_process(int argc, char * const argv[], cmd_tbl_t *cmdtp) return rv; }
-static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +#define CHECK(exp) do { \ + int _rv = exp; \ + if (_rv) { \ + printf("CHECK: %s %d %x\n", #exp, __LINE__, _rv);\ + } \ + } while (0) + +static int tpm_process_stress(int repeat_count) { + int i; int rv = 0; + u8 request[] = {0x0, 0xc1, + 0x0, 0x0, 0x0, 0x16, + 0x0, 0x0, 0x0, 0x65, + 0x0, 0x0, 0x0, 0x4, + 0x0, 0x0, 0x0, 0x4, + 0x0, 0x0, 0x1, 0x9}; + u8 response[MAX_TRANSACTION_SIZE]; + u32 rlength = MAX_TRANSACTION_SIZE; + + CHECK(tis_init()); + + for (i = 0; i < repeat_count; i++) { + CHECK(tis_open()); + rv = tis_sendrecv(request, sizeof(request), response, &rlength); + if (rv) { + printf("tpm test failed at step %d with 0x%x\n", i, rv); + CHECK(tis_close()); + break; + } + CHECK(tis_close()); + if ((response[6] || response[7] || response[8] || response[9]) + && response[9] != 0x26) { + /* Ignore postinit errors */ + printf("tpm command failed at step %d\n" + "tpm error code: %02x%02x%02x%02x\n", i, + response[6], response[7], + response[8], response[9]); + rv = -1; + break; + } + } + return rv; +}
- /* - * Verify that in case it is present, the first argument, it is - * exactly one character in size. - */ - if (argc < 7) { + +static int do_tpm_many(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[], int repeat_count) + +{ + int rv = 0; + + if (argc < 7 && repeat_count == 0) { puts("command should be at least six bytes in size\n"); return -1; }
+ if (repeat_count > 0) { + rv = tpm_process_stress(repeat_count); + return rv; + } + if (tis_init()) { puts("tis_init() failed!\n"); return -1; @@ -96,8 +145,40 @@ static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return rv; }
+ +static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + return do_tpm_many(cmdtp, flag, argc, argv, 0); +} + + U_BOOT_CMD(tpm, MAX_TRANSACTION_SIZE, 1, do_tpm, "<byte> [<byte> ...] - write data and read response", "send arbitrary data (at least 6 bytes) to the TPM " "device and read the response" ); + +static int do_tpm_stress(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + long unsigned int n; + int rv; + + if (argc != 2) { + puts("usage: tpm_stress <count>\n"); + return -1; + } + + rv = strict_strtoul(argv[1], 10, &n); + if (rv) { + puts("tpm_stress: bad count"); + return -1; + } + + return do_tpm_many(cmdtp, flag, argc, argv, n); +} + +U_BOOT_CMD(tpm_stress, 2, 1, do_tpm_stress, + "<n> - stress-test communication with TPM", + "Repeat a TPM transaction (request-response) N times" +);

Enable SHA1/SHA256 hashing and the hash command. Also enable EDID support for reading from an LCD.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: - Add patch to enable hashing and EDID on smdk5250
include/configs/smdk5250.h | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index c0f8622..39a347a 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -203,6 +203,7 @@ #define CONFIG_I2C_MULTI_BUS #define CONFIG_MAX_I2C_NUM 8 #define CONFIG_SYS_I2C_SLAVE 0x0 +#define CONFIG_I2C_EDID
/* Ethernet Controllor Driver */ #ifdef CONFIG_CMD_NET @@ -215,4 +216,10 @@ /* Enable devicetree support */ #define CONFIG_OF_LIBFDT
+/* SHA hashing */ +#define CONFIG_CMD_HASH +#define CONFIG_HASH_VERIFY +#define CONFIG_SHA1 +#define CONFIG_SHA256 + #endif /* __CONFIG_H */

Enable the io command for x86 on coreboot.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: - Add x86 patch to enable io command for coreboot
include/configs/coreboot.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h index a010adc..50f6964 100644 --- a/include/configs/coreboot.h +++ b/include/configs/coreboot.h @@ -152,6 +152,7 @@ #define CONFIG_CMD_FPGA #define CONFIG_CMD_IMI #undef CONFIG_CMD_IMLS +#define CONFIG_CMD_IO #define CONFIG_CMD_IRQ #define CONFIG_CMD_ITEST #define CONFIG_CMD_LOADB

From: Stefan Reinauer reinauer@chromium.org
Since U-Boot runs from coreboot on x86, the Coreboot version is an important part of the boot state. This version information is available in the coreboot tables, so print it when the 'version' command is used.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: None Changes in v2: - Add x86 tag to version command patch
common/cmd_version.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/common/cmd_version.c b/common/cmd_version.c index ab4c560..e8f40d3 100644 --- a/common/cmd_version.c +++ b/common/cmd_version.c @@ -25,6 +25,9 @@ #include <command.h> #include <version.h> #include <linux/compiler.h> +#ifdef CONFIG_SYS_COREBOOT +#include <asm/arch/sysinfo.h> +#endif
const char __weak version_string[] = U_BOOT_VERSION_STRING;
@@ -37,7 +40,9 @@ static int do_version(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #ifdef LD_VERSION_STRING puts(LD_VERSION_STRING "\n"); #endif - +#ifdef CONFIG_SYS_COREBOOT + printf("coreboot-%s (%s)\n", lib_sysinfo.version, lib_sysinfo.build); +#endif return 0; }

On Wed, Dec 05, 2012 at 04:46:27PM -0800, Simon Glass wrote:
This collection of patches to common/ adds the following:
- EDID support for LCD displays
- TPM stress test
- gettime command to find out the time since boot
- Adds coreboot information to the 'version' command
- Fixes LMB on x86
- SHA256 hashing using a new hashing framework created in response to list feedback
- Reading raw data from a partition of a block device
Some patches have been dropped from v2 in response to list feedback.
Also fixes a few minor bugs and tidy-ups.
Changes in v3:
- Rename stricmp() to strcasecmp() to match Linux / POSIX
- Bracket strcasecmp() declarations with __HAVE_ARCH_...
- Rename stricmp() to strcasecmp() to match Linux / POSIX
- Correct hash error message to show the algorithm name, not always SHA1
- Fix ordering of hash.o in Makefile
- Correct hash command help to say 'hash' instead of 'sha1sum'
- Drop meminfo from this series
- Drop patch 'Update time command to avoid using get_timer_masked()'
Changes in v2:
- Remove arm: tag from bootstage step patch
- Convert space to tab in README
- Update gettime commit message to include boards without CONFIG_SYS_HZ
- Add more comments to the stdio strncpy commit message
- Add new patch to adjust sha1 functions to use const/unsigned
- Add new patch to adjust sha256 functions to const and watchdog
- Add stricmp() patch again since it is used in this series
- Add generic hash API to allow SHA256 command to be added without duplication
- Add new patch to change sha1sum to use generic hash API
- Add new hash command to support generic hash API
- Add patch to enable hashing and EDID on smdk5250
- Add x86 patch to enable io command for coreboot
- Add x86 tag to version command patch
Anton Staaf (1): Add gettime command
Kenneth Waters (1): Add a command to read raw blocks from a partition
Luigi Semenzato (1): tpm: Add TPM stress test
Simon Glass (11): Add new bootstage step for the main loop Fix use of conditional LMB sha1: Use const where possible, and unsigned for input len sha256: Use const where possible and add watchdog function Add strcasecmp() and strncasecmp() Add generic hash API sha1sum: Use generic hash layer Add hash command to perform hashing using various algorithms console: Enable function to display console info exynos: Enable hashing functions and EDID for smdk5250 x86: coreboot: Enable io command
Stefan Reinauer (1): x86: Add coreboot version to u-boot's version command
Tom Wai-Hong Tam (3): edid: Library of EDID decode and print edid: Add I2C command for printing the EDID fdt: edid: Enable fdt_add_edid() function when CONFIG_LCD defined
Vadim Bendebury (1): Add console command to access io space registers
Vincent Palatin (1): stdio: remove useless strncpy
README | 25 +++ arch/m68k/include/asm/string.h | 2 +- arch/powerpc/include/asm/string.h | 2 +- arch/sparc/include/asm/string.h | 2 +- common/Makefile | 6 + common/cmd_bootm.c | 2 +- common/cmd_gettime.c | 56 +++++++ common/cmd_hash.c | 63 ++++++++ common/cmd_i2c.c | 39 +++++ common/cmd_io.c | 93 +++++++++++ common/cmd_read.c | 81 ++++++++++ common/cmd_sha1sum.c | 129 +--------------- common/cmd_tpm.c | 93 +++++++++++- common/cmd_version.c | 7 +- common/console.c | 6 +- common/edid.c | 307 +++++++++++++++++++++++++++++++++++++ common/fdt_support.c | 2 +- common/hash.c | 221 ++++++++++++++++++++++++++ common/main.c | 2 + common/stdio.c | 1 - include/command.h | 8 +- include/config_cmd_all.h | 4 + include/configs/coreboot.h | 1 + include/configs/smdk5250.h | 7 + include/edid.h | 275 +++++++++++++++++++++++++++++++++ include/hash.h | 69 +++++++++ include/linux/string.h | 7 +- include/sha1.h | 26 +-- include/sha256.h | 8 +- lib/sha1.c | 19 ++- lib/sha256.c | 37 +++++- lib/string.c | 16 ++- 32 files changed, 1438 insertions(+), 178 deletions(-) create mode 100644 common/cmd_gettime.c create mode 100644 common/cmd_hash.c create mode 100644 common/cmd_io.c create mode 100644 common/cmd_read.c create mode 100644 common/edid.c create mode 100644 common/hash.c create mode 100644 include/edid.h create mode 100644 include/hash.h
Except for 19 and 20, which never hit patchwork, this is now applied to u-boot/master. If you want to put 19 and 20 into u-boot-x86 that's fine with me. Thanks!

Hi Tom,
On Wed, Dec 12, 2012 at 5:13 AM, Tom Rini trini@ti.com wrote:
On Wed, Dec 05, 2012 at 04:46:27PM -0800, Simon Glass wrote:
This collection of patches to common/ adds the following:
- EDID support for LCD displays
- TPM stress test
- gettime command to find out the time since boot
- Adds coreboot information to the 'version' command
- Fixes LMB on x86
- SHA256 hashing using a new hashing framework created in response to list feedback
- Reading raw data from a partition of a block device
Some patches have been dropped from v2 in response to list feedback.
Also fixes a few minor bugs and tidy-ups.
Changes in v3:
- Rename stricmp() to strcasecmp() to match Linux / POSIX
- Bracket strcasecmp() declarations with __HAVE_ARCH_...
- Rename stricmp() to strcasecmp() to match Linux / POSIX
- Correct hash error message to show the algorithm name, not always SHA1
- Fix ordering of hash.o in Makefile
- Correct hash command help to say 'hash' instead of 'sha1sum'
- Drop meminfo from this series
- Drop patch 'Update time command to avoid using get_timer_masked()'
Changes in v2:
- Remove arm: tag from bootstage step patch
- Convert space to tab in README
- Update gettime commit message to include boards without CONFIG_SYS_HZ
- Add more comments to the stdio strncpy commit message
- Add new patch to adjust sha1 functions to use const/unsigned
- Add new patch to adjust sha256 functions to const and watchdog
- Add stricmp() patch again since it is used in this series
- Add generic hash API to allow SHA256 command to be added without duplication
- Add new patch to change sha1sum to use generic hash API
- Add new hash command to support generic hash API
- Add patch to enable hashing and EDID on smdk5250
- Add x86 patch to enable io command for coreboot
- Add x86 tag to version command patch
Anton Staaf (1): Add gettime command
Kenneth Waters (1): Add a command to read raw blocks from a partition
Luigi Semenzato (1): tpm: Add TPM stress test
Simon Glass (11): Add new bootstage step for the main loop Fix use of conditional LMB sha1: Use const where possible, and unsigned for input len sha256: Use const where possible and add watchdog function Add strcasecmp() and strncasecmp() Add generic hash API sha1sum: Use generic hash layer Add hash command to perform hashing using various algorithms console: Enable function to display console info exynos: Enable hashing functions and EDID for smdk5250 x86: coreboot: Enable io command
Stefan Reinauer (1): x86: Add coreboot version to u-boot's version command
Tom Wai-Hong Tam (3): edid: Library of EDID decode and print edid: Add I2C command for printing the EDID fdt: edid: Enable fdt_add_edid() function when CONFIG_LCD defined
Vadim Bendebury (1): Add console command to access io space registers
Vincent Palatin (1): stdio: remove useless strncpy
README | 25 +++ arch/m68k/include/asm/string.h | 2 +- arch/powerpc/include/asm/string.h | 2 +- arch/sparc/include/asm/string.h | 2 +- common/Makefile | 6 + common/cmd_bootm.c | 2 +- common/cmd_gettime.c | 56 +++++++ common/cmd_hash.c | 63 ++++++++ common/cmd_i2c.c | 39 +++++ common/cmd_io.c | 93 +++++++++++ common/cmd_read.c | 81 ++++++++++ common/cmd_sha1sum.c | 129 +--------------- common/cmd_tpm.c | 93 +++++++++++- common/cmd_version.c | 7 +- common/console.c | 6 +- common/edid.c | 307 +++++++++++++++++++++++++++++++++++++ common/fdt_support.c | 2 +- common/hash.c | 221 ++++++++++++++++++++++++++ common/main.c | 2 + common/stdio.c | 1 - include/command.h | 8 +- include/config_cmd_all.h | 4 + include/configs/coreboot.h | 1 + include/configs/smdk5250.h | 7 + include/edid.h | 275 +++++++++++++++++++++++++++++++++ include/hash.h | 69 +++++++++ include/linux/string.h | 7 +- include/sha1.h | 26 +-- include/sha256.h | 8 +- lib/sha1.c | 19 ++- lib/sha256.c | 37 +++++- lib/string.c | 16 ++- 32 files changed, 1438 insertions(+), 178 deletions(-) create mode 100644 common/cmd_gettime.c create mode 100644 common/cmd_hash.c create mode 100644 common/cmd_io.c create mode 100644 common/cmd_read.c create mode 100644 common/edid.c create mode 100644 common/hash.c create mode 100644 include/edid.h create mode 100644 include/hash.h
Except for 19 and 20, which never hit patchwork, this is now applied to u-boot/master. If you want to put 19 and 20 into u-boot-x86 that's fine with me. Thanks!
Thanks. Yes that is odd. I will try resending those two and if that works, pull into u-boot-x86.
Regards, Simon
-- Tom
participants (4)
-
Fabio Estevam
-
Simon Glass
-
Tom Rini
-
Vadim Bendebury