summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Makefile6
-rw-r--r--common/cmd_bootm.c2
-rw-r--r--common/cmd_gettime.c56
-rw-r--r--common/cmd_hash.c63
-rw-r--r--common/cmd_i2c.c249
-rw-r--r--common/cmd_io.c93
-rw-r--r--common/cmd_read.c81
-rw-r--r--common/cmd_sha1sum.c129
-rw-r--r--common/cmd_spl.c2
-rw-r--r--common/cmd_tpm.c93
-rw-r--r--common/console.c6
-rw-r--r--common/edid.c307
-rw-r--r--common/fdt_support.c2
-rw-r--r--common/hash.c221
-rw-r--r--common/main.c2
-rw-r--r--common/stdio.c1
16 files changed, 1153 insertions, 160 deletions
diff --git a/common/Makefile b/common/Makefile
index c29a7d82e..083df1781 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
@@ -100,8 +101,10 @@ 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_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
@@ -117,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
@@ -141,6 +145,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
@@ -184,6 +189,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/cmd_bootm.c b/common/cmd_bootm.c
index 4dbe952bb..f7595c031 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,
diff --git a/common/cmd_gettime.c b/common/cmd_gettime.c
new file mode 100644
index 000000000..d7d36a987
--- /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/common/cmd_hash.c b/common/cmd_hash.c
new file mode 100644
index 000000000..689c60857
--- /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/common/cmd_i2c.c b/common/cmd_i2c.c
index 4438db594..438079447 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -78,10 +78,12 @@
#include <common.h>
#include <command.h>
+#include <edid.h>
#include <environment.h>
#include <i2c.h>
#include <malloc.h>
#include <asm/byteorder.h>
+#include <linux/compiler.h>
/* Display values from last command.
* Memory modify remembered values are different from display memory.
@@ -132,35 +134,65 @@ DECLARE_GLOBAL_DATA_PTR;
#define DISP_LINE_LEN 16
-/* implement possible board specific board init */
-static void __def_i2c_init_board(void)
+/**
+ * i2c_init_board() - Board-specific I2C bus init
+ *
+ * This function is the default no-op implementation of I2C bus
+ * initialization. This function can be overriden by board-specific
+ * implementation if needed.
+ */
+__weak
+void i2c_init_board(void)
{
return;
}
-void i2c_init_board(void)
- __attribute__((weak, alias("__def_i2c_init_board")));
/* TODO: Implement architecture-specific get/set functions */
-static unsigned int __def_i2c_get_bus_speed(void)
+
+/**
+ * i2c_get_bus_speed() - Return I2C bus speed
+ *
+ * This function is the default implementation of function for retrieveing
+ * the current I2C bus speed in Hz.
+ *
+ * A driver implementing runtime switching of I2C bus speed must override
+ * this function to report the speed correctly. Simple or legacy drivers
+ * can use this fallback.
+ *
+ * Returns I2C bus speed in Hz.
+ */
+__weak
+unsigned int i2c_get_bus_speed(void)
{
return CONFIG_SYS_I2C_SPEED;
}
-unsigned int i2c_get_bus_speed(void)
- __attribute__((weak, alias("__def_i2c_get_bus_speed")));
-static int __def_i2c_set_bus_speed(unsigned int speed)
+/**
+ * i2c_set_bus_speed() - Configure I2C bus speed
+ * @speed: Newly set speed of the I2C bus in Hz
+ *
+ * This function is the default implementation of function for setting
+ * the I2C bus speed in Hz.
+ *
+ * A driver implementing runtime switching of I2C bus speed must override
+ * this function to report the speed correctly. Simple or legacy drivers
+ * can use this fallback.
+ *
+ * Returns zero on success, negative value on error.
+ */
+__weak
+int i2c_set_bus_speed(unsigned int speed)
{
if (speed != CONFIG_SYS_I2C_SPEED)
return -1;
return 0;
}
-int i2c_set_bus_speed(unsigned int)
- __attribute__((weak, alias("__def_i2c_set_bus_speed")));
-/*
- * get_alen: small parser helper function to get address length
- * returns the address length
+/**
+ * get_alen() - Small parser helper function to get address length
+ *
+ * Returns the address length.
*/
static uint get_alen(char *arg)
{
@@ -178,11 +210,19 @@ static uint get_alen(char *arg)
return alen;
}
-/*
+/**
+ * do_i2c_read() - Handle the "i2c read" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ *
* Syntax:
* i2c read {i2c_chip} {devaddr}{.0, .1, .2} {len} {memaddr}
*/
-
static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
u_char chip;
@@ -271,7 +311,16 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
return 0;
}
-/*
+/**
+ * do_i2c_md() - Handle the "i2c md" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ *
* Syntax:
* i2c md {i2c_chip} {addr}{.0, .1, .2} {len}
*/
@@ -363,8 +412,15 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
return 0;
}
-
-/* Write (fill) memory
+/**
+ * do_i2c_mw() - Handle the "i2c mw" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
*
* Syntax:
* i2c mw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}]
@@ -421,10 +477,20 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
#endif
}
- return (0);
+ return 0;
}
-/* Calculate a CRC on memory
+/**
+ * do_i2c_crc() - Handle the "i2c crc32" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Calculate a CRC on memory
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
*
* Syntax:
* i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count}
@@ -481,13 +547,22 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
return 0;
}
-/* Modify memory.
+/**
+ * mod_i2c_mem() - Handle the "i2c mm" and "i2c nm" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Modify memory.
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
*
* Syntax:
* i2c mm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}
* i2c nm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}
*/
-
static int
mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
{
@@ -603,7 +678,16 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg
return 0;
}
-/*
+/**
+ * do_i2c_probe() - Handle the "i2c probe" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ *
* Syntax:
* i2c probe {addr}
*
@@ -657,7 +741,16 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
return (0 == found);
}
-/*
+/**
+ * do_i2c_loop() - Handle the "i2c loop" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ *
* Syntax:
* i2c loop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}]
* {length} - Number of bytes to read
@@ -718,6 +811,8 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
/*
* The SDRAM command is separately configured because many
* (most?) embedded boards don't use SDRAM DIMMs.
+ *
+ * FIXME: Document and probably move elsewhere!
*/
#if defined(CONFIG_CMD_SDRAM)
static void print_ddr2_tcyc (u_char const b)
@@ -1246,7 +1341,48 @@ 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)
+/**
+ * do_i2c_add_bus() - Handle the "i2c bus" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero always.
+ */
static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
int ret=0;
@@ -1276,6 +1412,16 @@ static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar
#endif /* CONFIG_I2C_MUX */
#if defined(CONFIG_I2C_MULTI_BUS)
+/**
+ * do_i2c_bus_num() - Handle the "i2c dev" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
int bus_idx, ret=0;
@@ -1294,6 +1440,16 @@ static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar
}
#endif /* CONFIG_I2C_MULTI_BUS */
+/**
+ * do_i2c_bus_speed() - Handle the "i2c speed" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
int speed, ret=0;
@@ -1311,16 +1467,45 @@ static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const
return ret;
}
+/**
+ * do_i2c_mm() - Handle the "i2c mm" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
static int do_i2c_mm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
return mod_i2c_mem (cmdtp, 1, flag, argc, argv);
}
+/**
+ * do_i2c_nm() - Handle the "i2c nm" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
return mod_i2c_mem (cmdtp, 0, flag, argc, argv);
}
+/**
+ * do_i2c_reset() - Handle the "i2c reset" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero always.
+ */
static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
@@ -1335,6 +1520,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, "", ""),
@@ -1356,6 +1544,16 @@ void i2c_reloc(void) {
}
#endif
+/**
+ * do_i2c() - Handle the "i2c" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
cmd_tbl_t *c;
@@ -1385,6 +1583,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"
diff --git a/common/cmd_io.c b/common/cmd_io.c
new file mode 100644
index 000000000..6450cb576
--- /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/common/cmd_read.c b/common/cmd_read.c
new file mode 100644
index 000000000..f0fc9bfe1
--- /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/common/cmd_sha1sum.c b/common/cmd_sha1sum.c
index 8db5456c9..fe927ab24 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(
diff --git a/common/cmd_spl.c b/common/cmd_spl.c
index 9ec054af3..e3c543b46 100644
--- a/common/cmd_spl.c
+++ b/common/cmd_spl.c
@@ -130,10 +130,12 @@ static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (call_bootm(argc, argv, subcmd_list[(int)c->cmd]))
return -1;
switch ((int)c->cmd) {
+#ifdef CONFIG_OF_LIBFDT
case SPL_EXPORT_FDT:
printf("Argument image is now in RAM: 0x%p\n",
(void *)images.ft_addr);
break;
+#endif
case SPL_EXPORT_ATAGS:
printf("Argument image is now in RAM at: 0x%p\n",
(void *)gd->bd->bi_boot_params);
diff --git a/common/cmd_tpm.c b/common/cmd_tpm.c
index 6f5cd4895..0970a6fc1 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"
+);
diff --git a/common/console.c b/common/console.c
index 1177f7d39..25b141a32 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++) {
diff --git a/common/edid.c b/common/edid.c
new file mode 100644
index 000000000..c82c29809
--- /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/common/fdt_support.c b/common/fdt_support.c
index 963ea9023..6b9fa0550 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;
diff --git a/common/hash.c b/common/hash.c
new file mode 100644
index 000000000..e3a6e438a
--- /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/common/main.c b/common/main.c
index 5362781f1..b145f8556 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++;
diff --git a/common/stdio.c b/common/stdio.c
index 9f48e5f50..97ff9cf4a 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;
}