summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile26
-rw-r--r--README16
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/spl_boot.c7
-rw-r--r--arch/arm/cpu/arm926ejs/spear/spl.c7
-rw-r--r--arch/arm/cpu/armv7/zynq/slcr.c61
-rw-r--r--arch/arm/cpu/armv7/zynq/timer.c49
-rw-r--r--arch/arm/cpu/pxa/pxa2xx.c2
-rw-r--r--arch/arm/include/asm/arch-pxa/hardware.h11
-rw-r--r--arch/arm/include/asm/arch-zynq/hardware.h36
-rw-r--r--arch/arm/include/asm/arch-zynq/sys_proto.h7
-rw-r--r--arch/arm/lib/board.c6
-rw-r--r--arch/avr32/lib/board.c5
-rw-r--r--arch/blackfin/lib/board.c14
-rw-r--r--arch/m68k/lib/board.c7
-rw-r--r--arch/microblaze/include/asm/processor.h4
-rw-r--r--arch/microblaze/lib/board.c65
-rw-r--r--arch/mips/lib/board.c7
-rw-r--r--arch/nds32/lib/board.c7
-rw-r--r--arch/nios2/lib/board.c46
-rw-r--r--arch/openrisc/lib/board.c12
-rw-r--r--arch/powerpc/cpu/mpc512x/speed.c6
-rw-r--r--arch/powerpc/cpu/mpc85xx/cmd_errata.c3
-rw-r--r--arch/powerpc/cpu/mpc85xx/cpu.c18
-rw-r--r--arch/powerpc/cpu/mpc85xx/cpu_init.c14
-rw-r--r--arch/powerpc/cpu/mpc85xx/fdt.c7
-rw-r--r--arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c4
-rw-r--r--arch/powerpc/cpu/mpc85xx/p2041_ids.c20
-rw-r--r--arch/powerpc/cpu/mpc85xx/p3041_ids.c20
-rw-r--r--arch/powerpc/cpu/mpc85xx/p5020_ids.c20
-rw-r--r--arch/powerpc/cpu/mpc85xx/portals.c20
-rw-r--r--arch/powerpc/cpu/ppc4xx/Makefile4
-rw-r--r--arch/powerpc/cpu/ppc4xx/spl_boot.c72
-rw-r--r--arch/powerpc/cpu/ppc4xx/start.S37
-rw-r--r--arch/powerpc/cpu/ppc4xx/u-boot-spl.lds74
-rw-r--r--arch/powerpc/cpu/ppc4xx/u-boot.lds2
-rw-r--r--arch/powerpc/include/asm/config_mpc85xx.h12
-rw-r--r--arch/powerpc/include/asm/fsl_memac.h4
-rw-r--r--arch/powerpc/include/asm/immap_85xx.h12
-rw-r--r--arch/powerpc/lib/board.c9
-rw-r--r--arch/sandbox/config.mk5
-rw-r--r--arch/sandbox/cpu/cpu.c5
-rw-r--r--arch/sandbox/cpu/start.c9
-rw-r--r--arch/sandbox/include/asm/io.h8
-rw-r--r--arch/sandbox/include/asm/state.h1
-rw-r--r--arch/sandbox/include/asm/u-boot.h22
-rw-r--r--arch/sandbox/lib/Makefile1
-rw-r--r--arch/sandbox/lib/board.c285
-rw-r--r--arch/sh/lib/board.c9
-rw-r--r--arch/sparc/lib/board.c9
-rw-r--r--arch/x86/cpu/coreboot/sdram.c7
-rw-r--r--arch/x86/lib/board.c7
-rw-r--r--board/a3m071/a3m071.c26
-rw-r--r--board/freescale/b4860qds/tlb.c19
-rw-r--r--board/freescale/common/Makefile6
-rw-r--r--board/freescale/common/cds_pci_ft.c26
-rw-r--r--board/freescale/common/sdhc_boot.c2
-rw-r--r--board/freescale/p1010rdb/p1010rdb.c2
-rw-r--r--board/freescale/p1022ds/Makefile14
-rw-r--r--board/freescale/p1022ds/law.c1
-rw-r--r--board/freescale/p1022ds/spl_minimal.c129
-rw-r--r--board/freescale/p1022ds/tlb.c20
-rw-r--r--board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c66
-rw-r--r--board/freescale/p1_p2_rdb_pc/spl_minimal.c15
-rw-r--r--board/h2200/h2200.c9
-rw-r--r--board/lwmon5/lwmon5.c75
-rw-r--r--board/lwmon5/sdram.c4
-rw-r--r--board/sandbox/sandbox/sandbox.c2
-rw-r--r--board/xilinx/microblaze-generic/microblaze-generic.c11
-rw-r--r--board/xilinx/microblaze-generic/xparameters.h4
-rw-r--r--board/xilinx/zynq/board.c66
-rw-r--r--boards.cfg3
-rw-r--r--common/board_f.c113
-rw-r--r--common/board_r.c11
-rw-r--r--common/cmd_fdt.c87
-rw-r--r--common/cmd_fpga.c254
-rw-r--r--common/cmd_ide.c5
-rw-r--r--common/cmd_mmc.c2
-rw-r--r--common/cmd_nvedit.c105
-rw-r--r--common/cmd_sandbox.c18
-rw-r--r--common/cmd_sata.c1
-rw-r--r--common/cmd_scsi.c4
-rw-r--r--common/cmd_setexpr.c296
-rw-r--r--common/cmd_source.c11
-rw-r--r--common/cmd_tpm.c709
-rw-r--r--common/env_mmc.c132
-rw-r--r--common/flash.c11
-rw-r--r--common/main.c8
-rw-r--r--common/spl/spl.c7
-rw-r--r--common/usb_storage.c1
-rw-r--r--config.mk8
-rw-r--r--disk/part_dos.c19
-rw-r--r--disk/part_efi.c38
-rw-r--r--disk/part_iso.c3
-rw-r--r--doc/README.fdt-control6
-rw-r--r--doc/README.p1010rdb199
-rw-r--r--doc/README.ramboot-ppc85xx102
-rw-r--r--doc/README.watchdog3
-rw-r--r--doc/feature-removal-schedule.txt19
-rw-r--r--doc/git-mailrc3
-rw-r--r--drivers/block/ata_piix.c1
-rw-r--r--drivers/block/pata_bfin.c2
-rw-r--r--drivers/block/systemace.c1
-rw-r--r--drivers/fpga/Makefile1
-rw-r--r--drivers/fpga/fpga.c225
-rw-r--r--drivers/fpga/xilinx.c146
-rw-r--r--drivers/fpga/zynqpl.c355
-rw-r--r--drivers/i2c/Makefile1
-rw-r--r--drivers/i2c/zynq_i2c.c306
-rw-r--r--drivers/mmc/Makefile1
-rw-r--r--drivers/mmc/mmc.c46
-rw-r--r--drivers/mmc/spl_mmc.c17
-rw-r--r--drivers/mmc/zynq_sdhci.c40
-rw-r--r--drivers/mtd/cfi_flash.c78
-rw-r--r--drivers/mtd/nand/Makefile2
-rw-r--r--drivers/mtd/nand/docg4.c1028
-rw-r--r--drivers/mtd/nand/docg4_spl.c222
-rw-r--r--drivers/mtd/nand/mxc_nand_spl.c12
-rw-r--r--drivers/net/fm/memac.c17
-rw-r--r--drivers/net/phy/marvell.c11
-rw-r--r--drivers/net/zynq_gem.c199
-rw-r--r--drivers/tpm/Makefile4
-rw-r--r--drivers/tpm/generic_lpc_tpm.c10
-rw-r--r--drivers/tpm/slb9635_i2c/compatibility.h51
-rw-r--r--drivers/tpm/slb9635_i2c/tpm.c453
-rw-r--r--drivers/tpm/slb9635_i2c/tpm.h161
-rw-r--r--drivers/tpm/slb9635_i2c/tpm_tis_i2c.c561
-rw-r--r--drivers/tpm/tis_i2c.c181
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c4
-rw-r--r--drivers/video/pxa_lcd.c34
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/xilinx_tb_wdt.c87
-rw-r--r--fs/fat/fat_write.c1
-rw-r--r--fs/fs.c75
-rw-r--r--fs/sandbox/sandboxfs.c33
-rw-r--r--include/altera.h17
-rw-r--r--include/asm-generic/sections.h2
-rw-r--r--include/common.h34
-rw-r--r--include/config_cmd_default.h1
-rw-r--r--include/configs/M54455EVB.h2
-rw-r--r--include/configs/MERGERBOX.h2
-rw-r--r--include/configs/MVBC_P.h2
-rw-r--r--include/configs/MVBLM7.h2
-rw-r--r--include/configs/MVSMR.h2
-rw-r--r--include/configs/P1022DS.h132
-rw-r--r--include/configs/a3m071.h92
-rw-r--r--include/configs/amcc-common.h9
-rw-r--r--include/configs/coreboot.h1
-rw-r--r--include/configs/corenet_ds.h1
-rw-r--r--include/configs/exynos5250-dt.h7
-rw-r--r--include/configs/lwmon5.h68
-rw-r--r--include/configs/m28evk.h259
-rw-r--r--include/configs/microblaze-generic.h17
-rw-r--r--include/configs/mx28evk.h4
-rw-r--r--include/configs/mx31pdk.h1
-rw-r--r--include/configs/omap3_mvblx.h2
-rw-r--r--include/configs/omap5_uevm.h2
-rw-r--r--include/configs/sandbox.h11
-rw-r--r--include/configs/tx25.h1
-rw-r--r--include/configs/zynq.h39
-rw-r--r--include/fdtdec.h1
-rw-r--r--include/fpga.h13
-rw-r--r--include/fs.h2
-rw-r--r--include/lattice.h3
-rw-r--r--include/linux/bitrev.h23
-rw-r--r--include/linux/mtd/docg4.h134
-rw-r--r--include/mmc.h25
-rw-r--r--include/mtd/cfi_flash.h41
-rw-r--r--include/netdev.h2
-rw-r--r--include/part.h9
-rw-r--r--include/part_efi.h2
-rw-r--r--include/sandboxfs.h1
-rw-r--r--include/search.h15
-rw-r--r--include/slre.h100
-rw-r--r--include/tis.h73
-rw-r--r--include/tpm.h197
-rw-r--r--include/xilinx.h25
-rw-r--r--include/zynqpl.h59
-rw-r--r--lib/Makefile4
-rw-r--r--lib/bitrev.c59
-rw-r--r--lib/crc32.c5
-rw-r--r--lib/fdtdec.c6
-rw-r--r--lib/hang.c47
-rw-r--r--lib/hashtable.c93
-rw-r--r--lib/slre.c724
-rw-r--r--lib/tpm.c581
-rw-r--r--post/drivers/i2c.c2
-rw-r--r--tools/Makefile3
-rw-r--r--tools/patman/gitutil.py8
-rw-r--r--tools/patman/patchstream.py3
189 files changed, 9465 insertions, 1668 deletions
diff --git a/Makefile b/Makefile
index dd7e02a..c52f0f1 100644
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@
VERSION = 2013
PATCHLEVEL = 04
SUBLEVEL =
-EXTRAVERSION = -rc2
+EXTRAVERSION =
ifneq "$(SUBLEVEL)" ""
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
else
@@ -183,6 +183,16 @@ endif
# load other configuration
include $(TOPDIR)/config.mk
+# Targets which don't build the source code
+NON_BUILD_TARGETS = backup clean clobber distclean mkproper tidy unconfig
+
+# Only do the generic board check when actually building, not configuring
+ifeq ($(filter $(NON_BUILD_TARGETS),$(MAKECMDGOALS)),)
+ifeq ($(findstring _config,$(MAKECMDGOALS)),)
+$(CHECK_GENERIC_BOARD)
+endif
+endif
+
# If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
# that (or fail if absent). Otherwise, search for a linker script in a
# standard location.
@@ -310,7 +320,7 @@ endif
LIBS-y += drivers/rtc/librtc.o
LIBS-y += drivers/serial/libserial.o
LIBS-y += drivers/sound/libsound.o
-LIBS-$(CONFIG_GENERIC_LPC_TPM) += drivers/tpm/libtpm.o
+LIBS-y += drivers/tpm/libtpm.o
LIBS-y += drivers/twserial/libtws.o
LIBS-y += drivers/usb/eth/libusb_eth.o
LIBS-y += drivers/usb/gadget/libusb_gadget.o
@@ -550,6 +560,18 @@ endif
$(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
cat $(obj)spl/u-boot-spl.bin $(obj)u-boot.img > $@
+# PPC4xx needs the SPL at the end of the image, since the reset vector
+# is located at 0xfffffffc. So we can't use the "u-boot-img.bin" target
+# and need to introduce a new build target with the full blown U-Boot
+# at the start padded up to the start of the SPL image. And then concat
+# the SPL image to the end.
+$(obj)u-boot-img-spl-at-end.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
+ tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_UBOOT_PAD_TO) \
+ of=$(obj)u-boot-pad.img 2>/dev/null
+ dd if=$(obj)u-boot.img of=$(obj)u-boot-pad.img \
+ conv=notrunc 2>/dev/null
+ cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@
+
ifeq ($(CONFIG_SANDBOX),y)
GEN_UBOOT = \
cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
diff --git a/README b/README
index 7f9f547..bab1a95 100644
--- a/README
+++ b/README
@@ -931,6 +931,13 @@ The following options need to be configured:
XXX - this list needs to get updated!
+- Regular expression support:
+ CONFIG_REGEX
+ If this variable is defined, U-Boot is linked against
+ the SLRE (Super Light Regular Expression) library,
+ which adds regex support to some commands, as for
+ example "env grep" and "setexpr".
+
- Device tree:
CONFIG_OF_CONTROL
If this variable is defined, U-Boot will use a device tree
@@ -3249,6 +3256,15 @@ Configuration Settings:
digits and dots. Recommended value: 45 (9..1) for 80
column displays, 15 (3..1) for 40 column displays.
+- CONFIG_FLASH_VERIFY
+ If defined, the content of the flash (destination) is compared
+ against the source after the write operation. An error message
+ will be printed when the contents are not identical.
+ Please note that this option is useless in nearly all cases,
+ since such flash programming errors usually are detected earlier
+ while unprotecting/erasing/programming. Please only enable
+ this option if you really know what you are doing.
+
- CONFIG_SYS_RX_ETH_BUFFER:
Defines the number of Ethernet receive buffers. On some
Ethernet controllers it is recommended to set this value
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
index 7e70440..ed525e5 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
@@ -148,10 +148,3 @@ inline void board_init_r(gd_t *id, ulong dest_addr)
for (;;)
;
}
-
-void hang(void) __attribute__ ((noreturn));
-void hang(void)
-{
- for (;;)
- ;
-}
diff --git a/arch/arm/cpu/arm926ejs/spear/spl.c b/arch/arm/cpu/arm926ejs/spear/spl.c
index 48e6efb..0101c5d 100644
--- a/arch/arm/cpu/arm926ejs/spear/spl.c
+++ b/arch/arm/cpu/arm926ejs/spear/spl.c
@@ -31,13 +31,6 @@
#include <asm/arch/spr_misc.h>
#include <asm/arch/spr_syscntl.h>
-inline void hang(void)
-{
- serial_puts("### ERROR ### Please RESET the board ###\n");
- for (;;)
- ;
-}
-
static void ddr_clock_init(void)
{
struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c
index 788a8fd..52048c6 100644
--- a/arch/arm/cpu/armv7/zynq/slcr.c
+++ b/arch/arm/cpu/armv7/zynq/slcr.c
@@ -28,6 +28,9 @@
#define SLCR_LOCK_MAGIC 0x767B
#define SLCR_UNLOCK_MAGIC 0xDF0D
+#define SLCR_IDCODE_MASK 0x1F000
+#define SLCR_IDCODE_SHIFT 12
+
static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */
void zynq_slcr_lock(void)
@@ -61,3 +64,61 @@ void zynq_slcr_cpu_reset(void)
writel(1, &slcr_base->pss_rst_ctrl);
}
+
+/* Setup clk for network */
+void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk)
+{
+ zynq_slcr_unlock();
+
+ if (gem_id > 1) {
+ printf("Non existing GEM id %d\n", gem_id);
+ goto out;
+ }
+
+ if (gem_id) {
+ /* Set divisors for appropriate frequency in GEM_CLK_CTRL */
+ writel(clk, &slcr_base->gem1_clk_ctrl);
+ /* Configure GEM_RCLK_CTRL */
+ writel(rclk, &slcr_base->gem1_rclk_ctrl);
+ } else {
+ /* Set divisors for appropriate frequency in GEM_CLK_CTRL */
+ writel(clk, &slcr_base->gem0_clk_ctrl);
+ /* Configure GEM_RCLK_CTRL */
+ writel(rclk, &slcr_base->gem0_rclk_ctrl);
+ }
+
+out:
+ zynq_slcr_lock();
+}
+
+void zynq_slcr_devcfg_disable(void)
+{
+ zynq_slcr_unlock();
+
+ /* Disable AXI interface */
+ writel(0xFFFFFFFF, &slcr_base->fpga_rst_ctrl);
+
+ /* Set Level Shifters DT618760 */
+ writel(0xA, &slcr_base->lvl_shftr_en);
+
+ zynq_slcr_lock();
+}
+
+void zynq_slcr_devcfg_enable(void)
+{
+ zynq_slcr_unlock();
+
+ /* Set Level Shifters DT618760 */
+ writel(0xF, &slcr_base->lvl_shftr_en);
+
+ /* Disable AXI interface */
+ writel(0x0, &slcr_base->fpga_rst_ctrl);
+
+ zynq_slcr_lock();
+}
+
+u32 zynq_slcr_get_idcode(void)
+{
+ return (readl(&slcr_base->pss_idcode) & SLCR_IDCODE_MASK) >>
+ SLCR_IDCODE_SHIFT;
+}
diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/cpu/armv7/zynq/timer.c
index 45b405a..8c4357d 100644
--- a/arch/arm/cpu/armv7/zynq/timer.c
+++ b/arch/arm/cpu/armv7/zynq/timer.c
@@ -44,6 +44,7 @@
#include <common.h>
#include <div64.h>
#include <asm/io.h>
+#include <asm/arch/hardware.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -54,7 +55,7 @@ struct scu_timer {
};
static struct scu_timer *timer_base =
- (struct scu_timer *) CONFIG_SCUTIMER_BASEADDR;
+ (struct scu_timer *)ZYNQ_SCUTIMER_BASEADDR;
#define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */
#define SCUTIMER_CONTROL_PRESCALER_SHIFT 8
@@ -114,15 +115,43 @@ ulong get_timer_masked(void)
void __udelay(unsigned long usec)
{
- unsigned long long tmp;
- ulong tmo;
-
- tmo = usec / (1000000 / CONFIG_SYS_HZ);
- tmp = get_ticks() + tmo; /* Get current timestamp */
-
- while (get_ticks() < tmp) { /* Loop till event */
- /* NOP */;
- }
+ u32 countticks;
+ u32 timeend;
+ u32 timediff;
+ u32 timenow;
+
+ if (usec == 0)
+ return;
+
+ countticks = (u32) (((unsigned long long) TIMER_TICK_HZ * usec) /
+ 1000000);
+
+ /* decrementing timer */
+ timeend = readl(&timer_base->counter) - countticks;
+
+#if TIMER_LOAD_VAL != 0xFFFFFFFF
+ /* do not manage multiple overflow */
+ if (countticks >= TIMER_LOAD_VAL)
+ countticks = TIMER_LOAD_VAL - 1;
+#endif
+
+ do {
+ timenow = readl(&timer_base->counter);
+
+ if (timenow >= timeend) {
+ /* normal case */
+ timediff = timenow - timeend;
+ } else {
+ if ((TIMER_LOAD_VAL - timeend + timenow) <=
+ countticks) {
+ /* overflow */
+ timediff = TIMER_LOAD_VAL - timeend + timenow;
+ } else {
+ /* missed the exact match */
+ break;
+ }
+ }
+ } while (timediff > 0);
}
/* Timer without interrupts */
diff --git a/arch/arm/cpu/pxa/pxa2xx.c b/arch/arm/cpu/pxa/pxa2xx.c
index 09e8177..0c18610 100644
--- a/arch/arm/cpu/pxa/pxa2xx.c
+++ b/arch/arm/cpu/pxa/pxa2xx.c
@@ -284,7 +284,7 @@ void i2c_clk_enable(void)
writel(readl(CKEN) | CKEN14_I2C, CKEN);
}
-void reset_cpu(ulong ignored) __attribute__((noreturn));
+void __attribute__((weak)) reset_cpu(ulong ignored) __attribute__((noreturn));
void reset_cpu(ulong ignored)
{
diff --git a/arch/arm/include/asm/arch-pxa/hardware.h b/arch/arm/include/asm/arch-pxa/hardware.h
index 44b800f..2397bce 100644
--- a/arch/arm/include/asm/arch-pxa/hardware.h
+++ b/arch/arm/include/asm/arch-pxa/hardware.h
@@ -77,17 +77,6 @@
#define GPIO_FALLING_EDGE 1
#define GPIO_RISING_EDGE 2
#define GPIO_BOTH_EDGES 3
-extern void set_GPIO_IRQ_edge( int gpio_nr, int edge_mask );
-
-/*
- * Handy routine to set GPIO alternate functions
- */
-extern void set_GPIO_mode( int gpio_mode );
-
-/*
- * return current lclk frequency in units of 10kHz
- */
-extern unsigned int get_lclk_frequency_10khz(void);
#endif
diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/include/asm/arch-zynq/hardware.h
index d0c69da..8b8a91a 100644
--- a/arch/arm/include/asm/arch-zynq/hardware.h
+++ b/arch/arm/include/asm/arch-zynq/hardware.h
@@ -23,16 +23,28 @@
#ifndef _ASM_ARCH_HARDWARE_H
#define _ASM_ARCH_HARDWARE_H
-#define XPSS_SYS_CTRL_BASEADDR 0xF8000000
-#define XPSS_DEV_CFG_APB_BASEADDR 0xF8007000
-#define XPSS_SCU_BASEADDR 0xF8F00000
+#define ZYNQ_SYS_CTRL_BASEADDR 0xF8000000
+#define ZYNQ_DEV_CFG_APB_BASEADDR 0xF8007000
+#define ZYNQ_SCU_BASEADDR 0xF8F00000
+#define ZYNQ_SCUTIMER_BASEADDR 0xF8F00600
+#define ZYNQ_GEM_BASEADDR0 0xE000B000
+#define ZYNQ_GEM_BASEADDR1 0xE000C000
+#define ZYNQ_SDHCI_BASEADDR0 0xE0100000
+#define ZYNQ_SDHCI_BASEADDR1 0xE0101000
+#define ZYNQ_I2C_BASEADDR0 0xE0004000
+#define ZYNQ_I2C_BASEADDR1 0xE0005000
/* Reflect slcr offsets */
struct slcr_regs {
u32 scl; /* 0x0 */
u32 slcr_lock; /* 0x4 */
u32 slcr_unlock; /* 0x8 */
- u32 reserved1[125];
+ u32 reserved0[75];
+ u32 gem0_rclk_ctrl; /* 0x138 */
+ u32 gem1_rclk_ctrl; /* 0x13c */
+ u32 gem0_clk_ctrl; /* 0x140 */
+ u32 gem1_clk_ctrl; /* 0x144 */
+ u32 reserved1[46];
u32 pss_rst_ctrl; /* 0x200 */
u32 reserved2[15];
u32 fpga_rst_ctrl; /* 0x240 */
@@ -41,15 +53,21 @@ struct slcr_regs {
u32 boot_mode; /* 0x25c */
u32 reserved4[116];
u32 trust_zone; /* 0x430 */ /* FIXME */
- u32 reserved5[115];
+ u32 reserved5_1[63];
+ u32 pss_idcode; /* 0x530 */
+ u32 reserved5_2[51];
u32 ddr_urgent; /* 0x600 */
u32 reserved6[6];
u32 ddr_urgent_sel; /* 0x61c */
- u32 reserved7[188];
+ u32 reserved7[56];
+ u32 mio_pin[54]; /* 0x700 - 0x7D4 */
+ u32 reserved8[74];
+ u32 lvl_shftr_en; /* 0x900 */
+ u32 reserved9[3];
u32 ocm_cfg; /* 0x910 */
};
-#define slcr_base ((struct slcr_regs *) XPSS_SYS_CTRL_BASEADDR)
+#define slcr_base ((struct slcr_regs *)ZYNQ_SYS_CTRL_BASEADDR)
struct devcfg_regs {
u32 ctrl; /* 0x0 */
@@ -72,7 +90,7 @@ struct devcfg_regs {
u32 read_count; /* 0x8c */
};
-#define devcfg_base ((struct devcfg_regs *) XPSS_DEV_CFG_APB_BASEADDR)
+#define devcfg_base ((struct devcfg_regs *)ZYNQ_DEV_CFG_APB_BASEADDR)
struct scu_regs {
u32 reserved1[16];
@@ -80,6 +98,6 @@ struct scu_regs {
u32 filter_end; /* 0x44 */
};
-#define scu_base ((struct scu_regs *) XPSS_SCU_BASEADDR)
+#define scu_base ((struct scu_regs *)ZYNQ_SCU_BASEADDR)
#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/include/asm/arch-zynq/sys_proto.h
index e788900..2317121 100644
--- a/arch/arm/include/asm/arch-zynq/sys_proto.h
+++ b/arch/arm/include/asm/arch-zynq/sys_proto.h
@@ -26,5 +26,12 @@
extern void zynq_slcr_lock(void);
extern void zynq_slcr_unlock(void);
extern void zynq_slcr_cpu_reset(void);
+extern void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk);
+extern void zynq_slcr_devcfg_disable(void);
+extern void zynq_slcr_devcfg_enable(void);
+extern u32 zynq_slcr_get_idcode(void);
+
+/* Driver extern functions */
+extern int zynq_sdhci_init(u32 regbase);
#endif /* _SYS_PROTO_H_ */
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 0521178..09ab4ad 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -706,9 +706,3 @@ void board_init_r(gd_t *id, ulong dest_addr)
/* NOTREACHED - no way out of command loop except booting */
}
-
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;);
-}
diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c
index 57e07df..ccf862a 100644
--- a/arch/avr32/lib/board.c
+++ b/arch/avr32/lib/board.c
@@ -120,11 +120,6 @@ static int display_banner (void)
return 0;
}
-void hang(void)
-{
- for (;;) ;
-}
-
static int display_dram_config (void)
{
int i;
diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c
index 75b6c46..ccea3b9 100644
--- a/arch/blackfin/lib/board.c
+++ b/arch/blackfin/lib/board.c
@@ -432,17 +432,3 @@ void board_init_r(gd_t * id, ulong dest_addr)
for (;;)
main_loop();
}
-
-void hang(void)
-{
-#ifdef CONFIG_STATUS_LED
- status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
- status_led_set(STATUS_LED_CRASH, STATUS_LED_BLINKING);
-#endif
- puts("### ERROR ### Please RESET the board ###\n");
- while (1)
- /* If a JTAG emulator is hooked up, we'll automatically trigger
- * a breakpoint in it. If one isn't, this is just a NOP.
- */
- asm("emuexcpt;");
-}
diff --git a/arch/m68k/lib/board.c b/arch/m68k/lib/board.c
index adaccfe..b2e3068 100644
--- a/arch/m68k/lib/board.c
+++ b/arch/m68k/lib/board.c
@@ -663,10 +663,3 @@ void board_init_r (gd_t *id, ulong dest_addr)
/* NOTREACHED - no way out of command loop except booting */
}
-
-
-void hang(void)
-{
- puts ("### ERROR ### Please RESET the board ###\n");
- for (;;);
-}
diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h
index 2c4d5ff..d33faeb 100644
--- a/arch/microblaze/include/asm/processor.h
+++ b/arch/microblaze/include/asm/processor.h
@@ -31,4 +31,8 @@ extern char __text_start[];
/* Microblaze board initialization function */
void board_init(void);
+/* Watchdog functions */
+extern int hw_watchdog_init(void);
+extern void hw_watchdog_disable(void);
+
#endif /* __ASM_MICROBLAZE_PROCESSOR_H */
diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c
index a7c2f76..bb40243 100644
--- a/arch/microblaze/lib/board.c
+++ b/arch/microblaze/lib/board.c
@@ -61,6 +61,9 @@ init_fnc_t *init_sequence[] = {
serial_init,
console_init_f,
interrupts_init,
+#ifdef CONFIG_XILINX_TB_WATCHDOG
+ hw_watchdog_init,
+#endif
timer_init,
NULL,
};
@@ -71,15 +74,15 @@ void board_init_f(ulong not_used)
{
bd_t *bd;
init_fnc_t **init_fnc_ptr;
- gd = (gd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET);
- bd = (bd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET \
+ gd = (gd_t *)(CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET);
+ bd = (bd_t *)(CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET
- GENERATED_BD_INFO_SIZE);
#if defined(CONFIG_CMD_FLASH)
ulong flash_size = 0;
#endif
asm ("nop"); /* FIXME gd is not initialize - wait */
- memset ((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
- memset ((void *)bd, 0, GENERATED_BD_INFO_SIZE);
+ memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
+ memset((void *)bd, 0, GENERATED_BD_INFO_SIZE);
gd->bd = bd;
gd->baudrate = CONFIG_BAUDRATE;
bd->bi_baudrate = CONFIG_BAUDRATE;
@@ -105,57 +108,55 @@ void board_init_f(ulong not_used)
* aka CONFIG_SYS_MONITOR_BASE - Note there is no need for reloc_off
* as our monitory code is run from SDRAM
*/
- mem_malloc_init (CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
+ mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
serial_initialize();
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
- WATCHDOG_RESET ();
- if ((*init_fnc_ptr) () != 0) {
- hang ();
- }
+ WATCHDOG_RESET();
+ if ((*init_fnc_ptr) () != 0)
+ hang();
}
#ifdef CONFIG_OF_CONTROL
/* For now, put this check after the console is ready */
- if (fdtdec_prepare_fdt()) {
- panic("** CONFIG_OF_CONTROL defined but no FDT - please see "
- "doc/README.fdt-control");
- } else
+ if (fdtdec_prepare_fdt())
+ panic("** No FDT - please see doc/README.fdt-control");
+ else
printf("DTB: 0x%x\n", (u32)gd->fdt_blob);
#endif
- puts ("SDRAM :\n");
- printf ("\t\tIcache:%s\n", icache_status() ? "ON" : "OFF");
- printf ("\t\tDcache:%s\n", dcache_status() ? "ON" : "OFF");
- printf ("\tU-Boot Start:0x%08x\n", CONFIG_SYS_TEXT_BASE);
+ puts("SDRAM :\n");
+ printf("\t\tIcache:%s\n", icache_status() ? "ON" : "OFF");
+ printf("\t\tDcache:%s\n", dcache_status() ? "ON" : "OFF");
+ printf("\tU-Boot Start:0x%08x\n", CONFIG_SYS_TEXT_BASE);
#if defined(CONFIG_CMD_FLASH)
- puts ("Flash: ");
+ puts("Flash: ");
bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
flash_size = flash_init();
if (bd->bi_flashstart && flash_size > 0) {
# ifdef CONFIG_SYS_FLASH_CHECKSUM
- print_size (flash_size, "");
+ print_size(flash_size, "");
/*
* Compute and print flash CRC if flashchecksum is set to 'y'
*
* NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
*/
if (getenv_yesno("flashchecksum") == 1) {
- printf (" CRC: %08X",
- crc32(0, (const u8 *)bd->bi_flashstart,
- flash_size)
+ printf(" CRC: %08X",
+ crc32(0, (const u8 *)bd->bi_flashstart,
+ flash_size)
);
}
- putc ('\n');
+ putc('\n');
# else /* !CONFIG_SYS_FLASH_CHECKSUM */
- print_size (flash_size, "\n");
+ print_size(flash_size, "\n");
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
bd->bi_flashsize = flash_size;
bd->bi_flashoffset = bd->bi_flashstart + flash_size;
} else {
- puts ("Flash init FAILED");
+ puts("Flash init FAILED");
bd->bi_flashstart = 0;
bd->bi_flashsize = 0;
bd->bi_flashoffset = 0;
@@ -163,10 +164,10 @@ void board_init_f(ulong not_used)
#endif
/* relocate environment function pointers etc. */
- env_relocate ();
+ env_relocate();
/* Initialize stdio devices */
- stdio_init ();
+ stdio_init();
/* Initialize the jump table for applications */
jumptable_init();
@@ -190,13 +191,7 @@ void board_init_f(ulong not_used)
/* main_loop */
for (;;) {
- WATCHDOG_RESET ();
- main_loop ();
+ WATCHDOG_RESET();
+ main_loop();
}
}
-
-void hang (void)
-{
- puts ("### ERROR ### Please RESET the board ###\n");
- for (;;) ;
-}
diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c
index f19f198..fac7915 100644
--- a/arch/mips/lib/board.c
+++ b/arch/mips/lib/board.c
@@ -344,10 +344,3 @@ void board_init_r(gd_t *id, ulong dest_addr)
/* NOTREACHED - no way out of command loop except booting */
}
-
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;)
- ;
-}
diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c
index a7d27fc..57af1be 100644
--- a/arch/nds32/lib/board.c
+++ b/arch/nds32/lib/board.c
@@ -404,10 +404,3 @@ void board_init_r(gd_t *id, ulong dest_addr)
/* NOTREACHED - no way out of command loop except booting */
}
-
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;)
- ;
-}
diff --git a/arch/nios2/lib/board.c b/arch/nios2/lib/board.c
index 1e495d4..f430ef0 100644
--- a/arch/nios2/lib/board.c
+++ b/arch/nios2/lib/board.c
@@ -64,7 +64,6 @@ typedef int (init_fnc_t) (void);
***********************************************************************/
init_fnc_t *init_sequence[] = {
-
#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f, /* Call board-specific init code early.*/
#endif
@@ -83,7 +82,7 @@ init_fnc_t *init_sequence[] = {
/***********************************************************************/
-void board_init (void)
+void board_init(void)
{
bd_t *bd;
init_fnc_t **init_fnc_ptr;
@@ -93,7 +92,7 @@ void board_init (void)
/* Pointer is writable since we allocated a register for it. */
gd = &gd_data;
/* compiler optimization barrier needed for GCC >= 3.4 */
- __asm__ __volatile__("": : :"memory");
+ __asm__ __volatile__("" : : : "memory");
gd->bd = &bd_data;
gd->baudrate = CONFIG_BAUDRATE;
@@ -106,25 +105,24 @@ void board_init (void)
bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
#endif
#if defined(CONFIG_SYS_SRAM_BASE) && defined(CONFIG_SYS_SRAM_SIZE)
- bd->bi_sramstart= CONFIG_SYS_SRAM_BASE;
+ bd->bi_sramstart = CONFIG_SYS_SRAM_BASE;
bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE;
#endif
bd->bi_baudrate = CONFIG_BAUDRATE;
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
- WATCHDOG_RESET ();
- if ((*init_fnc_ptr) () != 0) {
- hang ();
- }
+ WATCHDOG_RESET();
+ if ((*init_fnc_ptr) () != 0)
+ hang();
}
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
/* The Malloc area is immediately below the monitor copy in RAM */
mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
#ifndef CONFIG_SYS_NO_FLASH
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
bd->bi_flashsize = flash_init();
#endif
@@ -138,39 +136,29 @@ void board_init (void)
mmc_initialize(bd);
#endif
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
env_relocate();
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
stdio_init();
jumptable_init();
console_init_r();
- WATCHDOG_RESET ();
- interrupt_init ();
+ WATCHDOG_RESET();
+ interrupt_init();
#if defined(CONFIG_BOARD_LATE_INIT)
- board_late_init ();
+ board_late_init();
#endif
#if defined(CONFIG_CMD_NET)
- puts ("Net: ");
- eth_initialize (bd);
+ puts("Net: ");
+ eth_initialize(bd);
#endif
/* main_loop */
for (;;) {
- WATCHDOG_RESET ();
- main_loop ();
+ WATCHDOG_RESET();
+ main_loop();
}
}
-
-
-/***********************************************************************/
-
-void hang (void)
-{
- disable_interrupts ();
- puts("### ERROR ### Please reset board ###\n");
- for (;;);
-}
diff --git a/arch/openrisc/lib/board.c b/arch/openrisc/lib/board.c
index 85aa189..630e45f 100644
--- a/arch/openrisc/lib/board.c
+++ b/arch/openrisc/lib/board.c
@@ -154,15 +154,3 @@ void board_init(void)
main_loop();
}
}
-
-
-/***********************************************************************/
-
-void hang(void)
-{
- disable_interrupts();
- puts("### ERROR ### Please reset board ###\n");
-
- for (;;)
- ;
-}
diff --git a/arch/powerpc/cpu/mpc512x/speed.c b/arch/powerpc/cpu/mpc512x/speed.c
index 9a8f315..6761877 100644
--- a/arch/powerpc/cpu/mpc512x/speed.c
+++ b/arch/powerpc/cpu/mpc512x/speed.c
@@ -151,9 +151,3 @@ U_BOOT_CMD(clocks, 1, 0, do_clocks,
"print clock configuration",
" clocks"
);
-
-int prt_mpc512x_clks (void)
-{
- do_clocks (NULL, 0, 0, NULL);
- return (0);
-}
diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
index 5d72f4c..422782c 100644
--- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c
+++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
@@ -255,6 +255,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003
puts("Work-around for Erratum PCIe-A003 enabled\n");
#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_USB14
+ puts("Work-around for Erratum USB14 enabled\n");
+#endif
return 0;
}
diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c
index df2ab6d..6ce483e 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu.c
@@ -282,14 +282,6 @@ unsigned long get_tbclk (void)
#if defined(CONFIG_WATCHDOG)
void
-watchdog_reset(void)
-{
- int re_enable = disable_interrupts();
- reset_85xx_watchdog();
- if (re_enable) enable_interrupts();
-}
-
-void
reset_85xx_watchdog(void)
{
/*
@@ -297,6 +289,16 @@ reset_85xx_watchdog(void)
*/
mtspr(SPRN_TSR, TSR_WIS);
}
+
+void
+watchdog_reset(void)
+{
+ int re_enable = disable_interrupts();
+
+ reset_85xx_watchdog();
+ if (re_enable)
+ enable_interrupts();
+}
#endif /* CONFIG_WATCHDOG */
/*
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c
index de9d916..53713e3 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c
@@ -623,6 +623,20 @@ skip_l2:
}
#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_USB14
+ /* On P204x/P304x/P50x0 Rev1.0, USB transmit will result internal
+ * multi-bit ECC errors which has impact on performance, so software
+ * should disable all ECC reporting from USB1 and USB2.
+ */
+ if (IS_SVR_REV(get_svr(), 1, 0)) {
+ struct dcsr_dcfg_regs *dcfg = (struct dcsr_dcfg_regs *)
+ (CONFIG_SYS_DCSRBAR + CONFIG_SYS_DCSR_DCFG_OFFSET);
+ setbits_be32(&dcfg->ecccr1,
+ (DCSR_DCFG_ECC_DISABLE_USB1 |
+ DCSR_DCFG_ECC_DISABLE_USB2));
+ }
+#endif
+
#ifdef CONFIG_FMAN_ENET
fman_enet_init();
#endif
diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c
index 24eb978..288f7b2 100644
--- a/arch/powerpc/cpu/mpc85xx/fdt.c
+++ b/arch/powerpc/cpu/mpc85xx/fdt.c
@@ -663,6 +663,13 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#ifdef CONFIG_FSL_CORENET
do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-1.0",
"clock-frequency", CONFIG_SYS_CLK_FREQ, 1);
+ do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-2",
+ "clock-frequency", CONFIG_SYS_CLK_FREQ, 1);
+ do_fixup_by_compat_u32(blob, "fsl,mpic",
+ "clock-frequency", get_bus_freq(0)/2, 1);
+#else
+ do_fixup_by_compat_u32(blob, "fsl,mpic",
+ "clock-frequency", get_bus_freq(0), 1);
#endif
fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
index 825a292..b621adf 100644
--- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
@@ -103,6 +103,10 @@ static const struct {
{ 22, 168, FSL_SRDS_BANK_3 },
{ 23, 169, FSL_SRDS_BANK_3 },
#endif
+#if SRDS_MAX_BANK > 3
+ { 24, 175, FSL_SRDS_BANK_4 },
+ { 25, 176, FSL_SRDS_BANK_4 },
+#endif
};
int serdes_get_lane_idx(int lane)
diff --git a/arch/powerpc/cpu/mpc85xx/p2041_ids.c b/arch/powerpc/cpu/mpc85xx/p2041_ids.c
index 91d9cac..ef685fe 100644
--- a/arch/powerpc/cpu/mpc85xx/p2041_ids.c
+++ b/arch/powerpc/cpu/mpc85xx/p2041_ids.c
@@ -27,16 +27,16 @@
#ifdef CONFIG_SYS_DPAA_QBMAN
struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
/* dqrr liodn, frame data liodn, liodn off, sdest */
- SET_QP_INFO(1, 2, 1, 0),
- SET_QP_INFO(3, 4, 2, 1),
- SET_QP_INFO(5, 6, 3, 2),
- SET_QP_INFO(7, 8, 4, 3),
- SET_QP_INFO(9, 10, 5, 0),
- SET_QP_INFO(11, 12, 1, 1),
- SET_QP_INFO(13, 14, 2, 2),
- SET_QP_INFO(15, 16, 3, 3),
- SET_QP_INFO(17, 18, 4, 0), /* for now sdest to 0 */
- SET_QP_INFO(19, 20, 5, 0), /* for now sdest to 0 */
+ SET_QP_INFO(1, 2, 1, 0),
+ SET_QP_INFO(3, 4, 2, 1),
+ SET_QP_INFO(5, 6, 3, 2),
+ SET_QP_INFO(7, 8, 4, 3),
+ SET_QP_INFO(9, 10, 5, 0),
+ SET_QP_INFO(11, 12, 6, 1),
+ SET_QP_INFO(13, 14, 7, 2),
+ SET_QP_INFO(15, 16, 8, 3),
+ SET_QP_INFO(17, 18, 9, 0), /* for now sdest to 0 */
+ SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */
};
#endif
diff --git a/arch/powerpc/cpu/mpc85xx/p3041_ids.c b/arch/powerpc/cpu/mpc85xx/p3041_ids.c
index e46a714..cab03f8 100644
--- a/arch/powerpc/cpu/mpc85xx/p3041_ids.c
+++ b/arch/powerpc/cpu/mpc85xx/p3041_ids.c
@@ -27,16 +27,16 @@
#ifdef CONFIG_SYS_DPAA_QBMAN
struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
/* dqrr liodn, frame data liodn, liodn off, sdest */
- SET_QP_INFO(1, 2, 1, 0),
- SET_QP_INFO(3, 4, 2, 1),
- SET_QP_INFO(5, 6, 3, 2),
- SET_QP_INFO(7, 8, 4, 3),
- SET_QP_INFO(9, 10, 5, 0),
- SET_QP_INFO(11, 12, 1, 1),
- SET_QP_INFO(13, 14, 2, 2),
- SET_QP_INFO(15, 16, 3, 3),
- SET_QP_INFO(17, 18, 4, 0), /* for now sdest to 0 */
- SET_QP_INFO(19, 20, 5, 0), /* for now sdest to 0 */
+ SET_QP_INFO(1, 2, 1, 0),
+ SET_QP_INFO(3, 4, 2, 1),
+ SET_QP_INFO(5, 6, 3, 2),
+ SET_QP_INFO(7, 8, 4, 3),
+ SET_QP_INFO(9, 10, 5, 0),
+ SET_QP_INFO(1, 12, 6, 1),
+ SET_QP_INFO(13, 14, 7, 2),
+ SET_QP_INFO(15, 16, 8, 3),
+ SET_QP_INFO(17, 18, 9, 0), /* for now sdest to 0 */
+ SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */
};
#endif
diff --git a/arch/powerpc/cpu/mpc85xx/p5020_ids.c b/arch/powerpc/cpu/mpc85xx/p5020_ids.c
index e8c26bf..ca05b9c 100644
--- a/arch/powerpc/cpu/mpc85xx/p5020_ids.c
+++ b/arch/powerpc/cpu/mpc85xx/p5020_ids.c
@@ -27,16 +27,16 @@
#ifdef CONFIG_SYS_DPAA_QBMAN
struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
/* dqrr liodn, frame data liodn, liodn off, sdest */
- SET_QP_INFO(1, 2, 1, 0),
- SET_QP_INFO(3, 4, 2, 1),
- SET_QP_INFO(5, 6, 3, 0),
- SET_QP_INFO(7, 8, 4, 1),
- SET_QP_INFO(9, 10, 5, 0),
- SET_QP_INFO(11, 12, 1, 1),
- SET_QP_INFO(13, 14, 2, 0),
- SET_QP_INFO(15, 16, 3, 1),
- SET_QP_INFO(17, 18, 4, 0),
- SET_QP_INFO(19, 20, 5, 1),
+ SET_QP_INFO(1, 2, 1, 0),
+ SET_QP_INFO(3, 4, 2, 1),
+ SET_QP_INFO(5, 6, 3, 0),
+ SET_QP_INFO(7, 8, 4, 1),
+ SET_QP_INFO(9, 10, 5, 0),
+ SET_QP_INFO(11, 12, 6, 1),
+ SET_QP_INFO(13, 14, 7, 0),
+ SET_QP_INFO(15, 16, 8, 1),
+ SET_QP_INFO(17, 18, 9, 0),
+ SET_QP_INFO(19, 20, 10, 1),
};
#endif
diff --git a/arch/powerpc/cpu/mpc85xx/portals.c b/arch/powerpc/cpu/mpc85xx/portals.c
index b59ef69..d529095 100644
--- a/arch/powerpc/cpu/mpc85xx/portals.c
+++ b/arch/powerpc/cpu/mpc85xx/portals.c
@@ -30,11 +30,9 @@
#include <asm/fsl_portals.h>
#include <asm/fsl_liodn.h>
-static ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
-static ccsr_bman_t *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR;
-
void setup_portals(void)
{
+ ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
#ifdef CONFIG_FSL_CORENET
int i;
@@ -166,6 +164,20 @@ static int fdt_qportal(void *blob, int off, int id, char *name,
num = get_dpaa_liodn(dev, &liodns[0], id);
ret = fdt_setprop(blob, childoff, "fsl,liodn",
&liodns[0], sizeof(u32) * num);
+ if (!strncmp(name, "pme", 3)) {
+ u32 pme_rev1, pme_rev2;
+ ccsr_pme_t *pme_regs =
+ (void *)CONFIG_SYS_FSL_CORENET_PME_ADDR;
+
+ pme_rev1 = in_be32(&pme_regs->pm_ip_rev_1);
+ pme_rev2 = in_be32(&pme_regs->pm_ip_rev_2);
+ ret = fdt_setprop(blob, childoff,
+ "fsl,pme-rev1", &pme_rev1, sizeof(u32));
+ if (ret < 0)
+ return ret;
+ ret = fdt_setprop(blob, childoff,
+ "fsl,pme-rev2", &pme_rev2, sizeof(u32));
+ }
#endif
} else {
return childoff;
@@ -183,6 +195,7 @@ void fdt_fixup_qportals(void *blob)
int off, err;
unsigned int maj, min;
unsigned int ip_cfg;
+ ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
u32 rev_1 = in_be32(&qman->ip_rev_1);
u32 rev_2 = in_be32(&qman->ip_rev_2);
char compat[64];
@@ -272,6 +285,7 @@ void fdt_fixup_bportals(void *blob)
int off, err;
unsigned int maj, min;
unsigned int ip_cfg;
+ ccsr_bman_t *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR;
u32 rev_1 = in_be32(&bman->ip_rev_1);
u32 rev_2 = in_be32(&bman->ip_rev_2);
char compat[64];
diff --git a/arch/powerpc/cpu/ppc4xx/Makefile b/arch/powerpc/cpu/ppc4xx/Makefile
index 8da2f86..e301dc6 100644
--- a/arch/powerpc/cpu/ppc4xx/Makefile
+++ b/arch/powerpc/cpu/ppc4xx/Makefile
@@ -68,6 +68,10 @@ COBJS += miiphy.o
COBJS += uic.o
endif
+ifdef CONFIG_SPL_BUILD
+COBJS-y += spl_boot.o
+endif
+
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS-y))
START := $(addprefix $(obj),$(START))
diff --git a/arch/powerpc/cpu/ppc4xx/spl_boot.c b/arch/powerpc/cpu/ppc4xx/spl_boot.c
new file mode 100644
index 0000000..80869f6
--- /dev/null
+++ b/arch/powerpc/cpu/ppc4xx/spl_boot.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 Stefan Roese <sr@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.
+ */
+
+#include <common.h>
+#include <spl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Return selected boot device. On PPC4xx its only NOR flash right now.
+ */
+u32 spl_boot_device(void)
+{
+ return BOOT_DEVICE_NOR;
+}
+
+/*
+ * SPL version of board_init_f()
+ */
+void board_init_f(ulong bootflag)
+{
+ /*
+ * First we need to initialize the SDRAM, so that the real
+ * U-Boot or the OS (Linux) can be loaded
+ */
+ initdram(0);
+
+ /* Clear bss */
+ memset(__bss_start, '\0', __bss_end - __bss_start);
+
+ /*
+ * Init global_data pointer. Has to be done before calling
+ * get_clocks(), as it stores some clock values into gd needed
+ * later on in the serial driver.
+ */
+ /* Pointer is writable since we allocated a register for it */
+ gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET);
+ /* Clear initial global data */
+ memset((void *)gd, 0, sizeof(gd_t));
+
+ /*
+ * get_clocks() needs to be called so that the serial driver
+ * works correctly
+ */
+ get_clocks();
+
+ /*
+ * Do rudimental console / serial setup
+ */
+ preloader_console_init();
+
+ /*
+ * Call board_init_r() (SPL framework version) to load and boot
+ * real U-Boot or OS
+ */
+ board_init_r(NULL, 0);
+ /* Does not return!!! */
+}
diff --git a/arch/powerpc/cpu/ppc4xx/start.S b/arch/powerpc/cpu/ppc4xx/start.S
index 52f2623..57ae1d3 100644
--- a/arch/powerpc/cpu/ppc4xx/start.S
+++ b/arch/powerpc/cpu/ppc4xx/start.S
@@ -232,7 +232,7 @@
*
* Use r12 to access the GOT
*/
-#if !defined(CONFIG_NAND_SPL)
+#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)
START_GOT
GOT_ENTRY(_GOT2_TABLE_)
GOT_ENTRY(_FIXUP_TABLE_)
@@ -248,7 +248,8 @@
END_GOT
#endif /* CONFIG_NAND_SPL */
-#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) && \
+ !defined(CONFIG_SPL_BUILD)
/*
* NAND U-Boot image is started from offset 0
*/
@@ -270,6 +271,18 @@
bl _start_440
#endif
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+ /*
+ * This is the entry of the real U-Boot from a board port
+ * that supports SPL booting on the PPC4xx. We only need
+ * to call board_init_f() here. Everything else has already
+ * been done in the SPL u-boot version.
+ */
+ GET_GOT /* initialize GOT access */
+ bl board_init_f /* run 1st part of board init code (in Flash)*/
+ /* NOTREACHED - board_init_f() does not return */
+#endif
+
/*
* 440 Startup -- on reset only the top 4k of the effective
* address space is mapped in by an entry in the instruction
@@ -539,7 +552,7 @@ tlbnx2: addi r4,r4,1 /* Next TLB */
* r3 - 1st arg to board_init(): IMMP pointer
* r4 - 2nd arg to board_init(): boot flag
*/
-#ifndef CONFIG_NAND_SPL
+#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)
.text
.long 0x27051956 /* U-Boot Magic Number */
.globl version_string
@@ -612,6 +625,18 @@ _end_of_vectors:
.globl _start
_start:
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+ /*
+ * This is the entry of the real U-Boot from a board port
+ * that supports SPL booting on the PPC4xx. We only need
+ * to call board_init_f() here. Everything else has already
+ * been done in the SPL u-boot version.
+ */
+ GET_GOT /* initialize GOT access */
+ bl board_init_f /* run 1st part of board init code (in Flash)*/
+ /* NOTREACHED - board_init_f() does not return */
+#endif
+
/*****************************************************************************/
#if defined(CONFIG_440)
@@ -796,7 +821,9 @@ _start:
#ifdef CONFIG_NAND_SPL
bl nand_boot_common /* will not return */
#else
+#ifndef CONFIG_SPL_BUILD
GET_GOT
+#endif
bl cpu_init_f /* run low-level CPU init code (from Flash) */
bl board_init_f
@@ -1080,7 +1107,7 @@ _start:
/*----------------------------------------------------------------------- */
-#ifndef CONFIG_NAND_SPL
+#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)
/*
* This code finishes saving the registers to the exception frame
* and jumps to the appropriate handler for the exception.
@@ -1262,6 +1289,7 @@ in32r:
lwbrx r3,r0,r3
blr
+#if !defined(CONFIG_SPL_BUILD)
/*
* void relocate_code (addr_sp, gd, addr_moni)
*
@@ -1626,6 +1654,7 @@ __440_msr_continue:
mtlr r4 /* restore link register */
blr
+#endif /* CONFIG_SPL_BUILD */
#if defined(CONFIG_440)
/*----------------------------------------------------------------------------+
diff --git a/arch/powerpc/cpu/ppc4xx/u-boot-spl.lds b/arch/powerpc/cpu/ppc4xx/u-boot-spl.lds
new file mode 100644
index 0000000..ae1df17
--- /dev/null
+++ b/arch/powerpc/cpu/ppc4xx/u-boot-spl.lds
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2012-2013 Stefan Roese <sr@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
+ */
+
+MEMORY
+{
+ sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR,
+ LENGTH = CONFIG_SPL_BSS_MAX_SIZE
+ flash : ORIGIN = CONFIG_SPL_TEXT_BASE,
+ LENGTH = CONFIG_SYS_SPL_MAX_LEN
+}
+
+OUTPUT_ARCH(powerpc)
+ENTRY(_start)
+SECTIONS
+{
+#ifdef CONFIG_440
+ .bootpg 0xfffff000 :
+ {
+ arch/powerpc/cpu/ppc4xx/start.o (.bootpg)
+
+ /*
+ * PPC440 board need a board specific object with the
+ * TLB definitions. This needs to get included right after
+ * start.o, since the first shadow TLB only covers 4k
+ * of address space.
+ */
+ CONFIG_BOARDDIR/init.o (.bootpg)
+ } > flash
+#endif
+
+ .resetvec 0xFFFFFFFC :
+ {
+ KEEP(*(.resetvec))
+ } > flash
+
+ .text :
+ {
+ __start = .;
+ arch/powerpc/cpu/ppc4xx/start.o (.text)
+ CONFIG_BOARDDIR/init.o (.text)
+ *(.text*)
+ } > flash
+
+ . = ALIGN(4);
+ .data : { *(SORT_BY_ALIGNMENT(.data*)) } > flash
+
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > flash
+
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_end = .;
+ } > sdram
+}
diff --git a/arch/powerpc/cpu/ppc4xx/u-boot.lds b/arch/powerpc/cpu/ppc4xx/u-boot.lds
index 06010d6..e994f02 100644
--- a/arch/powerpc/cpu/ppc4xx/u-boot.lds
+++ b/arch/powerpc/cpu/ppc4xx/u-boot.lds
@@ -96,6 +96,7 @@ SECTIONS
. = ALIGN(256);
__init_end = .;
+#ifndef CONFIG_SPL
#ifdef CONFIG_440
.bootpg RESET_VECTOR_ADDRESS - 0xffc :
{
@@ -132,6 +133,7 @@ SECTIONS
#if (RESET_VECTOR_ADDRESS == 0xfffffffc)
. |= 0x10;
#endif
+#endif /* CONFIG_SPL */
__bss_start = .;
.bss (NOLOAD) :
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h
index d57c178..7267611 100644
--- a/arch/powerpc/include/asm/config_mpc85xx.h
+++ b/arch/powerpc/include/asm/config_mpc85xx.h
@@ -333,7 +333,9 @@
#define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
#define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011
+#define CONFIG_SYS_FSL_ERRATUM_USB14
#define CONFIG_SYS_FSL_ERRATUM_CPU_A003999
+#define CONFIG_SYS_FSL_ERRATUM_DDR_A003
#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
#define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2
@@ -365,7 +367,9 @@
#define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
#define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011
+#define CONFIG_SYS_FSL_ERRATUM_USB14
#define CONFIG_SYS_FSL_ERRATUM_CPU_A003999
+#define CONFIG_SYS_FSL_ERRATUM_DDR_A003
#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
#define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2
@@ -442,6 +446,8 @@
#define CONFIG_SYS_FSL_USB2_PHY_ENABLE
#define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+#define CONFIG_SYS_FSL_ERRATUM_USB14
+#define CONFIG_SYS_FSL_ERRATUM_DDR_A003
#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
#define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2
@@ -473,7 +479,7 @@
#define CONFIG_SYS_FSL_USB2_PHY_ENABLE
#define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
-#define CONFIG_SYS_FSL_ERRATUM_USB138
+#define CONFIG_SYS_FSL_ERRATUM_USB14
#define CONFIG_SYS_FSL_ERRATUM_DDR_A003
#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
#define CONFIG_SYS_FSL_ERRATUM_A004699
@@ -490,7 +496,6 @@
#define CONFIG_NUM_DDR_CONTROLLERS 1
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000
#define CONFIG_NAND_FSL_IFC
-#define CONFIG_SYS_FSL_ERRATUM_IFC_A003399
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
#elif defined(CONFIG_BSC9132)
@@ -503,7 +508,6 @@
#define CONFIG_NUM_DDR_CONTROLLERS 2
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000
#define CONFIG_NAND_FSL_IFC
-#define CONFIG_SYS_FSL_ERRATUM_IFC_A003399
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
#define CONFIG_SYS_FSL_ESDHC_P1010_BROKEN_SDCLK
#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2"
@@ -560,6 +564,7 @@
#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.4"
#define CONFIG_SYS_FSL_USB1_PHY_ENABLE
#define CONFIG_SYS_FSL_ERRATUM_A_004934
+#define CONFIG_SYS_FSL_ERRATUM_A005871
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000
#elif defined(CONFIG_PPC_B4860)
@@ -585,6 +590,7 @@
#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5
#define CONFIG_SYS_FSL_USB1_PHY_ENABLE
#define CONFIG_SYS_FSL_ERRATUM_A_004934
+#define CONFIG_SYS_FSL_ERRATUM_A005871
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000
#else
diff --git a/arch/powerpc/include/asm/fsl_memac.h b/arch/powerpc/include/asm/fsl_memac.h
index d6b60e6..69f95d1 100644
--- a/arch/powerpc/include/asm/fsl_memac.h
+++ b/arch/powerpc/include/asm/fsl_memac.h
@@ -222,6 +222,10 @@ struct memac {
/* IF_MODE - Interface Mode Register */
#define IF_MODE_EN_AUTO 0x00008000 /* 1 - Enable automatic speed selection */
+#define IF_MODE_SETSP_100M 0x00000000 /* 00 - 100Mbps RGMII */
+#define IF_MODE_SETSP_10M 0x00002000 /* 01 - 10Mbps RGMII */
+#define IF_MODE_SETSP_1000M 0x00004000 /* 10 - 1000Mbps RGMII */
+#define IF_MODE_SETSP_MASK 0x00006000 /* setsp mask bits */
#define IF_MODE_XGMII 0x00000000 /* 00- XGMII(10) interface mode */
#define IF_MODE_GMII 0x00000002 /* 10- GMII interface mode */
#define IF_MODE_MASK 0x00000003 /* mask for mode interface mode */
diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h
index 4eb3f79..baaa9fe 100644
--- a/arch/powerpc/include/asm/immap_85xx.h
+++ b/arch/powerpc/include/asm/immap_85xx.h
@@ -2914,7 +2914,8 @@ struct ccsr_pman {
#define CONFIG_SYS_MPC85xx_IFC_OFFSET 0x124000
#define CONFIG_SYS_MPC85xx_GPIO_OFFSET 0x130000
#define CONFIG_SYS_FSL_CORENET_RMAN_OFFSET 0x1e0000
-#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
+#if defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2) && !defined(CONFIG_PPC_B4860)\
+ && !defined(CONFIG_PPC_B4420)
#define CONFIG_SYS_MPC85xx_PCIE1_OFFSET 0x240000
#define CONFIG_SYS_MPC85xx_PCIE2_OFFSET 0x250000
#define CONFIG_SYS_MPC85xx_PCIE3_OFFSET 0x260000
@@ -3160,4 +3161,13 @@ struct ccsr_cluster_l2 {
#define CONFIG_SYS_FSL_CLUSTER_1_L2 \
(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_CLUSTER_1_L2_OFFSET)
#endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
+
+#define CONFIG_SYS_DCSR_DCFG_OFFSET 0X20000
+struct dcsr_dcfg_regs {
+ u8 res_0[0x520];
+ u32 ecccr1;
+#define DCSR_DCFG_ECC_DISABLE_USB1 0x00008000
+#define DCSR_DCFG_ECC_DISABLE_USB2 0x00004000
+ u8 res_524[0x1000 - 0x524]; /* 0x524 - 0x1000 */
+};
#endif /*__IMMAP_85xx__*/
diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c
index 422b4a3..41b2294 100644
--- a/arch/powerpc/lib/board.c
+++ b/arch/powerpc/lib/board.c
@@ -1050,15 +1050,6 @@ void board_init_r(gd_t *id, ulong dest_addr)
/* NOTREACHED - no way out of command loop except booting */
}
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- bootstage_error(BOOTSTAGE_ID_NEED_RESET);
- for (;;)
- ;
-}
-
-
#if 0 /* We could use plain global data, but the resulting code is bigger */
/*
* Pointer to initial global data area
diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk
index 4fd0d4e..988b52c 100644
--- a/arch/sandbox/config.mk
+++ b/arch/sandbox/config.mk
@@ -18,5 +18,8 @@
# MA 02111-1307 USA
PLATFORM_CPPFLAGS += -DCONFIG_SANDBOX -D__SANDBOX__ -U_FORTIFY_SOURCE
-PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM
+PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM -DCONFIG_SYS_GENERIC_BOARD
PLATFORM_LIBS += -lrt
+
+# Support generic board on sandbox
+__HAVE_ARCH_GENERIC_BOARD := y
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index b2788d5..dd8d495 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -57,6 +57,11 @@ void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
return (void *)(gd->arch.ram_buf + paddr);
}
+phys_addr_t map_to_sysmem(void *ptr)
+{
+ return (u8 *)ptr - gd->arch.ram_buf;
+}
+
void flush_dcache_range(unsigned long start, unsigned long stop)
{
}
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 5287fd5..ae6e16c 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -90,7 +90,7 @@ int sandbox_main_loop_init(void)
/* Execute command if required */
if (state->cmd) {
- run_command(state->cmd, 0);
+ run_command_list(state->cmd, -1, 0);
os_exit(state->exit_type);
}
@@ -104,6 +104,13 @@ static int sb_cmdline_cb_command(struct sandbox_state *state, const char *arg)
}
SB_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command");
+static int sb_cmdline_cb_fdt(struct sandbox_state *state, const char *arg)
+{
+ state->fdt_fname = arg;
+ return 0;
+}
+SB_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT");
+
int main(int argc, char *argv[])
{
struct sandbox_state *state;
diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h
index d8c0236..0c022f1 100644
--- a/arch/sandbox/include/asm/io.h
+++ b/arch/sandbox/include/asm/io.h
@@ -20,6 +20,9 @@
* MA 02111-1307 USA
*/
+#ifndef __SANDBOX_ASM_IO_H
+#define __SANDBOX_ASM_IO_H
+
/*
* Given a physical address and a length, return a virtual address
* that can be used to access the memory range with the caching
@@ -49,3 +52,8 @@ static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
static inline void unmap_sysmem(const void *vaddr)
{
}
+
+/* Map from a pointer to our RAM buffer */
+phys_addr_t map_to_sysmem(void *ptr);
+
+#endif
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 2b62b46..9552708 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -34,6 +34,7 @@ enum exit_type_id {
/* The complete state of the test system */
struct sandbox_state {
const char *cmd; /* Command to execute */
+ const char *fdt_fname; /* Filename of FDT binary */
enum exit_type_id exit_type; /* How we exited U-Boot */
const char *parse_err; /* Error to report from parsing */
int argc; /* Program arguments */
diff --git a/arch/sandbox/include/asm/u-boot.h b/arch/sandbox/include/asm/u-boot.h
index de8120a..5bea1f2 100644
--- a/arch/sandbox/include/asm/u-boot.h
+++ b/arch/sandbox/include/asm/u-boot.h
@@ -36,26 +36,8 @@
#ifndef _U_BOOT_H_
#define _U_BOOT_H_ 1
-typedef struct bd_info {
- unsigned long bi_memstart; /* start of DRAM memory */
- phys_size_t bi_memsize; /* size of DRAM memory in bytes */
- unsigned long bi_flashstart; /* start of FLASH memory */
- unsigned long bi_flashsize; /* size of FLASH memory */
- unsigned long bi_flashoffset; /* reserved area for startup monitor */
- unsigned long bi_sramstart; /* start of SRAM memory */
- unsigned long bi_sramsize; /* size of SRAM memory */
- unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */
- unsigned short bi_ethspeed; /* Ethernet speed in Mbps */
- unsigned long bi_intfreq; /* Internal Freq, in MHz */
- unsigned long bi_busfreq; /* Bus Freq, in MHz */
- unsigned int bi_baudrate; /* Console Baudrate */
- unsigned long bi_boot_params; /* where this board expects params */
- struct /* RAM configuration */
- {
- ulong start;
- ulong size;
- } bi_dram[CONFIG_NR_DRAM_BANKS];
-} bd_t;
+/* Use the generic board which requires a unified bd_info */
+#include <asm-generic/u-boot.h>
/* For image.h:image_check_target_arch() */
#define IH_ARCH_DEFAULT IH_ARCH_SANDBOX
diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile
index fbe579b..3aad574 100644
--- a/arch/sandbox/lib/Makefile
+++ b/arch/sandbox/lib/Makefile
@@ -27,7 +27,6 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(ARCH).o
-COBJS-y += board.o
COBJS-y += interrupts.o
SRCS := $(COBJS-y:.o=.c)
diff --git a/arch/sandbox/lib/board.c b/arch/sandbox/lib/board.c
deleted file mode 100644
index 3752fab..0000000
--- a/arch/sandbox/lib/board.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2011 The Chromium OS Authors.
- *
- * (C) Copyright 2002-2006
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.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
- */
-
-/*
- * This file was taken from ARM and changed to remove things we don't
- * need. This is most of it, so have tried to avoid being over-zealous!
- * For example, we want to have an emulation of the 'DRAM' used by
- * U-Boot.
- *
- * has been talk upstream of unifying the architectures w.r.t board.c,
- * so the less change here the better.
- */
-
-#include <common.h>
-#include <command.h>
-#include <malloc.h>
-#include <stdio_dev.h>
-#include <timestamp.h>
-#include <version.h>
-#include <serial.h>
-
-#include <os.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static gd_t gd_mem;
-
-/************************************************************************
- * Init Utilities *
- ************************************************************************
- * Some of this code should be moved into the core functions,
- * or dropped completely,
- * but let's get it working (again) first...
- */
-
-static int display_banner(void)
-{
- display_options();
-
- return 0;
-}
-
-/**
- * Configure and report on the DRAM configuration, which in our case is
- * fairly simple.
- */
-static int display_dram_config(void)
-{
- ulong size = 0;
- int i;
-
- debug("RAM Configuration:\n");
-
- for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
-#ifdef DEBUG
- printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
- print_size(gd->bd->bi_dram[i].size, "\n");
-#endif
- size += gd->bd->bi_dram[i].size;
- }
- puts("DRAM: ");
- print_size(size, "\n");
- return 0;
-}
-
-/*
- * Breathe some life into the board...
- *
- * Initialize a serial port as console, and carry out some hardware
- * tests.
- *
- * The first part of initialization is running from Flash memory;
- * its main purpose is to initialize the RAM so that we
- * can relocate the monitor code to RAM.
- */
-
-/*
- * All attempts to come up with a "common" initialization sequence
- * that works for all boards and architectures failed: some of the
- * requirements are just _too_ different. To get rid of the resulting
- * mess of board dependent #ifdef'ed code we now make the whole
- * initialization sequence configurable to the user.
- *
- * The requirements for any new initalization function is simple: it
- * receives a pointer to the "global data" structure as it's only
- * argument, and returns an integer return code, where 0 means
- * "continue" and != 0 means "fatal error, hang the system".
- */
-typedef int (init_fnc_t) (void);
-
-void __dram_init_banksize(void)
-{
- gd->bd->bi_dram[0].start = 0;
- gd->bd->bi_dram[0].size = gd->ram_size;
-}
-
-void dram_init_banksize(void)
- __attribute__((weak, alias("__dram_init_banksize")));
-
-init_fnc_t *init_sequence[] = {
-#if defined(CONFIG_ARCH_CPU_INIT)
- arch_cpu_init, /* basic arch cpu dependent setup */
-#endif
-#if defined(CONFIG_BOARD_EARLY_INIT_F)
- board_early_init_f,
-#endif
- timer_init, /* initialize timer */
- env_init, /* initialize environment */
- serial_init, /* serial communications setup */
- console_init_f, /* stage 1 init of console */
- sandbox_early_getopt_check, /* process command line flags (err/help) */
- display_banner, /* say that we are here */
-#if defined(CONFIG_DISPLAY_CPUINFO)
- print_cpuinfo, /* display cpu info (and speed) */
-#endif
-#if defined(CONFIG_DISPLAY_BOARDINFO)
- checkboard, /* display board info */
-#endif
- dram_init, /* configure available RAM banks */
- NULL,
-};
-
-void board_init_f(ulong bootflag)
-{
- init_fnc_t **init_fnc_ptr;
- uchar *mem;
- unsigned long addr_sp, addr, size;
-
- gd = &gd_mem;
- assert(gd);
-
- memset((void *)gd, 0, sizeof(gd_t));
-
-#if defined(CONFIG_OF_EMBED)
- /* Get a pointer to the FDT */
- gd->fdt_blob = _binary_dt_dtb_start;
-#elif defined(CONFIG_OF_SEPARATE)
- /* FDT is at end of image */
- gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE);
-#endif
-
- for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
- if ((*init_fnc_ptr)() != 0)
- hang();
- }
-
- size = CONFIG_SYS_SDRAM_SIZE;
- mem = os_malloc(CONFIG_SYS_SDRAM_SIZE);
-
- assert(mem);
- gd->arch.ram_buf = mem;
- addr = (ulong)(mem + size);
-
- /*
- * reserve memory for malloc() arena
- */
- addr_sp = addr - TOTAL_MALLOC_LEN;
- debug("Reserving %dk for malloc() at: %08lx\n",
- TOTAL_MALLOC_LEN >> 10, addr_sp);
- /*
- * (permanently) allocate a Board Info struct
- * and a permanent copy of the "global" data
- */
- addr_sp -= sizeof(bd_t);
- gd->bd = (bd_t *) addr_sp;
- debug("Reserving %zu Bytes for Board Info at: %08lx\n",
- sizeof(bd_t), addr_sp);
-
- /* Ram ist board specific, so move it to board code ... */
- dram_init_banksize();
- display_dram_config(); /* and display it */
-
- /* We don't relocate, so just run the post-relocation code */
- board_init_r(NULL, 0);
-
- /* NOTREACHED - no way out of command loop except booting */
-}
-
-/************************************************************************
- *
- * This is the next part if the initialization sequence: we are now
- * running from RAM and have a "normal" C environment, i. e. global
- * data can be written, BSS has been cleared, the stack size in not
- * that critical any more, etc.
- *
- ************************************************************************
- */
-
-void board_init_r(gd_t *id, ulong dest_addr)
-{
-
- if (id)
- gd = id;
-
- gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
-
- serial_initialize();
-
-#ifdef CONFIG_POST
- post_output_backlog();
-#endif
-
- /* The Malloc area is at the top of simulated DRAM */
- mem_malloc_init((ulong)gd->arch.ram_buf + gd->ram_size -
- TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN);
-
- /* initialize environment */
- env_relocate();
-
- stdio_init(); /* get the devices list going. */
-
- jumptable_init();
-
- console_init_r(); /* fully init console as a device */
-
-#if defined(CONFIG_DISPLAY_BOARDINFO_LATE)
- checkboard();
-#endif
-
-#if defined(CONFIG_ARCH_MISC_INIT)
- /* miscellaneous arch dependent initialisations */
- arch_misc_init();
-#endif
-#if defined(CONFIG_MISC_INIT_R)
- /* miscellaneous platform dependent initialisations */
- misc_init_r();
-#endif
-
- /* set up exceptions */
- interrupt_init();
- /* enable exceptions */
- enable_interrupts();
-
-#ifdef CONFIG_BOARD_LATE_INIT
- board_late_init();
-#endif
-
-#ifdef CONFIG_POST
- post_run(NULL, POST_RAM | post_bootmode_get(0));
-#endif
-
- sandbox_main_loop_init();
-
- /*
- * For now, run the main loop. Later we might let this be done
- * in the main program.
- */
- while (1)
- main_loop();
-
- /* NOTREACHED - no way out of command loop except booting */
-}
-
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;)
- ;
-}
diff --git a/arch/sh/lib/board.c b/arch/sh/lib/board.c
index 6e43acf..0789ed0 100644
--- a/arch/sh/lib/board.c
+++ b/arch/sh/lib/board.c
@@ -200,12 +200,3 @@ void sh_generic_init(void)
main_loop();
}
}
-
-/***********************************************************************/
-
-void hang(void)
-{
- puts("Board ERROR\n");
- for (;;)
- ;
-}
diff --git a/arch/sparc/lib/board.c b/arch/sparc/lib/board.c
index 79fb4c8..fbc535f 100644
--- a/arch/sparc/lib/board.c
+++ b/arch/sparc/lib/board.c
@@ -411,13 +411,4 @@ void board_init_f(ulong bootflag)
}
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
-#ifdef CONFIG_SHOW_BOOT_PROGRESS
- bootstage_error(BOOTSTAGE_ID_NEED_RESET);
-#endif
- for (;;) ;
-}
-
/************************************************************************/
diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c
index 786009c..b4fe6c9 100644
--- a/arch/x86/cpu/coreboot/sdram.c
+++ b/arch/x86/cpu/coreboot/sdram.c
@@ -113,7 +113,7 @@ int dram_init_f(void)
return 0;
}
-int dram_init(void)
+int dram_init_banksize(void)
{
int i, j;
@@ -132,3 +132,8 @@ int dram_init(void)
}
return 0;
}
+
+int dram_init(void)
+{
+ return dram_init_banksize();
+}
diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c
index f372898..228c2c8 100644
--- a/arch/x86/lib/board.c
+++ b/arch/x86/lib/board.c
@@ -264,10 +264,3 @@ void board_init_r(gd_t *id, ulong dest_addr)
/* NOTREACHED - no way out of command loop except booting */
}
-
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;)
- ;
-}
diff --git a/board/a3m071/a3m071.c b/board/a3m071/a3m071.c
index 0f9f883..c62ba62 100644
--- a/board/a3m071/a3m071.c
+++ b/board/a3m071/a3m071.c
@@ -8,7 +8,7 @@
* (C) Copyright 2006
* MicroSys GmbH
*
- * Copyright 2012 Stefan Roese <sr@denx.de>
+ * Copyright 2012-2013 Stefan Roese <sr@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -241,12 +241,26 @@ void spl_board_init(void)
/* And write new value back to register */
out_be32(&mm->ipbi_ws_ctrl, val);
-#endif
- /*
- * No need to change the pin multiplexing (MPC5XXX_GPS_PORT_CONFIG)
- * as all 3 config versions (failsave level) have the same setup.
- */
+
+ /* Setup pin multiplexing */
+ if (failsavelevel == 2) {
+ /* fpga-version ok */
+#if defined(CONFIG_SYS_GPS_PORT_CONFIG_2)
+ out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG_2);
+#endif
+ } else if (failsavelevel == 1) {
+ /* digiboard-version ok - fpga not */
+#if defined(CONFIG_SYS_GPS_PORT_CONFIG_1)
+ out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG_1);
+#endif
+ } else {
+ /* full failsave-mode */
+#if defined(CONFIG_SYS_GPS_PORT_CONFIG)
+ out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG);
+#endif
+ }
+#endif
/*
* Setup gpio_wkup_7 as watchdog AS INPUT to disable it - see
diff --git a/board/freescale/b4860qds/tlb.c b/board/freescale/b4860qds/tlb.c
index 373cb78..6d634bf 100644
--- a/board/freescale/b4860qds/tlb.c
+++ b/board/freescale/b4860qds/tlb.c
@@ -111,8 +111,6 @@ struct fsl_e_tlb_entry tlb_table[] = {
#ifdef CONFIG_SYS_NAND_BASE
/*
* *I*G - NAND
- * entry 14 and 15 has been used hard coded, they will be disabled
- * in cpu_init_f, so we use entry 16 for nand.
*/
SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS,
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
@@ -122,6 +120,23 @@ struct fsl_e_tlb_entry tlb_table[] = {
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
0, 12, BOOKE_PAGESZ_4K, 1),
+ /*
+ * *I*G - SRIO
+ * entry 14 and 15 has been used hard coded, they will be disabled
+ * in cpu_init_f, so we use entry 16 for SRIO2.
+ */
+#ifdef CONFIG_SYS_SRIO1_MEM_PHYS
+ /* *I*G* - SRIO1 */
+ SET_TLB_ENTRY(1, CONFIG_SYS_SRIO1_MEM_VIRT, CONFIG_SYS_SRIO1_MEM_PHYS,
+ MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 13, BOOKE_PAGESZ_256M, 1),
+#endif
+#ifdef CONFIG_SYS_SRIO2_MEM_PHYS
+ /* *I*G* - SRIO2 */
+ SET_TLB_ENTRY(1, CONFIG_SYS_SRIO2_MEM_VIRT, CONFIG_SYS_SRIO2_MEM_PHYS,
+ MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 16, BOOKE_PAGESZ_256M, 1),
+#endif
};
int num_tlb_entries = ARRAY_SIZE(tlb_table);
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile
index 75725b4..72bb56c 100644
--- a/board/freescale/common/Makefile
+++ b/board/freescale/common/Makefile
@@ -33,10 +33,14 @@ COBJS-$(CONFIG_FSL_CADMUS) += cadmus.o
COBJS-$(CONFIG_FSL_VIA) += cds_via.o
COBJS-$(CONFIG_FMAN_ENET) += fman.o
COBJS-$(CONFIG_FSL_PIXIS) += pixis.o
+ifndef CONFIG_SPL_BUILD
COBJS-$(CONFIG_FSL_NGPIXIS) += ngpixis.o
+endif
COBJS-$(CONFIG_FSL_QIXIS) += qixis.o
COBJS-$(CONFIG_PQ_MDS_PIB) += pq-mds-pib.o
+ifndef CONFIG_SPL_BUILD
COBJS-$(CONFIG_ID_EEPROM) += sys_eeprom.o
+endif
COBJS-$(CONFIG_FSL_SGMII_RISER) += sgmii_riser.o
ifndef CONFIG_RAMBOOT_PBL
COBJS-$(CONFIG_FSL_FIXED_MMC_LOCATION) += sdhc_boot.o
@@ -48,7 +52,9 @@ COBJS-$(CONFIG_MPC8555CDS) += cds_pci_ft.o
COBJS-$(CONFIG_MPC8536DS) += ics307_clk.o
COBJS-$(CONFIG_MPC8572DS) += ics307_clk.o
+ifndef CONFIG_SPL_BUILD
COBJS-$(CONFIG_P1022DS) += ics307_clk.o
+endif
COBJS-$(CONFIG_P2020DS) += ics307_clk.o
COBJS-$(CONFIG_P3041DS) += ics307_clk.o
COBJS-$(CONFIG_P4080DS) += ics307_clk.o
diff --git a/board/freescale/common/cds_pci_ft.c b/board/freescale/common/cds_pci_ft.c
index 8a09f99..32233db 100644
--- a/board/freescale/common/cds_pci_ft.c
+++ b/board/freescale/common/cds_pci_ft.c
@@ -31,7 +31,8 @@ static void cds_pci_fixup(void *blob)
int node;
const char *path;
int len, slot, i;
- u32 *map = NULL;
+ u32 *map = NULL, *piccells = NULL;
+ int off, cells;
node = fdt_path_offset(blob, "/aliases");
if (node >= 0) {
@@ -41,6 +42,25 @@ static void cds_pci_fixup(void *blob)
if (node >= 0) {
map = fdt_getprop_w(blob, node, "interrupt-map", &len);
}
+ /* Each item in "interrupt-map" property is translated with
+ * following cells:
+ * PCI #address-cells, PCI #interrupt-cells,
+ * PIC address, PIC #address-cells, PIC #interrupt-cells.
+ */
+ cells = fdt_getprop_u32_default(blob, path, "#address-cells", 1);
+ cells += fdt_getprop_u32_default(blob, path, "#interrupt-cells", 1);
+ off = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*(map+cells)));
+ if (off <= 0)
+ return;
+ cells += 1;
+ piccells = (u32 *)fdt_getprop(blob, off, "#address-cells", NULL);
+ if (piccells == NULL)
+ return;
+ cells += *piccells;
+ piccells = (u32 *)fdt_getprop(blob, off, "#interrupt-cells", NULL);
+ if (piccells == NULL)
+ return;
+ cells += *piccells;
}
}
@@ -49,12 +69,12 @@ static void cds_pci_fixup(void *blob)
slot = get_pci_slot();
- for (i=0;i<len;i+=7) {
+ for (i=0;i<len;i+=cells) {
/* We rotate the interrupt pins so that the mapping
* changes depending on the slot the carrier card is in.
*/
map[3] = ((map[3] + slot - 2) % 4) + 1;
- map+=7;
+ map+=cells;
}
}
}
diff --git a/board/freescale/common/sdhc_boot.c b/board/freescale/common/sdhc_boot.c
index e432318..fd0e910 100644
--- a/board/freescale/common/sdhc_boot.c
+++ b/board/freescale/common/sdhc_boot.c
@@ -32,7 +32,7 @@
#define ESDHC_BOOT_IMAGE_SIZE 0x48
#define ESDHC_BOOT_IMAGE_ADDR 0x50
-int mmc_get_env_addr(struct mmc *mmc, u32 *env_addr)
+int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
{
u8 *tmp_buf;
u32 blklen, code_offset, code_len, n;
diff --git a/board/freescale/p1010rdb/p1010rdb.c b/board/freescale/p1010rdb/p1010rdb.c
index 11e2e8a..0c30d76 100644
--- a/board/freescale/p1010rdb/p1010rdb.c
+++ b/board/freescale/p1010rdb/p1010rdb.c
@@ -217,7 +217,7 @@ void fdt_del_flexcan(void *blob)
int nodeoff = 0;
while ((nodeoff = fdt_node_offset_by_compatible(blob, 0,
- "fsl,flexcan-v1.0")) >= 0) {
+ "fsl,p1010-flexcan")) >= 0) {
fdt_del_node(blob, nodeoff);
}
}
diff --git a/board/freescale/p1022ds/Makefile b/board/freescale/p1022ds/Makefile
index c6d3418..0eeef05 100644
--- a/board/freescale/p1022ds/Makefile
+++ b/board/freescale/p1022ds/Makefile
@@ -11,12 +11,26 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).o
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+ifdef MINIMAL
+
+COBJS-y += spl_minimal.o tlb.o law.o
+
+else
COBJS-y += $(BOARD).o
COBJS-y += ddr.o
COBJS-y += law.o
COBJS-y += tlb.o
COBJS-$(CONFIG_FSL_DIU_FB) += diu.o
+endif
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS-y))
diff --git a/board/freescale/p1022ds/law.c b/board/freescale/p1022ds/law.c
index b23b8f9..c4398dd 100644
--- a/board/freescale/p1022ds/law.c
+++ b/board/freescale/p1022ds/law.c
@@ -16,6 +16,7 @@
struct law_entry law_table[] = {
SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_LBC),
SET_LAW(PIXIS_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC),
+ SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_32K, LAW_TRGT_IF_LBC),
};
int num_law_entries = ARRAY_SIZE(law_table);
diff --git a/board/freescale/p1022ds/spl_minimal.c b/board/freescale/p1022ds/spl_minimal.c
new file mode 100644
index 0000000..8d12fa6
--- /dev/null
+++ b/board/freescale/p1022ds/spl_minimal.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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 <ns16550.h>
+#include <asm/io.h>
+#include <nand.h>
+#include <asm/fsl_law.h>
+#include <asm/fsl_ddr_sdram.h>
+
+
+/*
+ * Fixed sdram init -- doesn't use serial presence detect.
+ */
+void sdram_init(void)
+{
+ volatile ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
+
+ __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds);
+ __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config);
+#if CONFIG_CHIP_SELECTS_PER_CTRL > 1
+ __raw_writel(CONFIG_SYS_DDR_CS1_BNDS, &ddr->cs1_bnds);
+ __raw_writel(CONFIG_SYS_DDR_CS1_CONFIG, &ddr->cs1_config);
+#endif
+ __raw_writel(CONFIG_SYS_DDR_TIMING_3, &ddr->timing_cfg_3);
+ __raw_writel(CONFIG_SYS_DDR_TIMING_0, &ddr->timing_cfg_0);
+ __raw_writel(CONFIG_SYS_DDR_TIMING_1, &ddr->timing_cfg_1);
+ __raw_writel(CONFIG_SYS_DDR_TIMING_2, &ddr->timing_cfg_2);
+
+ __raw_writel(CONFIG_SYS_DDR_CONTROL_2, &ddr->sdram_cfg_2);
+ __raw_writel(CONFIG_SYS_DDR_MODE_1, &ddr->sdram_mode);
+ __raw_writel(CONFIG_SYS_DDR_MODE_2, &ddr->sdram_mode_2);
+
+ __raw_writel(CONFIG_SYS_DDR_INTERVAL, &ddr->sdram_interval);
+ __raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init);
+ __raw_writel(CONFIG_SYS_DDR_CLK_CTRL, &ddr->sdram_clk_cntl);
+
+ __raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4);
+ __raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5);
+ __raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl);
+ __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL, &ddr->ddr_wrlvl_cntl);
+
+ /* Set, but do not enable the memory */
+ __raw_writel(CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN,
+ &ddr->sdram_cfg);
+
+ in_be32(&ddr->sdram_cfg);
+ udelay(500);
+
+ /* Let the controller go */
+ out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN);
+ in_be32(&ddr->sdram_cfg);
+
+ set_next_law(0, CONFIG_SYS_SDRAM_SIZE_LAW, LAW_TRGT_IF_DDR_1);
+}
+
+const static u32 sysclk_tbl[] = {
+ 66666000, 7499900, 83332500, 8999900,
+ 99999000, 11111000, 12499800, 13333200
+};
+
+void board_init_f(ulong bootflag)
+{
+ int px_spd;
+ u32 plat_ratio, sys_clk, bus_clk;
+ ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
+
+ /* for FPGA */
+ set_lbc_br(2, CONFIG_SYS_BR2_PRELIM);
+ set_lbc_or(2, CONFIG_SYS_OR2_PRELIM);
+
+ /* initialize selected port with appropriate baud rate */
+ px_spd = in_8((unsigned char *)(PIXIS_BASE + PIXIS_SPD));
+ sys_clk = sysclk_tbl[px_spd & PIXIS_SPD_SYSCLK_MASK];
+ plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO;
+ bus_clk = sys_clk * plat_ratio / 2;
+
+ NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1,
+ bus_clk / 16 / CONFIG_BAUDRATE);
+
+ puts("\nNAND boot... ");
+
+ /* Initialize the DDR3 */
+ sdram_init();
+
+ /* copy code to RAM and jump to it - this should not return */
+ /* NOTE - code has to be copied out of NAND buffer before
+ * other blocks can be read.
+ */
+ relocate_code(CONFIG_SPL_RELOC_STACK, 0,
+ CONFIG_SPL_RELOC_TEXT_BASE);
+}
+
+void board_init_r(gd_t *gd, ulong dest_addr)
+{
+ nand_boot();
+}
+
+void putc(char c)
+{
+ if (c == '\n')
+ NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, '\r');
+
+ NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, c);
+}
+
+void puts(const char *str)
+{
+ while (*str)
+ putc(*str++);
+}
diff --git a/board/freescale/p1022ds/tlb.c b/board/freescale/p1022ds/tlb.c
index 71e71f7..3acc449 100644
--- a/board/freescale/p1022ds/tlb.c
+++ b/board/freescale/p1022ds/tlb.c
@@ -41,6 +41,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
0, 1, BOOKE_PAGESZ_1M, 1),
+#ifndef CONFIG_SPL_BUILD
/* W**G* - Flash/promjet, localbus */
/* This will be changed to *I*G* after relocation to RAM. */
SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS,
@@ -67,24 +68,31 @@ struct fsl_e_tlb_entry tlb_table[] = {
SET_TLB_ENTRY(1, CONFIG_SYS_PCIE3_IO_VIRT, CONFIG_SYS_PCIE3_IO_PHYS,
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
0, 6, BOOKE_PAGESZ_256K, 1),
+#endif
SET_TLB_ENTRY(1, PIXIS_BASE, PIXIS_BASE_PHYS,
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
0, 7, BOOKE_PAGESZ_4K, 1),
-#ifdef CONFIG_SYS_RAMBOOT
- /* *I*G - eSDHC/eSPI/NAND boot */
+#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)
+ /* **** - eSDHC/eSPI/NAND boot */
SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE,
MAS3_SX|MAS3_SW|MAS3_SR, 0,
0, 8, BOOKE_PAGESZ_1G, 1),
-
- /* map the second 1G */
+ /* **** - eSDHC/eSPI/NAND boot - second 1GB of memory */
SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000,
CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000,
- MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ MAS3_SX|MAS3_SW|MAS3_SR, 0,
0, 9, BOOKE_PAGESZ_1G, 1),
#endif
-#
+
+#ifdef CONFIG_SYS_NAND_BASE
+ /* *I*G - NAND */
+ SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS,
+ MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 10, BOOKE_PAGESZ_16K, 1),
+#endif
+
};
int num_tlb_entries = ARRAY_SIZE(tlb_table);
diff --git a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
index 5b5b86c..2e0e0c7 100644
--- a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
+++ b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
@@ -55,6 +55,13 @@
#define GPIO_SLIC_PIN 30
#define GPIO_SLIC_DATA (1 << (31 - GPIO_SLIC_PIN))
+#if defined(CONFIG_P1021RDB) && !defined(CONFIG_SYS_RAMBOOT)
+#define GPIO_DDR_RST_PORT 1
+#define GPIO_DDR_RST_PIN 8
+#define GPIO_DDR_RST_DATA (1 << (31 - GPIO_DDR_RST_PIN))
+
+#define GPIO_2BIT_MASK (0x3 << (32 - (GPIO_DDR_RST_PIN + 1) * 2))
+#endif
#if defined(CONFIG_P1025RDB) || defined(CONFIG_P1021RDB)
#define PCA_IOPORT_I2C_ADDR 0x23
@@ -67,7 +74,7 @@
const qe_iop_conf_t qe_iop_conf_tab[] = {
/* GPIO */
{1, 1, 2, 0, 0}, /* GPIO7/PB1 - LOAD_DEFAULT_N */
-#if 0
+#if defined(CONFIG_P1021RDB) && !defined(CONFIG_SYS_RAMBOOT)
{1, 8, 1, 1, 0}, /* GPIO10/PB8 - DDR_RST */
#endif
{0, 15, 1, 0, 0}, /* GPIO11/A15 - WDI */
@@ -159,6 +166,16 @@ void board_gpio_init(void)
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
par_io_t *par_io = (par_io_t *) &(gur->qe_par_io);
+#if defined(CONFIG_P1021RDB) && !defined(CONFIG_SYS_RAMBOOT)
+ /* reset DDR3 */
+ setbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdat, GPIO_DDR_RST_DATA);
+ udelay(1000);
+ clrbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdat, GPIO_DDR_RST_DATA);
+ udelay(1000);
+ setbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdat, GPIO_DDR_RST_DATA);
+ /* disable CE_PB8 */
+ clrbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdir1, GPIO_2BIT_MASK);
+#endif
/* Enable VSC7385 switch */
setbits_be32(&par_io[GPIO_GETH_SW_PORT].cpdat, GPIO_GETH_SW_DATA);
@@ -421,6 +438,8 @@ void ft_board_setup(void *blob, bd_t *bd)
{
phys_addr_t base;
phys_size_t size;
+ const char *soc_usb_compat = "fsl-usb2-dr";
+ int err, usb1_off, usb2_off;
ft_cpu_setup(blob, bd);
@@ -442,5 +461,50 @@ void ft_board_setup(void *blob, bd_t *bd)
#if defined(CONFIG_HAS_FSL_DR_USB)
fdt_fixup_dr_usb(blob, bd);
#endif
+
+#if defined(CONFIG_SDCARD) || defined(CONFIG_SPIFLASH)
+ /* Delete eLBC node as it is muxed with USB2 controller */
+ if (hwconfig("usb2")) {
+ const char *soc_elbc_compat = "fsl,p1020-elbc";
+ int off = fdt_node_offset_by_compatible(blob, -1,
+ soc_elbc_compat);
+ if (off < 0) {
+ printf("WARNING: could not find compatible node %s: %s.\n",
+ soc_elbc_compat,
+ fdt_strerror(off));
+ return;
+ }
+ err = fdt_del_node(blob, off);
+ if (err < 0) {
+ printf("WARNING: could not remove %s: %s.\n",
+ soc_elbc_compat, fdt_strerror(err));
+ }
+ return;
+ }
+#endif
+
+/* Delete USB2 node as it is muxed with eLBC */
+ usb1_off = fdt_node_offset_by_compatible(blob, -1,
+ soc_usb_compat);
+ if (usb1_off < 0) {
+ printf("WARNING: could not find compatible node %s: %s.\n",
+ soc_usb_compat,
+ fdt_strerror(usb1_off));
+ return;
+ }
+ usb2_off = fdt_node_offset_by_compatible(blob, usb1_off,
+ soc_usb_compat);
+ if (usb2_off < 0) {
+ printf("WARNING: could not find compatible node %s: %s.\n",
+ soc_usb_compat,
+ fdt_strerror(usb2_off));
+ return;
+ }
+ err = fdt_del_node(blob, usb2_off);
+ if (err < 0) {
+ printf("WARNING: could not remove %s: %s.\n",
+ soc_usb_compat, fdt_strerror(err));
+ }
+
}
#endif
diff --git a/board/freescale/p1_p2_rdb_pc/spl_minimal.c b/board/freescale/p1_p2_rdb_pc/spl_minimal.c
index 09019e9..e2bfb0d 100644
--- a/board/freescale/p1_p2_rdb_pc/spl_minimal.c
+++ b/board/freescale/p1_p2_rdb_pc/spl_minimal.c
@@ -81,6 +81,8 @@ void board_init_f(ulong bootflag)
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
#ifndef CONFIG_QE
ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
+#elif defined(CONFIG_P1021RDB)
+ par_io_t *par_io = (par_io_t *)&(gur->qe_par_io);
#endif
/* initialize selected port with appropriate baud rate */
@@ -102,6 +104,19 @@ void board_init_f(ulong bootflag)
__raw_writel(0x00200000, &pgpio->gpdat);
udelay(1000);
__raw_writel(0x00000000, &pgpio->gpdir);
+#elif defined(CONFIG_P1021RDB)
+ /* init DDR3 reset signal CE_PB8 */
+ out_be32(&par_io[1].cpdir1, 0x00004000);
+ out_be32(&par_io[1].cpodr, 0x00800000);
+ out_be32(&par_io[1].cppar1, 0x00000000);
+ /* reset DDR3 */
+ out_be32(&par_io[1].cpdat, 0x00800000);
+ udelay(1000);
+ out_be32(&par_io[1].cpdat, 0x00000000);
+ udelay(1000);
+ out_be32(&par_io[1].cpdat, 0x00800000);
+ /* disable the CE_PB8 */
+ out_be32(&par_io[1].cpdir1, 0x00000000);
#endif
#ifndef CONFIG_SYS_INIT_L2_ADDR
diff --git a/board/h2200/h2200.c b/board/h2200/h2200.c
index 720b06e..738e480 100644
--- a/board/h2200/h2200.c
+++ b/board/h2200/h2200.c
@@ -32,6 +32,15 @@ int board_eth_init(bd_t *bis)
return 0;
}
+void reset_cpu(ulong ignore)
+{
+ /* Enable VLIO interface on Hamcop */
+ writeb(0x1, 0x4000);
+
+ /* Reset board (cold reset) */
+ writeb(0xff, 0x4002);
+}
+
int board_init(void)
{
/* We have RAM, disable cache */
diff --git a/board/lwmon5/lwmon5.c b/board/lwmon5/lwmon5.c
index 29e24fb..9cf0fa1 100644
--- a/board/lwmon5/lwmon5.c
+++ b/board/lwmon5/lwmon5.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2007-2010
+ * (C) Copyright 2007-2013
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* This program is free software; you can redistribute it and/or
@@ -200,9 +200,11 @@ int misc_init_r(void)
u32 pbcr;
int size_val = 0;
u32 reg;
+#ifndef CONFIG_LCD4_LWMON5
unsigned long usb2d0cr = 0;
unsigned long usb2phy0cr, usb2h0cr = 0;
unsigned long sdr0_pfc1, sdr0_srst;
+#endif
/*
* FLASH stuff...
@@ -233,6 +235,7 @@ int misc_init_r(void)
CONFIG_ENV_ADDR_REDUND + 2 * CONFIG_ENV_SECT_SIZE - 1,
&flash_info[cfi_flash_num_flash_banks - 1]);
+#ifndef CONFIG_LCD4_LWMON5
/*
* USB suff...
*/
@@ -306,6 +309,7 @@ int misc_init_r(void)
/* 7. Reassert internal PHY reset: */
mtsdr(SDR0_SRST1, SDR0_SRST1_USB20PHY);
udelay(1000);
+#endif
/*
* Clear resets
@@ -313,7 +317,9 @@ int misc_init_r(void)
mtsdr(SDR0_SRST1, 0x00000000);
mtsdr(SDR0_SRST0, 0x00000000);
+#ifndef CONFIG_LCD4_LWMON5
printf("USB: Host(int phy) Device(ext phy)\n");
+#endif
/*
* Clear PLB4A0_ACR[WRP]
@@ -323,10 +329,12 @@ int misc_init_r(void)
reg = mfdcr(PLB4A0_ACR) & ~PLB4Ax_ACR_WRP_MASK;
mtdcr(PLB4A0_ACR, reg);
+#ifndef CONFIG_LCD4_LWMON5
/*
* Init matrix keyboard
*/
misc_init_r_kbd();
+#endif
return 0;
}
@@ -336,7 +344,7 @@ int checkboard(void)
char buf[64];
int i = getenv_f("serial#", buf, sizeof(buf));
- puts("Board: lwmon5");
+ printf("Board: %s", __stringify(CONFIG_HOSTNAME));
if (i > 0) {
puts(", serial# ");
@@ -495,3 +503,66 @@ void board_reset(void)
{
gpio_write_bit(CONFIG_SYS_GPIO_BOARD_RESET, 1);
}
+
+#ifdef CONFIG_SPL_OS_BOOT
+/*
+ * lwmon5 specific implementation of spl_start_uboot()
+ *
+ * RETURN
+ * 0 if booting into OS is selected (default)
+ * 1 if booting into U-Boot is selected
+ */
+int spl_start_uboot(void)
+{
+ char s[8];
+
+ env_init();
+ getenv_f("boot_os", s, sizeof(s));
+ if ((s != NULL) && (strcmp(s, "yes") == 0))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * This function is called from the SPL U-Boot version for
+ * early init stuff, that needs to be done for OS (e.g. Linux)
+ * booting. Doing it later in the real U-Boot would not work
+ * in case that the SPL U-Boot boots Linux directly.
+ */
+void spl_board_init(void)
+{
+ const gdc_regs *regs = board_get_regs();
+
+ /*
+ * Setup PFC registers, mainly for ethernet support
+ * later on in Linux
+ */
+ board_early_init_f();
+
+ /*
+ * Clear resets
+ */
+ mtsdr(SDR0_SRST1, 0x00000000);
+ mtsdr(SDR0_SRST0, 0x00000000);
+
+ /*
+ * Reset Lime controller
+ */
+ gpio_write_bit(CONFIG_SYS_GPIO_LIME_S, 1);
+ udelay(500);
+ gpio_write_bit(CONFIG_SYS_GPIO_LIME_RST, 1);
+
+ out_be32((void *)CONFIG_SYS_LIME_SDRAM_CLOCK, CONFIG_SYS_MB862xx_CCF);
+ udelay(300);
+ out_be32((void *)CONFIG_SYS_LIME_MMR, CONFIG_SYS_MB862xx_MMR);
+
+ while (regs->index) {
+ out_be32((void *)(CONFIG_SYS_LIME_BASE_0 + GC_DISP_BASE) +
+ regs->index, regs->value);
+ regs++;
+ }
+
+ board_backlight_brightness(DEFAULT_BRIGHTNESS);
+}
+#endif
diff --git a/board/lwmon5/sdram.c b/board/lwmon5/sdram.c
index b64b35a..78b8fbc 100644
--- a/board/lwmon5/sdram.c
+++ b/board/lwmon5/sdram.c
@@ -6,7 +6,7 @@
* Alain Saurel, AMCC/IBM, alain.saurel@fr.ibm.com
* Robert Snyder, AMCC/IBM, rob.snyder@fr.ibm.com
*
- * (C) Copyright 2007-2008
+ * (C) Copyright 2007-2013
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* This program is free software; you can redistribute it and/or
@@ -160,6 +160,7 @@ static void program_ecc(u32 start_address,
************************************************************************/
phys_size_t initdram (int board_type)
{
+#if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_LCD4_LWMON5)
/* CL=4 */
mtsdram(DDR0_02, 0x00000000);
@@ -253,6 +254,7 @@ phys_size_t initdram (int board_type)
* exceptions are enabled.
*/
set_mcsr(get_mcsr());
+#endif /* CONFIG_SPL_BUILD */
return (CONFIG_SYS_MBYTES_SDRAM << 20);
}
diff --git a/board/sandbox/sandbox/sandbox.c b/board/sandbox/sandbox/sandbox.c
index 9883013..8bdba92 100644
--- a/board/sandbox/sandbox/sandbox.c
+++ b/board/sandbox/sandbox/sandbox.c
@@ -56,6 +56,6 @@ int timer_init(void)
int dram_init(void)
{
- gd->ram_size = CONFIG_DRAM_SIZE;
+ gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
return 0;
}
diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c
index 70f94c1..befbb3a 100644
--- a/board/xilinx/microblaze-generic/microblaze-generic.c
+++ b/board/xilinx/microblaze-generic/microblaze-generic.c
@@ -38,10 +38,15 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)) =
++(*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)));
#endif
-#ifdef CONFIG_SYS_RESET_ADDRESS
- puts ("Reseting board\n");
- asm ("bra r0");
+
+#ifdef CONFIG_XILINX_TB_WATCHDOG
+ hw_watchdog_disable();
#endif
+
+ puts ("Reseting board\n");
+ __asm__ __volatile__ (" mts rmsr, r0;" \
+ "bra r0");
+
return 0;
}
diff --git a/board/xilinx/microblaze-generic/xparameters.h b/board/xilinx/microblaze-generic/xparameters.h
index 50a82d9..c846f97 100644
--- a/board/xilinx/microblaze-generic/xparameters.h
+++ b/board/xilinx/microblaze-generic/xparameters.h
@@ -77,3 +77,7 @@
#define XILINX_LLTEMAC_SDMA_CTRL_BASEADDR 0x42000180
#define XILINX_LLTEMAC_BASEADDR1 0x44200000
#define XILINX_LLTEMAC_FIFO_BASEADDR1 0x42100000
+
+/* Watchdog IP is wxi_timebase_wdt_0 */
+#define XILINX_WATCHDOG_BASEADDR 0x50000000
+#define XILINX_WATCHDOG_IRQ 1
diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c
index 8ed75c3..b02c364 100644
--- a/board/xilinx/zynq/board.c
+++ b/board/xilinx/zynq/board.c
@@ -22,13 +22,52 @@
#include <common.h>
#include <netdev.h>
+#include <zynqpl.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_FPGA
+Xilinx_desc fpga;
+
+/* It can be done differently */
+Xilinx_desc fpga010 = XILINX_XC7Z010_DESC(0x10);
+Xilinx_desc fpga020 = XILINX_XC7Z020_DESC(0x20);
+Xilinx_desc fpga030 = XILINX_XC7Z030_DESC(0x30);
+Xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45);
+#endif
+
int board_init(void)
{
+#ifdef CONFIG_FPGA
+ u32 idcode;
+
+ idcode = zynq_slcr_get_idcode();
+
+ switch (idcode) {
+ case XILINX_ZYNQ_7010:
+ fpga = fpga010;
+ break;
+ case XILINX_ZYNQ_7020:
+ fpga = fpga020;
+ break;
+ case XILINX_ZYNQ_7030:
+ fpga = fpga030;
+ break;
+ case XILINX_ZYNQ_7045:
+ fpga = fpga045;
+ break;
+ }
+#endif
+
icache_enable();
+#ifdef CONFIG_FPGA
+ fpga_init();
+ fpga_add(fpga_xilinx, &fpga);
+#endif
+
return 0;
}
@@ -38,10 +77,33 @@ int board_eth_init(bd_t *bis)
{
u32 ret = 0;
-#if defined(CONFIG_ZYNQ_GEM) && defined(CONFIG_ZYNQ_GEM_BASEADDR0)
- ret = zynq_gem_initialize(bis, CONFIG_ZYNQ_GEM_BASEADDR0);
+#if defined(CONFIG_ZYNQ_GEM)
+# if defined(CONFIG_ZYNQ_GEM0)
+ ret |= zynq_gem_initialize(bis, ZYNQ_GEM_BASEADDR0,
+ CONFIG_ZYNQ_GEM_PHY_ADDR0, 0);
+# endif
+# if defined(CONFIG_ZYNQ_GEM1)
+ ret |= zynq_gem_initialize(bis, ZYNQ_GEM_BASEADDR1,
+ CONFIG_ZYNQ_GEM_PHY_ADDR1, 0);
+# endif
+#endif
+ return ret;
+}
#endif
+#ifdef CONFIG_CMD_MMC
+int board_mmc_init(bd_t *bd)
+{
+ int ret = 0;
+
+#if defined(CONFIG_ZYNQ_SDHCI)
+# if defined(CONFIG_ZYNQ_SDHCI0)
+ ret = zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR0);
+# endif
+# if defined(CONFIG_ZYNQ_SDHCI1)
+ ret |= zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR1);
+# endif
+#endif
return ret;
}
#endif
diff --git a/boards.cfg b/boards.cfg
index 91723b9..0e082a0 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -814,6 +814,8 @@ P1021RDB-PC_NAND powerpc mpc85xx p1_p2_rdb_pc freesca
P1021RDB-PC_SDCARD powerpc mpc85xx p1_p2_rdb_pc freescale - p1_p2_rdb_pc:P1021RDB,SDCARD
P1021RDB-PC_SPIFLASH powerpc mpc85xx p1_p2_rdb_pc freescale - p1_p2_rdb_pc:P1021RDB,SPIFLASH
P1022DS powerpc mpc85xx p1022ds freescale
+P1022DS_NAND powerpc mpc85xx p1022ds freescale - P1022DS:NAND
+P1022DS_36BIT_NAND powerpc mpc85xx p1022ds freescale - P1022DS:36BIT,NAND
P1022DS_SPIFLASH powerpc mpc85xx p1022ds freescale - P1022DS:SPIFLASH
P1022DS_36BIT_SPIFLASH powerpc mpc85xx p1022ds freescale - P1022DS:36BIT,SPIFLASH
P1022DS_SDCARD powerpc mpc85xx p1022ds freescale - P1022DS:SDCARD
@@ -1013,6 +1015,7 @@ JSE powerpc ppc4xx jse
korat powerpc ppc4xx
korat_perm powerpc ppc4xx korat - - korat:KORAT_PERMANENT
lwmon5 powerpc ppc4xx
+lcd4_lwmon5 powerpc ppc4xx lwmon5 - - lwmon5:LCD4_LWMON5
pcs440ep powerpc ppc4xx
quad100hd powerpc ppc4xx
sbc405 powerpc ppc4xx
diff --git a/common/board_f.c b/common/board_f.c
index 7698891..32e59fa 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -31,6 +31,7 @@
#include <version.h>
#include <environment.h>
#include <fdtdec.h>
+#include <fs.h>
#if defined(CONFIG_CMD_IDE)
#include <ide.h>
#endif
@@ -49,9 +50,11 @@
#include <mpc5xxx.h>
#endif
+#include <os.h>
#include <post.h>
#include <spi.h>
#include <watchdog.h>
+#include <asm/errno.h>
#include <asm/io.h>
#ifdef CONFIG_MP
#include <asm/mp.h>
@@ -61,6 +64,9 @@
#include <asm/init_helpers.h>
#include <asm/relocate.h>
#endif
+#ifdef CONFIG_SANDBOX
+#include <asm/state.h>
+#endif
#include <linux/compiler.h>
/*
@@ -155,6 +161,7 @@ static int init_baud_rate(void)
static int display_text_info(void)
{
+#ifndef CONFIG_SANDBOX
ulong bss_start, bss_end;
#ifdef CONFIG_SYS_SYM_OFFSETS
@@ -166,6 +173,7 @@ static int display_text_info(void)
#endif
debug("U-Boot code: %08X -> %08lX BSS: -> %08lX\n",
CONFIG_SYS_TEXT_BASE, bss_start, bss_end);
+#endif
#ifdef CONFIG_MODEM_SUPPORT
debug("Modem Support enabled\n");
@@ -284,6 +292,8 @@ static int setup_mon_len(void)
{
#ifdef CONFIG_SYS_SYM_OFFSETS
gd->mon_len = _bss_end_ofs;
+#elif defined(CONFIG_SANDBOX)
+ gd->mon_len = (ulong)&_end - (ulong)_init;
#else
/* TODO: use (ulong)&__bss_end - (ulong)&__text_start; ? */
gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
@@ -296,6 +306,66 @@ __weak int arch_cpu_init(void)
return 0;
}
+#ifdef CONFIG_OF_HOSTFILE
+
+#define CHECK(x) err = (x); if (err) goto failed;
+
+/* Create an empty device tree blob */
+static int make_empty_fdt(void *fdt)
+{
+ int err;
+
+ CHECK(fdt_create(fdt, 256));
+ CHECK(fdt_finish_reservemap(fdt));
+ CHECK(fdt_begin_node(fdt, ""));
+ CHECK(fdt_end_node(fdt));
+ CHECK(fdt_finish(fdt));
+
+ return 0;
+failed:
+ printf("Unable to create empty FDT: %s\n", fdt_strerror(err));
+ return -EACCES;
+}
+
+static int read_fdt_from_file(void)
+{
+ struct sandbox_state *state = state_get_current();
+ void *blob;
+ int size;
+ int err;
+
+ blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0);
+ if (!state->fdt_fname) {
+ err = make_empty_fdt(blob);
+ if (!err)
+ goto done;
+ return err;
+ }
+ err = fs_set_blk_dev("host", NULL, FS_TYPE_SANDBOX);
+ if (err)
+ return err;
+ size = fs_read(state->fdt_fname, CONFIG_SYS_FDT_LOAD_ADDR, 0, 0);
+ if (size < 0)
+ return -EIO;
+
+done:
+ gd->fdt_blob = blob;
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_SANDBOX
+static int setup_ram_buf(void)
+{
+ gd->arch.ram_buf = os_malloc(CONFIG_SYS_SDRAM_SIZE);
+ assert(gd->arch.ram_buf);
+ gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+
+ return 0;
+}
+#endif
+
static int setup_fdt(void)
{
#ifdef CONFIG_OF_EMBED
@@ -308,6 +378,11 @@ static int setup_fdt(void)
# else
gd->fdt_blob = (ulong *)&_end;
# endif
+#elif defined(CONFIG_OF_HOSTFILE)
+ if (read_fdt_from_file()) {
+ puts("Failed to read control FDT\n");
+ return -1;
+ }
#endif
/* Allow the early environment to override the fdt address */
gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
@@ -470,7 +545,7 @@ static int reserve_malloc(void)
static int reserve_board(void)
{
gd->dest_addr_sp -= sizeof(bd_t);
- gd->bd = (bd_t *)gd->dest_addr_sp;
+ gd->bd = (bd_t *)map_sysmem(gd->dest_addr_sp, sizeof(bd_t));
memset(gd->bd, '\0', sizeof(bd_t));
debug("Reserving %zu Bytes for Board Info at: %08lx\n",
sizeof(bd_t), gd->dest_addr_sp);
@@ -489,7 +564,7 @@ static int setup_machine(void)
static int reserve_global_data(void)
{
gd->dest_addr_sp -= sizeof(gd_t);
- gd->new_gd = (gd_t *)gd->dest_addr_sp;
+ gd->new_gd = (gd_t *)map_sysmem(gd->dest_addr_sp, sizeof(gd_t));
debug("Reserving %zu Bytes for Global Data at: %08lx\n",
sizeof(gd_t), gd->dest_addr_sp);
return 0;
@@ -506,9 +581,9 @@ static int reserve_fdt(void)
gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
gd->dest_addr_sp -= gd->fdt_size;
- gd->new_fdt = (void *)gd->dest_addr_sp;
- debug("Reserving %lu Bytes for FDT at: %p\n",
- gd->fdt_size, gd->new_fdt);
+ gd->new_fdt = map_sysmem(gd->dest_addr_sp, gd->fdt_size);
+ debug("Reserving %lu Bytes for FDT at: %08lx\n",
+ gd->fdt_size, gd->dest_addr_sp);
}
return 0;
@@ -709,8 +784,9 @@ static int setup_reloc(void)
memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
debug("Relocation Offset is: %08lx\n", gd->reloc_off);
- debug("Relocating to %08lx, new gd at %p, sp at %08lx\n",
- gd->dest_addr, gd->new_gd, gd->dest_addr_sp);
+ debug("Relocating to %08lx, new gd at %08lx, sp at %08lx\n",
+ gd->dest_addr, (ulong)map_to_sysmem(gd->new_gd),
+ gd->dest_addr_sp);
return 0;
}
@@ -736,6 +812,8 @@ static int jump_to_copy(void)
* (CPU cache)
*/
board_init_f_r_trampoline(gd->start_addr_sp);
+#elif defined(CONFIG_SANDBOX)
+ board_init_r(gd->new_gd, 0);
#else
relocate_code(gd->dest_addr_sp, gd->new_gd, gd->dest_addr);
#endif
@@ -755,9 +833,12 @@ static int mark_bootstage(void)
static init_fnc_t init_sequence_f[] = {
#if !defined(CONFIG_CPM2) && !defined(CONFIG_MPC512X) && \
!defined(CONFIG_MPC83xx) && !defined(CONFIG_MPC85xx) && \
- !defined(CONFIG_MPC86xx)
+ !defined(CONFIG_MPC86xx) && !defined(CONFIG_X86)
zero_global_data,
#endif
+#ifdef CONFIG_SANDBOX
+ setup_ram_buf,
+#endif
setup_fdt,
setup_mon_len,
#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
@@ -816,8 +897,11 @@ static init_fnc_t init_sequence_f[] = {
init_baud_rate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
-#if defined(CONFIG_X86) && defined(CONFIG_OF_CONTROL)
- prepare_fdt, /* TODO(sjg@chromium.org): remove */
+#ifdef CONFIG_SANDBOX
+ sandbox_early_getopt_check,
+#endif
+#ifdef CONFIG_OF_CONTROL
+ fdtdec_prepare_fdt,
#endif
display_options, /* say that we are here */
display_text_info, /* show debugging info if required */
@@ -856,8 +940,7 @@ static init_fnc_t init_sequence_f[] = {
#endif
#ifdef CONFIG_X86
dram_init_f, /* configure available RAM banks */
- /* x86 would prefer that this happens after relocation */
- dram_init,
+ calculate_relocation_address,
#endif
announce_dram_init,
/* TODO: unify all these dram functions? */
@@ -1004,9 +1087,3 @@ void board_init_f_r(void)
hang();
}
#endif /* CONFIG_X86 */
-
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;);
-}
diff --git a/common/board_r.c b/common/board_r.c
index 9605f80..f801e41 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -136,7 +136,7 @@ static int initr_reloc_global_data(void)
{
#ifdef CONFIG_SYS_SYM_OFFSETS
monitor_flash_len = _end_ofs;
-#else
+#elif !defined(CONFIG_SANDBOX)
monitor_flash_len = (ulong)&__init_end - gd->dest_addr;
#endif
#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
@@ -264,7 +264,8 @@ static int initr_malloc(void)
/* The malloc area is immediately below the monitor copy in DRAM */
malloc_start = gd->dest_addr - TOTAL_MALLOC_LEN;
- mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN);
+ mem_malloc_init((ulong)map_sysmem(malloc_start, TOTAL_MALLOC_LEN),
+ TOTAL_MALLOC_LEN);
return 0;
}
@@ -691,6 +692,9 @@ static int initr_modem(void)
static int run_main_loop(void)
{
+#ifdef CONFIG_SANDBOX
+ sandbox_main_loop_init();
+#endif
/* main_loop() can return to retry autoboot, if so just run it again */
for (;;)
main_loop();
@@ -722,9 +726,6 @@ init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_CLOCKS
set_cpu_clk_info, /* Setup clock information */
#endif
-#ifdef CONFIG_X86
- init_bd_struct_r,
-#endif
initr_reloc_global_data,
initr_serial,
initr_announce,
diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c
index ac77a08..edefd77 100644
--- a/common/cmd_fdt.c
+++ b/common/cmd_fdt.c
@@ -31,6 +31,7 @@
#include <asm/global_data.h>
#include <libfdt.h>
#include <fdt_support.h>
+#include <asm/io.h>
#define MAX_LEVEL 32 /* how deeply nested we will go */
#define SCRATCHPAD 1024 /* bytes of scratchpad memory */
@@ -43,7 +44,7 @@
*/
DECLARE_GLOBAL_DATA_PTR;
-static int fdt_valid(void);
+static int fdt_valid(struct fdt_header **blobp);
static int fdt_parse_prop(char *const*newval, int count, char *data, int *len);
static int fdt_print(const char *pathp, char *prop, int depth);
static int is_printable_string(const void *data, int len);
@@ -55,7 +56,10 @@ struct fdt_header *working_fdt;
void set_working_fdt_addr(void *addr)
{
- working_fdt = addr;
+ void *buf;
+
+ buf = map_sysmem((ulong)addr, 0);
+ working_fdt = buf;
setenv_addr("fdtaddr", addr);
}
@@ -100,40 +104,59 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
*/
if (argv[1][0] == 'a') {
unsigned long addr;
+ int control = 0;
+ struct fdt_header *blob;
/*
* Set the address [and length] of the fdt.
*/
- if (argc == 2) {
- if (!fdt_valid()) {
+ argc -= 2;
+ argv += 2;
+/* Temporary #ifdef - some archs don't have fdt_blob yet */
+#ifdef CONFIG_OF_CONTROL
+ if (argc && !strcmp(*argv, "-c")) {
+ control = 1;
+ argc--;
+ argv++;
+ }
+#endif
+ if (argc == 0) {
+ if (control)
+ blob = (struct fdt_header *)gd->fdt_blob;
+ else
+ blob = working_fdt;
+ if (!blob || !fdt_valid(&blob))
return 1;
- }
- printf("The address of the fdt is %p\n", working_fdt);
+ printf("The address of the fdt is %#08lx\n",
+ control ? (ulong)blob :
+ getenv_hex("fdtaddr", 0));
return 0;
}
- addr = simple_strtoul(argv[2], NULL, 16);
- set_working_fdt_addr((void *)addr);
-
- if (!fdt_valid()) {
+ addr = simple_strtoul(argv[0], NULL, 16);
+ blob = map_sysmem(addr, 0);
+ if (!fdt_valid(&blob))
return 1;
- }
+ if (control)
+ gd->fdt_blob = blob;
+ else
+ set_working_fdt_addr(blob);
- if (argc >= 4) {
+ if (argc >= 2) {
int len;
int err;
/*
* Optional new length
*/
- len = simple_strtoul(argv[3], NULL, 16);
- if (len < fdt_totalsize(working_fdt)) {
+ len = simple_strtoul(argv[1], NULL, 16);
+ if (len < fdt_totalsize(blob)) {
printf ("New length %d < existing length %d, "
"ignoring.\n",
- len, fdt_totalsize(working_fdt));
+ len, fdt_totalsize(blob));
} else {
/*
* Open in place with a new length.
*/
- err = fdt_open_into(working_fdt, working_fdt, len);
+ err = fdt_open_into(blob, blob, len);
if (err != 0) {
printf ("libfdt fdt_open_into(): %s\n",
fdt_strerror(err));
@@ -167,9 +190,8 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
* Set the address and length of the fdt.
*/
working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16);
- if (!fdt_valid()) {
+ if (!fdt_valid(&working_fdt))
return 1;
- }
newaddr = (struct fdt_header *)simple_strtoul(argv[3],NULL,16);
@@ -592,16 +614,23 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
/****************************************************************************/
-static int fdt_valid(void)
+/**
+ * fdt_valid() - Check if an FDT is valid. If not, change it to NULL
+ *
+ * @blobp: Pointer to FDT pointer
+ * @return 1 if OK, 0 if bad (in which case *blobp is set to NULL)
+ */
+static int fdt_valid(struct fdt_header **blobp)
{
- int err;
+ const void *blob = *blobp;
+ int err;
- if (working_fdt == NULL) {
+ if (blob == NULL) {
printf ("The address of the fdt is invalid (NULL).\n");
return 0;
}
- err = fdt_check_header(working_fdt);
+ err = fdt_check_header(blob);
if (err == 0)
return 1; /* valid */
@@ -611,23 +640,21 @@ static int fdt_valid(void)
* Be more informative on bad version.
*/
if (err == -FDT_ERR_BADVERSION) {
- if (fdt_version(working_fdt) <
+ if (fdt_version(blob) <
FDT_FIRST_SUPPORTED_VERSION) {
printf (" - too old, fdt %d < %d",
- fdt_version(working_fdt),
+ fdt_version(blob),
FDT_FIRST_SUPPORTED_VERSION);
- working_fdt = NULL;
}
- if (fdt_last_comp_version(working_fdt) >
+ if (fdt_last_comp_version(blob) >
FDT_LAST_SUPPORTED_VERSION) {
printf (" - too new, fdt %d > %d",
- fdt_version(working_fdt),
+ fdt_version(blob),
FDT_LAST_SUPPORTED_VERSION);
- working_fdt = NULL;
}
- return 0;
}
printf("\n");
+ *blobp = NULL;
return 0;
}
return 1;
@@ -958,7 +985,7 @@ static int fdt_print(const char *pathp, char *prop, int depth)
/********************************************************************/
#ifdef CONFIG_SYS_LONGHELP
static char fdt_help_text[] =
- "addr <addr> [<length>] - Set the fdt location to <addr>\n"
+ "addr [-c] <addr> [<length>] - Set the [control] fdt location to <addr>\n"
#ifdef CONFIG_OF_BOARD_SETUP
"fdt boardsetup - Do board-specific set up\n"
#endif
diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c
index 1834246..5e1d037 100644
--- a/common/cmd_fpga.c
+++ b/common/cmd_fpga.c
@@ -27,14 +27,11 @@
*/
#include <common.h>
#include <command.h>
-#if defined(CONFIG_CMD_NET)
-#include <net.h>
-#endif
#include <fpga.h>
#include <malloc.h>
/* Local functions */
-static int fpga_get_op (char *opstr);
+static int fpga_get_op(char *opstr);
/* Local defines */
#define FPGA_NONE -1
@@ -44,102 +41,6 @@ static int fpga_get_op (char *opstr);
#define FPGA_DUMP 3
#define FPGA_LOADMK 4
-/* Convert bitstream data and load into the fpga */
-int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size)
-{
-#if defined(CONFIG_FPGA_XILINX)
- unsigned int length;
- unsigned int swapsize;
- char buffer[80];
- unsigned char *dataptr;
- unsigned int i;
- int rc;
-
- dataptr = (unsigned char *)fpgadata;
-
- /* skip the first bytes of the bitsteam, their meaning is unknown */
- length = (*dataptr << 8) + *(dataptr+1);
- dataptr+=2;
- dataptr+=length;
-
- /* get design name (identifier, length, string) */
- length = (*dataptr << 8) + *(dataptr+1);
- dataptr+=2;
- if (*dataptr++ != 0x61) {
- debug("%s: Design name identifier not recognized "
- "in bitstream\n",
- __func__);
- return FPGA_FAIL;
- }
-
- length = (*dataptr << 8) + *(dataptr+1);
- dataptr+=2;
- for(i=0;i<length;i++)
- buffer[i] = *dataptr++;
-
- printf(" design filename = \"%s\"\n", buffer);
-
- /* get part number (identifier, length, string) */
- if (*dataptr++ != 0x62) {
- printf("%s: Part number identifier not recognized "
- "in bitstream\n",
- __func__);
- return FPGA_FAIL;
- }
-
- length = (*dataptr << 8) + *(dataptr+1);
- dataptr+=2;
- for(i=0;i<length;i++)
- buffer[i] = *dataptr++;
- printf(" part number = \"%s\"\n", buffer);
-
- /* get date (identifier, length, string) */
- if (*dataptr++ != 0x63) {
- printf("%s: Date identifier not recognized in bitstream\n",
- __func__);
- return FPGA_FAIL;
- }
-
- length = (*dataptr << 8) + *(dataptr+1);
- dataptr+=2;
- for(i=0;i<length;i++)
- buffer[i] = *dataptr++;
- printf(" date = \"%s\"\n", buffer);
-
- /* get time (identifier, length, string) */
- if (*dataptr++ != 0x64) {
- printf("%s: Time identifier not recognized in bitstream\n",
- __func__);
- return FPGA_FAIL;
- }
-
- length = (*dataptr << 8) + *(dataptr+1);
- dataptr+=2;
- for(i=0;i<length;i++)
- buffer[i] = *dataptr++;
- printf(" time = \"%s\"\n", buffer);
-
- /* get fpga data length (identifier, length) */
- if (*dataptr++ != 0x65) {
- printf("%s: Data length identifier not recognized in bitstream\n",
- __func__);
- return FPGA_FAIL;
- }
- swapsize = ((unsigned int) *dataptr <<24) +
- ((unsigned int) *(dataptr+1) <<16) +
- ((unsigned int) *(dataptr+2) <<8 ) +
- ((unsigned int) *(dataptr+3) ) ;
- dataptr+=4;
- printf(" bytes in bitstream = %d\n", swapsize);
-
- rc = fpga_load(dev, dataptr, swapsize);
- return rc;
-#else
- printf("Bitstream support only for Xilinx devices\n");
- return FPGA_FAIL;
-#endif
-}
-
/* ------------------------------------------------------------------------- */
/* command form:
* fpga <op> <device number> <data addr> <datasize>
@@ -148,81 +49,81 @@ int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size)
* If there is no data addr field, the fpgadata environment variable is used.
* The info command requires no data address field.
*/
-int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
int op, dev = FPGA_INVALID_DEVICE;
size_t data_size = 0;
void *fpga_data = NULL;
- char *devstr = getenv ("fpga");
- char *datastr = getenv ("fpgadata");
+ char *devstr = getenv("fpga");
+ char *datastr = getenv("fpgadata");
int rc = FPGA_FAIL;
int wrong_parms = 0;
-#if defined (CONFIG_FIT)
+#if defined(CONFIG_FIT)
const char *fit_uname = NULL;
ulong fit_addr;
#endif
if (devstr)
- dev = (int) simple_strtoul (devstr, NULL, 16);
+ dev = (int) simple_strtoul(devstr, NULL, 16);
if (datastr)
- fpga_data = (void *) simple_strtoul (datastr, NULL, 16);
+ fpga_data = (void *)simple_strtoul(datastr, NULL, 16);
switch (argc) {
case 5: /* fpga <op> <dev> <data> <datasize> */
- data_size = simple_strtoul (argv[4], NULL, 16);
+ data_size = simple_strtoul(argv[4], NULL, 16);
case 4: /* fpga <op> <dev> <data> */
#if defined(CONFIG_FIT)
- if (fit_parse_subimage (argv[3], (ulong)fpga_data,
- &fit_addr, &fit_uname)) {
+ if (fit_parse_subimage(argv[3], (ulong)fpga_data,
+ &fit_addr, &fit_uname)) {
fpga_data = (void *)fit_addr;
- debug("* fpga: subimage '%s' from FIT image "
- "at 0x%08lx\n",
- fit_uname, fit_addr);
+ debug("* fpga: subimage '%s' from FIT image ",
+ fit_uname);
+ debug("at 0x%08lx\n", fit_addr);
} else
#endif
{
- fpga_data = (void *) simple_strtoul (argv[3], NULL, 16);
+ fpga_data = (void *)simple_strtoul(argv[3], NULL, 16);
debug("* fpga: cmdline image address = 0x%08lx\n",
- (ulong)fpga_data);
+ (ulong)fpga_data);
}
- debug("%s: fpga_data = 0x%x\n", __func__, (uint) fpga_data);
+ debug("%s: fpga_data = 0x%x\n", __func__, (uint)fpga_data);
case 3: /* fpga <op> <dev | data addr> */
- dev = (int) simple_strtoul (argv[2], NULL, 16);
+ dev = (int)simple_strtoul(argv[2], NULL, 16);
debug("%s: device = %d\n", __func__, dev);
/* FIXME - this is a really weak test */
- if ((argc == 3) && (dev > fpga_count ())) { /* must be buffer ptr */
+ if ((argc == 3) && (dev > fpga_count())) {
+ /* must be buffer ptr */
debug("%s: Assuming buffer pointer in arg 3\n",
- __func__);
+ __func__);
#if defined(CONFIG_FIT)
- if (fit_parse_subimage (argv[2], (ulong)fpga_data,
- &fit_addr, &fit_uname)) {
+ if (fit_parse_subimage(argv[2], (ulong)fpga_data,
+ &fit_addr, &fit_uname)) {
fpga_data = (void *)fit_addr;
- debug("* fpga: subimage '%s' from FIT image "
- "at 0x%08lx\n",
- fit_uname, fit_addr);
+ debug("* fpga: subimage '%s' from FIT image ",
+ fit_uname);
+ debug("at 0x%08lx\n", fit_addr);
} else
#endif
{
- fpga_data = (void *) dev;
- debug("* fpga: cmdline image address = "
- "0x%08lx\n", (ulong)fpga_data);
+ fpga_data = (void *)dev;
+ debug("* fpga: cmdline image addr = 0x%08lx\n",
+ (ulong)fpga_data);
}
debug("%s: fpga_data = 0x%x\n",
- __func__, (uint) fpga_data);
+ __func__, (uint)fpga_data);
dev = FPGA_INVALID_DEVICE; /* reset device num */
}
case 2: /* fpga <op> */
- op = (int) fpga_get_op (argv[1]);
+ op = (int)fpga_get_op(argv[1]);
break;
default:
- debug("%s: Too many or too few args (%d)\n",
- __func__, argc);
+ debug("%s: Too many or too few args (%d)\n", __func__, argc);
op = FPGA_NONE; /* force usage display */
break;
}
@@ -258,11 +159,11 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
return CMD_RET_USAGE;
case FPGA_INFO:
- rc = fpga_info (dev);
+ rc = fpga_info(dev);
break;
case FPGA_LOAD:
- rc = fpga_load (dev, fpga_data, data_size);
+ rc = fpga_load(dev, fpga_data, data_size);
break;
case FPGA_LOADB:
@@ -270,15 +171,16 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
break;
case FPGA_LOADMK:
- switch (genimg_get_format (fpga_data)) {
+ switch (genimg_get_format(fpga_data)) {
case IMAGE_FORMAT_LEGACY:
{
- image_header_t *hdr = (image_header_t *)fpga_data;
- ulong data;
+ image_header_t *hdr =
+ (image_header_t *)fpga_data;
+ ulong data;
- data = (ulong)image_get_data (hdr);
- data_size = image_get_data_size (hdr);
- rc = fpga_load (dev, (void *)data, data_size);
+ data = (ulong)image_get_data(hdr);
+ data_size = image_get_data_size(hdr);
+ rc = fpga_load(dev, (void *)data, data_size);
}
break;
#if defined(CONFIG_FIT)
@@ -289,95 +191,97 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
const void *fit_data;
if (fit_uname == NULL) {
- puts ("No FIT subimage unit name\n");
+ puts("No FIT subimage unit name\n");
return 1;
}
- if (!fit_check_format (fit_hdr)) {
- puts ("Bad FIT image format\n");
+ if (!fit_check_format(fit_hdr)) {
+ puts("Bad FIT image format\n");
return 1;
}
/* get fpga component image node offset */
- noffset = fit_image_get_node (fit_hdr, fit_uname);
+ noffset = fit_image_get_node(fit_hdr,
+ fit_uname);
if (noffset < 0) {
- printf ("Can't find '%s' FIT subimage\n", fit_uname);
+ printf("Can't find '%s' FIT subimage\n",
+ fit_uname);
return 1;
}
/* verify integrity */
- if (!fit_image_check_hashes (fit_hdr, noffset)) {
- puts ("Bad Data Hash\n");
+ if (!fit_image_check_hashes(fit_hdr, noffset)) {
+ puts("Bad Data Hash\n");
return 1;
}
/* get fpga subimage data address and length */
- if (fit_image_get_data (fit_hdr, noffset, &fit_data, &data_size)) {
- puts ("Could not find fpga subimage data\n");
+ if (fit_image_get_data(fit_hdr, noffset,
+ &fit_data, &data_size)) {
+ puts("Fpga subimage data not found\n");
return 1;
}
- rc = fpga_load (dev, fit_data, data_size);
+ rc = fpga_load(dev, fit_data, data_size);
}
break;
#endif
default:
- puts ("** Unknown image type\n");
+ puts("** Unknown image type\n");
rc = FPGA_FAIL;
break;
}
break;
case FPGA_DUMP:
- rc = fpga_dump (dev, fpga_data, data_size);
+ rc = fpga_dump(dev, fpga_data, data_size);
break;
default:
- printf ("Unknown operation\n");
+ printf("Unknown operation\n");
return CMD_RET_USAGE;
}
- return (rc);
+ return rc;
}
/*
* Map op to supported operations. We don't use a table since we
* would just have to relocate it from flash anyway.
*/
-static int fpga_get_op (char *opstr)
+static int fpga_get_op(char *opstr)
{
int op = FPGA_NONE;
- if (!strcmp ("info", opstr)) {
+ if (!strcmp("info", opstr))
op = FPGA_INFO;
- } else if (!strcmp ("loadb", opstr)) {
+ else if (!strcmp("loadb", opstr))
op = FPGA_LOADB;
- } else if (!strcmp ("load", opstr)) {
+ else if (!strcmp("load", opstr))
op = FPGA_LOAD;
- } else if (!strcmp ("loadmk", opstr)) {
+ else if (!strcmp("loadmk", opstr))
op = FPGA_LOADMK;
- } else if (!strcmp ("dump", opstr)) {
+ else if (!strcmp("dump", opstr))
op = FPGA_DUMP;
- }
- if (op == FPGA_NONE) {
- printf ("Unknown fpga operation \"%s\"\n", opstr);
- }
+ if (op == FPGA_NONE)
+ printf("Unknown fpga operation \"%s\"\n", opstr);
+
return op;
}
-U_BOOT_CMD (fpga, 6, 1, do_fpga,
- "loadable FPGA image support",
- "[operation type] [device number] [image address] [image size]\n"
- "fpga operations:\n"
- " dump\t[dev]\t\t\tLoad device to memory buffer\n"
- " info\t[dev]\t\t\tlist known device information\n"
- " load\t[dev] [address] [size]\tLoad device from memory buffer\n"
- " loadb\t[dev] [address] [size]\t"
- "Load device from bitstream buffer (Xilinx only)\n"
- " loadmk [dev] [address]\tLoad device generated with mkimage"
+U_BOOT_CMD(fpga, 6, 1, do_fpga,
+ "loadable FPGA image support",
+ "[operation type] [device number] [image address] [image size]\n"
+ "fpga operations:\n"
+ " dump\t[dev]\t\t\tLoad device to memory buffer\n"
+ " info\t[dev]\t\t\tlist known device information\n"
+ " load\t[dev] [address] [size]\tLoad device from memory buffer\n"
+ " loadb\t[dev] [address] [size]\t"
+ "Load device from bitstream buffer (Xilinx only)\n"
+ " loadmk [dev] [address]\tLoad device generated with mkimage"
#if defined(CONFIG_FIT)
- "\n"
- "\tFor loadmk operating on FIT format uImage address must include\n"
- "\tsubimage unit name in the form of addr:<subimg_uname>"
+ "\n"
+ "\tFor loadmk operating on FIT format uImage address must include\n"
+ "\tsubimage unit name in the form of addr:<subimg_uname>"
#endif
);
diff --git a/common/cmd_ide.c b/common/cmd_ide.c
index 0105bdb..78b4aa7 100644
--- a/common/cmd_ide.c
+++ b/common/cmd_ide.c
@@ -455,6 +455,8 @@ void ide_init(void)
ide_dev_desc[i].dev = i;
ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
ide_dev_desc[i].blksz = 0;
+ ide_dev_desc[i].log2blksz =
+ LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz));
ide_dev_desc[i].lba = 0;
ide_dev_desc[i].block_read = ide_read;
ide_dev_desc[i].block_write = ide_write;
@@ -806,6 +808,7 @@ static void ide_ident(block_dev_desc_t *dev_desc)
/* assuming HD */
dev_desc->type = DEV_TYPE_HARDDISK;
dev_desc->blksz = ATA_BLOCKSIZE;
+ dev_desc->log2blksz = LOG2(dev_desc->blksz);
dev_desc->lun = 0; /* just to fill something in... */
#if 0 /* only used to test the powersaving mode,
@@ -1448,6 +1451,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc)
dev_desc->lun = 0;
dev_desc->lba = 0;
dev_desc->blksz = 0;
+ dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz));
dev_desc->type = iobuf[0] & 0x1f;
if ((iobuf[1] & 0x80) == 0x80)
@@ -1492,6 +1496,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc)
dev_desc->blksz = ((unsigned long) iobuf[4] << 24) +
((unsigned long) iobuf[5] << 16) +
((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]);
+ dev_desc->log2blksz = LOG2(dev_desc->blksz);
#ifdef CONFIG_LBA48
/* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
dev_desc->lba48 = 0;
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 9f3d6c5..7d82469 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -106,7 +106,7 @@ static void print_mmcinfo(struct mmc *mmc)
printf("Rd Block Len: %d\n", mmc->read_bl_len);
printf("%s version %d.%d\n", IS_SD(mmc) ? "SD" : "MMC",
- (mmc->version >> 4) & 0xf, mmc->version & 0xf);
+ (mmc->version >> 8) & 0xf, mmc->version & 0xff);
printf("High Capacity: %s\n", mmc->high_capacity ? "Yes" : "No");
puts("Capacity: ");
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index afa128e..f8dc38e 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2000-2010
+ * (C) Copyright 2000-2013
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
@@ -96,7 +96,7 @@ int get_env_id(void)
static int env_print(char *name, int flag)
{
char *res = NULL;
- size_t len;
+ ssize_t len;
if (name) { /* print a single name */
ENTRY e, *ep;
@@ -120,6 +120,7 @@ static int env_print(char *name, int flag)
}
/* should never happen */
+ printf("## Error: cannot export environment\n");
return 0;
}
@@ -163,31 +164,57 @@ static int do_env_print(cmd_tbl_t *cmdtp, int flag, int argc,
static int do_env_grep(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
- ENTRY *match;
- unsigned char matched[env_htab.size / 8];
- int rcode = 1, arg = 1, idx;
+ char *res = NULL;
+ int len, grep_how, grep_what;
if (argc < 2)
return CMD_RET_USAGE;
- memset(matched, 0, env_htab.size / 8);
+ grep_how = H_MATCH_SUBSTR; /* default: substring search */
+ grep_what = H_MATCH_BOTH; /* default: grep names and values */
- while (arg <= argc) {
- idx = 0;
- while ((idx = hstrstr_r(argv[arg], idx, &match, &env_htab))) {
- if (!(matched[idx / 8] & (1 << (idx & 7)))) {
- puts(match->key);
- puts("=");
- puts(match->data);
- puts("\n");
+ while (argc > 1 && **(argv + 1) == '-') {
+ char *arg = *++argv;
+
+ --argc;
+ while (*++arg) {
+ switch (*arg) {
+#ifdef CONFIG_REGEX
+ case 'e': /* use regex matching */
+ grep_how = H_MATCH_REGEX;
+ break;
+#endif
+ case 'n': /* grep for name */
+ grep_what = H_MATCH_KEY;
+ break;
+ case 'v': /* grep for value */
+ grep_what = H_MATCH_DATA;
+ break;
+ case 'b': /* grep for both */
+ grep_what = H_MATCH_BOTH;
+ break;
+ case '-':
+ goto DONE;
+ default:
+ return CMD_RET_USAGE;
}
- matched[idx / 8] |= 1 << (idx & 7);
- rcode = 0;
}
- arg++;
}
- return rcode;
+DONE:
+ len = hexport_r(&env_htab, '\n',
+ flag | grep_what | grep_how,
+ &res, 0, argc, argv);
+
+ if (len > 0) {
+ puts(res);
+ free(res);
+ }
+
+ if (len < 2)
+ return 1;
+
+ return 0;
}
#endif
#endif /* CONFIG_SPL_BUILD */
@@ -314,6 +341,21 @@ int setenv_hex(const char *varname, ulong value)
return setenv(varname, str);
}
+ulong getenv_hex(const char *varname, ulong default_val)
+{
+ const char *s;
+ ulong value;
+ char *endp;
+
+ s = getenv(varname);
+ if (s)
+ value = simple_strtoul(s, &endp, 16);
+ if (!s || endp == s)
+ return default_val;
+
+ return value;
+}
+
#ifndef CONFIG_SPL_BUILD
static int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
@@ -876,7 +918,9 @@ NXTARG: ;
argv++;
if (sep) { /* export as text file */
- len = hexport_r(&env_htab, sep, 0, &addr, size, argc, argv);
+ len = hexport_r(&env_htab, sep,
+ H_MATCH_KEY | H_MATCH_IDENT,
+ &addr, size, argc, argv);
if (len < 0) {
error("Cannot export environment: errno = %d\n", errno);
return 1;
@@ -894,7 +938,9 @@ NXTARG: ;
else /* export as raw binary data */
res = addr;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, argc, argv);
+ len = hexport_r(&env_htab, '\0',
+ H_MATCH_KEY | H_MATCH_IDENT,
+ &res, ENV_SIZE, argc, argv);
if (len < 0) {
error("Cannot export environment: errno = %d\n", errno);
return 1;
@@ -1113,7 +1159,11 @@ static char env_help_text[] =
"env flags - print variables that have non-default flags\n"
#endif
#if defined(CONFIG_CMD_GREPENV)
- "env grep string [...] - search environment\n"
+#ifdef CONFIG_REGEX
+ "env grep [-e] [-n | -v | -b] string [...] - search environment\n"
+#else
+ "env grep [-n | -v | -b] string [...] - search environment\n"
+#endif
#endif
#if defined(CONFIG_CMD_IMPORTENV)
"env import [-d] [-t | -b | -c] addr [size] - import environment\n"
@@ -1160,8 +1210,17 @@ U_BOOT_CMD_COMPLETE(
U_BOOT_CMD_COMPLETE(
grepenv, CONFIG_SYS_MAXARGS, 0, do_env_grep,
"search environment variables",
- "string ...\n"
- " - list environment name=value pairs matching 'string'",
+#ifdef CONFIG_REGEX
+ "[-e] [-n | -v | -b] string ...\n"
+#else
+ "[-n | -v | -b] string ...\n"
+#endif
+ " - list environment name=value pairs matching 'string'\n"
+#ifdef CONFIG_REGEX
+ " \"-e\": enable regular expressions;\n"
+#endif
+ " \"-n\": search variable names; \"-v\": search values;\n"
+ " \"-b\": search both names and values (default)",
var_complete
);
#endif
diff --git a/common/cmd_sandbox.c b/common/cmd_sandbox.c
index 206a486..a28a844 100644
--- a/common/cmd_sandbox.c
+++ b/common/cmd_sandbox.c
@@ -32,9 +32,16 @@ static int do_sandbox_ls(cmd_tbl_t *cmdtp, int flag, int argc,
return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
}
+static int do_sandbox_save(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX, 16);
+}
+
static cmd_tbl_t cmd_sandbox_sub[] = {
- U_BOOT_CMD_MKENT(load, 3, 0, do_sandbox_load, "", ""),
+ U_BOOT_CMD_MKENT(load, 7, 0, do_sandbox_load, "", ""),
U_BOOT_CMD_MKENT(ls, 3, 0, do_sandbox_ls, "", ""),
+ U_BOOT_CMD_MKENT(save, 6, 0, do_sandbox_save, "", ""),
};
static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc,
@@ -56,8 +63,11 @@ static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc,
}
U_BOOT_CMD(
- sb, 6, 1, do_sandbox,
+ sb, 8, 1, do_sandbox,
"Miscellaneous sandbox commands",
- "load host <addr> <filename> [<bytes> <offset>] - load a file from host\n"
- "sb ls host <filename> - save a file to host"
+ "load host <dev> <addr> <filename> [<bytes> <offset>] - "
+ "load a file from host\n"
+ "sb ls host <filename> - list files on host\n"
+ "sb save host <dev> <filename> <addr> <bytes> [<offset>] - "
+ "save a file to host\n"
);
diff --git a/common/cmd_sata.c b/common/cmd_sata.c
index 8d57285..5a57a37 100644
--- a/common/cmd_sata.c
+++ b/common/cmd_sata.c
@@ -44,6 +44,7 @@ int __sata_initialize(void)
sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
sata_dev_desc[i].lba = 0;
sata_dev_desc[i].blksz = 512;
+ sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);
sata_dev_desc[i].block_read = sata_read;
sata_dev_desc[i].block_write = sata_write;
diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c
index 13b3d99..294d9f5 100644
--- a/common/cmd_scsi.c
+++ b/common/cmd_scsi.c
@@ -106,6 +106,8 @@ void scsi_scan(int mode)
scsi_dev_desc[i].lun=0xff;
scsi_dev_desc[i].lba=0;
scsi_dev_desc[i].blksz=0;
+ scsi_dev_desc[i].log2blksz =
+ LOG2_INVALID(typeof(scsi_dev_desc[i].log2blksz));
scsi_dev_desc[i].type=DEV_TYPE_UNKNOWN;
scsi_dev_desc[i].vendor[0]=0;
scsi_dev_desc[i].product[0]=0;
@@ -166,6 +168,8 @@ void scsi_scan(int mode)
}
scsi_dev_desc[scsi_max_devs].lba=capacity;
scsi_dev_desc[scsi_max_devs].blksz=blksz;
+ scsi_dev_desc[scsi_max_devs].log2blksz =
+ LOG2(scsi_dev_desc[scsi_max_devs].blksz);
scsi_dev_desc[scsi_max_devs].type=perq;
init_part(&scsi_dev_desc[scsi_max_devs]);
removable:
diff --git a/common/cmd_setexpr.c b/common/cmd_setexpr.c
index 7a38e94..93cb255 100644
--- a/common/cmd_setexpr.c
+++ b/common/cmd_setexpr.c
@@ -1,5 +1,6 @@
/*
* Copyright 2008 Freescale Semiconductor, Inc.
+ * Copyright 2013 Wolfgang Denk <wd@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -50,28 +51,295 @@ static ulong get_arg(char *s, int w)
}
}
+#ifdef CONFIG_REGEX
+
+#include <slre.h>
+
+#define SLRE_BUFSZ 16384
+#define SLRE_PATSZ 4096
+
+/*
+ * memstr - Find the first substring in memory
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ *
+ * Similar to and based on strstr(),
+ * but strings do not need to be NUL terminated.
+ */
+static char *memstr(const char *s1, int l1, const char *s2, int l2)
+{
+ if (!l2)
+ return (char *)s1;
+
+ while (l1 >= l2) {
+ l1--;
+ if (!memcmp(s1, s2, l2))
+ return (char *)s1;
+ s1++;
+ }
+ return NULL;
+}
+
+static char *substitute(char *string, /* string buffer */
+ int *slen, /* current string length */
+ int ssize, /* string bufer size */
+ const char *old,/* old (replaced) string */
+ int olen, /* length of old string */
+ const char *new,/* new (replacement) string */
+ int nlen) /* length of new string */
+{
+ char *p = memstr(string, *slen, old, olen);
+
+ if (p == NULL)
+ return NULL;
+
+ debug("## Match at pos %ld: match len %d, subst len %d\n",
+ (long)(p - string), olen, nlen);
+
+ /* make sure replacement matches */
+ if (*slen + nlen - olen > ssize) {
+ printf("## error: substitution buffer overflow\n");
+ return NULL;
+ }
+
+ /* move tail if needed */
+ if (olen != nlen) {
+ int tail, len;
+
+ len = (olen > nlen) ? olen : nlen;
+
+ tail = ssize - (p + len - string);
+
+ debug("## tail len %d\n", tail);
+
+ memmove(p + nlen, p + olen, tail);
+ }
+
+ /* insert substitue */
+ memcpy(p, new, nlen);
+
+ *slen += nlen - olen;
+
+ return p + nlen;
+}
+
+/*
+ * Perform regex operations on a environment variable
+ *
+ * Returns 0 if OK, 1 in case of errors.
+ */
+static int regex_sub(const char *name,
+ const char *r, const char *s, const char *t,
+ int global)
+{
+ struct slre slre;
+ char data[SLRE_BUFSZ];
+ char *datap = data;
+ const char *value;
+ int res, len, nlen, loop;
+
+ if (name == NULL)
+ return 1;
+
+ if (slre_compile(&slre, r) == 0) {
+ printf("Error compiling regex: %s\n", slre.err_str);
+ return 1;
+ }
+
+ if (t == NULL) {
+ value = getenv(name);
+
+ if (value == NULL) {
+ printf("## Error: variable \"%s\" not defined\n", name);
+ return 1;
+ }
+ t = value;
+ }
+
+ debug("REGEX on %s=%s\n", name, t);
+ debug("REGEX=\"%s\", SUBST=\"%s\", GLOBAL=%d\n",
+ r, s ? s : "<NULL>", global);
+
+ len = strlen(t);
+ if (len + 1 > SLRE_BUFSZ) {
+ printf("## error: subst buffer overflow: have %d, need %d\n",
+ SLRE_BUFSZ, len + 1);
+ return 1;
+ }
+
+ strcpy(data, t);
+
+ if (s == NULL)
+ nlen = 0;
+ else
+ nlen = strlen(s);
+
+ for (loop = 0;; loop++) {
+ struct cap caps[slre.num_caps + 2];
+ char nbuf[SLRE_PATSZ];
+ const char *old;
+ char *np;
+ int i, olen;
+
+ (void) memset(caps, 0, sizeof(caps));
+
+ res = slre_match(&slre, datap, len, caps);
+
+ debug("Result: %d\n", res);
+
+ for (i = 0; i < slre.num_caps; i++) {
+ if (caps[i].len > 0) {
+ debug("Substring %d: [%.*s]\n", i,
+ caps[i].len, caps[i].ptr);
+ }
+ }
+
+ if (res == 0) {
+ if (loop == 0) {
+ printf("%s: No match\n", t);
+ return 1;
+ } else {
+ break;
+ }
+ }
+
+ debug("## MATCH ## %s\n", data);
+
+ if (s == NULL) {
+ printf("%s=%s\n", name, t);
+ return 1;
+ }
+
+ old = caps[0].ptr;
+ olen = caps[0].len;
+
+ if (nlen + 1 >= SLRE_PATSZ) {
+ printf("## error: pattern buffer overflow: have %d, need %d\n",
+ SLRE_BUFSZ, nlen + 1);
+ return 1;
+ }
+ strcpy(nbuf, s);
+
+ debug("## SUBST(1) ## %s\n", nbuf);
+
+ /*
+ * Handle back references
+ *
+ * Support for \0 ... \9, where \0 is the
+ * whole matched pattern (similar to &).
+ *
+ * Implementation is a bit simpleminded as
+ * backrefs are substituted sequentially, one
+ * by one. This will lead to somewhat
+ * unexpected results if the replacement
+ * strings contain any \N strings then then
+ * may get substitued, too. We accept this
+ * restriction for the sake of simplicity.
+ */
+ for (i = 0; i < 10; ++i) {
+ char backref[2] = {
+ '\\',
+ '0',
+ };
+
+ if (caps[i].len == 0)
+ break;
+
+ backref[1] += i;
+
+ debug("## BACKREF %d: replace \"%.*s\" by \"%.*s\" in \"%s\"\n",
+ i,
+ 2, backref,
+ caps[i].len, caps[i].ptr,
+ nbuf);
+
+ for (np = nbuf;;) {
+ char *p = memstr(np, nlen, backref, 2);
+
+ if (p == NULL)
+ break;
+
+ np = substitute(np, &nlen,
+ SLRE_PATSZ,
+ backref, 2,
+ caps[i].ptr, caps[i].len);
+
+ if (np == NULL)
+ return 1;
+ }
+ }
+ debug("## SUBST(2) ## %s\n", nbuf);
+
+ datap = substitute(datap, &len, SLRE_BUFSZ,
+ old, olen,
+ nbuf, nlen);
+
+ if (datap == NULL)
+ return 1;
+
+ debug("## REMAINDER: %s\n", datap);
+
+ debug("## RESULT: %s\n", data);
+
+ if (!global)
+ break;
+ }
+ debug("## FINAL (now setenv()) : %s\n", data);
+
+ printf("%s=%s\n", name, data);
+
+ return setenv(name, data);
+}
+#endif
+
static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
ulong a, b;
ulong value;
int w;
- /* Validate arguments */
- if (argc != 5 && argc != 3)
- return CMD_RET_USAGE;
- if (argc == 5 && strlen(argv[3]) != 1)
+ /*
+ * We take 3, 5, or 6 arguments:
+ * 3 : setexpr name value
+ * 5 : setexpr name val1 op val2
+ * setexpr name [g]sub r s
+ * 6 : setexpr name [g]sub r s t
+ */
+
+ /* > 6 already tested by max command args */
+ if ((argc < 3) || (argc == 4))
return CMD_RET_USAGE;
w = cmd_get_data_size(argv[0], 4);
a = get_arg(argv[2], w);
+ /* plain assignment: "setexpr name value" */
if (argc == 3) {
setenv_hex(argv[1], a);
-
return 0;
}
+ /* 5 or 6 args (6 args only with [g]sub) */
+#ifdef CONFIG_REGEX
+ /*
+ * rexep handling: "setexpr name [g]sub r s [t]"
+ * with 5 args, "t" will be NULL
+ */
+ if (strcmp(argv[2], "gsub") == 0)
+ return regex_sub(argv[1], argv[3], argv[4], argv[5], 1);
+
+ if (strcmp(argv[2], "sub") == 0)
+ return regex_sub(argv[1], argv[3], argv[4], argv[5], 0);
+#endif
+
+ /* standard operators: "setexpr name val1 op val2" */
+ if (argc != 5)
+ return CMD_RET_USAGE;
+
+ if (strlen(argv[3]) != 1)
+ return CMD_RET_USAGE;
+
b = get_arg(argv[4], w);
switch (argv[3][0]) {
@@ -110,13 +378,23 @@ static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
U_BOOT_CMD(
- setexpr, 5, 0, do_setexpr,
+ setexpr, 6, 0, do_setexpr,
"set environment variable as the result of eval expression",
"[.b, .w, .l] name [*]value1 <op> [*]value2\n"
" - set environment variable 'name' to the result of the evaluated\n"
- " express specified by <op>. <op> can be &, |, ^, +, -, *, /, %\n"
+ " expression specified by <op>. <op> can be &, |, ^, +, -, *, /, %\n"
" size argument is only meaningful if value1 and/or value2 are\n"
" memory addresses (*)\n"
- "setexpr[.b, .w, .l] name *value\n"
- " - load a memory address into a variable"
+ "setexpr[.b, .w, .l] name [*]value\n"
+ " - load a value into a variable"
+#ifdef CONFIG_REGEX
+ "\n"
+ "setexpr name gsub r s [t]\n"
+ " - For each substring matching the regular expression <r> in the\n"
+ " string <t>, substitute the string <s>. The result is\n"
+ " assigned to <name>. If <t> is not supplied, use the old\n"
+ " value of <name>\n"
+ "setexpr name sub r s [t]\n"
+ " - Just like gsub(), but replace only the first matching substring"
+#endif
);
diff --git a/common/cmd_source.c b/common/cmd_source.c
index 02a862c..f0d7f52 100644
--- a/common/cmd_source.c
+++ b/common/cmd_source.c
@@ -36,6 +36,7 @@
#include <image.h>
#include <malloc.h>
#include <asm/byteorder.h>
+#include <asm/io.h>
#if defined(CONFIG_8xx)
#include <mpc8xx.h>
#endif
@@ -44,9 +45,10 @@ int
source (ulong addr, const char *fit_uname)
{
ulong len;
- image_header_t *hdr;
+ const image_header_t *hdr;
ulong *data;
int verify;
+ void *buf;
#if defined(CONFIG_FIT)
const void* fit_hdr;
int noffset;
@@ -56,9 +58,10 @@ source (ulong addr, const char *fit_uname)
verify = getenv_yesno ("verify");
- switch (genimg_get_format ((void *)addr)) {
+ buf = map_sysmem(addr, 0);
+ switch (genimg_get_format(buf)) {
case IMAGE_FORMAT_LEGACY:
- hdr = (image_header_t *)addr;
+ hdr = buf;
if (!image_check_magic (hdr)) {
puts ("Bad magic number\n");
@@ -104,7 +107,7 @@ source (ulong addr, const char *fit_uname)
return 1;
}
- fit_hdr = (const void *)addr;
+ fit_hdr = buf;
if (!fit_check_format (fit_hdr)) {
puts ("Bad FIT image format\n");
return 1;
diff --git a/common/cmd_tpm.c b/common/cmd_tpm.c
index 0970a6f..46fae18 100644
--- a/common/cmd_tpm.c
+++ b/common/cmd_tpm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 The Chromium OS Authors.
+ * Copyright (c) 2013 The Chromium OS Authors.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -22,163 +22,652 @@
#include <common.h>
#include <command.h>
+#include <malloc.h>
#include <tpm.h>
+#include <asm/unaligned.h>
+#include <linux/string.h>
-#define MAX_TRANSACTION_SIZE 30
+/**
+ * Print a byte string in hexdecimal format, 16-bytes per line.
+ *
+ * @param data byte string to be printed
+ * @param count number of bytes to be printed
+ */
+static void print_byte_string(uint8_t *data, size_t count)
+{
+ int i, print_newline = 0;
-/*
- * tpm_write() expects a variable number of parameters: the internal address
- * followed by data to write, byte by byte.
+ for (i = 0; i < count; i++) {
+ printf(" %02x", data[i]);
+ print_newline = (i % 16 == 15);
+ if (print_newline)
+ putc('\n');
+ }
+ /* Avoid duplicated newline at the end */
+ if (!print_newline)
+ putc('\n');
+}
+
+/**
+ * Convert a text string of hexdecimal values into a byte string.
*
- * Returns 0 on success or -1 on errors (wrong arguments or TPM failure).
+ * @param bytes text string of hexdecimal values with no space
+ * between them
+ * @param data output buffer for byte string. The caller has to make
+ * sure it is large enough for storing the output. If
+ * NULL is passed, a large enough buffer will be allocated,
+ * and the caller must free it.
+ * @param count_ptr output variable for the length of byte string
+ * @return pointer to output buffer
*/
-static int tpm_process(int argc, char * const argv[], cmd_tbl_t *cmdtp)
-{
- u8 tpm_buffer[MAX_TRANSACTION_SIZE];
- u32 write_size, read_size;
- char *p;
- int rv = -1;
-
- for (write_size = 0; write_size < argc; write_size++) {
- u32 datum = simple_strtoul(argv[write_size], &p, 0);
- if (*p || (datum > 0xff)) {
- printf("\n%s: bad data value\n\n", argv[write_size]);
- cmd_usage(cmdtp);
- return rv;
- }
- tpm_buffer[write_size] = (u8)datum;
+static void *parse_byte_string(char *bytes, uint8_t *data, size_t *count_ptr)
+{
+ char byte[3];
+ size_t count, length;
+ int i;
+
+ length = strlen(bytes);
+ count = length / 2;
+
+ if (!data)
+ data = malloc(count);
+ if (!data)
+ return NULL;
+
+ byte[2] = '\0';
+ for (i = 0; i < length; i += 2) {
+ byte[0] = bytes[i];
+ byte[1] = bytes[i + 1];
+ data[i / 2] = (uint8_t)simple_strtoul(byte, NULL, 16);
}
- read_size = sizeof(tpm_buffer);
- if (!tis_sendrecv(tpm_buffer, write_size, tpm_buffer, &read_size)) {
- int i;
- puts("Got TPM response:\n");
- for (i = 0; i < read_size; i++)
- printf(" %2.2x", tpm_buffer[i]);
- puts("\n");
- rv = 0;
- } else {
- puts("tpm command failed\n");
+ if (count_ptr)
+ *count_ptr = count;
+
+ return data;
+}
+
+/**
+ * Convert TPM command return code to U-Boot command error codes.
+ *
+ * @param return_code TPM command return code
+ * @return value of enum command_ret_t
+ */
+static int convert_return_code(uint32_t return_code)
+{
+ if (return_code)
+ return CMD_RET_FAILURE;
+ else
+ return CMD_RET_SUCCESS;
+}
+
+/**
+ * Return number of values defined by a type string.
+ *
+ * @param type_str type string
+ * @return number of values of type string
+ */
+static int type_string_get_num_values(const char *type_str)
+{
+ return strlen(type_str);
+}
+
+/**
+ * Return total size of values defined by a type string.
+ *
+ * @param type_str type string
+ * @return total size of values of type string, or 0 if type string
+ * contains illegal type character.
+ */
+static size_t type_string_get_space_size(const char *type_str)
+{
+ size_t size;
+
+ for (size = 0; *type_str; type_str++) {
+ switch (*type_str) {
+ case 'b':
+ size += 1;
+ break;
+ case 'w':
+ size += 2;
+ break;
+ case 'd':
+ size += 4;
+ break;
+ default:
+ return 0;
+ }
}
- return rv;
+
+ return size;
}
-#define CHECK(exp) do { \
- int _rv = exp; \
- if (_rv) { \
- printf("CHECK: %s %d %x\n", #exp, __LINE__, _rv);\
- } \
- } while (0)
+/**
+ * Allocate a buffer large enough to hold values defined by a type
+ * string. The caller has to free the buffer.
+ *
+ * @param type_str type string
+ * @param count pointer for storing size of buffer
+ * @return pointer to buffer or NULL on error
+ */
+static void *type_string_alloc(const char *type_str, uint32_t *count)
+{
+ void *data;
+ size_t size;
+
+ size = type_string_get_space_size(type_str);
+ if (!size)
+ return NULL;
+ data = malloc(size);
+ if (data)
+ *count = size;
-static int tpm_process_stress(int repeat_count)
+ return data;
+}
+
+/**
+ * Pack values defined by a type string into a buffer. The buffer must have
+ * large enough space.
+ *
+ * @param type_str type string
+ * @param values text strings of values to be packed
+ * @param data output buffer of values
+ * @return 0 on success, non-0 on error
+ */
+static int type_string_pack(const char *type_str, char * const values[],
+ uint8_t *data)
{
- 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());
+ size_t offset;
+ uint32_t value;
+
+ for (offset = 0; *type_str; type_str++, values++) {
+ value = simple_strtoul(values[0], NULL, 0);
+ switch (*type_str) {
+ case 'b':
+ data[offset] = value;
+ offset += 1;
+ break;
+ case 'w':
+ put_unaligned_be16(value, data + offset);
+ offset += 2;
+ break;
+ case 'd':
+ put_unaligned_be32(value, data + offset);
+ offset += 4;
break;
+ default:
+ return -1;
}
- 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;
+ }
+
+ return 0;
+}
+
+/**
+ * Read values defined by a type string from a buffer, and write these values
+ * to environment variables.
+ *
+ * @param type_str type string
+ * @param data input buffer of values
+ * @param vars names of environment variables
+ * @return 0 on success, non-0 on error
+ */
+static int type_string_write_vars(const char *type_str, uint8_t *data,
+ char * const vars[])
+{
+ size_t offset;
+ uint32_t value;
+
+ for (offset = 0; *type_str; type_str++, vars++) {
+ switch (*type_str) {
+ case 'b':
+ value = data[offset];
+ offset += 1;
+ break;
+ case 'w':
+ value = get_unaligned_be16(data + offset);
+ offset += 2;
break;
+ case 'd':
+ value = get_unaligned_be32(data + offset);
+ offset += 4;
+ break;
+ default:
+ return -1;
}
+ if (setenv_ulong(*vars, value))
+ return -1;
}
- return rv;
+
+ return 0;
}
+static int do_tpm_startup(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ enum tpm_startup_type mode;
-static int do_tpm_many(cmd_tbl_t *cmdtp, int flag,
- int argc, char * const argv[], int repeat_count)
+ if (argc != 2)
+ return CMD_RET_USAGE;
+ if (!strcasecmp("TPM_ST_CLEAR", argv[1])) {
+ mode = TPM_ST_CLEAR;
+ } else if (!strcasecmp("TPM_ST_STATE", argv[1])) {
+ mode = TPM_ST_STATE;
+ } else if (!strcasecmp("TPM_ST_DEACTIVATED", argv[1])) {
+ mode = TPM_ST_DEACTIVATED;
+ } else {
+ printf("Couldn't recognize mode string: %s\n", argv[1]);
+ return CMD_RET_FAILURE;
+ }
+
+ return convert_return_code(tpm_startup(mode));
+}
+
+static int do_tpm_nv_define_space(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ uint32_t index, perm, size;
+
+ if (argc != 4)
+ return CMD_RET_USAGE;
+ index = simple_strtoul(argv[1], NULL, 0);
+ perm = simple_strtoul(argv[2], NULL, 0);
+ size = simple_strtoul(argv[3], NULL, 0);
+
+ return convert_return_code(tpm_nv_define_space(index, perm, size));
+}
+static int do_tpm_nv_read_value(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
{
- int rv = 0;
+ uint32_t index, count, rc;
+ void *data;
- if (argc < 7 && repeat_count == 0) {
- puts("command should be at least six bytes in size\n");
- return -1;
+ if (argc != 4)
+ return CMD_RET_USAGE;
+ index = simple_strtoul(argv[1], NULL, 0);
+ data = (void *)simple_strtoul(argv[2], NULL, 0);
+ count = simple_strtoul(argv[3], NULL, 0);
+
+ rc = tpm_nv_read_value(index, data, count);
+ if (!rc) {
+ puts("area content:\n");
+ print_byte_string(data, count);
}
- if (repeat_count > 0) {
- rv = tpm_process_stress(repeat_count);
- return rv;
+ return convert_return_code(rc);
+}
+
+static int do_tpm_nv_write_value(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ uint32_t index, rc;
+ size_t count;
+ void *data;
+
+ if (argc != 3)
+ return CMD_RET_USAGE;
+ index = simple_strtoul(argv[1], NULL, 0);
+ data = parse_byte_string(argv[2], NULL, &count);
+ if (!data) {
+ printf("Couldn't parse byte string %s\n", argv[2]);
+ return CMD_RET_FAILURE;
}
- if (tis_init()) {
- puts("tis_init() failed!\n");
- return -1;
+ rc = tpm_nv_write_value(index, data, count);
+ free(data);
+
+ return convert_return_code(rc);
+}
+
+static int do_tpm_extend(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ uint32_t index, rc;
+ uint8_t in_digest[20], out_digest[20];
+
+ if (argc != 3)
+ return CMD_RET_USAGE;
+ index = simple_strtoul(argv[1], NULL, 0);
+ if (!parse_byte_string(argv[2], in_digest, NULL)) {
+ printf("Couldn't parse byte string %s\n", argv[2]);
+ return CMD_RET_FAILURE;
}
- if (tis_open()) {
- puts("tis_open() failed!\n");
- return -1;
+ rc = tpm_extend(index, in_digest, out_digest);
+ if (!rc) {
+ puts("PCR value after execution of the command:\n");
+ print_byte_string(out_digest, sizeof(out_digest));
}
- rv = tpm_process(argc - 1, argv + 1, cmdtp);
+ return convert_return_code(rc);
+}
+
+static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ uint32_t index, count, rc;
+ void *data;
+
+ if (argc != 4)
+ return CMD_RET_USAGE;
+ index = simple_strtoul(argv[1], NULL, 0);
+ data = (void *)simple_strtoul(argv[2], NULL, 0);
+ count = simple_strtoul(argv[3], NULL, 0);
- if (tis_close()) {
- puts("tis_close() failed!\n");
- rv = -1;
+ rc = tpm_pcr_read(index, data, count);
+ if (!rc) {
+ puts("Named PCR content:\n");
+ print_byte_string(data, count);
}
- return rv;
+ return convert_return_code(rc);
}
+static int do_tpm_tsc_physical_presence(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ uint16_t presence;
+
+ if (argc != 2)
+ return CMD_RET_USAGE;
+ presence = (uint16_t)simple_strtoul(argv[1], NULL, 0);
-static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+ return convert_return_code(tpm_tsc_physical_presence(presence));
+}
+
+static int do_tpm_read_pubek(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
{
- return do_tpm_many(cmdtp, flag, argc, argv, 0);
+ uint32_t count, rc;
+ void *data;
+
+ if (argc != 3)
+ return CMD_RET_USAGE;
+ data = (void *)simple_strtoul(argv[1], NULL, 0);
+ count = simple_strtoul(argv[2], NULL, 0);
+
+ rc = tpm_read_pubek(data, count);
+ if (!rc) {
+ puts("pubek value:\n");
+ print_byte_string(data, count);
+ }
+
+ return convert_return_code(rc);
}
+static int do_tpm_physical_set_deactivated(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ uint8_t state;
+
+ if (argc != 2)
+ return CMD_RET_USAGE;
+ state = (uint8_t)simple_strtoul(argv[1], NULL, 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"
-);
+ return convert_return_code(tpm_physical_set_deactivated(state));
+}
+
+static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ uint32_t cap_area, sub_cap, rc;
+ void *cap;
+ size_t count;
+
+ if (argc != 5)
+ return CMD_RET_USAGE;
+ cap_area = simple_strtoul(argv[1], NULL, 0);
+ sub_cap = simple_strtoul(argv[2], NULL, 0);
+ cap = (void *)simple_strtoul(argv[3], NULL, 0);
+ count = simple_strtoul(argv[4], NULL, 0);
+
+ rc = tpm_get_capability(cap_area, sub_cap, cap, count);
+ if (!rc) {
+ puts("capability information:\n");
+ print_byte_string(cap, count);
+ }
+
+ return convert_return_code(rc);
+}
-static int do_tpm_stress(cmd_tbl_t *cmdtp, int flag,
- int argc, char * const argv[])
+#define TPM_COMMAND_NO_ARG(cmd) \
+static int do_##cmd(cmd_tbl_t *cmdtp, int flag, \
+ int argc, char * const argv[]) \
+{ \
+ if (argc != 1) \
+ return CMD_RET_USAGE; \
+ return convert_return_code(cmd()); \
+}
+
+TPM_COMMAND_NO_ARG(tpm_init)
+TPM_COMMAND_NO_ARG(tpm_self_test_full)
+TPM_COMMAND_NO_ARG(tpm_continue_self_test)
+TPM_COMMAND_NO_ARG(tpm_force_clear)
+TPM_COMMAND_NO_ARG(tpm_physical_enable)
+TPM_COMMAND_NO_ARG(tpm_physical_disable)
+
+static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ void *command;
+ uint8_t response[1024];
+ size_t count, response_length = sizeof(response);
+ uint32_t rc;
+
+ command = parse_byte_string(argv[1], NULL, &count);
+ if (!command) {
+ printf("Couldn't parse byte string %s\n", argv[1]);
+ return CMD_RET_FAILURE;
+ }
+
+ rc = tis_sendrecv(command, count, response, &response_length);
+ free(command);
+ if (!rc) {
+ puts("tpm response:\n");
+ print_byte_string(response, response_length);
+ }
+
+ return convert_return_code(rc);
+}
+
+static int do_tpm_nv_define(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ uint32_t index, perm, size;
+
+ if (argc != 4)
+ return CMD_RET_USAGE;
+ size = type_string_get_space_size(argv[1]);
+ if (!size) {
+ printf("Couldn't parse arguments\n");
+ return CMD_RET_USAGE;
+ }
+ index = simple_strtoul(argv[2], NULL, 0);
+ perm = simple_strtoul(argv[3], NULL, 0);
+
+ return convert_return_code(tpm_nv_define_space(index, perm, size));
+}
+
+static int do_tpm_nv_read(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
{
- long unsigned int n;
- int rv;
+ uint32_t index, count, err;
+ void *data;
- if (argc != 2) {
- puts("usage: tpm_stress <count>\n");
- return -1;
+ if (argc < 3)
+ return CMD_RET_USAGE;
+ if (argc != 3 + type_string_get_num_values(argv[1]))
+ return CMD_RET_USAGE;
+ index = simple_strtoul(argv[2], NULL, 0);
+ data = type_string_alloc(argv[1], &count);
+ if (!data) {
+ printf("Couldn't parse arguments\n");
+ return CMD_RET_USAGE;
}
- rv = strict_strtoul(argv[1], 10, &n);
- if (rv) {
- puts("tpm_stress: bad count");
- return -1;
+ err = tpm_nv_read_value(index, data, count);
+ if (!err) {
+ if (type_string_write_vars(argv[1], data, argv + 3)) {
+ printf("Couldn't write to variables\n");
+ err = ~0;
+ }
}
+ free(data);
+
+ return convert_return_code(err);
+}
+
+static int do_tpm_nv_write(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ uint32_t index, count, err;
+ void *data;
+
+ if (argc < 3)
+ return CMD_RET_USAGE;
+ if (argc != 3 + type_string_get_num_values(argv[1]))
+ return CMD_RET_USAGE;
+ index = simple_strtoul(argv[2], NULL, 0);
+ data = type_string_alloc(argv[1], &count);
+ if (!data) {
+ printf("Couldn't parse arguments\n");
+ return CMD_RET_USAGE;
+ }
+ if (type_string_pack(argv[1], argv + 3, data)) {
+ printf("Couldn't parse arguments\n");
+ free(data);
+ return CMD_RET_USAGE;
+ }
+
+ err = tpm_nv_write_value(index, data, count);
+ free(data);
+
+ return convert_return_code(err);
+}
+
+#define MAKE_TPM_CMD_ENTRY(cmd) \
+ U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
+
+static cmd_tbl_t tpm_commands[] = {
+ U_BOOT_CMD_MKENT(init, 0, 1,
+ do_tpm_init, "", ""),
+ U_BOOT_CMD_MKENT(startup, 0, 1,
+ do_tpm_startup, "", ""),
+ U_BOOT_CMD_MKENT(self_test_full, 0, 1,
+ do_tpm_self_test_full, "", ""),
+ U_BOOT_CMD_MKENT(continue_self_test, 0, 1,
+ do_tpm_continue_self_test, "", ""),
+ U_BOOT_CMD_MKENT(force_clear, 0, 1,
+ do_tpm_force_clear, "", ""),
+ U_BOOT_CMD_MKENT(physical_enable, 0, 1,
+ do_tpm_physical_enable, "", ""),
+ U_BOOT_CMD_MKENT(physical_disable, 0, 1,
+ do_tpm_physical_disable, "", ""),
+ U_BOOT_CMD_MKENT(nv_define_space, 0, 1,
+ do_tpm_nv_define_space, "", ""),
+ U_BOOT_CMD_MKENT(nv_read_value, 0, 1,
+ do_tpm_nv_read_value, "", ""),
+ U_BOOT_CMD_MKENT(nv_write_value, 0, 1,
+ do_tpm_nv_write_value, "", ""),
+ U_BOOT_CMD_MKENT(extend, 0, 1,
+ do_tpm_extend, "", ""),
+ U_BOOT_CMD_MKENT(pcr_read, 0, 1,
+ do_tpm_pcr_read, "", ""),
+ U_BOOT_CMD_MKENT(tsc_physical_presence, 0, 1,
+ do_tpm_tsc_physical_presence, "", ""),
+ U_BOOT_CMD_MKENT(read_pubek, 0, 1,
+ do_tpm_read_pubek, "", ""),
+ U_BOOT_CMD_MKENT(physical_set_deactivated, 0, 1,
+ do_tpm_physical_set_deactivated, "", ""),
+ U_BOOT_CMD_MKENT(get_capability, 0, 1,
+ do_tpm_get_capability, "", ""),
+ U_BOOT_CMD_MKENT(raw_transfer, 0, 1,
+ do_tpm_raw_transfer, "", ""),
+ U_BOOT_CMD_MKENT(nv_define, 0, 1,
+ do_tpm_nv_define, "", ""),
+ U_BOOT_CMD_MKENT(nv_read, 0, 1,
+ do_tpm_nv_read, "", ""),
+ U_BOOT_CMD_MKENT(nv_write, 0, 1,
+ do_tpm_nv_write, "", ""),
+};
+
+static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ cmd_tbl_t *tpm_cmd;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+ tpm_cmd = find_cmd_tbl(argv[1], tpm_commands, ARRAY_SIZE(tpm_commands));
+ if (!tpm_cmd)
+ return CMD_RET_USAGE;
- return do_tpm_many(cmdtp, flag, argc, argv, n);
+ return tpm_cmd->cmd(cmdtp, flag, argc - 1, argv + 1);
}
-U_BOOT_CMD(tpm_stress, 2, 1, do_tpm_stress,
- "<n> - stress-test communication with TPM",
- "Repeat a TPM transaction (request-response) N times"
+U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
+"Issue a TPM command",
+"cmd args...\n"
+" - Issue TPM command <cmd> with arguments <args...>.\n"
+"Admin Startup and State Commands:\n"
+" init\n"
+" - Put TPM into a state where it waits for 'startup' command.\n"
+" startup mode\n"
+" - Issue TPM_Starup command. <mode> is one of TPM_ST_CLEAR,\n"
+" TPM_ST_STATE, and TPM_ST_DEACTIVATED.\n"
+"Admin Testing Commands:\n"
+" self_test_full\n"
+" - Test all of the TPM capabilities.\n"
+" continue_self_test\n"
+" - Inform TPM that it should complete the self-test.\n"
+"Admin Opt-in Commands:\n"
+" physical_enable\n"
+" - Set the PERMANENT disable flag to FALSE using physical presence as\n"
+" authorization.\n"
+" physical_disable\n"
+" - Set the PERMANENT disable flag to TRUE using physical presence as\n"
+" authorization.\n"
+" physical_set_deactivated 0|1\n"
+" - Set deactivated flag.\n"
+"Admin Ownership Commands:\n"
+" force_clear\n"
+" - Issue TPM_ForceClear command.\n"
+" tsc_physical_presence flags\n"
+" - Set TPM device's Physical Presence flags to <flags>.\n"
+"The Capability Commands:\n"
+" get_capability cap_area sub_cap addr count\n"
+" - Read <count> bytes of TPM capability indexed by <cap_area> and\n"
+" <sub_cap> to memory address <addr>.\n"
+"Endorsement Key Handling Commands:\n"
+" read_pubek addr count\n"
+" - Read <count> bytes of the public endorsement key to memory\n"
+" address <addr>\n"
+"Integrity Collection and Reporting Commands:\n"
+" extend index digest_hex_string\n"
+" - Add a new measurement to a PCR. Update PCR <index> with the 20-bytes\n"
+" <digest_hex_string>\n"
+" pcr_read index addr count\n"
+" - Read <count> bytes from PCR <index> to memory address <addr>.\n"
+"Non-volatile Storage Commands:\n"
+" nv_define_space index permission size\n"
+" - Establish a space at index <index> with <permission> of <size> bytes.\n"
+" nv_read_value index addr count\n"
+" - Read <count> bytes from space <index> to memory address <addr>.\n"
+" nv_write_value index addr count\n"
+" - Write <count> bytes from memory address <addr> to space <index>.\n"
+"Miscellaneous helper functions:\n"
+" raw_transfer byte_string\n"
+" - Send a byte string <byte_string> to TPM and print the response.\n"
+" Non-volatile storage helper functions:\n"
+" These helper functions treat a non-volatile space as a non-padded\n"
+" sequence of integer values. These integer values are defined by a type\n"
+" string, which is a text string of 'bwd' characters: 'b' means a 8-bit\n"
+" value, 'w' 16-bit value, 'd' 32-bit value. All helper functions take\n"
+" a type string as their first argument.\n"
+" nv_define type_string index perm\n"
+" - Define a space <index> with permission <perm>.\n"
+" nv_read types_string index vars...\n"
+" - Read from space <index> to environment variables <vars...>.\n"
+" nv_write types_string index values...\n"
+" - Write to space <index> from values <values...>.\n"
);
diff --git a/common/env_mmc.c b/common/env_mmc.c
index 02bd5ae..9ca098f 100644
--- a/common/env_mmc.c
+++ b/common/env_mmc.c
@@ -32,6 +32,11 @@
#include <search.h>
#include <errno.h>
+#if defined(CONFIG_ENV_SIZE_REDUND) && \
+ (CONFIG_ENV_SIZE_REDUND != CONFIG_ENV_SIZE)
+#error CONFIG_ENV_SIZE_REDUND should be the same as CONFIG_ENV_SIZE
+#endif
+
char *env_name_spec = "MMC";
#ifdef ENV_IS_EMBEDDED
@@ -46,9 +51,13 @@ DECLARE_GLOBAL_DATA_PTR;
#define CONFIG_ENV_OFFSET 0
#endif
-__weak int mmc_get_env_addr(struct mmc *mmc, u32 *env_addr)
+__weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
{
*env_addr = CONFIG_ENV_OFFSET;
+#ifdef CONFIG_ENV_OFFSET_REDUND
+ if (copy)
+ *env_addr = CONFIG_ENV_OFFSET_REDUND;
+#endif
return 0;
}
@@ -110,6 +119,10 @@ static inline int write_env(struct mmc *mmc, unsigned long size,
return (n == blk_cnt) ? 0 : -1;
}
+#ifdef CONFIG_ENV_OFFSET_REDUND
+static unsigned char env_flags;
+#endif
+
int saveenv(void)
{
ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
@@ -117,16 +130,11 @@ int saveenv(void)
char *res;
struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
u32 offset;
- int ret;
+ int ret, copy = 0;
if (init_mmc_for_env(mmc))
return 1;
- if (mmc_get_env_addr(mmc, &offset)) {
- ret = 1;
- goto fini;
- }
-
res = (char *)&env_new->data;
len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
if (len < 0) {
@@ -136,7 +144,21 @@ int saveenv(void)
}
env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE);
- printf("Writing to MMC(%d)... ", CONFIG_SYS_MMC_ENV_DEV);
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+ env_new->flags = ++env_flags; /* increase the serial */
+
+ if (gd->env_valid == 1)
+ copy = 1;
+#endif
+
+ if (mmc_get_env_addr(mmc, copy, &offset)) {
+ ret = 1;
+ goto fini;
+ }
+
+ printf("Writing to %sMMC(%d)... ", copy ? "redundant " : "",
+ CONFIG_SYS_MMC_ENV_DEV);
if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) {
puts("failed\n");
ret = 1;
@@ -146,6 +168,10 @@ int saveenv(void)
puts("done\n");
ret = 0;
+#ifdef CONFIG_ENV_OFFSET_REDUND
+ gd->env_valid = gd->env_valid == 2 ? 1 : 2;
+#endif
+
fini:
fini_mmc_for_env(mmc);
return ret;
@@ -166,6 +192,93 @@ static inline int read_env(struct mmc *mmc, unsigned long size,
return (n == blk_cnt) ? 0 : -1;
}
+#ifdef CONFIG_ENV_OFFSET_REDUND
+void env_relocate_spec(void)
+{
+#if !defined(ENV_IS_EMBEDDED)
+ struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
+ u32 offset1, offset2;
+ int read1_fail = 0, read2_fail = 0;
+ int crc1_ok = 0, crc2_ok = 0;
+ env_t *ep, *tmp_env1, *tmp_env2;
+ int ret;
+
+ tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE);
+ tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE);
+ if (tmp_env1 == NULL || tmp_env2 == NULL) {
+ puts("Can't allocate buffers for environment\n");
+ ret = 1;
+ goto err;
+ }
+
+ if (init_mmc_for_env(mmc)) {
+ ret = 1;
+ goto err;
+ }
+
+ if (mmc_get_env_addr(mmc, 0, &offset1) ||
+ mmc_get_env_addr(mmc, 1, &offset2)) {
+ ret = 1;
+ goto fini;
+ }
+
+ read1_fail = read_env(mmc, CONFIG_ENV_SIZE, offset1, tmp_env1);
+ read2_fail = read_env(mmc, CONFIG_ENV_SIZE, offset2, tmp_env2);
+
+ if (read1_fail && read2_fail)
+ puts("*** Error - No Valid Environment Area found\n");
+ else if (read1_fail || read2_fail)
+ puts("*** Warning - some problems detected "
+ "reading environment; recovered successfully\n");
+
+ crc1_ok = !read1_fail &&
+ (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc);
+ crc2_ok = !read2_fail &&
+ (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc);
+
+ if (!crc1_ok && !crc2_ok) {
+ ret = 1;
+ goto fini;
+ } else if (crc1_ok && !crc2_ok) {
+ gd->env_valid = 1;
+ } else if (!crc1_ok && crc2_ok) {
+ gd->env_valid = 2;
+ } else {
+ /* both ok - check serial */
+ if (tmp_env1->flags == 255 && tmp_env2->flags == 0)
+ gd->env_valid = 2;
+ else if (tmp_env2->flags == 255 && tmp_env1->flags == 0)
+ gd->env_valid = 1;
+ else if (tmp_env1->flags > tmp_env2->flags)
+ gd->env_valid = 1;
+ else if (tmp_env2->flags > tmp_env1->flags)
+ gd->env_valid = 2;
+ else /* flags are equal - almost impossible */
+ gd->env_valid = 1;
+ }
+
+ free(env_ptr);
+
+ if (gd->env_valid == 1)
+ ep = tmp_env1;
+ else
+ ep = tmp_env2;
+
+ env_flags = ep->flags;
+ env_import((char *)ep, 0);
+ ret = 0;
+
+fini:
+ fini_mmc_for_env(mmc);
+err:
+ if (ret)
+ set_default_env(NULL);
+
+ free(tmp_env1);
+ free(tmp_env2);
+#endif
+}
+#else /* ! CONFIG_ENV_OFFSET_REDUND */
void env_relocate_spec(void)
{
#if !defined(ENV_IS_EMBEDDED)
@@ -179,7 +292,7 @@ void env_relocate_spec(void)
goto err;
}
- if (mmc_get_env_addr(mmc, &offset)) {
+ if (mmc_get_env_addr(mmc, 0, &offset)) {
ret = 1;
goto fini;
}
@@ -199,3 +312,4 @@ err:
set_default_env(NULL);
#endif
}
+#endif /* CONFIG_ENV_OFFSET_REDUND */
diff --git a/common/flash.c b/common/flash.c
index 8244ba2..0c57a3f 100644
--- a/common/flash.c
+++ b/common/flash.c
@@ -149,6 +149,9 @@ flash_write (char *src, ulong addr, ulong cnt)
flash_info_t *info_first = addr2info (addr);
flash_info_t *info_last = addr2info (end );
flash_info_t *info;
+ __maybe_unused char *src_orig = src;
+ __maybe_unused char *addr_orig = (char *)addr;
+ __maybe_unused ulong cnt_orig = cnt;
if (cnt == 0) {
return (ERR_OK);
@@ -185,6 +188,14 @@ flash_write (char *src, ulong addr, ulong cnt)
addr += len;
src += len;
}
+
+#if defined(CONFIG_FLASH_VERIFY)
+ if (memcmp(src_orig, addr_orig, cnt_orig)) {
+ printf("\nVerify failed!\n");
+ return ERR_PROG_ERROR;
+ }
+#endif /* CONFIG_SYS_FLASH_VERIFY_AFTER_WRITE */
+
return (ERR_OK);
#endif /* CONFIG_SPD823TS */
}
diff --git a/common/main.c b/common/main.c
index a15f020..953ef29 100644
--- a/common/main.c
+++ b/common/main.c
@@ -45,10 +45,6 @@
#include <fdtdec.h>
#endif
-#ifdef CONFIG_OF_LIBFDT
-#include <fdt_support.h>
-#endif /* CONFIG_OF_LIBFDT */
-
#include <post.h>
#include <linux/ctype.h>
#include <menu.h>
@@ -376,10 +372,6 @@ void main_loop (void)
bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
-#if defined CONFIG_OF_CONTROL
- set_working_fdt_addr((void *)gd->fdt_blob);
-#endif /* CONFIG_OF_CONTROL */
-
#ifdef CONFIG_BOOTCOUNT_LIMIT
bootcount = bootcount_load();
bootcount++;
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 6715e0d..7ce2d5f 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -48,13 +48,6 @@ struct spl_image_info spl_image;
/* Define board data structure */
static bd_t bdata __attribute__ ((section(".data")));
-inline void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;)
- ;
-}
-
/*
* Default function to determine if u-boot or the OS should
* be started. This implementation always returns 1.
diff --git a/common/usb_storage.c b/common/usb_storage.c
index fb322b4..c5db044 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -1430,6 +1430,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
*capacity, *blksz);
dev_desc->lba = *capacity;
dev_desc->blksz = *blksz;
+ dev_desc->log2blksz = LOG2(dev_desc->blksz);
dev_desc->type = perq;
USB_STOR_PRINTF(" address %d\n", dev_desc->target);
USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);
diff --git a/config.mk b/config.mk
index 1fd109f..b427a4e 100644
--- a/config.mk
+++ b/config.mk
@@ -222,6 +222,10 @@ ifneq ($(CONFIG_SPL_PAD_TO),)
CPPFLAGS += -DCONFIG_SPL_PAD_TO=$(CONFIG_SPL_PAD_TO)
endif
+ifneq ($(CONFIG_UBOOT_PAD_TO),)
+CPPFLAGS += -DCONFIG_UBOOT_PAD_TO=$(CONFIG_UBOOT_PAD_TO)
+endif
+
ifeq ($(CONFIG_SPL_BUILD),y)
CPPFLAGS += -DCONFIG_SPL_BUILD
endif
@@ -229,8 +233,8 @@ endif
# Does this architecture support generic board init?
ifeq ($(__HAVE_ARCH_GENERIC_BOARD),)
ifneq ($(CONFIG_SYS_GENERIC_BOARD),)
-$(error Your architecture does not support generic board. Please undefined \
-CONFIG_SYS_GENERIC_BOARD in your board config file)
+CHECK_GENERIC_BOARD = $(error Your architecture does not support generic board. \
+Please undefined CONFIG_SYS_GENERIC_BOARD in your board config file)
endif
endif
diff --git a/disk/part_dos.c b/disk/part_dos.c
index 37087a6..ab984cd 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -74,13 +74,26 @@ static void print_one_part(dos_partition_t *p, int ext_part_sector,
static int test_block_type(unsigned char *buffer)
{
+ int slot;
+ struct dos_partition *p;
+
if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
(buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
return (-1);
} /* no DOS Signature at all */
- if (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],"FAT",3)==0 ||
- strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],"FAT32",5)==0) {
- return DOS_PBR; /* is PBR */
+ p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET];
+ for (slot = 0; slot < 3; slot++) {
+ if (p->boot_ind != 0 && p->boot_ind != 0x80) {
+ if (!slot &&
+ (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],
+ "FAT", 3) == 0 ||
+ strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],
+ "FAT32", 5) == 0)) {
+ return DOS_PBR; /* is PBR */
+ } else {
+ return -1;
+ }
+ }
}
return DOS_MBR; /* Is MBR */
}
diff --git a/disk/part_efi.c b/disk/part_efi.c
index e9987f0..5986589 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -115,7 +115,7 @@ static inline int is_bootable(gpt_entry *p)
void print_part_efi(block_dev_desc_t * dev_desc)
{
- ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
+ ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
gpt_entry *gpt_pte = NULL;
int i = 0;
char uuid[37];
@@ -162,7 +162,7 @@ void print_part_efi(block_dev_desc_t * dev_desc)
int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
disk_partition_t * info)
{
- ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
+ ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
gpt_entry *gpt_pte = NULL;
/* "part" argument must be at least 1 */
@@ -190,7 +190,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
/* The ending LBA is inclusive, to calculate size, add 1 to it */
info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1)
- info->start;
- info->blksz = GPT_BLOCK_SIZE;
+ info->blksz = dev_desc->blksz;
sprintf((char *)info->name, "%s",
print_efiname(&gpt_pte[part - 1]));
@@ -210,7 +210,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
int test_part_efi(block_dev_desc_t * dev_desc)
{
- ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, legacymbr, 1);
+ ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz);
/* Read legacy MBR from block 0 and validate it */
if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)legacymbr) != 1)
@@ -311,9 +311,8 @@ static int string_uuid(char *uuid, u8 *dst)
int write_gpt_table(block_dev_desc_t *dev_desc,
gpt_header *gpt_h, gpt_entry *gpt_e)
{
- const int pte_blk_num = (gpt_h->num_partition_entries
- * sizeof(gpt_entry)) / dev_desc->blksz;
-
+ const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries
+ * sizeof(gpt_entry)), dev_desc);
u32 calc_crc32;
u64 val;
@@ -336,8 +335,8 @@ int write_gpt_table(block_dev_desc_t *dev_desc,
if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1)
goto err;
- if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e)
- != pte_blk_num)
+ if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_cnt, gpt_e)
+ != pte_blk_cnt)
goto err;
/* recalculate the values for the Second GPT Header */
@@ -352,7 +351,7 @@ int write_gpt_table(block_dev_desc_t *dev_desc,
if (dev_desc->block_write(dev_desc->dev,
le32_to_cpu(gpt_h->last_usable_lba + 1),
- pte_blk_num, gpt_e) != pte_blk_num)
+ pte_blk_cnt, gpt_e) != pte_blk_cnt)
goto err;
if (dev_desc->block_write(dev_desc->dev,
@@ -462,13 +461,18 @@ int gpt_restore(block_dev_desc_t *dev_desc, char *str_disk_guid,
{
int ret;
- gpt_header *gpt_h = calloc(1, sizeof(gpt_header));
+ gpt_header *gpt_h = calloc(1, PAD_TO_BLOCKSIZE(sizeof(gpt_header),
+ dev_desc));
+ gpt_entry *gpt_e;
+
if (gpt_h == NULL) {
printf("%s: calloc failed!\n", __func__);
return -1;
}
- gpt_entry *gpt_e = calloc(GPT_ENTRY_NUMBERS, sizeof(gpt_entry));
+ gpt_e = calloc(1, PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS
+ * sizeof(gpt_entry),
+ dev_desc));
if (gpt_e == NULL) {
printf("%s: calloc failed!\n", __func__);
free(gpt_h);
@@ -652,7 +656,7 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
gpt_header * pgpt_head)
{
- size_t count = 0;
+ size_t count = 0, blk_cnt;
gpt_entry *pte = NULL;
if (!dev_desc || !pgpt_head) {
@@ -669,7 +673,8 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
/* Allocate memory for PTE, remember to FREE */
if (count != 0) {
- pte = memalign(ARCH_DMA_MINALIGN, count);
+ pte = memalign(ARCH_DMA_MINALIGN,
+ PAD_TO_BLOCKSIZE(count, dev_desc));
}
if (count == 0 || pte == NULL) {
@@ -680,10 +685,11 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
}
/* Read GPT Entries from device */
+ blk_cnt = BLOCK_CNT(count, dev_desc);
if (dev_desc->block_read (dev_desc->dev,
le64_to_cpu(pgpt_head->partition_entry_lba),
- (lbaint_t) (count / GPT_BLOCK_SIZE), pte)
- != (count / GPT_BLOCK_SIZE)) {
+ (lbaint_t) (blk_cnt), pte)
+ != blk_cnt) {
printf("*** ERROR: Can't read GPT Entries ***\n");
free(pte);
diff --git a/disk/part_iso.c b/disk/part_iso.c
index 49639af..cc323b0 100644
--- a/disk/part_iso.c
+++ b/disk/part_iso.c
@@ -73,6 +73,9 @@ int get_partition_info_iso_verb(block_dev_desc_t * dev_desc, int part_num, disk_
iso_val_entry_t *pve = (iso_val_entry_t *)tmpbuf;
iso_init_def_entry_t *pide;
+ if (dev_desc->blksz != CD_SECTSIZE)
+ return -1;
+
/* the first sector (sector 0x10) must be a primary volume desc */
blkaddr=PVD_OFFSET;
if (dev_desc->block_read (dev_desc->dev, PVD_OFFSET, 1, (ulong *) tmpbuf) != 1)
diff --git a/doc/README.fdt-control b/doc/README.fdt-control
index 8352835..5963f78 100644
--- a/doc/README.fdt-control
+++ b/doc/README.fdt-control
@@ -142,7 +142,11 @@ join the two:
and then flash image.bin onto your board.
-You cannot use both of these options at the same time.
+If CONFIG_OF_HOSTFILE is defined, then it will be read from a file on
+startup. This is only useful for sandbox. Use the -d flag to U-Boot to
+specify the file to read.
+
+You cannot use more than one of these options at the same time.
If you wish to put the fdt at a different address in memory, you can
define the "fdtcontroladdr" environment variable. This is the hex
diff --git a/doc/README.p1010rdb b/doc/README.p1010rdb
new file mode 100644
index 0000000..dee63d7
--- /dev/null
+++ b/doc/README.p1010rdb
@@ -0,0 +1,199 @@
+Overview
+=========
+The P1010RDB is a Freescale reference design board that hosts the P1010 SoC.
+
+The P1010 is a cost-effective, low-power, highly integrated host processor
+based on a Power Architecture e500v2 core (maximum core frequency 800/1000 MHz),
+that addresses the requirements of several routing, gateways, storage, consumer,
+and industrial applications. Applications of interest include the main CPUs and
+I/O processors in network attached storage (NAS), the voice over IP (VoIP)
+router/gateway, and wireless LAN (WLAN) and industrial controllers.
+
+The P1010RDB board features are as follows:
+Memory subsystem:
+ - 1Gbyte unbuffered DDR3 SDRAM discrete devices (32-bit bus)
+ - 32 Mbyte NOR flash single-chip memory
+ - 32 Mbyte NAND flash memory
+ - 256 Kbit M24256 I2C EEPROM
+ - 16 Mbyte SPI memory
+ - I2C Board EEPROM 128x8 bit memory
+ - SD/MMC connector to interface with the SD memory card
+Interfaces:
+ - PCIe:
+ - Lane0: x1 mini-PCIe slot
+ - Lane1: x1 PCIe standard slot
+ - SATA:
+ - 1 internal SATA connector to 2.5" 160G SATA2 HDD
+ - 1 eSATA connector to rear panel
+ - 10/100/1000 BaseT Ethernet ports:
+ - eTSEC1, RGMII: one 10/100/1000 port using Vitesse VSC8641XKO
+ - eTSEC2, SGMII: one 10/100/1000 port using Vitesse VSC8221
+ - eTSEC3, SGMII: one 10/100/1000 port using Vitesse VSC8221
+ - USB 2.0 port:
+ - x1 USB2.0 port: via an ULPI PHY to micro-AB connector
+ - x1 USB2.0 poort via an internal PHY to micro-AB connector
+ - FlexCAN ports:
+ - x2 DB-9 female connectors for FlexCAN bus(revision 2.0B)
+ interface;
+ - DUART interface:
+ - DUART interface: supports two UARTs up to 115200 bps for
+ console display
+ - J45 connectors are used for these 2 UART ports.
+ - TDM
+ - 2 FXS ports connected via an external SLIC to the TDM
+ interface. SLIC is controllled via SPI.
+ - 1 FXO port connected via a relay to FXS for switchover to
+ POTS
+Board connectors:
+ - Mini-ITX power supply connector
+ - JTAG/COP for debugging
+IEEE Std. 1588 signals for test and measurement
+Real-time clock on I2C bus
+POR
+ - support critical POR setting changed via switch on board
+PCB
+ - 6-layer routing (4-layer signals, 2-layer power and ground)
+
+
+Serial Port Configuration on P1010RDB
+=====================================
+Configure the serial port of the attached computer with the following values:
+ -Data rate: 115200 bps
+ -Number of data bits: 8
+ -Parity: None
+ -Number of Stop bits: 1
+ -Flow Control: Hardware/None
+
+
+Settings of DIP-switch
+======================
+ SW4[1:4]= 1111 and SW6[4]=0 for boot from 16bit NOR flash
+ SW4[1:4]= 1000 and SW6[4]=1 for boot from 8bit NAND flash
+ SW4[1:4]= 0110 and SW6[4]=0 for boot from SPI flash
+Note: 1 stands for 'on', 0 stands for 'off'
+
+
+Setting of hwconfig
+===================
+If FlexCAN or TDM is needed, please set "fsl_p1010mux:tdm_can=can" or
+"fsl_p1010mux:tdm_can=tdm" explicitly in u-booot prompt as below for example:
+setenv hwconfig "fsl_p1010mux:tdm_can=tdm;usb1:dr_mode=host,phy_type=utmi"
+By default, don't set fsl_p1010mux:tdm_can, in this case, spi chip selection
+is set to spi-flash instead of to SLIC/TDM/DAC and tdm_can_sel is set to TDM
+instead of to CAN/UART1.
+
+
+Build and burn u-boot to NOR flash
+==================================
+1. Build u-boot.bin image
+ export ARCH=powerpc
+ export CROSS_COMPILE=/your_path/powerpc-linux-gnu-
+ make P1010RDB_NOR
+
+2. Burn u-boot.bin into NOR flash
+ => tftp $loadaddr $uboot
+ => protect off eff80000 +$filesize
+ => erase eff80000 +$filesize
+ => cp.b $loadaddr eff80000 $filesize
+
+3. Check SW4[1:4]= 1111 and SW6[4]=0, then power on.
+
+
+Alternate NOR bank
+============================
+1. Burn u-boot.bin into alternate NOR bank
+ => tftp $loadaddr $uboot
+ => protect off eef80000 +$filesize
+ => erase eef80000 +$filesize
+ => cp.b $loadaddr eef80000 $filesize
+
+2. Switch to alternate NOR bank
+ => mw.b ffb00009 1
+ => reset
+ or set SW1[8]= ON
+
+SW1[8]= OFF: Upper bank used for booting start
+SW1[8]= ON: Lower bank used for booting start
+CPLD NOR bank selection register address 0xFFB00009 Bit[0]:
+0 - boot from upper 4 sectors
+1 - boot from lower 4 sectors
+
+
+Build and burn u-boot to NAND flash
+===================================
+1. Build u-boot.bin image
+ export ARCH=powerpc
+ export CROSS_COMPILE=/your_path/powerpc-linux-gnu-
+ make P1010RDB_NAND
+
+2. Burn u-boot-nand.bin into NAND flash
+ => tftp $loadaddr $uboot-nand
+ => nand erase 0 $filesize
+ => nand write $loadaddr 0 $filesize
+
+3. Check SW4[1:4]= 1000 and SW6[4]=1, then power on.
+
+
+
+Build and burn u-boot to SPI flash
+==================================
+1. Build u-boot-spi.bin image
+ make P1010RDB_SPIFLASH_config; make
+ Boot up kernel with rootfs.ext2.gz.uboot.p1010rdb
+ Download u-boot.bin to linux and you can find some config files
+ under /usr/share such as config_xx.dat. Do below command:
+ boot_format config_ddr3_1gb_p1010rdb_800M.dat u-boot.bin -spi \
+ u-boot-spi.bin
+ to generate u-boot-spi.bin.
+
+2. Burn u-boot-spi.bin into SPI flash
+ => tftp $loadaddr $uboot-spi
+ => sf erase 0 100000
+ => sf write $loadaddr 0 $filesize
+
+3. Check SW4[1:4]= 0110 and SW6[4]=0, then power on.
+
+
+
+CPLD POR setting registers
+==========================
+1. Set POR switch selection register (addr 0xFFB00011) to 0.
+2. Write CPLD POR registers (BCSR0~BCSR3, addr 0xFFB00014~0xFFB00017) with
+ proper values.
+ If change boot ROM location to NOR or NAND flash, need write the IFC_CS0
+ switch command by I2C.
+3. Send reset command.
+ After reset, the new POR setting will be implemented.
+
+Two examples are given in below:
+Switch from NOR to NAND boot with default frequency:
+ => i2c dev 0
+ => i2c mw 18 1 f9
+ => i2c mw 18 3 f0
+ => mw.b ffb00011 0
+ => mw.b ffb00017 1
+ => reset
+Switch from NAND to NOR boot with Core/CCB/DDR (800/400/667 MHz):
+ => i2c dev 0
+ => i2c mw 18 1 f1
+ => i2c mw 18 3 f0
+ => mw.b ffb00011 0
+ => mw.b ffb00014 2
+ => mw.b ffb00015 5
+ => mw.b ffb00016 3
+ => mw.b ffb00017 f
+ => reset
+
+
+
+Boot Linux from network using TFTP on P1010RDB
+==============================================
+Place uImage, p1010rdb.dtb and rootfs files in the TFTP disk area.
+ => tftp 1000000 uImage
+ => tftp 2000000 p1010rdb.dtb
+ => tftp 3000000 rootfs.ext2.gz.uboot.p1010rdb
+ => bootm 1000000 3000000 2000000
+
+
+Please contact your local field applications engineer or sales representative
+to obtain related documents, such as P1010-RDB User Guide for details.
diff --git a/doc/README.ramboot-ppc85xx b/doc/README.ramboot-ppc85xx
new file mode 100644
index 0000000..8ed45fb
--- /dev/null
+++ b/doc/README.ramboot-ppc85xx
@@ -0,0 +1,102 @@
+ RAMBOOT for MPC85xx Platforms
+ ==============================
+
+RAMBOOT literally means boot from DDR. But since DDR is volatile memory some
+pre-mechanism is required to load the DDR with the bootloader binary.
+- In case of SD and SPI boot this is done by BootROM code inside the chip
+ itself.
+- In case of NAND boot FCM supports loading initial 4K code from NAND flash
+ which can initialize the DDR and get the complete bootloader copied to DDR.
+
+In addition to the above there could be some more methods to initialize the DDR
+and load it manually.
+Two of them are described below.There is also an explanation as to where these
+methods could be handy.
+1. Load the RAM based bootloader onto DDR via JTAG/BDI interface. And then
+ execute the bootloader from DDR.
+ This may be handy in the following cases:
+ - In very early stage of platform bringup where other boot options are not
+ functional because of various reasons.
+ - In case the support to program the flashes on the board is not available.
+
+2. Load the RAM based bootloader onto DDR using already existing bootloader on
+ the board.And then execute the bootloader from DDR.
+ Some usecases where this may be used:
+ - While developing some new feature of u-boot, for example USB driver or
+ SPI driver.
+ Suppose the board already has a working bootloader on it. And you would
+ prefer to keep it intact, at the same time want to test your bootloader.
+ In this case you can get your test bootloader binary into DDR via tftp
+ for example. Then execute the test bootloader.
+ - Suppose a platform already has a propreitery bootloader which does not
+ support for example AMP boot. In this case also RAM boot loader can be
+ utilized.
+
+ So basically when the original bootloader is required to be kept intact
+ RAM based bootloader can offer an updated bootloader on the system.
+
+Both the above Bootloaders are slight variants of SDcard or SPI Flash
+bootloader or for that matter even NAND bootloader.
+All of them define CONFIG_SYS_RAMBOOT.
+The main difference among all of them is the way the pre-environment is getting
+configured and who is doing that.
+- In case of SD card and SPI flash bootloader this is done by On Chip BootROM inside the Si itself.
+- In case of NAND boot SPL/TPL code does it with some support from Si itself.
+- In case of the pure RAM based bootloaders we have to do it by JTAG manually or already existing bootloader.
+
+How to use them:
+1. Using JTAG
+ Boot up in core hold off mode or stop the core after reset using JTAG
+ interface.
+ Preconfigure DDR/L2SRAM through JTAG interface.
+ - setup DDR controller registers.
+ - setup DDR LAWs
+ - setup DDR TLB
+ Load the RAM based boot loader to the proper location in DDR/L2SRAM.
+ set up IAR (Instruction counter properly)
+ Enable the core to execute.
+
+2. Using already existing bootloader.
+ get the rambased boot loader binary into DDR/L2SRAM via tftp.
+ execute the RAM based bootloader.
+ => tftp 11000000 u-boot-ram.bin
+ => go 1107f000
+
+Please note that L2SRAM can also be used instead of DDR if the SOC has
+sufficient size of L2SRAM.
+
+Necessary Code changes Required:
+=====================================
+Please note that below mentioned changes are for 85xx platforms.
+They have been tested on P1020/P2020/P1010 RDB.
+
+The main difference between the above two methods from technical perspective is
+that in 1st case SOC is just out of reset so it is in default configuration.
+(CCSRBAR is at 0xff700000).
+In the 2nd case bootloader has already re-located CCSRBAR to 0xffe00000
+
+1. File name-> boards.cfg
+ There can be added specific Make options for RAMBoot. We can keep different
+ options for the two cases mentioned above.
+ for example
+ P1020RDB_JTAG_RAMBOOT and P1020RDB_GO_RAMBOOT.
+
+2. platform config file
+ for example include/configs/P1_P2_RDB.h
+
+ #ifdef CONFIG_RAMBOOT
+ #define CONFIG_SDCARD
+ #endif
+
+ This will finally use the CONFIG_SYS_RAMBOOT.
+
+3. File name-> arch/powerpc/include/asm/config_mpc85xx.h
+ In the section of the particular SOC, for example P1020,
+
+ #if defined(CONFIG_GO)
+ #define CONFIG_SYS_CCSRBAR_DEFAULT 0xffe00000
+ #else
+ #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000
+ #endif
+
+For JTAG RAMBOOT this is not required because CCSRBAR is at ff700000.
diff --git a/doc/README.watchdog b/doc/README.watchdog
index ee65008..33f31c2 100644
--- a/doc/README.watchdog
+++ b/doc/README.watchdog
@@ -27,3 +27,6 @@ CONFIG_IMX_WATCHDOG
Available for i.mx31/35/5x/6x to service the watchdog. This is not
automatically set because some boards (vision2) still need to define
their own hw_watchdog_reset routine.
+
+CONFIG_XILINX_TB_WATCHDOG
+ Available for Xilinx Axi platforms to service timebase watchdog timer.
diff --git a/doc/feature-removal-schedule.txt b/doc/feature-removal-schedule.txt
index ce72861..1c79c14 100644
--- a/doc/feature-removal-schedule.txt
+++ b/doc/feature-removal-schedule.txt
@@ -7,20 +7,15 @@ file.
---------------------------
-What: Remove CONFIG_CMD_MEMTEST from default list
-When: Release v2013.07
+What: Remove unused CONFIG_SYS_MEMTEST_START/END
+When: Release v2013.10
-Why: The "mtest" command is of little practical use (if any), and
- experience has shown that a large number of board configu-
- rations define useless or even dangerous start and end
- addresses. If not even the board maintainers are able to
- figure out which memory range can be reliably tested, how can
- we expect such from the end users? As this problem comes up
- repeatedly, we rather do not enable this command by default,
- so only people who know what they are doing will be confronted
- with it.
+Why: As the 'mtest' command is no longer default, a number of platforms
+ have not opted to turn the command back on and thus provide unused
+ defines (which are likely to be propogated to new platforms from
+ copy/paste). Remove these defines when unused.
-Who: Wolfgang Denk <wd@denx.de>
+Who: Tom Rini <trini@ti.com>
---------------------------
diff --git a/doc/git-mailrc b/doc/git-mailrc
index 0f23776..e3a47c4 100644
--- a/doc/git-mailrc
+++ b/doc/git-mailrc
@@ -34,6 +34,7 @@ alias sjg Simon Glass <sjg@chromium.org>
alias smcnutt Scott McNutt <smcnutt@psyent.com>
alias sonic Sonic Zhang <sonic.adi@gmail.com>
alias stroese Stefan Roese <sr@denx.de>
+alias trini Tom Rini <trini@ti.com>
alias vapier Mike Frysinger <vapier@gentoo.org>
alias wd Wolfgang Denk <wd@denx.de>
@@ -54,7 +55,7 @@ alias s5pc samsung
alias samsung uboot, prom
alias tegra uboot, sjg, Tom Warren <twarren@nvidia.com>, Stephen Warren <swarren@nvidia.com>
alias tegra2 tegra
-alias ti uboot, Tom Rini <trini@ti.com>
+alias ti uboot, trini
alias avr32 uboot, abiessmann
diff --git a/drivers/block/ata_piix.c b/drivers/block/ata_piix.c
index 1e33a66..fcae448 100644
--- a/drivers/block/ata_piix.c
+++ b/drivers/block/ata_piix.c
@@ -406,6 +406,7 @@ void sata_identify(int num, int dev)
/* assuming HD */
sata_dev_desc[devno].type = DEV_TYPE_HARDDISK;
sata_dev_desc[devno].blksz = ATA_BLOCKSIZE;
+ sata_dev_desc[devno].log2blksz = LOG2(sata_dev_desc[devno].blksz);
sata_dev_desc[devno].lun = 0; /* just to fill something in... */
}
diff --git a/drivers/block/pata_bfin.c b/drivers/block/pata_bfin.c
index b847dd9..27ecaf4 100644
--- a/drivers/block/pata_bfin.c
+++ b/drivers/block/pata_bfin.c
@@ -897,6 +897,8 @@ static void bfin_ata_identify(struct ata_port *ap, int dev)
/* assuming HD */
sata_dev_desc[ap->port_no].type = DEV_TYPE_HARDDISK;
sata_dev_desc[ap->port_no].blksz = ATA_SECT_SIZE;
+ sata_dev_desc[ap->port_no].log2blksz =
+ LOG2(sata_dev_desc[ap->port_no].blksz);
sata_dev_desc[ap->port_no].lun = 0; /* just to fill something in... */
printf("PATA device#%d %s is found on ata port#%d.\n",
diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c
index bf29cbb..b08715f 100644
--- a/drivers/block/systemace.c
+++ b/drivers/block/systemace.c
@@ -127,6 +127,7 @@ block_dev_desc_t *systemace_get_dev(int dev)
systemace_dev.part_type = PART_TYPE_UNKNOWN;
systemace_dev.type = DEV_TYPE_HARDDISK;
systemace_dev.blksz = 512;
+ systemace_dev.log2blksz = LOG2(systemace_dev.blksz);
systemace_dev.removable = 1;
systemace_dev.block_read = systemace_read;
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index b48f623..0b51dcd 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -30,6 +30,7 @@ COBJS-y += fpga.o
COBJS-$(CONFIG_FPGA_SPARTAN2) += spartan2.o
COBJS-$(CONFIG_FPGA_SPARTAN3) += spartan3.o
COBJS-$(CONFIG_FPGA_VIRTEX2) += virtex2.o
+COBJS-$(CONFIG_FPGA_ZYNQPL) += zynqpl.o
COBJS-$(CONFIG_FPGA_XILINX) += xilinx.o
COBJS-$(CONFIG_FPGA_LATTICE) += ivm_core.o lattice.o
ifdef CONFIG_FPGA_ALTERA
diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c
index 26d2443..f70bff6 100644
--- a/drivers/fpga/fpga.c
+++ b/drivers/fpga/fpga.c
@@ -22,122 +22,99 @@
*
*/
-/*
- * Generic FPGA support
- */
+/* Generic FPGA support */
#include <common.h> /* core U-Boot definitions */
#include <xilinx.h> /* xilinx specific definitions */
#include <altera.h> /* altera specific definitions */
#include <lattice.h>
-#if 0
-#define FPGA_DEBUG /* define FPGA_DEBUG to get debug messages */
-#endif
-
/* Local definitions */
#ifndef CONFIG_MAX_FPGA_DEVICES
#define CONFIG_MAX_FPGA_DEVICES 5
#endif
-/* Enable/Disable debug console messages */
-#ifdef FPGA_DEBUG
-#define PRINTF(fmt,args...) printf (fmt ,##args)
-#else
-#define PRINTF(fmt,args...)
-#endif
-
/* Local static data */
static int next_desc = FPGA_INVALID_DEVICE;
static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES];
-/* Local static functions */
-static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum );
-static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate(int devnum, const void *buf,
- size_t bsize, char *fn );
-static int fpga_dev_info( int devnum );
-
-
-/* ------------------------------------------------------------------------- */
-
-/* fpga_no_sup
+/*
+ * fpga_no_sup
* 'no support' message function
*/
-static void fpga_no_sup( char *fn, char *msg )
+static void fpga_no_sup(char *fn, char *msg)
{
- if ( fn && msg ) {
- printf( "%s: No support for %s.\n", fn, msg);
- } else if ( msg ) {
- printf( "No support for %s.\n", msg);
- } else {
- printf( "No FPGA suport!\n");
- }
+ if (fn && msg)
+ printf("%s: No support for %s.\n", fn, msg);
+ else if (msg)
+ printf("No support for %s.\n", msg);
+ else
+ printf("No FPGA suport!\n");
}
/* fpga_get_desc
* map a device number to a descriptor
*/
-static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum )
+static const fpga_desc *const fpga_get_desc(int devnum)
{
- fpga_desc *desc = (fpga_desc * )NULL;
+ fpga_desc *desc = (fpga_desc *)NULL;
- if (( devnum >= 0 ) && (devnum < next_desc )) {
+ if ((devnum >= 0) && (devnum < next_desc)) {
desc = &desc_table[devnum];
- PRINTF( "%s: found fpga descriptor #%d @ 0x%p\n",
- __FUNCTION__, devnum, desc );
+ debug("%s: found fpga descriptor #%d @ 0x%p\n",
+ __func__, devnum, desc);
}
return desc;
}
-
-/* fpga_validate
+/*
+ * fpga_validate
* generic parameter checking code
*/
-static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate(int devnum, const void *buf,
- size_t bsize, char *fn )
+const fpga_desc *const fpga_validate(int devnum, const void *buf,
+ size_t bsize, char *fn)
{
- fpga_desc * desc = fpga_get_desc( devnum );
+ const fpga_desc *desc = fpga_get_desc(devnum);
- if ( !desc ) {
- printf( "%s: Invalid device number %d\n", fn, devnum );
- }
+ if (!desc)
+ printf("%s: Invalid device number %d\n", fn, devnum);
- if ( !buf ) {
- printf( "%s: Null buffer.\n", fn );
+ if (!buf) {
+ printf("%s: Null buffer.\n", fn);
return (fpga_desc * const)NULL;
}
return desc;
}
-
-/* fpga_dev_info
+/*
+ * fpga_dev_info
* generic multiplexing code
*/
-static int fpga_dev_info( int devnum )
+static int fpga_dev_info(int devnum)
{
- int ret_val = FPGA_FAIL; /* assume failure */
- const fpga_desc * const desc = fpga_get_desc( devnum );
+ int ret_val = FPGA_FAIL; /* assume failure */
+ const fpga_desc * const desc = fpga_get_desc(devnum);
- if ( desc ) {
- PRINTF( "%s: Device Descriptor @ 0x%p\n",
- __FUNCTION__, desc->devdesc );
+ if (desc) {
+ debug("%s: Device Descriptor @ 0x%p\n",
+ __func__, desc->devdesc);
- switch ( desc->devtype ) {
+ switch (desc->devtype) {
case fpga_xilinx:
#if defined(CONFIG_FPGA_XILINX)
- printf( "Xilinx Device\nDescriptor @ 0x%p\n", desc );
- ret_val = xilinx_info( desc->devdesc );
+ printf("Xilinx Device\nDescriptor @ 0x%p\n", desc);
+ ret_val = xilinx_info(desc->devdesc);
#else
- fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
+ fpga_no_sup((char *)__func__, "Xilinx devices");
#endif
break;
case fpga_altera:
#if defined(CONFIG_FPGA_ALTERA)
- printf( "Altera Device\nDescriptor @ 0x%p\n", desc );
- ret_val = altera_info( desc->devdesc );
+ printf("Altera Device\nDescriptor @ 0x%p\n", desc);
+ ret_val = altera_info(desc->devdesc);
#else
- fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
+ fpga_no_sup((char *)__func__, "Altera devices");
#endif
break;
case fpga_lattice:
@@ -145,171 +122,183 @@ static int fpga_dev_info( int devnum )
printf("Lattice Device\nDescriptor @ 0x%p\n", desc);
ret_val = lattice_info(desc->devdesc);
#else
- fpga_no_sup( (char *)__FUNCTION__, "Lattice devices" );
+ fpga_no_sup((char *)__func__, "Lattice devices");
#endif
break;
default:
- printf( "%s: Invalid or unsupported device type %d\n",
- __FUNCTION__, desc->devtype );
+ printf("%s: Invalid or unsupported device type %d\n",
+ __func__, desc->devtype);
}
} else {
- printf( "%s: Invalid device number %d\n",
- __FUNCTION__, devnum );
+ printf("%s: Invalid device number %d\n", __func__, devnum);
}
return ret_val;
}
-
-/* ------------------------------------------------------------------------- */
-/* fgpa_init is usually called from misc_init_r() and MUST be called
+/*
+ * fgpa_init is usually called from misc_init_r() and MUST be called
* before any of the other fpga functions are used.
*/
void fpga_init(void)
{
next_desc = 0;
- memset( desc_table, 0, sizeof(desc_table));
+ memset(desc_table, 0, sizeof(desc_table));
- PRINTF( "%s: CONFIG_FPGA = 0x%x\n", __FUNCTION__, CONFIG_FPGA );
+ debug("%s\n", __func__);
}
-/* fpga_count
+/*
+ * fpga_count
* Basic interface function to get the current number of devices available.
*/
-int fpga_count( void )
+int fpga_count(void)
{
return next_desc;
}
-/* fpga_add
+/*
+ * fpga_add
* Add the device descriptor to the device table.
*/
-int fpga_add( fpga_type devtype, void *desc )
+int fpga_add(fpga_type devtype, void *desc)
{
int devnum = FPGA_INVALID_DEVICE;
- if ( next_desc < 0 ) {
- printf( "%s: FPGA support not initialized!\n", __FUNCTION__ );
- } else if (( devtype > fpga_min_type ) && ( devtype < fpga_undefined )) {
- if ( desc ) {
- if ( next_desc < CONFIG_MAX_FPGA_DEVICES ) {
+ if (next_desc < 0) {
+ printf("%s: FPGA support not initialized!\n", __func__);
+ } else if ((devtype > fpga_min_type) && (devtype < fpga_undefined)) {
+ if (desc) {
+ if (next_desc < CONFIG_MAX_FPGA_DEVICES) {
devnum = next_desc;
desc_table[next_desc].devtype = devtype;
desc_table[next_desc++].devdesc = desc;
} else {
- printf( "%s: Exceeded Max FPGA device count\n", __FUNCTION__ );
+ printf("%s: Exceeded Max FPGA device count\n",
+ __func__);
}
} else {
- printf( "%s: NULL device descriptor\n", __FUNCTION__ );
+ printf("%s: NULL device descriptor\n", __func__);
}
} else {
- printf( "%s: Unsupported FPGA type %d\n", __FUNCTION__, devtype );
+ printf("%s: Unsupported FPGA type %d\n", __func__, devtype);
}
return devnum;
}
/*
- * Generic multiplexing code
+ * Convert bitstream data and load into the fpga
+ */
+int __weak fpga_loadbitstream(int devnum, char *fpgadata, size_t size)
+{
+ printf("Bitstream support not implemented for this FPGA device\n");
+ return FPGA_FAIL;
+}
+
+/*
+ * Generic multiplexing code
*/
int fpga_load(int devnum, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume failure */
- fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ );
+ const fpga_desc *desc = fpga_validate(devnum, buf, bsize,
+ (char *)__func__);
- if ( desc ) {
- switch ( desc->devtype ) {
+ if (desc) {
+ switch (desc->devtype) {
case fpga_xilinx:
#if defined(CONFIG_FPGA_XILINX)
- ret_val = xilinx_load( desc->devdesc, buf, bsize );
+ ret_val = xilinx_load(desc->devdesc, buf, bsize);
#else
- fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
+ fpga_no_sup((char *)__func__, "Xilinx devices");
#endif
break;
case fpga_altera:
#if defined(CONFIG_FPGA_ALTERA)
- ret_val = altera_load( desc->devdesc, buf, bsize );
+ ret_val = altera_load(desc->devdesc, buf, bsize);
#else
- fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
+ fpga_no_sup((char *)__func__, "Altera devices");
#endif
break;
case fpga_lattice:
#if defined(CONFIG_FPGA_LATTICE)
ret_val = lattice_load(desc->devdesc, buf, bsize);
#else
- fpga_no_sup( (char *)__FUNCTION__, "Lattice devices" );
+ fpga_no_sup((char *)__func__, "Lattice devices");
#endif
break;
default:
- printf( "%s: Invalid or unsupported device type %d\n",
- __FUNCTION__, desc->devtype );
+ printf("%s: Invalid or unsupported device type %d\n",
+ __func__, desc->devtype);
}
}
return ret_val;
}
-/* fpga_dump
+/*
+ * fpga_dump
* generic multiplexing code
*/
int fpga_dump(int devnum, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume failure */
- fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ );
+ const fpga_desc *desc = fpga_validate(devnum, buf, bsize,
+ (char *)__func__);
- if ( desc ) {
- switch ( desc->devtype ) {
+ if (desc) {
+ switch (desc->devtype) {
case fpga_xilinx:
#if defined(CONFIG_FPGA_XILINX)
- ret_val = xilinx_dump( desc->devdesc, buf, bsize );
+ ret_val = xilinx_dump(desc->devdesc, buf, bsize);
#else
- fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
+ fpga_no_sup((char *)__func__, "Xilinx devices");
#endif
break;
case fpga_altera:
#if defined(CONFIG_FPGA_ALTERA)
- ret_val = altera_dump( desc->devdesc, buf, bsize );
+ ret_val = altera_dump(desc->devdesc, buf, bsize);
#else
- fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
+ fpga_no_sup((char *)__func__, "Altera devices");
#endif
break;
case fpga_lattice:
#if defined(CONFIG_FPGA_LATTICE)
ret_val = lattice_dump(desc->devdesc, buf, bsize);
#else
- fpga_no_sup( (char *)__FUNCTION__, "Lattice devices" );
+ fpga_no_sup((char *)__func__, "Lattice devices");
#endif
break;
default:
- printf( "%s: Invalid or unsupported device type %d\n",
- __FUNCTION__, desc->devtype );
+ printf("%s: Invalid or unsupported device type %d\n",
+ __func__, desc->devtype);
}
}
return ret_val;
}
-
-/* fpga_info
+/*
+ * fpga_info
* front end to fpga_dev_info. If devnum is invalid, report on all
* available devices.
*/
-int fpga_info( int devnum )
+int fpga_info(int devnum)
{
- if ( devnum == FPGA_INVALID_DEVICE ) {
- if ( next_desc > 0 ) {
+ if (devnum == FPGA_INVALID_DEVICE) {
+ if (next_desc > 0) {
int dev;
- for ( dev = 0; dev < next_desc; dev++ ) {
- fpga_dev_info( dev );
- }
+ for (dev = 0; dev < next_desc; dev++)
+ fpga_dev_info(dev);
+
return FPGA_SUCCESS;
} else {
- printf( "%s: No FPGA devices available.\n", __FUNCTION__ );
+ printf("%s: No FPGA devices available.\n", __func__);
return FPGA_FAIL;
}
}
- else return fpga_dev_info( devnum );
-}
-/* ------------------------------------------------------------------------- */
+ return fpga_dev_info(devnum);
+}
diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c
index 32787b2..49e9437 100644
--- a/drivers/fpga/xilinx.c
+++ b/drivers/fpga/xilinx.c
@@ -1,4 +1,6 @@
/*
+ * (C) Copyright 2012-2013, Xilinx, Michal Simek
+ *
* (C) Copyright 2002
* Rich Ireland, Enterasys Networks, rireland@enterasys.com.
* Keith Outwater, keith_outwater@mvis.com
@@ -28,9 +30,11 @@
*/
#include <common.h>
+#include <fpga.h>
#include <virtex2.h>
#include <spartan2.h>
#include <spartan3.h>
+#include <zynqpl.h>
#if 0
#define FPGA_DEBUG
@@ -48,6 +52,112 @@ static int xilinx_validate (Xilinx_desc * desc, char *fn);
/* ------------------------------------------------------------------------- */
+int fpga_loadbitstream(int devnum, char *fpgadata, size_t size)
+{
+ unsigned int length;
+ unsigned int swapsize;
+ char buffer[80];
+ unsigned char *dataptr;
+ unsigned int i;
+ const fpga_desc *desc;
+ Xilinx_desc *xdesc;
+
+ dataptr = (unsigned char *)fpgadata;
+ /* Find out fpga_description */
+ desc = fpga_validate(devnum, dataptr, 0, (char *)__func__);
+ /* Assign xilinx device description */
+ xdesc = desc->devdesc;
+
+ /* skip the first bytes of the bitsteam, their meaning is unknown */
+ length = (*dataptr << 8) + *(dataptr + 1);
+ dataptr += 2;
+ dataptr += length;
+
+ /* get design name (identifier, length, string) */
+ length = (*dataptr << 8) + *(dataptr + 1);
+ dataptr += 2;
+ if (*dataptr++ != 0x61) {
+ debug("%s: Design name id not recognized in bitstream\n",
+ __func__);
+ return FPGA_FAIL;
+ }
+
+ length = (*dataptr << 8) + *(dataptr + 1);
+ dataptr += 2;
+ for (i = 0; i < length; i++)
+ buffer[i] = *dataptr++;
+
+ printf(" design filename = \"%s\"\n", buffer);
+
+ /* get part number (identifier, length, string) */
+ if (*dataptr++ != 0x62) {
+ printf("%s: Part number id not recognized in bitstream\n",
+ __func__);
+ return FPGA_FAIL;
+ }
+
+ length = (*dataptr << 8) + *(dataptr + 1);
+ dataptr += 2;
+ for (i = 0; i < length; i++)
+ buffer[i] = *dataptr++;
+
+ if (xdesc->name) {
+ i = strncmp(buffer, xdesc->name, strlen(xdesc->name));
+ if (i) {
+ printf("%s: Wrong bitstream ID for this device\n",
+ __func__);
+ printf("%s: Bitstream ID %s, current device ID %d/%s\n",
+ __func__, buffer, devnum, xdesc->name);
+ return FPGA_FAIL;
+ }
+ } else {
+ printf("%s: Please fill correct device ID to Xilinx_desc\n",
+ __func__);
+ }
+ printf(" part number = \"%s\"\n", buffer);
+
+ /* get date (identifier, length, string) */
+ if (*dataptr++ != 0x63) {
+ printf("%s: Date identifier not recognized in bitstream\n",
+ __func__);
+ return FPGA_FAIL;
+ }
+
+ length = (*dataptr << 8) + *(dataptr+1);
+ dataptr += 2;
+ for (i = 0; i < length; i++)
+ buffer[i] = *dataptr++;
+ printf(" date = \"%s\"\n", buffer);
+
+ /* get time (identifier, length, string) */
+ if (*dataptr++ != 0x64) {
+ printf("%s: Time identifier not recognized in bitstream\n",
+ __func__);
+ return FPGA_FAIL;
+ }
+
+ length = (*dataptr << 8) + *(dataptr+1);
+ dataptr += 2;
+ for (i = 0; i < length; i++)
+ buffer[i] = *dataptr++;
+ printf(" time = \"%s\"\n", buffer);
+
+ /* get fpga data length (identifier, length) */
+ if (*dataptr++ != 0x65) {
+ printf("%s: Data length id not recognized in bitstream\n",
+ __func__);
+ return FPGA_FAIL;
+ }
+ swapsize = ((unsigned int) *dataptr << 24) +
+ ((unsigned int) *(dataptr + 1) << 16) +
+ ((unsigned int) *(dataptr + 2) << 8) +
+ ((unsigned int) *(dataptr + 3));
+ dataptr += 4;
+ printf(" bytes in bitstream = %d\n", swapsize);
+
+ return fpga_load(devnum, dataptr, swapsize);
+}
+
int xilinx_load(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume a failure */
@@ -86,6 +196,16 @@ int xilinx_load(Xilinx_desc *desc, const void *buf, size_t bsize)
__FUNCTION__);
#endif
break;
+ case xilinx_zynq:
+#if defined(CONFIG_FPGA_ZYNQPL)
+ PRINTF("%s: Launching the Zynq PL Loader...\n",
+ __func__);
+ ret_val = zynq_load(desc, buf, bsize);
+#else
+ printf("%s: No support for Zynq devices.\n",
+ __func__);
+#endif
+ break;
default:
printf ("%s: Unsupported family type, %d\n",
@@ -133,6 +253,16 @@ int xilinx_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
__FUNCTION__);
#endif
break;
+ case xilinx_zynq:
+#if defined(CONFIG_FPGA_ZYNQPL)
+ PRINTF("%s: Launching the Zynq PL Reader...\n",
+ __func__);
+ ret_val = zynq_dump(desc, buf, bsize);
+#else
+ printf("%s: No support for Zynq devices.\n",
+ __func__);
+#endif
+ break;
default:
printf ("%s: Unsupported family type, %d\n",
@@ -158,6 +288,9 @@ int xilinx_info (Xilinx_desc * desc)
case Xilinx_Virtex2:
printf ("Virtex-II\n");
break;
+ case xilinx_zynq:
+ printf("Zynq PL\n");
+ break;
/* Add new family types here */
default:
printf ("Unknown family type, %d\n", desc->family);
@@ -183,6 +316,9 @@ int xilinx_info (Xilinx_desc * desc)
case master_selectmap:
printf ("Master SelectMap Mode\n");
break;
+ case devcfg:
+ printf("Device configuration interface (Zynq)\n");
+ break;
/* Add new interface types here */
default:
printf ("Unsupported interface type, %d\n", desc->iface);
@@ -191,6 +327,8 @@ int xilinx_info (Xilinx_desc * desc)
printf ("Device Size: \t%d bytes\n"
"Cookie: \t0x%x (%d)\n",
desc->size, desc->cookie, desc->cookie);
+ if (desc->name)
+ printf("Device name: \t%s\n", desc->name);
if (desc->iface_fns) {
printf ("Device Function Table @ 0x%p\n", desc->iface_fns);
@@ -222,6 +360,14 @@ int xilinx_info (Xilinx_desc * desc)
__FUNCTION__);
#endif
break;
+ case xilinx_zynq:
+#if defined(CONFIG_FPGA_ZYNQPL)
+ zynq_info(desc);
+#else
+ /* just in case */
+ printf("%s: No support for Zynq devices.\n",
+ __func__);
+#endif
/* Add new family types here */
default:
/* we don't need a message here - we give one up above */
diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c
new file mode 100644
index 0000000..8feccde
--- /dev/null
+++ b/drivers/fpga/zynqpl.c
@@ -0,0 +1,355 @@
+/*
+ * (C) Copyright 2012-2013, Xilinx, Michal Simek
+ *
+ * (C) Copyright 2012
+ * Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <zynqpl.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+
+#define DEVCFG_CTRL_PCFG_PROG_B 0x40000000
+#define DEVCFG_ISR_FATAL_ERROR_MASK 0x00740040
+#define DEVCFG_ISR_ERROR_FLAGS_MASK 0x00340840
+#define DEVCFG_ISR_RX_FIFO_OV 0x00040000
+#define DEVCFG_ISR_DMA_DONE 0x00002000
+#define DEVCFG_ISR_PCFG_DONE 0x00000004
+#define DEVCFG_STATUS_DMA_CMD_Q_F 0x80000000
+#define DEVCFG_STATUS_DMA_CMD_Q_E 0x40000000
+#define DEVCFG_STATUS_DMA_DONE_CNT_MASK 0x30000000
+#define DEVCFG_STATUS_PCFG_INIT 0x00000010
+#define DEVCFG_MCTRL_RFIFO_FLUSH 0x00000002
+#define DEVCFG_MCTRL_WFIFO_FLUSH 0x00000001
+
+#ifndef CONFIG_SYS_FPGA_WAIT
+#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
+#endif
+
+#ifndef CONFIG_SYS_FPGA_PROG_TIME
+#define CONFIG_SYS_FPGA_PROG_TIME CONFIG_SYS_HZ /* 1 s */
+#endif
+
+int zynq_info(Xilinx_desc *desc)
+{
+ return FPGA_SUCCESS;
+}
+
+#define DUMMY_WORD 0xffffffff
+
+/* Xilinx binary format header */
+static const u32 bin_format[] = {
+ DUMMY_WORD, /* Dummy words */
+ DUMMY_WORD,
+ DUMMY_WORD,
+ DUMMY_WORD,
+ DUMMY_WORD,
+ DUMMY_WORD,
+ DUMMY_WORD,
+ DUMMY_WORD,
+ 0x000000bb, /* Sync word */
+ 0x11220044, /* Sync word */
+ DUMMY_WORD,
+ DUMMY_WORD,
+ 0xaa995566, /* Sync word */
+};
+
+#define SWAP_NO 1
+#define SWAP_DONE 2
+
+/*
+ * Load the whole word from unaligned buffer
+ * Keep in your mind that it is byte loading on little-endian system
+ */
+static u32 load_word(const void *buf, u32 swap)
+{
+ u32 word = 0;
+ u8 *bitc = (u8 *)buf;
+ int p;
+
+ if (swap == SWAP_NO) {
+ for (p = 0; p < 4; p++) {
+ word <<= 8;
+ word |= bitc[p];
+ }
+ } else {
+ for (p = 3; p >= 0; p--) {
+ word <<= 8;
+ word |= bitc[p];
+ }
+ }
+
+ return word;
+}
+
+static u32 check_header(const void *buf)
+{
+ u32 i, pattern;
+ int swap = SWAP_NO;
+ u32 *test = (u32 *)buf;
+
+ debug("%s: Let's check bitstream header\n", __func__);
+
+ /* Checking that passing bin is not a bitstream */
+ for (i = 0; i < ARRAY_SIZE(bin_format); i++) {
+ pattern = load_word(&test[i], swap);
+
+ /*
+ * Bitstreams in binary format are swapped
+ * compare to regular bistream.
+ * Do not swap dummy word but if swap is done assume
+ * that parsing buffer is binary format
+ */
+ if ((__swab32(pattern) != DUMMY_WORD) &&
+ (__swab32(pattern) == bin_format[i])) {
+ pattern = __swab32(pattern);
+ swap = SWAP_DONE;
+ debug("%s: data swapped - let's swap\n", __func__);
+ }
+
+ debug("%s: %d/%x: pattern %x/%x bin_format\n", __func__, i,
+ (u32)&test[i], pattern, bin_format[i]);
+ if (pattern != bin_format[i]) {
+ debug("%s: Bitstream is not recognized\n", __func__);
+ return 0;
+ }
+ }
+ debug("%s: Found bitstream header at %x %s swapinng\n", __func__,
+ (u32)buf, swap == SWAP_NO ? "without" : "with");
+
+ return swap;
+}
+
+static void *check_data(u8 *buf, size_t bsize, u32 *swap)
+{
+ u32 word, p = 0; /* possition */
+
+ /* Because buf doesn't need to be aligned let's read it by chars */
+ for (p = 0; p < bsize; p++) {
+ word = load_word(&buf[p], SWAP_NO);
+ debug("%s: word %x %x/%x\n", __func__, word, p, (u32)&buf[p]);
+
+ /* Find the first bitstream dummy word */
+ if (word == DUMMY_WORD) {
+ debug("%s: Found dummy word at position %x/%x\n",
+ __func__, p, (u32)&buf[p]);
+ *swap = check_header(&buf[p]);
+ if (*swap) {
+ /* FIXME add full bitstream checking here */
+ return &buf[p];
+ }
+ }
+ /* Loop can be huge - support CTRL + C */
+ if (ctrlc())
+ return 0;
+ }
+ return 0;
+}
+
+
+int zynq_load(Xilinx_desc *desc, const void *buf, size_t bsize)
+{
+ unsigned long ts; /* Timestamp */
+ u32 partialbit = 0;
+ u32 i, control, isr_status, status, swap, diff;
+ u32 *buf_start;
+
+ /* Detect if we are going working with partial or full bitstream */
+ if (bsize != desc->size) {
+ printf("%s: Working with partial bitstream\n", __func__);
+ partialbit = 1;
+ }
+
+ buf_start = check_data((u8 *)buf, bsize, &swap);
+ if (!buf_start)
+ return FPGA_FAIL;
+
+ /* Check if data is postpone from start */
+ diff = (u32)buf_start - (u32)buf;
+ if (diff) {
+ printf("%s: Bitstream is not validated yet (diff %x)\n",
+ __func__, diff);
+ return FPGA_FAIL;
+ }
+
+ if ((u32)buf_start & 0x3) {
+ u32 *new_buf = (u32 *)((u32)buf & ~0x3);
+
+ printf("%s: Align buffer at %x to %x(swap %d)\n", __func__,
+ (u32)buf_start, (u32)new_buf, swap);
+
+ for (i = 0; i < (bsize/4); i++)
+ new_buf[i] = load_word(&buf_start[i], swap);
+
+ swap = SWAP_DONE;
+ buf = new_buf;
+ } else if (swap != SWAP_DONE) {
+ /* For bitstream which are aligned */
+ u32 *new_buf = (u32 *)buf;
+
+ printf("%s: Bitstream is not swapped(%d) - swap it\n", __func__,
+ swap);
+
+ for (i = 0; i < (bsize/4); i++)
+ new_buf[i] = load_word(&buf_start[i], swap);
+
+ swap = SWAP_DONE;
+ }
+
+ if (!partialbit) {
+ zynq_slcr_devcfg_disable();
+
+ /* Setting PCFG_PROG_B signal to high */
+ control = readl(&devcfg_base->ctrl);
+ writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl);
+ /* Setting PCFG_PROG_B signal to low */
+ writel(control & ~DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl);
+
+ /* Polling the PCAP_INIT status for Reset */
+ ts = get_timer(0);
+ while (readl(&devcfg_base->status) & DEVCFG_STATUS_PCFG_INIT) {
+ if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
+ printf("%s: Timeout wait for INIT to clear\n",
+ __func__);
+ return FPGA_FAIL;
+ }
+ }
+
+ /* Setting PCFG_PROG_B signal to high */
+ writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl);
+
+ /* Polling the PCAP_INIT status for Set */
+ ts = get_timer(0);
+ while (!(readl(&devcfg_base->status) &
+ DEVCFG_STATUS_PCFG_INIT)) {
+ if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
+ printf("%s: Timeout wait for INIT to set\n",
+ __func__);
+ return FPGA_FAIL;
+ }
+ }
+ }
+
+ isr_status = readl(&devcfg_base->int_sts);
+
+ /* Clear it all, so if Boot ROM comes back, it can proceed */
+ writel(0xFFFFFFFF, &devcfg_base->int_sts);
+
+ if (isr_status & DEVCFG_ISR_FATAL_ERROR_MASK) {
+ debug("%s: Fatal errors in PCAP 0x%X\n", __func__, isr_status);
+
+ /* If RX FIFO overflow, need to flush RX FIFO first */
+ if (isr_status & DEVCFG_ISR_RX_FIFO_OV) {
+ writel(DEVCFG_MCTRL_RFIFO_FLUSH, &devcfg_base->mctrl);
+ writel(0xFFFFFFFF, &devcfg_base->int_sts);
+ }
+ return FPGA_FAIL;
+ }
+
+ status = readl(&devcfg_base->status);
+
+ debug("%s: Status = 0x%08X\n", __func__, status);
+
+ if (status & DEVCFG_STATUS_DMA_CMD_Q_F) {
+ debug("%s: Error: device busy\n", __func__);
+ return FPGA_FAIL;
+ }
+
+ debug("%s: Device ready\n", __func__);
+
+ if (!(status & DEVCFG_STATUS_DMA_CMD_Q_E)) {
+ if (!(readl(&devcfg_base->int_sts) & DEVCFG_ISR_DMA_DONE)) {
+ /* Error state, transfer cannot occur */
+ debug("%s: ISR indicates error\n", __func__);
+ return FPGA_FAIL;
+ } else {
+ /* Clear out the status */
+ writel(DEVCFG_ISR_DMA_DONE, &devcfg_base->int_sts);
+ }
+ }
+
+ if (status & DEVCFG_STATUS_DMA_DONE_CNT_MASK) {
+ /* Clear the count of completed DMA transfers */
+ writel(DEVCFG_STATUS_DMA_DONE_CNT_MASK, &devcfg_base->status);
+ }
+
+ debug("%s: Source = 0x%08X\n", __func__, (u32)buf);
+ debug("%s: Size = %zu\n", __func__, bsize);
+
+ /* Set up the transfer */
+ writel((u32)buf | 1, &devcfg_base->dma_src_addr);
+ writel(0xFFFFFFFF, &devcfg_base->dma_dst_addr);
+ writel(bsize >> 2, &devcfg_base->dma_src_len);
+ writel(0, &devcfg_base->dma_dst_len);
+
+ isr_status = readl(&devcfg_base->int_sts);
+
+ /* Polling the PCAP_INIT status for Set */
+ ts = get_timer(0);
+ while (!(isr_status & DEVCFG_ISR_DMA_DONE)) {
+ if (isr_status & DEVCFG_ISR_ERROR_FLAGS_MASK) {
+ debug("%s: Error: isr = 0x%08X\n", __func__,
+ isr_status);
+ debug("%s: Write count = 0x%08X\n", __func__,
+ readl(&devcfg_base->write_count));
+ debug("%s: Read count = 0x%08X\n", __func__,
+ readl(&devcfg_base->read_count));
+
+ return FPGA_FAIL;
+ }
+ if (get_timer(ts) > CONFIG_SYS_FPGA_PROG_TIME) {
+ printf("%s: Timeout wait for DMA to complete\n",
+ __func__);
+ return FPGA_FAIL;
+ }
+ isr_status = readl(&devcfg_base->int_sts);
+ }
+
+ debug("%s: DMA transfer is done\n", __func__);
+
+ /* Check FPGA configuration completion */
+ ts = get_timer(0);
+ while (!(isr_status & DEVCFG_ISR_PCFG_DONE)) {
+ if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
+ printf("%s: Timeout wait for FPGA to config\n",
+ __func__);
+ return FPGA_FAIL;
+ }
+ isr_status = readl(&devcfg_base->int_sts);
+ }
+
+ debug("%s: FPGA config done\n", __func__);
+
+ /* Clear out the DMA status */
+ writel(DEVCFG_ISR_DMA_DONE, &devcfg_base->int_sts);
+
+ if (!partialbit)
+ zynq_slcr_devcfg_enable();
+
+ return FPGA_SUCCESS;
+}
+
+int zynq_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
+{
+ return FPGA_FAIL;
+}
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 5dbdbe3..72e85a3 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -46,6 +46,7 @@ COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
COBJS-$(CONFIG_SH_I2C) += sh_i2c.o
COBJS-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
+COBJS-$(CONFIG_ZYNQ_I2C) += zynq_i2c.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/i2c/zynq_i2c.c b/drivers/i2c/zynq_i2c.c
new file mode 100644
index 0000000..ec49660
--- /dev/null
+++ b/drivers/i2c/zynq_i2c.c
@@ -0,0 +1,306 @@
+/*
+ * Driver for the Zynq-7000 PS I2C controller
+ * IP from Cadence (ID T-CS-PE-0007-100, Version R1p10f2)
+ *
+ * Author: Joe Hershberger <joe.hershberger@ni.com>
+ * Copyright (c) 2012 Joe Hershberger.
+ *
+ * Copyright (c) 2012-2013 Xilinx, Michal Simek
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <i2c.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+
+/* i2c register set */
+struct zynq_i2c_registers {
+ u32 control;
+ u32 status;
+ u32 address;
+ u32 data;
+ u32 interrupt_status;
+ u32 transfer_size;
+ u32 slave_mon_pause;
+ u32 time_out;
+ u32 interrupt_mask;
+ u32 interrupt_enable;
+ u32 interrupt_disable;
+};
+
+/* Control register fields */
+#define ZYNQ_I2C_CONTROL_RW 0x00000001
+#define ZYNQ_I2C_CONTROL_MS 0x00000002
+#define ZYNQ_I2C_CONTROL_NEA 0x00000004
+#define ZYNQ_I2C_CONTROL_ACKEN 0x00000008
+#define ZYNQ_I2C_CONTROL_HOLD 0x00000010
+#define ZYNQ_I2C_CONTROL_SLVMON 0x00000020
+#define ZYNQ_I2C_CONTROL_CLR_FIFO 0x00000040
+#define ZYNQ_I2C_CONTROL_DIV_B_SHIFT 8
+#define ZYNQ_I2C_CONTROL_DIV_B_MASK 0x00003F00
+#define ZYNQ_I2C_CONTROL_DIV_A_SHIFT 14
+#define ZYNQ_I2C_CONTROL_DIV_A_MASK 0x0000C000
+
+/* Status register values */
+#define ZYNQ_I2C_STATUS_RXDV 0x00000020
+#define ZYNQ_I2C_STATUS_TXDV 0x00000040
+#define ZYNQ_I2C_STATUS_RXOVF 0x00000080
+#define ZYNQ_I2C_STATUS_BA 0x00000100
+
+/* Interrupt register fields */
+#define ZYNQ_I2C_INTERRUPT_COMP 0x00000001
+#define ZYNQ_I2C_INTERRUPT_DATA 0x00000002
+#define ZYNQ_I2C_INTERRUPT_NACK 0x00000004
+#define ZYNQ_I2C_INTERRUPT_TO 0x00000008
+#define ZYNQ_I2C_INTERRUPT_SLVRDY 0x00000010
+#define ZYNQ_I2C_INTERRUPT_RXOVF 0x00000020
+#define ZYNQ_I2C_INTERRUPT_TXOVF 0x00000040
+#define ZYNQ_I2C_INTERRUPT_RXUNF 0x00000080
+#define ZYNQ_I2C_INTERRUPT_ARBLOST 0x00000200
+
+#define ZYNQ_I2C_FIFO_DEPTH 16
+#define ZYNQ_I2C_TRANSFERT_SIZE_MAX 255 /* Controller transfer limit */
+
+#if defined(CONFIG_ZYNQ_I2C0)
+# define ZYNQ_I2C_BASE ZYNQ_I2C_BASEADDR0
+#else
+# define ZYNQ_I2C_BASE ZYNQ_I2C_BASEADDR1
+#endif
+
+static struct zynq_i2c_registers *zynq_i2c =
+ (struct zynq_i2c_registers *)ZYNQ_I2C_BASE;
+
+/* I2C init called by cmd_i2c when doing 'i2c reset'. */
+void i2c_init(int requested_speed, int slaveadd)
+{
+ /* 111MHz / ( (3 * 17) * 22 ) = ~100KHz */
+ writel((16 << ZYNQ_I2C_CONTROL_DIV_B_SHIFT) |
+ (2 << ZYNQ_I2C_CONTROL_DIV_A_SHIFT), &zynq_i2c->control);
+
+ /* Enable master mode, ack, and 7-bit addressing */
+ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_MS |
+ ZYNQ_I2C_CONTROL_ACKEN | ZYNQ_I2C_CONTROL_NEA);
+}
+
+#ifdef DEBUG
+static void zynq_i2c_debug_status(void)
+{
+ int int_status;
+ int status;
+ int_status = readl(&zynq_i2c->interrupt_status);
+
+ status = readl(&zynq_i2c->status);
+ if (int_status || status) {
+ debug("Status: ");
+ if (int_status & ZYNQ_I2C_INTERRUPT_COMP)
+ debug("COMP ");
+ if (int_status & ZYNQ_I2C_INTERRUPT_DATA)
+ debug("DATA ");
+ if (int_status & ZYNQ_I2C_INTERRUPT_NACK)
+ debug("NACK ");
+ if (int_status & ZYNQ_I2C_INTERRUPT_TO)
+ debug("TO ");
+ if (int_status & ZYNQ_I2C_INTERRUPT_SLVRDY)
+ debug("SLVRDY ");
+ if (int_status & ZYNQ_I2C_INTERRUPT_RXOVF)
+ debug("RXOVF ");
+ if (int_status & ZYNQ_I2C_INTERRUPT_TXOVF)
+ debug("TXOVF ");
+ if (int_status & ZYNQ_I2C_INTERRUPT_RXUNF)
+ debug("RXUNF ");
+ if (int_status & ZYNQ_I2C_INTERRUPT_ARBLOST)
+ debug("ARBLOST ");
+ if (status & ZYNQ_I2C_STATUS_RXDV)
+ debug("RXDV ");
+ if (status & ZYNQ_I2C_STATUS_TXDV)
+ debug("TXDV ");
+ if (status & ZYNQ_I2C_STATUS_RXOVF)
+ debug("RXOVF ");
+ if (status & ZYNQ_I2C_STATUS_BA)
+ debug("BA ");
+ debug("TS%d ", readl(&zynq_i2c->transfer_size));
+ debug("\n");
+ }
+}
+#endif
+
+/* Wait for an interrupt */
+static u32 zynq_i2c_wait(u32 mask)
+{
+ int timeout, int_status;
+
+ for (timeout = 0; timeout < 100; timeout++) {
+ udelay(100);
+ int_status = readl(&zynq_i2c->interrupt_status);
+ if (int_status & mask)
+ break;
+ }
+#ifdef DEBUG
+ zynq_i2c_debug_status();
+#endif
+ /* Clear interrupt status flags */
+ writel(int_status & mask, &zynq_i2c->interrupt_status);
+
+ return int_status & mask;
+}
+
+/*
+ * I2C probe called by cmd_i2c when doing 'i2c probe'.
+ * Begin read, nak data byte, end.
+ */
+int i2c_probe(u8 dev)
+{
+ /* Attempt to read a byte */
+ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
+ ZYNQ_I2C_CONTROL_RW);
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+ writel(0xFF, &zynq_i2c->interrupt_status);
+ writel(dev, &zynq_i2c->address);
+ writel(1, &zynq_i2c->transfer_size);
+
+ return (zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP |
+ ZYNQ_I2C_INTERRUPT_NACK) &
+ ZYNQ_I2C_INTERRUPT_COMP) ? 0 : -ETIMEDOUT;
+}
+
+/*
+ * I2C read called by cmd_i2c when doing 'i2c read' and by cmd_eeprom.c
+ * Begin write, send address byte(s), begin read, receive data bytes, end.
+ */
+int i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+ u32 status;
+ u32 i = 0;
+ u8 *cur_data = data;
+
+ /* Check the hardware can handle the requested bytes */
+ if ((length < 0) || (length > ZYNQ_I2C_TRANSFERT_SIZE_MAX))
+ return -EINVAL;
+
+ /* Write the register address */
+ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
+ ZYNQ_I2C_CONTROL_HOLD);
+ /*
+ * Temporarily disable restart (by clearing hold)
+ * It doesn't seem to work.
+ */
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW |
+ ZYNQ_I2C_CONTROL_HOLD);
+ writel(0xFF, &zynq_i2c->interrupt_status);
+ while (alen--)
+ writel(addr >> (8*alen), &zynq_i2c->data);
+ writel(dev, &zynq_i2c->address);
+
+ /* Wait for the address to be sent */
+ if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
+ /* Release the bus */
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+ return -ETIMEDOUT;
+ }
+ debug("Device acked address\n");
+
+ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
+ ZYNQ_I2C_CONTROL_RW);
+ /* Start reading data */
+ writel(dev, &zynq_i2c->address);
+ writel(length, &zynq_i2c->transfer_size);
+
+ /* Wait for data */
+ do {
+ status = zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP |
+ ZYNQ_I2C_INTERRUPT_DATA);
+ if (!status) {
+ /* Release the bus */
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+ return -ETIMEDOUT;
+ }
+ debug("Read %d bytes\n",
+ length - readl(&zynq_i2c->transfer_size));
+ for (; i < length - readl(&zynq_i2c->transfer_size); i++)
+ *(cur_data++) = readl(&zynq_i2c->data);
+ } while (readl(&zynq_i2c->transfer_size) != 0);
+ /* All done... release the bus */
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+
+#ifdef DEBUG
+ zynq_i2c_debug_status();
+#endif
+ return 0;
+}
+
+/*
+ * I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c
+ * Begin write, send address byte(s), send data bytes, end.
+ */
+int i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+ u8 *cur_data = data;
+
+ /* Write the register address */
+ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
+ ZYNQ_I2C_CONTROL_HOLD);
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW);
+ writel(0xFF, &zynq_i2c->interrupt_status);
+ while (alen--)
+ writel(addr >> (8*alen), &zynq_i2c->data);
+ /* Start the tranfer */
+ writel(dev, &zynq_i2c->address);
+ if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
+ /* Release the bus */
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+ return -ETIMEDOUT;
+ }
+
+ debug("Device acked address\n");
+ while (length--) {
+ writel(*(cur_data++), &zynq_i2c->data);
+ if (readl(&zynq_i2c->transfer_size) == ZYNQ_I2C_FIFO_DEPTH) {
+ if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
+ /* Release the bus */
+ clrbits_le32(&zynq_i2c->control,
+ ZYNQ_I2C_CONTROL_HOLD);
+ return -ETIMEDOUT;
+ }
+ }
+ }
+
+ /* All done... release the bus */
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+ /* Wait for the address and data to be sent */
+ if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP))
+ return -ETIMEDOUT;
+ return 0;
+}
+
+int i2c_set_bus_num(unsigned int bus)
+{
+ /* Only support bus 0 */
+ if (bus > 0)
+ return -1;
+ return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+ /* Only support bus 0 */
+ return 0;
+}
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 1d6faa2..7cd4281 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -49,6 +49,7 @@ COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
COBJS-$(CONFIG_DWMMC) += dw_mmc.o
COBJS-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o
+COBJS-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index d732581..2590f1b 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -601,7 +601,7 @@ static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
data.dest = (char *)ext_csd;
data.blocks = 1;
- data.blocksize = 512;
+ data.blocksize = MMC_MAX_BLOCK_LEN;
data.flags = MMC_DATA_READ;
err = mmc_send_cmd(mmc, &cmd, &data);
@@ -634,7 +634,7 @@ static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
static int mmc_change_freq(struct mmc *mmc)
{
- ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512);
+ ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
char cardtype;
int err;
@@ -784,6 +784,8 @@ retry_scr:
break;
case 2:
mmc->version = SD_VERSION_2;
+ if ((mmc->scr[0] >> 15) & 0x1)
+ mmc->version = SD_VERSION_3;
break;
default:
mmc->version = SD_VERSION_1_0;
@@ -897,8 +899,8 @@ static int mmc_startup(struct mmc *mmc)
uint mult, freq;
u64 cmult, csize, capacity;
struct mmc_cmd cmd;
- ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512);
- ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, 512);
+ ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+ ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
int timeout = 1000;
#ifdef CONFIG_MMC_SPI_CRC_ON
@@ -1014,11 +1016,11 @@ static int mmc_startup(struct mmc *mmc)
mmc->capacity = (csize + 1) << (cmult + 2);
mmc->capacity *= mmc->read_bl_len;
- if (mmc->read_bl_len > 512)
- mmc->read_bl_len = 512;
+ if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
+ mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
- if (mmc->write_bl_len > 512)
- mmc->write_bl_len = 512;
+ if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
+ mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
/* Select the card, and put it into Transfer Mode */
if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
@@ -1049,20 +1051,39 @@ static int mmc_startup(struct mmc *mmc)
| ext_csd[EXT_CSD_SEC_CNT + 1] << 8
| ext_csd[EXT_CSD_SEC_CNT + 2] << 16
| ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
- capacity *= 512;
+ capacity *= MMC_MAX_BLOCK_LEN;
if ((capacity >> 20) > 2 * 1024)
mmc->capacity = capacity;
}
+ switch (ext_csd[EXT_CSD_REV]) {
+ case 1:
+ mmc->version = MMC_VERSION_4_1;
+ break;
+ case 2:
+ mmc->version = MMC_VERSION_4_2;
+ break;
+ case 3:
+ mmc->version = MMC_VERSION_4_3;
+ break;
+ case 5:
+ mmc->version = MMC_VERSION_4_41;
+ break;
+ case 6:
+ mmc->version = MMC_VERSION_4_5;
+ break;
+ }
+
/*
* Check whether GROUP_DEF is set, if yes, read out
* group size from ext_csd directly, or calculate
* the group size from the csd value.
*/
- if (ext_csd[EXT_CSD_ERASE_GROUP_DEF])
+ if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {
mmc->erase_grp_size =
- ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 512 * 1024;
- else {
+ ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
+ MMC_MAX_BLOCK_LEN * 1024;
+ } else {
int erase_gsz, erase_gmul;
erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
@@ -1182,6 +1203,7 @@ static int mmc_startup(struct mmc *mmc)
mmc->block_dev.lun = 0;
mmc->block_dev.type = 0;
mmc->block_dev.blksz = mmc->read_bl_len;
+ mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
diff --git a/drivers/mmc/spl_mmc.c b/drivers/mmc/spl_mmc.c
index 753c6a0..7efdcb8 100644
--- a/drivers/mmc/spl_mmc.c
+++ b/drivers/mmc/spl_mmc.c
@@ -34,8 +34,9 @@ DECLARE_GLOBAL_DATA_PTR;
static void mmc_load_image_raw(struct mmc *mmc)
{
- u32 image_size_sectors, err;
- const struct image_header *header;
+ unsigned long err;
+ u32 image_size_sectors;
+ struct image_header *header;
header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
sizeof(struct image_header));
@@ -43,9 +44,9 @@ static void mmc_load_image_raw(struct mmc *mmc)
/* read image header to find the image size & load address */
err = mmc->block_dev.block_read(0,
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1,
- (void *)header);
+ header);
- if (err <= 0)
+ if (err == 0)
goto end;
spl_parse_image_header(header);
@@ -60,8 +61,8 @@ static void mmc_load_image_raw(struct mmc *mmc)
image_size_sectors, (void *)spl_image.load_addr);
end:
- if (err <= 0) {
- printf("spl: mmc blk read err - %d\n", err);
+ if (err == 0) {
+ printf("spl: mmc blk read err - %lu\n", err);
hang();
}
}
@@ -69,7 +70,7 @@ end:
#ifdef CONFIG_SPL_FAT_SUPPORT
static void mmc_load_image_fat(struct mmc *mmc)
{
- s32 err;
+ int err;
struct image_header *header;
header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
@@ -83,7 +84,7 @@ static void mmc_load_image_fat(struct mmc *mmc)
}
err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
- (u8 *)header, sizeof(struct image_header));
+ header, sizeof(struct image_header));
if (err <= 0)
goto end;
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
new file mode 100644
index 0000000..9e37af4
--- /dev/null
+++ b/drivers/mmc/zynq_sdhci.c
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2013 Inc.
+ *
+ * Xilinx Zynq SD Host Controller Interface
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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 <malloc.h>
+#include <sdhci.h>
+#include <asm/arch/sys_proto.h>
+
+int zynq_sdhci_init(u32 regbase)
+{
+ struct sdhci_host *host = NULL;
+
+ host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
+ if (!host) {
+ printf("zynq_sdhci_init: sdhci_host malloc fail\n");
+ return 1;
+ }
+
+ host->name = "zynq_sdhci";
+ host->ioaddr = (void *)regbase;
+ host->quirks = SDHCI_QUIRK_NO_CD | SDHCI_QUIRK_WAIT_SEND_CMD;
+ host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
+
+ host->host_caps = MMC_MODE_HC;
+
+ add_sdhci(host, 52000000, 52000000 >> 9);
+ return 0;
+}
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index cf10b0d..22d8440 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -210,11 +210,9 @@ unsigned long flash_sector_size(flash_info_t *info, flash_sect_t sect)
static inline void *
flash_map (flash_info_t * info, flash_sect_t sect, uint offset)
{
- unsigned int byte_offset = offset * info->portwidth / info->chipwidth;
- unsigned int addr = (info->start[sect] + byte_offset);
- unsigned int mask = 0xffffffff << (info->portwidth - 1);
+ unsigned int byte_offset = offset * info->portwidth;
- return (void *)(uintptr_t)(addr & mask);
+ return (void *)(info->start[sect] + byte_offset);
}
static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
@@ -400,8 +398,6 @@ void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
#endif
flash_write64(cword.ll, addr);
break;
- default:
- printf("fwc: Unknown port width %d\n", info->portwidth);
}
/* Ensure all the instructions are fully finished */
@@ -589,6 +585,7 @@ static int flash_status_check (flash_info_t * info, flash_sect_t sector,
prompt, info->start[sector],
flash_read_long (info, sector, 0));
flash_write_cmd (info, sector, 0, info->cmd_reset);
+ udelay(1);
return ERR_TIMOUT;
}
udelay (1); /* also triggers watchdog */
@@ -756,8 +753,12 @@ static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
static flash_sect_t find_sector (flash_info_t * info, ulong addr)
{
static flash_sect_t saved_sector; /* previously found sector */
+ static flash_info_t *saved_info; /* previously used flash bank */
flash_sect_t sector = saved_sector;
+ if ((info != saved_info) || (sector >= info->sector_count))
+ sector = 0;
+
while ((info->start[sector] < addr)
&& (sector < info->sector_count - 1))
sector++;
@@ -769,6 +770,7 @@ static flash_sect_t find_sector (flash_info_t * info, ulong addr)
sector--;
saved_sector = sector;
+ saved_info = info;
return sector;
}
@@ -785,15 +787,12 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
/* Check if Flash is (sufficiently) erased */
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- debug("%s: 8-bit 0x%02x\n", __func__, cword.c);
flag = ((flash_read8(dstaddr) & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
- debug("%s: 16-bit 0x%04x\n", __func__, cword.w);
flag = ((flash_read16(dstaddr) & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
- debug("%s: 32-bit 0x%08lx\n", __func__, cword.l);
flag = ((flash_read32(dstaddr) & cword.l) == cword.l);
break;
case FLASH_CFI_64BIT:
@@ -1054,8 +1053,6 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
flash_sect_t sect;
int st;
- debug("%s: erasing sectors %d to %d\n", __func__, s_first, s_last);
-
if (info->flash_id != FLASH_MAN_CFI) {
puts ("Can't erase unknown flash type - aborted\n");
return 1;
@@ -1165,9 +1162,6 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
rcode = 1;
else if (flash_verbose)
putc ('.');
- } else {
- debug("\nSector %d is protected.\n",
- info->protect[sect]);
}
}
@@ -1863,7 +1857,7 @@ static void flash_read_cfi (flash_info_t *info, void *buf,
unsigned int i;
for (i = 0; i < len; i++)
- p[i] = flash_read_uchar(info, start + (i * 2));
+ p[i] = flash_read_uchar(info, start + i);
}
static void __flash_cmd_reset(flash_info_t *info)
@@ -1884,40 +1878,21 @@ static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
{
int cfi_offset;
+ /* Issue FLASH reset command */
+ flash_cmd_reset(info);
+
for (cfi_offset=0;
cfi_offset < sizeof(flash_offset_cfi) / sizeof(uint);
cfi_offset++) {
- /* Issue FLASH reset command */
- flash_cmd_reset(info);
flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset],
FLASH_CMD_CFI);
- if (flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP, 'Q') &&
- flash_isequal(info, 0,
- FLASH_OFFSET_CFI_RESP + 2, 'R') &&
- flash_isequal(info, 0,
- FLASH_OFFSET_CFI_RESP + 4, 'Y')) {
+ if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
+ && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
+ && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,
sizeof(struct cfi_qry));
-#ifdef CONFIG_SYS_FLASH_INTERFACE_WIDTH
- info->interface = CONFIG_SYS_FLASH_INTERFACE_WIDTH;
-#else
info->interface = le16_to_cpu(qry->interface_desc);
- /* Some flash chips can support multiple bus widths.
- * In this case, override the interface width and
- * limit it to the port width.
- */
- if ((info->interface == FLASH_CFI_X8X16) &&
- (info->portwidth == FLASH_CFI_8BIT)) {
- debug("Overriding 16-bit interface"
- " width to 8-bit port width.\n");
- info->interface = FLASH_CFI_X8;
- } else if ((info->interface == FLASH_CFI_X16X32) &&
- (info->portwidth == FLASH_CFI_16BIT)) {
- debug("Overriding 16-bit interface"
- " width to 16-bit port width.\n");
- info->interface = FLASH_CFI_X16;
- }
-#endif
+
info->cfi_offset = flash_offset_cfi[cfi_offset];
debug ("device interface is %d\n",
info->interface);
@@ -1928,8 +1903,8 @@ static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
/* calculate command offsets as in the Linux driver */
- info->addr_unlock1 = 0xaaa;
- info->addr_unlock2 = 0x555;
+ info->addr_unlock1 = 0x555;
+ info->addr_unlock2 = 0x2aa;
/*
* modify the unlock address if we are
@@ -1963,12 +1938,8 @@ static int flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
for (info->chipwidth = FLASH_CFI_BY8;
info->chipwidth <= info->portwidth;
info->chipwidth <<= 1)
- if (__flash_detect_cfi(info, qry)) {
- debug("Found CFI flash, portwidth %d,"
- " chipwidth %d\n",
- info->portwidth, info->chipwidth);
+ if (__flash_detect_cfi(info, qry))
return 1;
- }
}
debug ("not found\n");
return 0;
@@ -1987,7 +1958,7 @@ static void flash_fixup_amd(flash_info_t *info, struct cfi_qry *qry)
/* CFI < 1.1, try to guess from device id */
if ((info->device_id & 0x80) != 0)
cfi_reverse_geometry(qry);
- } else if (flash_read_uchar(info, info->ext_addr + 0x1e) == 3) {
+ } else if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {
/* CFI >= 1.1, deduct from top/bottom flag */
/* note: ext_addr is valid since cfi_version > 0 */
cfi_reverse_geometry(qry);
@@ -2103,15 +2074,14 @@ ulong flash_get_size (phys_addr_t base, int banknum)
if (flash_detect_cfi (info, &qry)) {
info->vendor = le16_to_cpu(qry.p_id);
- info->ext_addr = le16_to_cpu(qry.p_adr) * 2;
- debug("extended address is 0x%x\n", info->ext_addr);
+ info->ext_addr = le16_to_cpu(qry.p_adr);
num_erase_regions = qry.num_erase_regions;
if (info->ext_addr) {
info->cfi_version = (ushort) flash_read_uchar (info,
- info->ext_addr + 6) << 8;
+ info->ext_addr + 3) << 8;
info->cfi_version |= (ushort) flash_read_uchar (info,
- info->ext_addr + 8);
+ info->ext_addr + 4);
}
#ifdef DEBUG
@@ -2165,8 +2135,6 @@ ulong flash_get_size (phys_addr_t base, int banknum)
debug ("device id is 0x%x\n", info->device_id);
debug ("device id2 is 0x%x\n", info->device_id2);
debug ("cfi version is 0x%04x\n", info->cfi_version);
- debug("port width: %d, chipwidth: %d, interface: %d\n",
- info->portwidth, info->chipwidth, info->interface);
size_ratio = info->portwidth / info->chipwidth;
/* if the chip is x8/x16 reduce the ratio by half */
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 35769c5..8821704 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -34,6 +34,7 @@ NORMAL_DRIVERS=y
endif
COBJS-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
+COBJS-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o
COBJS-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
COBJS-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
COBJS-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
@@ -77,6 +78,7 @@ COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o
COBJS-$(CONFIG_TEGRA_NAND) += tegra_nand.o
COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
+COBJS-$(CONFIG_NAND_DOCG4) += docg4.o
else # minimal SPL drivers
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
new file mode 100644
index 0000000..7dd9953
--- /dev/null
+++ b/drivers/mtd/nand/docg4.c
@@ -0,0 +1,1028 @@
+/*
+ * drivers/mtd/nand/docg4.c
+ *
+ * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ *
+ * mtd nand driver for M-Systems DiskOnChip G4
+ *
+ * Tested on the Palm Treo 680. The G4 is also present on Toshiba Portege, Asus
+ * P526, some HTC smartphones (Wizard, Prophet, ...), O2 XDA Zinc, maybe others.
+ * Should work on these as well. Let me know!
+ *
+ * TODO:
+ *
+ * Mechanism for management of password-protected areas
+ *
+ * Hamming ecc when reading oob only
+ *
+ * According to the M-Sys documentation, this device is also available in a
+ * "dual-die" configuration having a 256MB capacity, but no mechanism for
+ * detecting this variant is documented. Currently this driver assumes 128MB
+ * capacity.
+ *
+ * Support for multiple cascaded devices ("floors"). Not sure which gadgets
+ * contain multiple G4s in a cascaded configuration, if any.
+ *
+ */
+
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/errno.h>
+#include <malloc.h>
+#include <nand.h>
+#include <linux/bch.h>
+#include <linux/bitrev.h>
+#include <linux/mtd/docg4.h>
+
+/*
+ * The device has a nop register which M-Sys claims is for the purpose of
+ * inserting precise delays. But beware; at least some operations fail if the
+ * nop writes are replaced with a generic delay!
+ */
+static inline void write_nop(void __iomem *docptr)
+{
+ writew(0, docptr + DOC_NOP);
+}
+
+
+static int poll_status(void __iomem *docptr)
+{
+ /*
+ * Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL
+ * register. Operations known to take a long time (e.g., block erase)
+ * should sleep for a while before calling this.
+ */
+
+ uint8_t flash_status;
+
+ /* hardware quirk requires reading twice initially */
+ flash_status = readb(docptr + DOC_FLASHCONTROL);
+
+ do {
+ flash_status = readb(docptr + DOC_FLASHCONTROL);
+ } while (!(flash_status & DOC_CTRL_FLASHREADY));
+
+ return 0;
+}
+
+static void write_addr(void __iomem *docptr, uint32_t docg4_addr)
+{
+ /* write the four address bytes packed in docg4_addr to the device */
+
+ writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+ docg4_addr >>= 8;
+ writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+ docg4_addr >>= 8;
+ writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+ docg4_addr >>= 8;
+ writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+}
+
+/*
+ * This is a module parameter in the linux kernel version of this driver. It is
+ * hard-coded to 'off' for u-boot. This driver uses oob to mark bad blocks.
+ * This can be problematic when dealing with data not intended for the mtd/nand
+ * subsystem. For example, on boards that boot from the docg4 and use the IPL
+ * to load an spl + u-boot image, the blocks containing the image will be
+ * reported as "bad" because the oob of the first page of each block contains a
+ * magic number that the IPL looks for, which causes the badblock scan to
+ * erroneously add them to the bad block table. To erase such a block, use
+ * u-boot's 'nand scrub'. scrub is safe for the docg4. The device does have a
+ * factory bad block table, but it is read-only, and is used in conjunction with
+ * oob bad block markers that are written by mtd/nand when a block is deemed to
+ * be bad. To read data from "bad" blocks, use 'read.raw'. Unfortunately,
+ * read.raw does not use ecc, which would still work fine on such misidentified
+ * bad blocks. TODO: u-boot nand utilities need the ability to ignore bad
+ * blocks.
+ */
+static const int ignore_badblocks; /* remains false */
+
+struct docg4_priv {
+ int status;
+ struct {
+ unsigned int command;
+ int column;
+ int page;
+ } last_command;
+ uint8_t oob_buf[16];
+ uint8_t ecc_buf[7];
+ int oob_page;
+ struct bch_control *bch;
+};
+/*
+ * Oob bytes 0 - 6 are available to the user.
+ * Byte 7 is hamming ecc for first 7 bytes. Bytes 8 - 14 are hw-generated ecc.
+ * Byte 15 (the last) is used by the driver as a "page written" flag.
+ */
+static struct nand_ecclayout docg4_oobinfo = {
+ .eccbytes = 9,
+ .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15},
+ .oobavail = 7,
+ .oobfree = { {0, 7} }
+};
+
+static void reset(void __iomem *docptr)
+{
+ /* full device reset */
+
+ writew(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN, docptr + DOC_ASICMODE);
+ writew(~(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN),
+ docptr + DOC_ASICMODECONFIRM);
+ write_nop(docptr);
+
+ writew(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN,
+ docptr + DOC_ASICMODE);
+ writew(~(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN),
+ docptr + DOC_ASICMODECONFIRM);
+
+ writew(DOC_ECCCONF1_ECC_ENABLE, docptr + DOC_ECCCONF1);
+
+ poll_status(docptr);
+}
+
+static void docg4_select_chip(struct mtd_info *mtd, int chip)
+{
+ /*
+ * Select among multiple cascaded chips ("floors"). Multiple floors are
+ * not yet supported, so the only valid non-negative value is 0.
+ */
+ void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+
+ if (chip < 0)
+ return; /* deselected */
+
+ if (chip > 0)
+ printf("multiple floors currently unsupported\n");
+
+ writew(0, docptr + DOC_DEVICESELECT);
+}
+
+static void read_hw_ecc(void __iomem *docptr, uint8_t *ecc_buf)
+{
+ /* read the 7 hw-generated ecc bytes */
+
+ int i;
+ for (i = 0; i < 7; i++) { /* hw quirk; read twice */
+ ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i));
+ ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i));
+ }
+}
+
+static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page)
+{
+ /*
+ * Called after a page read when hardware reports bitflips.
+ * Up to four bitflips can be corrected.
+ */
+
+ struct nand_chip *nand = mtd->priv;
+ struct docg4_priv *doc = nand->priv;
+ void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+ int i, numerrs;
+ unsigned int errpos[4];
+ const uint8_t blank_read_hwecc[8] = {
+ 0xcf, 0x72, 0xfc, 0x1b, 0xa9, 0xc7, 0xb9, 0 };
+
+ read_hw_ecc(docptr, doc->ecc_buf); /* read 7 hw-generated ecc bytes */
+
+ /* check if read error is due to a blank page */
+ if (!memcmp(doc->ecc_buf, blank_read_hwecc, 7))
+ return 0; /* yes */
+
+ /* skip additional check of "written flag" if ignore_badblocks */
+ if (!ignore_badblocks) {
+ /*
+ * If the hw ecc bytes are not those of a blank page, there's
+ * still a chance that the page is blank, but was read with
+ * errors. Check the "written flag" in last oob byte, which
+ * is set to zero when a page is written. If more than half
+ * the bits are set, assume a blank page. Unfortunately, the
+ * bit flips(s) are not reported in stats.
+ */
+
+ if (doc->oob_buf[15]) {
+ int bit, numsetbits = 0;
+ unsigned long written_flag = doc->oob_buf[15];
+
+ for (bit = 0; bit < 8; bit++) {
+ if (written_flag & 0x01)
+ numsetbits++;
+ written_flag >>= 1;
+ }
+ if (numsetbits > 4) { /* assume blank */
+ printf("errors in blank page at offset %08x\n",
+ page * DOCG4_PAGE_SIZE);
+ return 0;
+ }
+ }
+ }
+
+ /*
+ * The hardware ecc unit produces oob_ecc ^ calc_ecc. The kernel's bch
+ * algorithm is used to decode this. However the hw operates on page
+ * data in a bit order that is the reverse of that of the bch alg,
+ * requiring that the bits be reversed on the result. Thanks to Ivan
+ * Djelic for his analysis!
+ */
+ for (i = 0; i < 7; i++)
+ doc->ecc_buf[i] = bitrev8(doc->ecc_buf[i]);
+
+ numerrs = decode_bch(doc->bch, NULL, DOCG4_USERDATA_LEN, NULL,
+ doc->ecc_buf, NULL, errpos);
+
+ if (numerrs == -EBADMSG) {
+ printf("uncorrectable errors at offset %08x\n",
+ page * DOCG4_PAGE_SIZE);
+ return -EBADMSG;
+ }
+
+ BUG_ON(numerrs < 0); /* -EINVAL, or anything other than -EBADMSG */
+
+ /* undo last step in BCH alg (modulo mirroring not needed) */
+ for (i = 0; i < numerrs; i++)
+ errpos[i] = (errpos[i] & ~7)|(7-(errpos[i] & 7));
+
+ /* fix the errors */
+ for (i = 0; i < numerrs; i++) {
+ /* ignore if error within oob ecc bytes */
+ if (errpos[i] > DOCG4_USERDATA_LEN * 8)
+ continue;
+
+ /* if error within oob area preceeding ecc bytes... */
+ if (errpos[i] > DOCG4_PAGE_SIZE * 8)
+ __change_bit(errpos[i] - DOCG4_PAGE_SIZE * 8,
+ (unsigned long *)doc->oob_buf);
+
+ else /* error in page data */
+ __change_bit(errpos[i], (unsigned long *)buf);
+ }
+
+ printf("%d error(s) corrected at offset %08x\n",
+ numerrs, page * DOCG4_PAGE_SIZE);
+
+ return numerrs;
+}
+
+static int read_progstatus(struct docg4_priv *doc, void __iomem *docptr)
+{
+ /*
+ * This apparently checks the status of programming. Done after an
+ * erasure, and after page data is written. On error, the status is
+ * saved, to be later retrieved by the nand infrastructure code.
+ */
+
+ /* status is read from the I/O reg */
+ uint16_t status1 = readw(docptr + DOC_IOSPACE_DATA);
+ uint16_t status2 = readw(docptr + DOC_IOSPACE_DATA);
+ uint16_t status3 = readw(docptr + DOCG4_MYSTERY_REG);
+
+ MTDDEBUG(MTD_DEBUG_LEVEL3, "docg4: %s: %02x %02x %02x\n",
+ __func__, status1, status2, status3);
+
+ if (status1 != DOCG4_PROGSTATUS_GOOD ||
+ status2 != DOCG4_PROGSTATUS_GOOD_2 ||
+ status3 != DOCG4_PROGSTATUS_GOOD_2) {
+ doc->status = NAND_STATUS_FAIL;
+ printf("read_progstatus failed: %02x, %02x, %02x\n",
+ status1, status2, status3);
+ return -EIO;
+ }
+ return 0;
+}
+
+static int pageprog(struct mtd_info *mtd)
+{
+ /*
+ * Final step in writing a page. Writes the contents of its
+ * internal buffer out to the flash array, or some such.
+ */
+
+ struct nand_chip *nand = mtd->priv;
+ struct docg4_priv *doc = nand->priv;
+ void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+ int retval = 0;
+
+ MTDDEBUG(MTD_DEBUG_LEVEL3, "docg4: %s\n", __func__);
+
+ writew(DOCG4_SEQ_PAGEPROG, docptr + DOC_FLASHSEQUENCE);
+ writew(DOC_CMD_PROG_CYCLE2, docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+ write_nop(docptr);
+
+ /* Just busy-wait; usleep_range() slows things down noticeably. */
+ poll_status(docptr);
+
+ writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE);
+ writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND);
+ writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+
+ retval = read_progstatus(doc, docptr);
+ writew(0, docptr + DOC_DATAEND);
+ write_nop(docptr);
+ poll_status(docptr);
+ write_nop(docptr);
+
+ return retval;
+}
+
+static void sequence_reset(void __iomem *docptr)
+{
+ /* common starting sequence for all operations */
+
+ writew(DOC_CTRL_UNKNOWN | DOC_CTRL_CE, docptr + DOC_FLASHCONTROL);
+ writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE);
+ writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+ write_nop(docptr);
+ poll_status(docptr);
+ write_nop(docptr);
+}
+
+static void read_page_prologue(void __iomem *docptr, uint32_t docg4_addr)
+{
+ /* first step in reading a page */
+
+ sequence_reset(docptr);
+
+ writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE);
+ writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+
+ write_addr(docptr, docg4_addr);
+
+ write_nop(docptr);
+ writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+ write_nop(docptr);
+
+ poll_status(docptr);
+}
+
+static void write_page_prologue(void __iomem *docptr, uint32_t docg4_addr)
+{
+ /* first step in writing a page */
+
+ sequence_reset(docptr);
+ writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE);
+ writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+ write_addr(docptr, docg4_addr);
+ write_nop(docptr);
+ write_nop(docptr);
+ poll_status(docptr);
+}
+
+static uint32_t mtd_to_docg4_address(int page, int column)
+{
+ /*
+ * Convert mtd address to format used by the device, 32 bit packed.
+ *
+ * Some notes on G4 addressing... The M-Sys documentation on this device
+ * claims that pages are 2K in length, and indeed, the format of the
+ * address used by the device reflects that. But within each page are
+ * four 512 byte "sub-pages", each with its own oob data that is
+ * read/written immediately after the 512 bytes of page data. This oob
+ * data contains the ecc bytes for the preceeding 512 bytes.
+ *
+ * Rather than tell the mtd nand infrastructure that page size is 2k,
+ * with four sub-pages each, we engage in a little subterfuge and tell
+ * the infrastructure code that pages are 512 bytes in size. This is
+ * done because during the course of reverse-engineering the device, I
+ * never observed an instance where an entire 2K "page" was read or
+ * written as a unit. Each "sub-page" is always addressed individually,
+ * its data read/written, and ecc handled before the next "sub-page" is
+ * addressed.
+ *
+ * This requires us to convert addresses passed by the mtd nand
+ * infrastructure code to those used by the device.
+ *
+ * The address that is written to the device consists of four bytes: the
+ * first two are the 2k page number, and the second is the index into
+ * the page. The index is in terms of 16-bit half-words and includes
+ * the preceeding oob data, so e.g., the index into the second
+ * "sub-page" is 0x108, and the full device address of the start of mtd
+ * page 0x201 is 0x00800108.
+ */
+ int g4_page = page / 4; /* device's 2K page */
+ int g4_index = (page % 4) * 0x108 + column/2; /* offset into page */
+ return (g4_page << 16) | g4_index; /* pack */
+}
+
+static void docg4_command(struct mtd_info *mtd, unsigned command, int column,
+ int page_addr)
+{
+ /* handle standard nand commands */
+
+ struct nand_chip *nand = mtd->priv;
+ struct docg4_priv *doc = nand->priv;
+ uint32_t g4_addr = mtd_to_docg4_address(page_addr, column);
+
+ MTDDEBUG(MTD_DEBUG_LEVEL3, "%s %x, page_addr=%x, column=%x\n",
+ __func__, command, page_addr, column);
+
+ /*
+ * Save the command and its arguments. This enables emulation of
+ * standard flash devices, and also some optimizations.
+ */
+ doc->last_command.command = command;
+ doc->last_command.column = column;
+ doc->last_command.page = page_addr;
+
+ switch (command) {
+ case NAND_CMD_RESET:
+ reset(CONFIG_SYS_NAND_BASE);
+ break;
+
+ case NAND_CMD_READ0:
+ read_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
+ break;
+
+ case NAND_CMD_STATUS:
+ /* next call to read_byte() will expect a status */
+ break;
+
+ case NAND_CMD_SEQIN:
+ write_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
+
+ /* hack for deferred write of oob bytes */
+ if (doc->oob_page == page_addr)
+ memcpy(nand->oob_poi, doc->oob_buf, 16);
+ break;
+
+ case NAND_CMD_PAGEPROG:
+ pageprog(mtd);
+ break;
+
+ /* we don't expect these, based on review of nand_base.c */
+ case NAND_CMD_READOOB:
+ case NAND_CMD_READID:
+ case NAND_CMD_ERASE1:
+ case NAND_CMD_ERASE2:
+ printf("docg4_command: unexpected nand command 0x%x\n",
+ command);
+ break;
+ }
+}
+
+static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ int i;
+ struct nand_chip *nand = mtd->priv;
+ uint16_t *p = (uint16_t *)buf;
+ len >>= 1;
+
+ for (i = 0; i < len; i++)
+ p[i] = readw(nand->IO_ADDR_R);
+}
+
+static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
+ int page, int sndcmd)
+{
+ struct docg4_priv *doc = nand->priv;
+ void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+ uint16_t status;
+
+ MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: page %x\n", __func__, page);
+
+ /*
+ * Oob bytes are read as part of a normal page read. If the previous
+ * nand command was a read of the page whose oob is now being read, just
+ * copy the oob bytes that we saved in a local buffer and avoid a
+ * separate oob read.
+ */
+ if (doc->last_command.command == NAND_CMD_READ0 &&
+ doc->last_command.page == page) {
+ memcpy(nand->oob_poi, doc->oob_buf, 16);
+ return 0;
+ }
+
+ /*
+ * Separate read of oob data only.
+ */
+ docg4_command(mtd, NAND_CMD_READ0, nand->ecc.size, page);
+
+ writew(DOC_ECCCONF0_READ_MODE | DOCG4_OOB_SIZE, docptr + DOC_ECCCONF0);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+
+ /* the 1st byte from the I/O reg is a status; the rest is oob data */
+ status = readw(docptr + DOC_IOSPACE_DATA);
+ if (status & DOCG4_READ_ERROR) {
+ printf("docg4_read_oob failed: status = 0x%02x\n", status);
+ return -EIO;
+ }
+
+ MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: status = 0x%x\n", __func__, status);
+
+ docg4_read_buf(mtd, nand->oob_poi, 16);
+
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ writew(0, docptr + DOC_DATAEND);
+ write_nop(docptr);
+
+ return 0;
+}
+
+static int docg4_write_oob(struct mtd_info *mtd, struct nand_chip *nand,
+ int page)
+{
+ /*
+ * Writing oob-only is not really supported, because MLC nand must write
+ * oob bytes at the same time as page data. Nonetheless, we save the
+ * oob buffer contents here, and then write it along with the page data
+ * if the same page is subsequently written. This allows user space
+ * utilities that write the oob data prior to the page data to work
+ * (e.g., nandwrite). The disdvantage is that, if the intention was to
+ * write oob only, the operation is quietly ignored. Also, oob can get
+ * corrupted if two concurrent processes are running nandwrite.
+ */
+
+ /* note that bytes 7..14 are hw generated hamming/ecc and overwritten */
+ struct docg4_priv *doc = nand->priv;
+ doc->oob_page = page;
+ memcpy(doc->oob_buf, nand->oob_poi, 16);
+ return 0;
+}
+
+static int docg4_block_neverbad(struct mtd_info *mtd, loff_t ofs, int getchip)
+{
+ /* only called when module_param ignore_badblocks is set */
+ return 0;
+}
+
+static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+ int i;
+ struct nand_chip *nand = mtd->priv;
+ uint16_t *p = (uint16_t *)buf;
+ len >>= 1;
+
+ for (i = 0; i < len; i++)
+ writew(p[i], nand->IO_ADDR_W);
+}
+
+static void write_page(struct mtd_info *mtd, struct nand_chip *nand,
+ const uint8_t *buf, int use_ecc)
+{
+ void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+ uint8_t ecc_buf[8];
+
+ writew(DOC_ECCCONF0_ECC_ENABLE |
+ DOC_ECCCONF0_UNKNOWN |
+ DOCG4_BCH_SIZE,
+ docptr + DOC_ECCCONF0);
+ write_nop(docptr);
+
+ /* write the page data */
+ docg4_write_buf16(mtd, buf, DOCG4_PAGE_SIZE);
+
+ /* oob bytes 0 through 5 are written to I/O reg */
+ docg4_write_buf16(mtd, nand->oob_poi, 6);
+
+ /* oob byte 6 written to a separate reg */
+ writew(nand->oob_poi[6], docptr + DOCG4_OOB_6_7);
+
+ write_nop(docptr);
+ write_nop(docptr);
+
+ /* write hw-generated ecc bytes to oob */
+ if (likely(use_ecc)) {
+ /* oob byte 7 is hamming code */
+ uint8_t hamming = readb(docptr + DOC_HAMMINGPARITY);
+ hamming = readb(docptr + DOC_HAMMINGPARITY); /* 2nd read */
+ writew(hamming, docptr + DOCG4_OOB_6_7);
+ write_nop(docptr);
+
+ /* read the 7 bch bytes from ecc regs */
+ read_hw_ecc(docptr, ecc_buf);
+ ecc_buf[7] = 0; /* clear the "page written" flag */
+ }
+
+ /* write user-supplied bytes to oob */
+ else {
+ writew(nand->oob_poi[7], docptr + DOCG4_OOB_6_7);
+ write_nop(docptr);
+ memcpy(ecc_buf, &nand->oob_poi[8], 8);
+ }
+
+ docg4_write_buf16(mtd, ecc_buf, 8);
+ write_nop(docptr);
+ write_nop(docptr);
+ writew(0, docptr + DOC_DATAEND);
+ write_nop(docptr);
+}
+
+static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
+ const uint8_t *buf)
+{
+ return write_page(mtd, nand, buf, 0);
+}
+
+static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
+ const uint8_t *buf)
+{
+ return write_page(mtd, nand, buf, 1);
+}
+
+static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
+ uint8_t *buf, int page, int use_ecc)
+{
+ struct docg4_priv *doc = nand->priv;
+ void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+ uint16_t status, edc_err, *buf16;
+
+ writew(DOC_ECCCONF0_READ_MODE |
+ DOC_ECCCONF0_ECC_ENABLE |
+ DOC_ECCCONF0_UNKNOWN |
+ DOCG4_BCH_SIZE,
+ docptr + DOC_ECCCONF0);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+
+ /* the 1st byte from the I/O reg is a status; the rest is page data */
+ status = readw(docptr + DOC_IOSPACE_DATA);
+ if (status & DOCG4_READ_ERROR) {
+ printf("docg4_read_page: bad status: 0x%02x\n", status);
+ writew(0, docptr + DOC_DATAEND);
+ return -EIO;
+ }
+
+ docg4_read_buf(mtd, buf, DOCG4_PAGE_SIZE); /* read the page data */
+
+ /* first 14 oob bytes read from I/O reg */
+ docg4_read_buf(mtd, nand->oob_poi, 14);
+
+ /* last 2 read from another reg */
+ buf16 = (uint16_t *)(nand->oob_poi + 14);
+ *buf16 = readw(docptr + DOCG4_MYSTERY_REG);
+
+ /*
+ * Diskonchips read oob immediately after a page read. Mtd
+ * infrastructure issues a separate command for reading oob after the
+ * page is read. So we save the oob bytes in a local buffer and just
+ * copy it if the next command reads oob from the same page.
+ */
+ memcpy(doc->oob_buf, nand->oob_poi, 16);
+
+ write_nop(docptr);
+
+ if (likely(use_ecc)) {
+ /* read the register that tells us if bitflip(s) detected */
+ edc_err = readw(docptr + DOC_ECCCONF1);
+ edc_err = readw(docptr + DOC_ECCCONF1);
+
+ /* If bitflips are reported, attempt to correct with ecc */
+ if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) {
+ int bits_corrected = correct_data(mtd, buf, page);
+ if (bits_corrected == -EBADMSG)
+ mtd->ecc_stats.failed++;
+ else
+ mtd->ecc_stats.corrected += bits_corrected;
+ }
+ }
+
+ writew(0, docptr + DOC_DATAEND);
+ return 0;
+}
+
+
+static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
+ uint8_t *buf, int page)
+{
+ return read_page(mtd, nand, buf, page, 0);
+}
+
+static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand,
+ uint8_t *buf, int page)
+{
+ return read_page(mtd, nand, buf, page, 1);
+}
+
+static void docg4_erase_block(struct mtd_info *mtd, int page)
+{
+ struct nand_chip *nand = mtd->priv;
+ struct docg4_priv *doc = nand->priv;
+ void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+ uint16_t g4_page;
+
+ MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: page %04x\n", __func__, page);
+
+ sequence_reset(docptr);
+
+ writew(DOCG4_SEQ_BLOCKERASE, docptr + DOC_FLASHSEQUENCE);
+ writew(DOC_CMD_PROG_BLOCK_ADDR, docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+
+ /* only 2 bytes of address are written to specify erase block */
+ g4_page = (uint16_t)(page / 4); /* to g4's 2k page addressing */
+ writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS);
+ g4_page >>= 8;
+ writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS);
+ write_nop(docptr);
+
+ /* start the erasure */
+ writew(DOC_CMD_ERASECYCLE2, docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+ write_nop(docptr);
+
+ poll_status(docptr);
+ writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE);
+ writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND);
+ writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+
+ read_progstatus(doc, docptr);
+
+ writew(0, docptr + DOC_DATAEND);
+ write_nop(docptr);
+ poll_status(docptr);
+ write_nop(docptr);
+}
+
+static int read_factory_bbt(struct mtd_info *mtd)
+{
+ /*
+ * The device contains a read-only factory bad block table. Read it and
+ * update the memory-based bbt accordingly.
+ */
+
+ struct nand_chip *nand = mtd->priv;
+ uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0);
+ uint8_t *buf;
+ int i, block, status;
+
+ buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ read_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
+ status = docg4_read_page(mtd, nand, buf, DOCG4_FACTORY_BBT_PAGE);
+ if (status)
+ goto exit;
+
+ /*
+ * If no memory-based bbt was created, exit. This will happen if module
+ * parameter ignore_badblocks is set. Then why even call this function?
+ * For an unknown reason, block erase always fails if it's the first
+ * operation after device power-up. The above read ensures it never is.
+ * Ugly, I know.
+ */
+ if (nand->bbt == NULL) /* no memory-based bbt */
+ goto exit;
+
+ /*
+ * Parse factory bbt and update memory-based bbt. Factory bbt format is
+ * simple: one bit per block, block numbers increase left to right (msb
+ * to lsb). Bit clear means bad block.
+ */
+ for (i = block = 0; block < DOCG4_NUMBLOCKS; block += 8, i++) {
+ int bitnum;
+ uint8_t mask;
+ for (bitnum = 0, mask = 0x80;
+ bitnum < 8; bitnum++, mask >>= 1) {
+ if (!(buf[i] & mask)) {
+ int badblock = block + bitnum;
+ nand->bbt[badblock / 4] |=
+ 0x03 << ((badblock % 4) * 2);
+ mtd->ecc_stats.badblocks++;
+ printf("factory-marked bad block: %d\n",
+ badblock);
+ }
+ }
+ }
+ exit:
+ kfree(buf);
+ return status;
+}
+
+static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+ /*
+ * Mark a block as bad. Bad blocks are marked in the oob area of the
+ * first page of the block. The default scan_bbt() in the nand
+ * infrastructure code works fine for building the memory-based bbt
+ * during initialization, as does the nand infrastructure function that
+ * checks if a block is bad by reading the bbt. This function replaces
+ * the nand default because writes to oob-only are not supported.
+ */
+
+ int ret, i;
+ uint8_t *buf;
+ struct nand_chip *nand = mtd->priv;
+ struct nand_bbt_descr *bbtd = nand->badblock_pattern;
+ int block = (int)(ofs >> nand->bbt_erase_shift);
+ int page = (int)(ofs >> nand->page_shift);
+ uint32_t g4_addr = mtd_to_docg4_address(page, 0);
+
+ MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: %08llx\n", __func__, ofs);
+
+ if (unlikely(ofs & (DOCG4_BLOCK_SIZE - 1)))
+ printf("%s: ofs %llx not start of block!\n",
+ __func__, ofs);
+
+ /* allocate blank buffer for page data */
+ buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ /* update bbt in memory */
+ nand->bbt[block / 4] |= 0x01 << ((block & 0x03) * 2);
+
+ /* write bit-wise negation of pattern to oob buffer */
+ memset(nand->oob_poi, 0xff, mtd->oobsize);
+ for (i = 0; i < bbtd->len; i++)
+ nand->oob_poi[bbtd->offs + i] = ~bbtd->pattern[i];
+
+ /* write first page of block */
+ write_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
+ docg4_write_page(mtd, nand, buf);
+ ret = pageprog(mtd);
+ if (!ret)
+ mtd->ecc_stats.badblocks++;
+
+ kfree(buf);
+
+ return ret;
+}
+
+static uint8_t docg4_read_byte(struct mtd_info *mtd)
+{
+ struct nand_chip *nand = mtd->priv;
+ struct docg4_priv *doc = nand->priv;
+
+ MTDDEBUG(MTD_DEBUG_LEVEL3, "%s\n", __func__);
+
+ if (doc->last_command.command == NAND_CMD_STATUS) {
+ int status;
+
+ /*
+ * Previous nand command was status request, so nand
+ * infrastructure code expects to read the status here. If an
+ * error occurred in a previous operation, report it.
+ */
+ doc->last_command.command = 0;
+
+ if (doc->status) {
+ status = doc->status;
+ doc->status = 0;
+ }
+
+ /* why is NAND_STATUS_WP inverse logic?? */
+ else
+ status = NAND_STATUS_WP | NAND_STATUS_READY;
+
+ return status;
+ }
+
+ printf("unexpectd call to read_byte()\n");
+
+ return 0;
+}
+
+static int docg4_wait(struct mtd_info *mtd, struct nand_chip *nand)
+{
+ struct docg4_priv *doc = nand->priv;
+ int status = NAND_STATUS_WP; /* inverse logic?? */
+ MTDDEBUG(MTD_DEBUG_LEVEL3, "%s...\n", __func__);
+
+ /* report any previously unreported error */
+ if (doc->status) {
+ status |= doc->status;
+ doc->status = 0;
+ return status;
+ }
+
+ status |= poll_status(CONFIG_SYS_NAND_BASE);
+ return status;
+}
+
+int docg4_nand_init(struct mtd_info *mtd, struct nand_chip *nand, int devnum)
+{
+ uint16_t id1, id2;
+ struct docg4_priv *docg4;
+ int retval;
+
+ docg4 = kzalloc(sizeof(*docg4), GFP_KERNEL);
+ if (!docg4)
+ return -1;
+
+ mtd->priv = nand;
+ nand->priv = docg4;
+
+ /* These must be initialized here because the docg4 is non-standard
+ * and doesn't produce an id that the nand code can use to look up
+ * these values (nand_scan_ident() not called).
+ */
+ mtd->size = DOCG4_CHIP_SIZE;
+ mtd->name = "Msys_Diskonchip_G4";
+ mtd->writesize = DOCG4_PAGE_SIZE;
+ mtd->erasesize = DOCG4_BLOCK_SIZE;
+ mtd->oobsize = DOCG4_OOB_SIZE;
+
+ nand->IO_ADDR_R =
+ (void __iomem *)CONFIG_SYS_NAND_BASE + DOC_IOSPACE_DATA;
+ nand->IO_ADDR_W = nand->IO_ADDR_R;
+ nand->chipsize = DOCG4_CHIP_SIZE;
+ nand->chip_shift = DOCG4_CHIP_SHIFT;
+ nand->bbt_erase_shift = DOCG4_ERASE_SHIFT;
+ nand->phys_erase_shift = DOCG4_ERASE_SHIFT;
+ nand->chip_delay = 20;
+ nand->page_shift = DOCG4_PAGE_SHIFT;
+ nand->pagemask = 0x3ffff;
+ nand->badblockpos = NAND_LARGE_BADBLOCK_POS;
+ nand->badblockbits = 8;
+ nand->ecc.layout = &docg4_oobinfo;
+ nand->ecc.mode = NAND_ECC_HW_SYNDROME;
+ nand->ecc.size = DOCG4_PAGE_SIZE;
+ nand->ecc.prepad = 8;
+ nand->ecc.bytes = 8;
+ nand->options =
+ NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR;
+ nand->controller = &nand->hwcontrol;
+
+ /* methods */
+ nand->cmdfunc = docg4_command;
+ nand->waitfunc = docg4_wait;
+ nand->select_chip = docg4_select_chip;
+ nand->read_byte = docg4_read_byte;
+ nand->block_markbad = docg4_block_markbad;
+ nand->read_buf = docg4_read_buf;
+ nand->write_buf = docg4_write_buf16;
+ nand->scan_bbt = nand_default_bbt;
+ nand->erase_cmd = docg4_erase_block;
+ nand->ecc.read_page = docg4_read_page;
+ nand->ecc.write_page = docg4_write_page;
+ nand->ecc.read_page_raw = docg4_read_page_raw;
+ nand->ecc.write_page_raw = docg4_write_page_raw;
+ nand->ecc.read_oob = docg4_read_oob;
+ nand->ecc.write_oob = docg4_write_oob;
+
+ /*
+ * The way the nand infrastructure code is written, a memory-based bbt
+ * is not created if NAND_SKIP_BBTSCAN is set. With no memory bbt,
+ * nand->block_bad() is used. So when ignoring bad blocks, we skip the
+ * scan and define a dummy block_bad() which always returns 0.
+ */
+ if (ignore_badblocks) {
+ nand->options |= NAND_SKIP_BBTSCAN;
+ nand->block_bad = docg4_block_neverbad;
+ }
+
+ reset(CONFIG_SYS_NAND_BASE);
+
+ /* check for presence of g4 chip by reading id registers */
+ id1 = readw(CONFIG_SYS_NAND_BASE + DOC_CHIPID);
+ id1 = readw(CONFIG_SYS_NAND_BASE + DOCG4_MYSTERY_REG);
+ id2 = readw(CONFIG_SYS_NAND_BASE + DOC_CHIPID_INV);
+ id2 = readw(CONFIG_SYS_NAND_BASE + DOCG4_MYSTERY_REG);
+ if (id1 != DOCG4_IDREG1_VALUE || id2 != DOCG4_IDREG2_VALUE)
+ return -1;
+
+ /* initialize bch algorithm */
+ docg4->bch = init_bch(DOCG4_M, DOCG4_T, DOCG4_PRIMITIVE_POLY);
+ if (docg4->bch == NULL)
+ return -1;
+
+ retval = nand_scan_tail(mtd);
+ if (retval)
+ return -1;
+
+ /*
+ * Scan for bad blocks and create bbt here, then add the factory-marked
+ * bad blocks to the bbt.
+ */
+ nand->scan_bbt(mtd);
+ nand->options |= NAND_BBT_SCANNED;
+ retval = read_factory_bbt(mtd);
+ if (retval)
+ return -1;
+
+ retval = nand_register(devnum);
+ if (retval)
+ return -1;
+
+ return 0;
+}
diff --git a/drivers/mtd/nand/docg4_spl.c b/drivers/mtd/nand/docg4_spl.c
new file mode 100644
index 0000000..95e856c
--- /dev/null
+++ b/drivers/mtd/nand/docg4_spl.c
@@ -0,0 +1,222 @@
+/*
+ * SPL driver for Diskonchip G4 nand flash
+ *
+ * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ *
+ *
+ * This driver basically mimics the load functionality of a typical IPL (initial
+ * program loader) resident in the 2k NOR-like region of the docg4 that is
+ * mapped to the reset vector. It allows the u-boot SPL to continue loading if
+ * the IPL loads a fixed number of flash blocks that is insufficient to contain
+ * the entire u-boot image. In this case, a concatenated spl + u-boot image is
+ * written at the flash offset from which the IPL loads an image, and when the
+ * IPL jumps to the SPL, the SPL resumes loading where the IPL left off. See
+ * the palmtreo680 for an example.
+ *
+ * This driver assumes that the data was written to the flash using the device's
+ * "reliable" mode, and also assumes that each 512 byte page is stored
+ * redundantly in the subsequent page. This storage format is likely to be used
+ * by all boards that boot from the docg4. The format compensates for the lack
+ * of ecc in the IPL.
+ *
+ * Reliable mode reduces the capacity of a block by half, and the redundant
+ * pages reduce it by half again. As a result, the normal 256k capacity of a
+ * block is reduced to 64k for the purposes of the IPL/SPL.
+ */
+
+#include <asm/io.h>
+#include <linux/mtd/docg4.h>
+
+/* forward declarations */
+static inline void write_nop(void __iomem *docptr);
+static int poll_status(void __iomem *docptr);
+static void write_addr(void __iomem *docptr, uint32_t docg4_addr);
+static void address_sequence(unsigned int g4_page, unsigned int g4_index,
+ void __iomem *docptr);
+static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr);
+
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
+{
+ void *load_addr = dst;
+ uint32_t flash_offset = offs;
+ const unsigned int block_count =
+ (size + DOCG4_BLOCK_CAPACITY_SPL - 1)
+ / DOCG4_BLOCK_CAPACITY_SPL;
+ int i;
+
+ for (i = 0; i < block_count; i++) {
+ int ret = docg4_load_block_reliable(flash_offset, load_addr);
+ if (ret)
+ return ret;
+ load_addr += DOCG4_BLOCK_CAPACITY_SPL;
+ flash_offset += DOCG4_BLOCK_SIZE;
+ }
+ return 0;
+}
+
+static inline void write_nop(void __iomem *docptr)
+{
+ writew(0, docptr + DOC_NOP);
+}
+
+static int poll_status(void __iomem *docptr)
+{
+ /*
+ * Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL
+ * register. Operations known to take a long time (e.g., block erase)
+ * should sleep for a while before calling this.
+ */
+
+ uint8_t flash_status;
+
+ /* hardware quirk requires reading twice initially */
+ flash_status = readb(docptr + DOC_FLASHCONTROL);
+
+ do {
+ flash_status = readb(docptr + DOC_FLASHCONTROL);
+ } while (!(flash_status & DOC_CTRL_FLASHREADY));
+
+ return 0;
+}
+
+static void write_addr(void __iomem *docptr, uint32_t docg4_addr)
+{
+ /* write the four address bytes packed in docg4_addr to the device */
+
+ writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+ docg4_addr >>= 8;
+ writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+ docg4_addr >>= 8;
+ writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+ docg4_addr >>= 8;
+ writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+}
+
+static void address_sequence(unsigned int g4_page, unsigned int g4_index,
+ void __iomem *docptr)
+{
+ writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE);
+ writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+ write_addr(docptr, ((uint32_t)g4_page << 16) | g4_index);
+ write_nop(docptr);
+}
+
+static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr)
+{
+ void __iomem *docptr = (void *)CONFIG_SYS_NAND_BASE;
+ unsigned int g4_page = flash_offset >> 11; /* 2k page */
+ const unsigned int last_g4_page = g4_page + 0x80; /* last in block */
+ int g4_index = 0;
+ uint16_t flash_status;
+ uint16_t *buf;
+ uint16_t discard, magic_high, magic_low;
+
+ /* flash_offset must be aligned to the start of a block */
+ if (flash_offset & 0x3ffff)
+ return -1;
+
+ writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE);
+ writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+ write_nop(docptr);
+ poll_status(docptr);
+ write_nop(docptr);
+ writew(0x45, docptr + DOC_FLASHSEQUENCE);
+ writew(0xa3, docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+ writew(0x22, docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+
+ /* read 1st 4 oob bytes of first subpage of block */
+ address_sequence(g4_page, 0x0100, docptr); /* index at oob */
+ write_nop(docptr);
+ flash_status = readw(docptr + DOC_FLASHCONTROL);
+ flash_status = readw(docptr + DOC_FLASHCONTROL);
+ if (flash_status & 0x06) /* sequence or protection errors */
+ return -1;
+ writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+ write_nop(docptr);
+ poll_status(docptr);
+ writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+
+ /*
+ * Here we read the first four oob bytes of the first page of the block.
+ * The IPL on the palmtreo680 requires that this contain a 32 bit magic
+ * number, or the load aborts. We'll ignore it.
+ */
+ discard = readw(docptr + 0x103c); /* hw quirk; 1st read discarded */
+ magic_low = readw(docptr + 0x103c);
+ magic_high = readw(docptr + DOCG4_MYSTERY_REG);
+ writew(0, docptr + DOC_DATAEND);
+ write_nop(docptr);
+ write_nop(docptr);
+
+ /* load contents of block to memory */
+ buf = (uint16_t *)dest_addr;
+ do {
+ int i;
+
+ address_sequence(g4_page, g4_index, docptr);
+ writew(DOCG4_CMD_READ2,
+ docptr + DOC_FLASHCOMMAND);
+ write_nop(docptr);
+ write_nop(docptr);
+ poll_status(docptr);
+ writew(DOC_ECCCONF0_READ_MODE |
+ DOC_ECCCONF0_ECC_ENABLE |
+ DOCG4_BCH_SIZE,
+ docptr + DOC_ECCCONF0);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+ write_nop(docptr);
+
+ /* read the 512 bytes of page data, 2 bytes at a time */
+ discard = readw(docptr + 0x103c);
+ for (i = 0; i < 256; i++)
+ *buf++ = readw(docptr + 0x103c);
+
+ /* read oob, but discard it */
+ for (i = 0; i < 7; i++)
+ discard = readw(docptr + 0x103c);
+ discard = readw(docptr + DOCG4_OOB_6_7);
+ discard = readw(docptr + DOCG4_OOB_6_7);
+
+ writew(0, docptr + DOC_DATAEND);
+ write_nop(docptr);
+ write_nop(docptr);
+
+ if (!(g4_index & 0x100)) {
+ /* not redundant subpage read; check for ecc error */
+ write_nop(docptr);
+ flash_status = readw(docptr + DOC_ECCCONF1);
+ flash_status = readw(docptr + DOC_ECCCONF1);
+ if (flash_status & 0x80) { /* ecc error */
+ g4_index += 0x108; /* read redundant subpage */
+ buf -= 256; /* back up ram ptr */
+ continue;
+ } else /* no ecc error */
+ g4_index += 0x210; /* skip redundant subpage */
+ } else /* redundant page was just read; skip ecc error check */
+ g4_index += 0x108;
+
+ if (g4_index == 0x420) { /* finished with 2k page */
+ g4_index = 0;
+ g4_page += 2; /* odd-numbered 2k pages skipped */
+ }
+
+ } while (g4_page != last_g4_page); /* while still on same block */
+
+ return 0;
+}
diff --git a/drivers/mtd/nand/mxc_nand_spl.c b/drivers/mtd/nand/mxc_nand_spl.c
index 5608352..f13d5fc 100644
--- a/drivers/mtd/nand/mxc_nand_spl.c
+++ b/drivers/mtd/nand/mxc_nand_spl.c
@@ -358,16 +358,4 @@ void nand_boot(void)
hang();
}
}
-
-/*
- * Called in case of an exception.
- */
-void hang(void)
-{
- /* Loop forever */
- while (1) ;
-}
#endif
-
-void nand_init(void) {}
-void nand_deselect(void) {}
diff --git a/drivers/net/fm/memac.c b/drivers/net/fm/memac.c
index 32c7054..d3eee24 100644
--- a/drivers/net/fm/memac.c
+++ b/drivers/net/fm/memac.c
@@ -112,6 +112,23 @@ static void memac_set_interface_mode(struct fsl_enet_mac *mac,
/* Enable automatic speed selection */
if_mode |= IF_MODE_EN_AUTO;
+ if (type == PHY_INTERFACE_MODE_RGMII) {
+ if_mode &= ~IF_MODE_EN_AUTO;
+ if_mode &= ~IF_MODE_SETSP_MASK;
+ switch (speed) {
+ case SPEED_1000:
+ if_mode |= IF_MODE_SETSP_1000M;
+ break;
+ case SPEED_100:
+ if_mode |= IF_MODE_SETSP_100M;
+ break;
+ case SPEED_10:
+ if_mode |= IF_MODE_SETSP_10M;
+ default:
+ break;
+ }
+ }
+
debug(" %s, if_mode = %x\n", __func__, if_mode);
debug(" %s, if_status = %x\n", __func__, if_status);
out_be32(&regs->if_mode, if_mode);
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 4b27198..46801c7 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -465,6 +465,16 @@ static struct phy_driver M88E1149S_driver = {
.shutdown = &genphy_shutdown,
};
+static struct phy_driver M88E1518_driver = {
+ .name = "Marvell 88E1518",
+ .uid = 0x1410dd1,
+ .mask = 0xffffff0,
+ .features = PHY_GBIT_FEATURES,
+ .config = &m88e1111s_config,
+ .startup = &m88e1011s_startup,
+ .shutdown = &genphy_shutdown,
+};
+
int phy_marvell_init(void)
{
phy_register(&M88E1149S_driver);
@@ -474,6 +484,7 @@ int phy_marvell_init(void)
phy_register(&M88E1118R_driver);
phy_register(&M88E1111S_driver);
phy_register(&M88E1011S_driver);
+ phy_register(&M88E1518_driver);
return 0;
}
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 3596065..eac9b6f 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -33,6 +33,8 @@
#include <phy.h>
#include <miiphy.h>
#include <watchdog.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
#if !defined(CONFIG_PHYLIB)
# error XILINX_GEM_ETHERNET requires PHYLIB
@@ -67,13 +69,14 @@
#define ZYNQ_GEM_NWCTRL_MDEN_MASK 0x00000010 /* Enable MDIO port */
#define ZYNQ_GEM_NWCTRL_STARTTX_MASK 0x00000200 /* Start tx (tx_go) */
-#define ZYNQ_GEM_NWCFG_SPEED 0x00000001 /* 100 Mbps operation */
-#define ZYNQ_GEM_NWCFG_FDEN 0x00000002 /* Full Duplex mode */
-#define ZYNQ_GEM_NWCFG_FSREM 0x00020000 /* FCS removal */
+#define ZYNQ_GEM_NWCFG_SPEED100 0x000000001 /* 100 Mbps operation */
+#define ZYNQ_GEM_NWCFG_SPEED1000 0x000000400 /* 1Gbps operation */
+#define ZYNQ_GEM_NWCFG_FDEN 0x000000002 /* Full Duplex mode */
+#define ZYNQ_GEM_NWCFG_FSREM 0x000020000 /* FCS removal */
#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000080000 /* Div pclk by 32, 80MHz */
+#define ZYNQ_GEM_NWCFG_MDCCLKDIV2 0x0000c0000 /* Div pclk by 48, 120MHz */
-#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_NWCFG_SPEED | \
- ZYNQ_GEM_NWCFG_FDEN | \
+#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_NWCFG_FDEN | \
ZYNQ_GEM_NWCFG_FSREM | \
ZYNQ_GEM_NWCFG_MDCCLKDIV)
@@ -92,6 +95,17 @@
ZYNQ_GEM_DMACR_TXSIZE | \
ZYNQ_GEM_DMACR_RXBUF)
+/* Use MII register 1 (MII status register) to detect PHY */
+#define PHY_DETECT_REG 1
+
+/* Mask used to verify certain PHY features (or register contents)
+ * in the register above:
+ * 0x1000: 10Mbps full duplex support
+ * 0x0800: 10Mbps half duplex support
+ * 0x0008: Auto-negotiation support
+ */
+#define PHY_DETECT_MASK 0x1808
+
/* Device registers */
struct zynq_gem_regs {
u32 nwctrl; /* Network Control reg */
@@ -134,6 +148,8 @@ struct zynq_gem_priv {
u32 rxbd_current;
u32 rx_first_buf;
int phyaddr;
+ u32 emio;
+ int init;
struct phy_device *phydev;
struct mii_dev *bus;
};
@@ -196,6 +212,44 @@ static u32 phywrite(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 data)
ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data);
}
+static void phy_detection(struct eth_device *dev)
+{
+ int i;
+ u16 phyreg;
+ struct zynq_gem_priv *priv = dev->priv;
+
+ if (priv->phyaddr != -1) {
+ phyread(dev, priv->phyaddr, PHY_DETECT_REG, &phyreg);
+ if ((phyreg != 0xFFFF) &&
+ ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
+ /* Found a valid PHY address */
+ debug("Default phy address %d is valid\n",
+ priv->phyaddr);
+ return;
+ } else {
+ debug("PHY address is not setup correctly %d\n",
+ priv->phyaddr);
+ priv->phyaddr = -1;
+ }
+ }
+
+ debug("detecting phy address\n");
+ if (priv->phyaddr == -1) {
+ /* detect the PHY address */
+ for (i = 31; i >= 0; i--) {
+ phyread(dev, i, PHY_DETECT_REG, &phyreg);
+ if ((phyreg != 0xFFFF) &&
+ ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
+ /* Found a valid PHY address */
+ priv->phyaddr = i;
+ debug("Found valid phy address, %d\n", i);
+ return;
+ }
+ }
+ }
+ printf("PHY is not detected\n");
+}
+
static int zynq_gem_setup_mac(struct eth_device *dev)
{
u32 i, macaddrlow, macaddrhigh;
@@ -226,7 +280,7 @@ static int zynq_gem_setup_mac(struct eth_device *dev)
static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
{
- u32 i;
+ u32 i, rclk, clk = 0;
struct phy_device *phydev;
const u32 stat_size = (sizeof(struct zynq_gem_regs) -
offsetof(struct zynq_gem_regs, stat)) / 4;
@@ -239,59 +293,92 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full;
- /* Disable all interrupts */
- writel(0xFFFFFFFF, &regs->idr);
-
- /* Disable the receiver & transmitter */
- writel(0, &regs->nwctrl);
- writel(0, &regs->txsr);
- writel(0, &regs->rxsr);
- writel(0, &regs->phymntnc);
-
- /* Clear the Hash registers for the mac address pointed by AddressPtr */
- writel(0x0, &regs->hashl);
- /* Write bits [63:32] in TOP */
- writel(0x0, &regs->hashh);
+ if (!priv->init) {
+ /* Disable all interrupts */
+ writel(0xFFFFFFFF, &regs->idr);
+
+ /* Disable the receiver & transmitter */
+ writel(0, &regs->nwctrl);
+ writel(0, &regs->txsr);
+ writel(0, &regs->rxsr);
+ writel(0, &regs->phymntnc);
+
+ /* Clear the Hash registers for the mac address
+ * pointed by AddressPtr
+ */
+ writel(0x0, &regs->hashl);
+ /* Write bits [63:32] in TOP */
+ writel(0x0, &regs->hashh);
+
+ /* Clear all counters */
+ for (i = 0; i <= stat_size; i++)
+ readl(&regs->stat[i]);
+
+ /* Setup RxBD space */
+ memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd));
+ /* Create the RxBD ring */
+ memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers));
+
+ for (i = 0; i < RX_BUF; i++) {
+ priv->rx_bd[i].status = 0xF0000000;
+ priv->rx_bd[i].addr =
+ (u32)((char *)&(priv->rxbuffers) +
+ (i * PKTSIZE_ALIGN));
+ }
+ /* WRAP bit to last BD */
+ priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
+ /* Write RxBDs to IP */
+ writel((u32)&(priv->rx_bd), &regs->rxqbase);
- /* Clear all counters */
- for (i = 0; i <= stat_size; i++)
- readl(&regs->stat[i]);
+ /* Setup for DMA Configuration register */
+ writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
- /* Setup RxBD space */
- memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd));
- /* Create the RxBD ring */
- memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers));
+ /* Setup for Network Control register, MDIO, Rx and Tx enable */
+ setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK);
- for (i = 0; i < RX_BUF; i++) {
- priv->rx_bd[i].status = 0xF0000000;
- priv->rx_bd[i].addr = (u32)((char *) &(priv->rxbuffers) +
- (i * PKTSIZE_ALIGN));
+ priv->init++;
}
- /* WRAP bit to last BD */
- priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
- /* Write RxBDs to IP */
- writel((u32) &(priv->rx_bd), &regs->rxqbase);
- /* MAC Setup */
- /* Setup Network Configuration register */
- writel(ZYNQ_GEM_NWCFG_INIT, &regs->nwcfg);
-
- /* Setup for DMA Configuration register */
- writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
-
- /* Setup for Network Control register, MDIO, Rx and Tx enable */
- setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK |
- ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK);
+ phy_detection(dev);
/* interface - look at tsec */
phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0);
- phydev->supported &= supported;
+ phydev->supported = supported | ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause;
phydev->advertising = phydev->supported;
priv->phydev = phydev;
phy_config(phydev);
phy_startup(phydev);
+ switch (phydev->speed) {
+ case SPEED_1000:
+ writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED1000,
+ &regs->nwcfg);
+ rclk = (0 << 4) | (1 << 0);
+ clk = (1 << 20) | (8 << 8) | (0 << 4) | (1 << 0);
+ break;
+ case SPEED_100:
+ clrsetbits_le32(&regs->nwcfg, ZYNQ_GEM_NWCFG_SPEED1000,
+ ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100);
+ rclk = 1 << 0;
+ clk = (5 << 20) | (8 << 8) | (0 << 4) | (1 << 0);
+ break;
+ case SPEED_10:
+ rclk = 1 << 0;
+ /* FIXME untested */
+ clk = (5 << 20) | (8 << 8) | (0 << 4) | (1 << 0);
+ break;
+ }
+
+ /* Change the rclk and clk only not using EMIO interface */
+ if (!priv->emio)
+ zynq_slcr_gem_clk_setup(dev->iobase !=
+ ZYNQ_GEM_BASEADDR0, rclk, clk);
+
+ setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
+ ZYNQ_GEM_NWCTRL_TXEN_MASK);
+
return 0;
}
@@ -307,11 +394,10 @@ static int zynq_gem_send(struct eth_device *dev, void *ptr, int len)
writel((u32)&(priv->tx_bd), &regs->txqbase);
/* Setup Tx BD */
- memset((void *) &(priv->tx_bd), 0, sizeof(struct emac_bd));
+ memset((void *)&(priv->tx_bd), 0, sizeof(struct emac_bd));
priv->tx_bd.addr = (u32)ptr;
- priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK |
- ZYNQ_GEM_TXBUF_WRAP_MASK;
+ priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK;
/* Start transmit */
setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK);
@@ -364,19 +450,17 @@ static int zynq_gem_recv(struct eth_device *dev)
if ((++priv->rxbd_current) >= RX_BUF)
priv->rxbd_current = 0;
-
- return frame_len;
}
- return 0;
+ return frame_len;
}
static void zynq_gem_halt(struct eth_device *dev)
{
struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
- /* Disable the receiver & transmitter */
- writel(0, &regs->nwctrl);
+ clrsetbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
+ ZYNQ_GEM_NWCTRL_TXEN_MASK, 0);
}
static int zynq_gem_miiphyread(const char *devname, uchar addr,
@@ -399,7 +483,7 @@ static int zynq_gem_miiphy_write(const char *devname, uchar addr,
return phywrite(dev, addr, reg, val);
}
-int zynq_gem_initialize(bd_t *bis, int base_addr)
+int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio)
{
struct eth_device *dev;
struct zynq_gem_priv *priv;
@@ -415,11 +499,8 @@ int zynq_gem_initialize(bd_t *bis, int base_addr)
}
priv = dev->priv;
-#ifdef CONFIG_PHY_ADDR
- priv->phyaddr = CONFIG_PHY_ADDR;
-#else
- priv->phyaddr = -1;
-#endif
+ priv->phyaddr = phy_addr;
+ priv->emio = emio;
sprintf(dev->name, "Gem.%x", base_addr);
diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile
index be11c8b..e8c159c 100644
--- a/drivers/tpm/Makefile
+++ b/drivers/tpm/Makefile
@@ -23,7 +23,11 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libtpm.o
+$(shell mkdir -p $(obj)slb9635_i2c)
+
COBJS-$(CONFIG_GENERIC_LPC_TPM) = generic_lpc_tpm.o
+COBJS-$(CONFIG_INFINEON_TPM_I2C) += tis_i2c.o slb9635_i2c/tpm.o
+COBJS-$(CONFIG_INFINEON_TPM_I2C) += slb9635_i2c/tpm_tis_i2c.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/tpm/generic_lpc_tpm.c b/drivers/tpm/generic_lpc_tpm.c
index 6c494eb..04ad418 100644
--- a/drivers/tpm/generic_lpc_tpm.c
+++ b/drivers/tpm/generic_lpc_tpm.c
@@ -135,7 +135,7 @@ static u8 tpm_read_byte(const u8 *ptr)
{
u8 ret = readb(ptr);
debug(PREFIX "Read reg 0x%4.4x returns 0x%2.2x\n",
- (u32)ptr - (u32)lpc_tpm_dev, ret);
+ (u32)(uintptr_t)ptr - (u32)(uintptr_t)lpc_tpm_dev, ret);
return ret;
}
@@ -143,21 +143,21 @@ static u32 tpm_read_word(const u32 *ptr)
{
u32 ret = readl(ptr);
debug(PREFIX "Read reg 0x%4.4x returns 0x%8.8x\n",
- (u32)ptr - (u32)lpc_tpm_dev, ret);
+ (u32)(uintptr_t)ptr - (u32)(uintptr_t)lpc_tpm_dev, ret);
return ret;
}
static void tpm_write_byte(u8 value, u8 *ptr)
{
debug(PREFIX "Write reg 0x%4.4x with 0x%2.2x\n",
- (u32)ptr - (u32)lpc_tpm_dev, value);
+ (u32)(uintptr_t)ptr - (u32)(uintptr_t)lpc_tpm_dev, value);
writeb(value, ptr);
}
static void tpm_write_word(u32 value, u32 *ptr)
{
debug(PREFIX "Write reg 0x%4.4x with 0x%8.8x\n",
- (u32)ptr - (u32)lpc_tpm_dev, value);
+ (u32)(uintptr_t)ptr - (u32)(uintptr_t)lpc_tpm_dev, value);
writel(value, ptr);
}
@@ -491,5 +491,5 @@ int tis_sendrecv(const u8 *sendbuf, size_t send_size,
return TPM_DRIVER_ERR;
}
- return tis_readresponse(recvbuf, recv_len);
+ return tis_readresponse(recvbuf, (u32 *)recv_len);
}
diff --git a/drivers/tpm/slb9635_i2c/compatibility.h b/drivers/tpm/slb9635_i2c/compatibility.h
new file mode 100644
index 0000000..62dc9fa
--- /dev/null
+++ b/drivers/tpm/slb9635_i2c/compatibility.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 Infineon Technologies
+ *
+ * Authors:
+ * Peter Huewe <huewe.external@infineon.com>
+ *
+ * Version: 2.1.1
+ *
+ * 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 _COMPATIBILITY_H_
+#define _COMPATIBILITY_H_
+
+/* all includes from U-Boot */
+#include <linux/types.h>
+#include <linux/unaligned/be_byteshift.h>
+#include <asm-generic/errno.h>
+#include <compiler.h>
+#include <common.h>
+
+/* extended error numbers from linux (see errno.h) */
+#define ECANCELED 125 /* Operation Canceled */
+
+#define msleep(t) udelay((t)*1000)
+
+/* Timer frequency. Corresponds to msec timer resolution*/
+#define HZ 1000
+
+#define dev_dbg(dev, format, arg...) debug(format, ##arg)
+#define dev_err(dev, format, arg...) printf(format, ##arg)
+#define dev_info(dev, format, arg...) debug(format, ##arg)
+#define dbg_printf debug
+
+#endif
diff --git a/drivers/tpm/slb9635_i2c/tpm.c b/drivers/tpm/slb9635_i2c/tpm.c
new file mode 100644
index 0000000..496c48e
--- /dev/null
+++ b/drivers/tpm/slb9635_i2c/tpm.c
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2011 Infineon Technologies
+ *
+ * Authors:
+ * Peter Huewe <huewe.external@infineon.com>
+ *
+ * Description:
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * It is based on the Linux kernel driver tpm.c from Leendert van
+ * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
+ *
+ * Version: 2.1.1
+ *
+ * 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, version 2 of the
+ * License.
+ *
+ * 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 <malloc.h>
+#include "tpm.h"
+
+/* global structure for tpm chip data */
+struct tpm_chip g_chip;
+
+enum tpm_duration {
+ TPM_SHORT = 0,
+ TPM_MEDIUM = 1,
+ TPM_LONG = 2,
+ TPM_UNDEFINED,
+};
+
+#define TPM_MAX_ORDINAL 243
+#define TPM_MAX_PROTECTED_ORDINAL 12
+#define TPM_PROTECTED_ORDINAL_MASK 0xFF
+
+/*
+ * Array with one entry per ordinal defining the maximum amount
+ * of time the chip could take to return the result. The ordinal
+ * designation of short, medium or long is defined in a table in
+ * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
+ * values of the SHORT, MEDIUM, and LONG durations are retrieved
+ * from the chip during initialization with a call to tpm_get_timeouts.
+ */
+static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
+ TPM_UNDEFINED, /* 0 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 5 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 10 */
+ TPM_SHORT,
+};
+
+static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
+ TPM_UNDEFINED, /* 0 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 5 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 10 */
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_LONG,
+ TPM_LONG,
+ TPM_MEDIUM, /* 15 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_LONG,
+ TPM_SHORT, /* 20 */
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_SHORT, /* 25 */
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_MEDIUM, /* 30 */
+ TPM_LONG,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT, /* 35 */
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_MEDIUM, /* 40 */
+ TPM_LONG,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT, /* 45 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_LONG,
+ TPM_MEDIUM, /* 50 */
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 55 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_MEDIUM, /* 60 */
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_MEDIUM, /* 65 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 70 */
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 75 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_LONG, /* 80 */
+ TPM_UNDEFINED,
+ TPM_MEDIUM,
+ TPM_LONG,
+ TPM_SHORT,
+ TPM_UNDEFINED, /* 85 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 90 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED, /* 95 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_MEDIUM, /* 100 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 105 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 110 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT, /* 115 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_LONG, /* 120 */
+ TPM_LONG,
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_SHORT,
+ TPM_SHORT, /* 125 */
+ TPM_SHORT,
+ TPM_LONG,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT, /* 130 */
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_UNDEFINED, /* 135 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 140 */
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 145 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 150 */
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED, /* 155 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 160 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 165 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_LONG, /* 170 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 175 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_MEDIUM, /* 180 */
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_MEDIUM, /* 185 */
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 190 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 195 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 200 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT,
+ TPM_SHORT, /* 205 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_MEDIUM, /* 210 */
+ TPM_UNDEFINED,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_UNDEFINED, /* 215 */
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT,
+ TPM_SHORT, /* 220 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED, /* 225 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 230 */
+ TPM_LONG,
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 235 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 240 */
+ TPM_UNDEFINED,
+ TPM_MEDIUM,
+};
+
+/*
+ * Returns max number of milliseconds to wait
+ */
+unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
+{
+ int duration_idx = TPM_UNDEFINED;
+ int duration = 0;
+
+ if (ordinal < TPM_MAX_ORDINAL)
+ duration_idx = tpm_ordinal_duration[ordinal];
+ else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
+ TPM_MAX_PROTECTED_ORDINAL)
+ duration_idx =
+ tpm_protected_ordinal_duration[ordinal &
+ TPM_PROTECTED_ORDINAL_MASK];
+
+ if (duration_idx != TPM_UNDEFINED)
+ duration = chip->vendor.duration[duration_idx];
+ if (duration <= 0)
+ return 2 * 60 * HZ; /*two minutes timeout*/
+ else
+ return duration;
+}
+
+#define TPM_CMD_COUNT_BYTE 2
+#define TPM_CMD_ORDINAL_BYTE 6
+
+ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
+{
+ ssize_t rc;
+ u32 count, ordinal;
+ unsigned long start, stop;
+
+ struct tpm_chip *chip = &g_chip;
+
+ /* switch endianess: big->little */
+ count = get_unaligned_be32(buf + TPM_CMD_COUNT_BYTE);
+ ordinal = get_unaligned_be32(buf + TPM_CMD_ORDINAL_BYTE);
+
+ if (count == 0) {
+ dev_err(chip->dev, "no data\n");
+ return -ENODATA;
+ }
+ if (count > bufsiz) {
+ dev_err(chip->dev,
+ "invalid count value %x %zx\n", count, bufsiz);
+ return -E2BIG;
+ }
+
+ rc = chip->vendor.send(chip, (u8 *)buf, count);
+ if (rc < 0) {
+ dev_err(chip->dev, "tpm_transmit: tpm_send: error %zd\n", rc);
+ goto out;
+ }
+
+ if (chip->vendor.irq)
+ goto out_recv;
+
+ start = get_timer(0);
+ stop = tpm_calc_ordinal_duration(chip, ordinal);
+ do {
+ dbg_printf("waiting for status...\n");
+ u8 status = chip->vendor.status(chip);
+ if ((status & chip->vendor.req_complete_mask) ==
+ chip->vendor.req_complete_val) {
+ dbg_printf("...got it;\n");
+ goto out_recv;
+ }
+
+ if ((status == chip->vendor.req_canceled)) {
+ dev_err(chip->dev, "Operation Canceled\n");
+ rc = -ECANCELED;
+ goto out;
+ }
+ msleep(TPM_TIMEOUT);
+ } while (get_timer(start) < stop);
+
+ chip->vendor.cancel(chip);
+ dev_err(chip->dev, "Operation Timed out\n");
+ rc = -ETIME;
+ goto out;
+
+out_recv:
+
+ dbg_printf("out_recv: reading response...\n");
+ rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
+ if (rc < 0)
+ dev_err(chip->dev, "tpm_transmit: tpm_recv: error %zd\n", rc);
+out:
+ return rc;
+}
+
+#define TPM_ERROR_SIZE 10
+
+enum tpm_capabilities {
+ TPM_CAP_PROP = cpu_to_be32(5),
+};
+
+enum tpm_sub_capabilities {
+ TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
+ TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
+};
+
+struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
+{
+ struct tpm_chip *chip;
+
+ /* Driver specific per-device data */
+ chip = &g_chip;
+ memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
+ chip->is_open = 1;
+
+ return chip;
+}
+
+int tpm_open(uint32_t dev_addr)
+{
+ int rc;
+ if (g_chip.is_open)
+ return -EBUSY;
+ rc = tpm_vendor_init(dev_addr);
+ if (rc < 0)
+ g_chip.is_open = 0;
+ return rc;
+}
+
+void tpm_close(void)
+{
+ if (g_chip.is_open) {
+ tpm_vendor_cleanup(&g_chip);
+ g_chip.is_open = 0;
+ }
+}
diff --git a/drivers/tpm/slb9635_i2c/tpm.h b/drivers/tpm/slb9635_i2c/tpm.h
new file mode 100644
index 0000000..9ddee86
--- /dev/null
+++ b/drivers/tpm/slb9635_i2c/tpm.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2011 Infineon Technologies
+ *
+ * Authors:
+ * Peter Huewe <huewe.external@infineon.com>
+ *
+ * Version: 2.1.1
+ *
+ * Description:
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * It is based on the Linux kernel driver tpm.c from Leendert van
+ * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
+ *
+ *
+ * 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, version 2 of the
+ * License.
+ *
+ * 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 _TPM_H_
+#define _TPM_H_
+
+#include <linux/compiler.h>
+
+#include "compatibility.h"
+
+enum tpm_timeout {
+ TPM_TIMEOUT = 5, /* msecs */
+};
+
+/* Size of external transmit buffer (used in tpm_transmit)*/
+#define TPM_BUFSIZE 4096
+
+/* Index of fields in TPM command buffer */
+#define TPM_CMD_SIZE_BYTE 2
+#define TPM_CMD_ORDINAL_BYTE 6
+
+/* Index of Count field in TPM response buffer */
+#define TPM_RSP_SIZE_BYTE 2
+#define TPM_RSP_RC_BYTE 6
+
+struct tpm_chip;
+
+struct tpm_vendor_specific {
+ const u8 req_complete_mask;
+ const u8 req_complete_val;
+ const u8 req_canceled;
+ int irq;
+ int (*recv) (struct tpm_chip *, u8 *, size_t);
+ int (*send) (struct tpm_chip *, u8 *, size_t);
+ void (*cancel) (struct tpm_chip *);
+ u8(*status) (struct tpm_chip *);
+ int locality;
+ unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */
+ unsigned long duration[3]; /* msec */
+};
+
+struct tpm_chip {
+ int is_open;
+ struct tpm_vendor_specific vendor;
+};
+
+struct tpm_input_header {
+ __be16 tag;
+ __be32 length;
+ __be32 ordinal;
+} __packed;
+
+struct tpm_output_header {
+ __be16 tag;
+ __be32 length;
+ __be32 return_code;
+} __packed;
+
+struct timeout_t {
+ __be32 a;
+ __be32 b;
+ __be32 c;
+ __be32 d;
+} __packed;
+
+struct duration_t {
+ __be32 tpm_short;
+ __be32 tpm_medium;
+ __be32 tpm_long;
+} __packed;
+
+union cap_t {
+ struct timeout_t timeout;
+ struct duration_t duration;
+};
+
+struct tpm_getcap_params_in {
+ __be32 cap;
+ __be32 subcap_size;
+ __be32 subcap;
+} __packed;
+
+struct tpm_getcap_params_out {
+ __be32 cap_size;
+ union cap_t cap;
+} __packed;
+
+union tpm_cmd_header {
+ struct tpm_input_header in;
+ struct tpm_output_header out;
+};
+
+union tpm_cmd_params {
+ struct tpm_getcap_params_out getcap_out;
+ struct tpm_getcap_params_in getcap_in;
+};
+
+struct tpm_cmd_t {
+ union tpm_cmd_header header;
+ union tpm_cmd_params params;
+} __packed;
+
+
+/* ---------- Interface for TPM vendor ------------ */
+
+extern struct tpm_chip *tpm_register_hardware(
+ const struct tpm_vendor_specific *);
+
+extern int tpm_vendor_init(uint32_t dev_addr);
+
+extern void tpm_vendor_cleanup(struct tpm_chip *chip);
+
+/* ---------- Interface for TDDL ------------------- */
+
+/*
+ * if dev_addr != 0 - redefines TPM device address
+ * Returns < 0 on error, 0 on success.
+ */
+extern int tpm_open(uint32_t dev_addr);
+
+extern void tpm_close(void);
+
+/*
+ * Transmit bufsiz bytes out of buf to TPM and get results back in buf, too.
+ * Returns < 0 on error, 0 on success.
+ */
+extern ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz);
+
+#endif
diff --git a/drivers/tpm/slb9635_i2c/tpm_tis_i2c.c b/drivers/tpm/slb9635_i2c/tpm_tis_i2c.c
new file mode 100644
index 0000000..82a41bf
--- /dev/null
+++ b/drivers/tpm/slb9635_i2c/tpm_tis_i2c.c
@@ -0,0 +1,561 @@
+/*
+ * Copyright (C) 2011 Infineon Technologies
+ *
+ * Authors:
+ * Peter Huewe <huewe.external@infineon.com>
+ *
+ * Description:
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This device driver implements the TPM interface as defined in
+ * the TCG TPM Interface Spec version 1.2, revision 1.0 and the
+ * Infineon I2C Protocol Stack Specification v0.20.
+ *
+ * It is based on the Linux kernel driver tpm.c from Leendert van
+ * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
+ *
+ * Version: 2.1.1
+ *
+ * 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, version 2 of the
+ * License.
+ *
+ * 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 <i2c.h>
+#include <linux/types.h>
+
+#include "compatibility.h"
+#include "tpm.h"
+
+/* max. buffer size supported by our tpm */
+#ifdef TPM_BUFSIZE
+#undef TPM_BUFSIZE
+#endif
+#define TPM_BUFSIZE 1260
+/* Address of the TPM on the I2C bus */
+#define TPM_I2C_ADDR 0x20
+/* max. number of iterations after i2c NAK */
+#define MAX_COUNT 3
+
+#define SLEEP_DURATION 60 /*in usec*/
+
+/* max. number of iterations after i2c NAK for 'long' commands
+ * we need this especially for sending TPM_READY, since the cleanup after the
+ * transtion to the ready state may take some time, but it is unpredictable
+ * how long it will take.
+ */
+#define MAX_COUNT_LONG 50
+
+#define SLEEP_DURATION_LONG 210 /* in usec */
+
+/* expected value for DIDVID register */
+#define TPM_TIS_I2C_DID_VID 0x000b15d1L
+
+/* Structure to store I2C TPM specific stuff */
+struct tpm_inf_dev {
+ uint addr;
+ u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */
+};
+
+static struct tpm_inf_dev tpm_dev = {
+ .addr = TPM_I2C_ADDR
+};
+
+/*
+ * iic_tpm_read() - read from TPM register
+ * @addr: register address to read from
+ * @buffer: provided by caller
+ * @len: number of bytes to read
+ *
+ * Read len bytes from TPM register and put them into
+ * buffer (little-endian format, i.e. first byte is put into buffer[0]).
+ *
+ * NOTE: TPM is big-endian for multi-byte values. Multi-byte
+ * values have to be swapped.
+ *
+ * Return -EIO on error, 0 on success.
+ */
+int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
+{
+ int rc;
+ int count;
+ uint myaddr = addr;
+ /* we have to use uint here, uchar hangs the board */
+
+ for (count = 0; count < MAX_COUNT; count++) {
+ rc = i2c_write(tpm_dev.addr, 0, 0, (uchar *)&myaddr, 1);
+ if (rc == 0)
+ break; /*success, break to skip sleep*/
+
+ udelay(SLEEP_DURATION);
+ }
+
+ if (rc)
+ return -rc;
+
+ /* After the TPM has successfully received the register address it needs
+ * some time, thus we're sleeping here again, before retrieving the data
+ */
+ for (count = 0; count < MAX_COUNT; count++) {
+ udelay(SLEEP_DURATION);
+ rc = i2c_read(tpm_dev.addr, 0, 0, buffer, len);
+ if (rc == 0)
+ break; /*success, break to skip sleep*/
+ }
+
+ if (rc)
+ return -rc;
+
+ return 0;
+}
+
+static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
+ unsigned int sleep_time,
+ u8 max_count)
+{
+ int rc = 0;
+ int count;
+
+ /* prepare send buffer */
+ tpm_dev.buf[0] = addr;
+ memcpy(&(tpm_dev.buf[1]), buffer, len);
+
+ for (count = 0; count < max_count; count++) {
+ rc = i2c_write(tpm_dev.addr, 0, 0, tpm_dev.buf, len + 1);
+ if (rc == 0)
+ break; /*success, break to skip sleep*/
+
+ udelay(sleep_time);
+ }
+
+ if (rc)
+ return -rc;
+
+ return 0;
+}
+
+/*
+ * iic_tpm_write() - write to TPM register
+ * @addr: register address to write to
+ * @buffer: containing data to be written
+ * @len: number of bytes to write
+ *
+ * Write len bytes from provided buffer to TPM register (little
+ * endian format, i.e. buffer[0] is written as first byte).
+ *
+ * NOTE: TPM is big-endian for multi-byte values. Multi-byte
+ * values have to be swapped.
+ *
+ * NOTE: use this function instead of the iic_tpm_write_generic function.
+ *
+ * Return -EIO on error, 0 on success
+ */
+static int iic_tpm_write(u8 addr, u8 *buffer, size_t len)
+{
+ return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION,
+ MAX_COUNT);
+}
+
+/*
+ * This function is needed especially for the cleanup situation after
+ * sending TPM_READY
+ * */
+static int iic_tpm_write_long(u8 addr, u8 *buffer, size_t len)
+{
+ return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
+ MAX_COUNT_LONG);
+}
+
+#define TPM_HEADER_SIZE 10
+
+enum tis_access {
+ TPM_ACCESS_VALID = 0x80,
+ TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
+ TPM_ACCESS_REQUEST_PENDING = 0x04,
+ TPM_ACCESS_REQUEST_USE = 0x02,
+};
+
+enum tis_status {
+ TPM_STS_VALID = 0x80,
+ TPM_STS_COMMAND_READY = 0x40,
+ TPM_STS_GO = 0x20,
+ TPM_STS_DATA_AVAIL = 0x10,
+ TPM_STS_DATA_EXPECT = 0x08,
+};
+
+enum tis_defaults {
+ TIS_SHORT_TIMEOUT = 750, /* ms */
+ TIS_LONG_TIMEOUT = 2000, /* 2 sec */
+};
+
+#define TPM_ACCESS(l) (0x0000 | ((l) << 4))
+#define TPM_STS(l) (0x0001 | ((l) << 4))
+#define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4))
+#define TPM_DID_VID(l) (0x0006 | ((l) << 4))
+
+static int check_locality(struct tpm_chip *chip, int loc)
+{
+ u8 buf;
+ int rc;
+
+ rc = iic_tpm_read(TPM_ACCESS(loc), &buf, 1);
+ if (rc < 0)
+ return rc;
+
+ if ((buf & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
+ (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
+ chip->vendor.locality = loc;
+ return loc;
+ }
+
+ return -1;
+}
+
+static void release_locality(struct tpm_chip *chip, int loc, int force)
+{
+ u8 buf;
+ if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
+ return;
+
+ if (force || (buf & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
+ (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) {
+ buf = TPM_ACCESS_ACTIVE_LOCALITY;
+ iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
+ }
+}
+
+static int request_locality(struct tpm_chip *chip, int loc)
+{
+ unsigned long start, stop;
+ u8 buf = TPM_ACCESS_REQUEST_USE;
+
+ if (check_locality(chip, loc) >= 0)
+ return loc; /* we already have the locality */
+
+ iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
+
+ /* wait for burstcount */
+ start = get_timer(0);
+ stop = chip->vendor.timeout_a;
+ do {
+ if (check_locality(chip, loc) >= 0)
+ return loc;
+ msleep(TPM_TIMEOUT);
+ } while (get_timer(start) < stop);
+
+ return -1;
+}
+
+static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
+{
+ /* NOTE: since i2c read may fail, return 0 in this case --> time-out */
+ u8 buf;
+ if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
+ return 0;
+ else
+ return buf;
+}
+
+static void tpm_tis_i2c_ready(struct tpm_chip *chip)
+{
+ /* this causes the current command to be aborted */
+ u8 buf = TPM_STS_COMMAND_READY;
+ iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1);
+}
+
+static ssize_t get_burstcount(struct tpm_chip *chip)
+{
+ unsigned long start, stop;
+ ssize_t burstcnt;
+ u8 buf[3];
+
+ /* wait for burstcount */
+ /* which timeout value, spec has 2 answers (c & d) */
+ start = get_timer(0);
+ stop = chip->vendor.timeout_d;
+ do {
+ /* Note: STS is little endian */
+ if (iic_tpm_read(TPM_STS(chip->vendor.locality) + 1, buf, 3)
+ < 0)
+ burstcnt = 0;
+ else
+ burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
+
+ if (burstcnt)
+ return burstcnt;
+ msleep(TPM_TIMEOUT);
+ } while (get_timer(start) < stop);
+
+ return -EBUSY;
+}
+
+static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
+ int *status)
+{
+ unsigned long start, stop;
+
+ /* check current status */
+ *status = tpm_tis_i2c_status(chip);
+ if ((*status & mask) == mask)
+ return 0;
+
+ start = get_timer(0);
+ stop = timeout;
+ do {
+ msleep(TPM_TIMEOUT);
+ *status = tpm_tis_i2c_status(chip);
+ if ((*status & mask) == mask)
+ return 0;
+
+ } while (get_timer(start) < stop);
+
+ return -ETIME;
+}
+
+static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+ size_t size = 0;
+ ssize_t burstcnt;
+ int rc;
+
+ while (size < count) {
+ burstcnt = get_burstcount(chip);
+
+ /* burstcount < 0 = tpm is busy */
+ if (burstcnt < 0)
+ return burstcnt;
+
+ /* limit received data to max. left */
+ if (burstcnt > (count - size))
+ burstcnt = count - size;
+
+ rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality),
+ &(buf[size]),
+ burstcnt);
+ if (rc == 0)
+ size += burstcnt;
+ }
+
+ return size;
+}
+
+static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+ int size = 0;
+ int expected, status;
+
+ if (count < TPM_HEADER_SIZE) {
+ size = -EIO;
+ goto out;
+ }
+
+ /* read first 10 bytes, including tag, paramsize, and result */
+ size = recv_data(chip, buf, TPM_HEADER_SIZE);
+ if (size < TPM_HEADER_SIZE) {
+ dev_err(chip->dev, "Unable to read header\n");
+ goto out;
+ }
+
+ expected = get_unaligned_be32(buf + TPM_RSP_SIZE_BYTE);
+ if ((size_t)expected > count) {
+ size = -EIO;
+ goto out;
+ }
+
+ size += recv_data(chip, &buf[TPM_HEADER_SIZE],
+ expected - TPM_HEADER_SIZE);
+ if (size < expected) {
+ dev_err(chip->dev, "Unable to read remainder of result\n");
+ size = -ETIME;
+ goto out;
+ }
+
+ wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
+ if (status & TPM_STS_DATA_AVAIL) { /* retry? */
+ dev_err(chip->dev, "Error left over data\n");
+ size = -EIO;
+ goto out;
+ }
+
+out:
+ tpm_tis_i2c_ready(chip);
+ /* The TPM needs some time to clean up here,
+ * so we sleep rather than keeping the bus busy
+ */
+ udelay(2000);
+ release_locality(chip, chip->vendor.locality, 0);
+
+ return size;
+}
+
+static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
+{
+ int rc, status;
+ ssize_t burstcnt;
+ size_t count = 0;
+ u8 sts = TPM_STS_GO;
+
+ if (len > TPM_BUFSIZE)
+ return -E2BIG; /* command is too long for our tpm, sorry */
+
+ if (request_locality(chip, 0) < 0)
+ return -EBUSY;
+
+ status = tpm_tis_i2c_status(chip);
+ if ((status & TPM_STS_COMMAND_READY) == 0) {
+ tpm_tis_i2c_ready(chip);
+ if (wait_for_stat
+ (chip, TPM_STS_COMMAND_READY,
+ chip->vendor.timeout_b, &status) < 0) {
+ rc = -ETIME;
+ goto out_err;
+ }
+ }
+
+ while (count < len - 1) {
+ burstcnt = get_burstcount(chip);
+
+ /* burstcount < 0 = tpm is busy */
+ if (burstcnt < 0)
+ return burstcnt;
+
+ if (burstcnt > (len-1-count))
+ burstcnt = len-1-count;
+
+#ifdef CONFIG_TPM_I2C_BURST_LIMITATION
+ if (burstcnt > CONFIG_TPM_I2C_BURST_LIMITATION)
+ burstcnt = CONFIG_TPM_I2C_BURST_LIMITATION;
+#endif /* CONFIG_TPM_I2C_BURST_LIMITATION */
+
+ rc = iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
+ &(buf[count]), burstcnt);
+ if (rc == 0)
+ count += burstcnt;
+
+ wait_for_stat(chip, TPM_STS_VALID,
+ chip->vendor.timeout_c, &status);
+
+ if ((status & TPM_STS_DATA_EXPECT) == 0) {
+ rc = -EIO;
+ goto out_err;
+ }
+ }
+
+ /* write last byte */
+ iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), &(buf[count]), 1);
+ wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
+ if ((status & TPM_STS_DATA_EXPECT) != 0) {
+ rc = -EIO;
+ goto out_err;
+ }
+
+ /* go and do it */
+ iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1);
+
+ return len;
+out_err:
+ tpm_tis_i2c_ready(chip);
+ /* The TPM needs some time to clean up here,
+ * so we sleep rather than keeping the bus busy
+ */
+ udelay(2000);
+ release_locality(chip, chip->vendor.locality, 0);
+
+ return rc;
+}
+
+static struct tpm_vendor_specific tpm_tis_i2c = {
+ .status = tpm_tis_i2c_status,
+ .recv = tpm_tis_i2c_recv,
+ .send = tpm_tis_i2c_send,
+ .cancel = tpm_tis_i2c_ready,
+ .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ .req_canceled = TPM_STS_COMMAND_READY,
+};
+
+/* initialisation of i2c tpm */
+
+
+int tpm_vendor_init(uint32_t dev_addr)
+{
+ u32 vendor;
+ uint old_addr;
+ int rc = 0;
+ struct tpm_chip *chip;
+
+ old_addr = tpm_dev.addr;
+ if (dev_addr != 0)
+ tpm_dev.addr = dev_addr;
+
+ chip = tpm_register_hardware(&tpm_tis_i2c);
+ if (chip < 0) {
+ rc = -ENODEV;
+ goto out_err;
+ }
+
+ /* Disable interrupts (not supported) */
+ chip->vendor.irq = 0;
+
+ /* Default timeouts */
+ chip->vendor.timeout_a = TIS_SHORT_TIMEOUT;
+ chip->vendor.timeout_b = TIS_LONG_TIMEOUT;
+ chip->vendor.timeout_c = TIS_SHORT_TIMEOUT;
+ chip->vendor.timeout_d = TIS_SHORT_TIMEOUT;
+
+ if (request_locality(chip, 0) != 0) {
+ rc = -ENODEV;
+ goto out_err;
+ }
+
+ /* read four bytes from DID_VID register */
+ if (iic_tpm_read(TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) {
+ rc = -EIO;
+ goto out_release;
+ }
+
+ /* create DID_VID register value, after swapping to little-endian */
+ vendor = be32_to_cpu(vendor);
+
+ if (vendor != TPM_TIS_I2C_DID_VID) {
+ rc = -ENODEV;
+ goto out_release;
+ }
+
+ dev_info(dev, "1.2 TPM (device-id 0x%X)\n", vendor >> 16);
+
+ /*
+ * A timeout query to TPM can be placed here.
+ * Standard timeout values are used so far
+ */
+
+ return 0;
+
+out_release:
+ release_locality(chip, 0, 1);
+
+out_err:
+ tpm_dev.addr = old_addr;
+ return rc;
+}
+
+void tpm_vendor_cleanup(struct tpm_chip *chip)
+{
+ release_locality(chip, chip->vendor.locality, 1);
+}
diff --git a/drivers/tpm/tis_i2c.c b/drivers/tpm/tis_i2c.c
new file mode 100644
index 0000000..e818fba
--- /dev/null
+++ b/drivers/tpm/tis_i2c.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include "slb9635_i2c/tpm.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* TPM configuration */
+struct tpm {
+ int i2c_bus;
+ int slave_addr;
+ char inited;
+ int old_bus;
+} tpm;
+
+
+static int tpm_select(void)
+{
+ int ret;
+
+ tpm.old_bus = i2c_get_bus_num();
+ if (tpm.old_bus != tpm.i2c_bus) {
+ ret = i2c_set_bus_num(tpm.i2c_bus);
+ if (ret) {
+ debug("%s: Fail to set i2c bus %d\n", __func__,
+ tpm.i2c_bus);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int tpm_deselect(void)
+{
+ int ret;
+
+ if (tpm.old_bus != i2c_get_bus_num()) {
+ ret = i2c_set_bus_num(tpm.old_bus);
+ if (ret) {
+ debug("%s: Fail to restore i2c bus %d\n",
+ __func__, tpm.old_bus);
+ return -1;
+ }
+ }
+ tpm.old_bus = -1;
+ return 0;
+}
+
+/**
+ * Decode TPM configuration.
+ *
+ * @param dev Returns a configuration of TPM device
+ * @return 0 if ok, -1 on error
+ */
+static int tpm_decode_config(struct tpm *dev)
+{
+#ifdef CONFIG_OF_CONTROL
+ const void *blob = gd->fdt_blob;
+ int node, parent;
+ int i2c_bus;
+
+ node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
+ if (node < 0) {
+ debug("%s: Node not found\n", __func__);
+ return -1;
+ }
+ parent = fdt_parent_offset(blob, node);
+ if (parent < 0) {
+ debug("%s: Cannot find node parent\n", __func__);
+ return -1;
+ }
+ i2c_bus = i2c_get_bus_num_fdt(parent);
+ if (i2c_bus < 0)
+ return -1;
+ dev->i2c_bus = i2c_bus;
+ dev->slave_addr = fdtdec_get_addr(blob, node, "reg");
+#else
+ dev->i2c_bus = CONFIG_INFINEON_TPM_I2C_BUS;
+ dev->slave_addr = CONFIG_INFINEON_TPM_I2C_ADDR;
+#endif
+ return 0;
+}
+
+int tis_init(void)
+{
+ if (tpm.inited)
+ return 0;
+
+ if (tpm_decode_config(&tpm))
+ return -1;
+
+ if (tpm_select())
+ return -1;
+
+ /*
+ * Probe TPM twice; the first probing might fail because TPM is asleep,
+ * and the probing can wake up TPM.
+ */
+ if (i2c_probe(tpm.slave_addr) && i2c_probe(tpm.slave_addr)) {
+ debug("%s: fail to probe i2c addr 0x%x\n", __func__,
+ tpm.slave_addr);
+ return -1;
+ }
+
+ tpm_deselect();
+
+ tpm.inited = 1;
+
+ return 0;
+}
+
+int tis_open(void)
+{
+ int rc;
+
+ if (!tpm.inited)
+ return -1;
+
+ if (tpm_select())
+ return -1;
+
+ rc = tpm_open(tpm.slave_addr);
+
+ tpm_deselect();
+
+ return rc;
+}
+
+int tis_close(void)
+{
+ if (!tpm.inited)
+ return -1;
+
+ if (tpm_select())
+ return -1;
+
+ tpm_close();
+
+ tpm_deselect();
+
+ return 0;
+}
+
+int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
+ uint8_t *recvbuf, size_t *rbuf_len)
+{
+ int len;
+ uint8_t buf[4096];
+
+ if (!tpm.inited)
+ return -1;
+
+ if (sizeof(buf) < sbuf_size)
+ return -1;
+
+ memcpy(buf, sendbuf, sbuf_size);
+
+ if (tpm_select())
+ return -1;
+
+ len = tpm_transmit(buf, sbuf_size);
+
+ tpm_deselect();
+
+ if (len < 10) {
+ *rbuf_len = 0;
+ return -1;
+ }
+
+ memcpy(recvbuf, buf, len);
+ *rbuf_len = len;
+
+ return 0;
+}
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 4c00081..71cc0f2 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -610,7 +610,9 @@ void udc_connect(void)
#ifdef CONFIG_USB_DEV_PULLUP_GPIO
/* Turn on the USB connection by enabling the pullup resistor */
- set_GPIO_mode(CONFIG_USB_DEV_PULLUP_GPIO | GPIO_OUT);
+ writel(readl(GPDR(CONFIG_USB_DEV_PULLUP_GPIO))
+ | GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO),
+ GPDR(CONFIG_USB_DEV_PULLUP_GPIO));
writel(GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO), GPSR(CONFIG_USB_DEV_PULLUP_GPIO));
#else
/* Host port 2 transceiver D+ pull up enable */
diff --git a/drivers/video/pxa_lcd.c b/drivers/video/pxa_lcd.c
index b40ec36..5e4c685 100644
--- a/drivers/video/pxa_lcd.c
+++ b/drivers/video/pxa_lcd.c
@@ -248,6 +248,38 @@ vidinfo_t panel_info = {
};
#endif /* CONFIG_ACX517AKN */
+#ifdef CONFIG_ACX544AKN
+
+# define LCD_BPP LCD_COLOR16
+
+/* you have to set lccr0 and lccr3 (including pcd) */
+# define REG_LCCR0 0x003008f9
+# define REG_LCCR3 0x04700007 /* 16bpp */
+
+vidinfo_t panel_info = {
+ .vl_col = 320,
+ .vl_row = 320,
+ .vl_width = 320,
+ .vl_height = 320,
+ .vl_clkp = CONFIG_SYS_LOW,
+ .vl_oep = CONFIG_SYS_LOW,
+ .vl_hsp = CONFIG_SYS_LOW,
+ .vl_vsp = CONFIG_SYS_LOW,
+ .vl_dp = CONFIG_SYS_LOW,
+ .vl_bpix = LCD_BPP,
+ .vl_lbw = 0,
+ .vl_splt = 0,
+ .vl_clor = 1,
+ .vl_tft = 1,
+ .vl_hpw = 0x05,
+ .vl_blw = 0x13,
+ .vl_elw = 0x08,
+ .vl_vpw = 0x02,
+ .vl_bfw = 0x07,
+ .vl_efw = 0x05,
+};
+#endif /* CONFIG_ACX544AKN */
+
/*----------------------------------------------------------------------*/
#ifdef CONFIG_LQ038J7DH53
@@ -378,7 +410,7 @@ void lcd_initcolregs (void)
#endif /* LCD_MONOCHROME */
/*----------------------------------------------------------------------*/
-void lcd_enable (void)
+__weak void lcd_enable(void)
{
}
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index b1f4e0f..13e7c37 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -32,6 +32,7 @@ COBJS-y += imx_watchdog.o
endif
COBJS-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
COBJS-$(CONFIG_S5P) += s5p_wdt.o
+COBJS-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/watchdog/xilinx_tb_wdt.c b/drivers/watchdog/xilinx_tb_wdt.c
new file mode 100644
index 0000000..f7c722e
--- /dev/null
+++ b/drivers/watchdog/xilinx_tb_wdt.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2011-2013 Xilinx Inc.
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/microblaze_intc.h>
+#include <asm/processor.h>
+#include <watchdog.h>
+
+#define XWT_CSR0_WRS_MASK 0x00000008 /* Reset status Mask */
+#define XWT_CSR0_WDS_MASK 0x00000004 /* Timer state Mask */
+#define XWT_CSR0_EWDT1_MASK 0x00000002 /* Enable bit 1 Mask*/
+#define XWT_CSRX_EWDT2_MASK 0x00000001 /* Enable bit 2 Mask */
+
+struct watchdog_regs {
+ u32 twcsr0; /* 0x0 */
+ u32 twcsr1; /* 0x4 */
+ u32 tbr; /* 0x8 */
+};
+
+static struct watchdog_regs *watchdog_base =
+ (struct watchdog_regs *)CONFIG_WATCHDOG_BASEADDR;
+
+void hw_watchdog_reset(void)
+{
+ u32 reg;
+
+ /* Read the current contents of TCSR0 */
+ reg = readl(&watchdog_base->twcsr0);
+
+ /* Clear the watchdog WDS bit */
+ if (reg & (XWT_CSR0_EWDT1_MASK | XWT_CSRX_EWDT2_MASK))
+ writel(reg | XWT_CSR0_WDS_MASK, &watchdog_base->twcsr0);
+}
+
+void hw_watchdog_disable(void)
+{
+ u32 reg;
+
+ /* Read the current contents of TCSR0 */
+ reg = readl(&watchdog_base->twcsr0);
+
+ writel(reg & ~XWT_CSR0_EWDT1_MASK, &watchdog_base->twcsr0);
+ writel(~XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1);
+
+ puts("Watchdog disabled!\n");
+}
+
+static void hw_watchdog_isr(void *arg)
+{
+ hw_watchdog_reset();
+}
+
+int hw_watchdog_init(void)
+{
+ int ret;
+
+ writel((XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK | XWT_CSR0_EWDT1_MASK),
+ &watchdog_base->twcsr0);
+ writel(XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1);
+
+ ret = install_interrupt_handler(CONFIG_WATCHDOG_IRQ,
+ hw_watchdog_isr, NULL);
+ if (ret)
+ return 1;
+
+ return 0;
+}
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index b4022aa..fd07240 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -120,7 +120,6 @@ static int flush_fat_buffer(fsdata *mydata)
__u8 *bufptr = mydata->fatbuf;
__u32 startblock = mydata->fatbufnum * FATBUFBLOCKS;
- fatlength *= mydata->sect_size;
startblock += mydata->fat_sect;
if (getsize > fatlength)
diff --git a/fs/fs.c b/fs/fs.c
index 6f5063c..99e516a 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -47,6 +47,12 @@ static inline int fs_read_unsupported(const char *filename, void *buf,
return -1;
}
+static inline int fs_write_unsupported(const char *filename, void *buf,
+ int offset, int len)
+{
+ return -1;
+}
+
static inline void fs_close_unsupported(void)
{
}
@@ -57,6 +63,7 @@ struct fstype_info {
disk_partition_t *fs_partition);
int (*ls)(const char *dirname);
int (*read)(const char *filename, void *buf, int offset, int len);
+ int (*write)(const char *filename, void *buf, int offset, int len);
void (*close)(void);
};
@@ -86,6 +93,7 @@ static struct fstype_info fstypes[] = {
.close = sandbox_fs_close,
.ls = sandbox_fs_ls,
.read = fs_read_sandbox,
+ .write = fs_write_sandbox,
},
#endif
{
@@ -94,6 +102,7 @@ static struct fstype_info fstypes[] = {
.close = fs_close_unsupported,
.ls = fs_ls_unsupported,
.read = fs_read_unsupported,
+ .write = fs_write_unsupported,
},
};
@@ -125,6 +134,7 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
info->close += gd->reloc_off;
info->ls += gd->reloc_off;
info->read += gd->reloc_off;
+ info->write += gd->reloc_off;
}
relocated = 1;
}
@@ -196,6 +206,30 @@ int fs_read(const char *filename, ulong addr, int offset, int len)
return ret;
}
+int fs_write(const char *filename, ulong addr, int offset, int len)
+{
+ struct fstype_info *info = fs_get_info(fs_type);
+ void *buf;
+ int ret;
+
+ /*
+ * We don't actually know how many bytes are being read, since len==0
+ * means read the whole file.
+ */
+ buf = map_sysmem(addr, len);
+ ret = info->write(filename, buf, offset, len);
+ unmap_sysmem(buf);
+
+ /* If we requested a specific number of bytes, check we got it */
+ if (ret >= 0 && len && ret != len) {
+ printf("** Unable to write file %s **\n", filename);
+ ret = -1;
+ }
+ fs_close();
+
+ return ret;
+}
+
int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
int fstype, int cmdline_base)
{
@@ -277,3 +311,44 @@ int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
return 0;
}
+
+int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+ int fstype, int cmdline_base)
+{
+ unsigned long addr;
+ const char *filename;
+ unsigned long bytes;
+ unsigned long pos;
+ int len;
+ unsigned long time;
+
+ if (argc < 6 || argc > 7)
+ return CMD_RET_USAGE;
+
+ if (fs_set_blk_dev(argv[1], argv[2], fstype))
+ return 1;
+
+ filename = argv[3];
+ addr = simple_strtoul(argv[4], NULL, cmdline_base);
+ bytes = simple_strtoul(argv[5], NULL, cmdline_base);
+ if (argc >= 7)
+ pos = simple_strtoul(argv[6], NULL, cmdline_base);
+ else
+ pos = 0;
+
+ time = get_timer(0);
+ len = fs_write(filename, addr, pos, bytes);
+ time = get_timer(time);
+ if (len <= 0)
+ return 1;
+
+ printf("%d bytes written in %lu ms", len, time);
+ if (time > 0) {
+ puts(" (");
+ print_size(len / time * 1000, "/s");
+ puts(")");
+ }
+ puts("\n");
+
+ return 0;
+}
diff --git a/fs/sandbox/sandboxfs.c b/fs/sandbox/sandboxfs.c
index 02d26ff..89769e8 100644
--- a/fs/sandbox/sandboxfs.c
+++ b/fs/sandbox/sandboxfs.c
@@ -48,6 +48,26 @@ long sandbox_fs_read_at(const char *filename, unsigned long pos,
return size;
}
+long sandbox_fs_write_at(const char *filename, unsigned long pos,
+ void *buffer, unsigned long towrite)
+{
+ ssize_t size;
+ int fd, ret;
+
+ fd = os_open(filename, OS_O_RDWR | OS_O_CREAT);
+ if (fd < 0)
+ return fd;
+ ret = os_lseek(fd, pos, OS_SEEK_SET);
+ if (ret == -1) {
+ os_close(fd);
+ return ret;
+ }
+ size = os_write(fd, buffer, towrite);
+ os_close(fd);
+
+ return size;
+}
+
int sandbox_fs_ls(const char *dirname)
{
struct os_dirent_node *head, *node;
@@ -81,3 +101,16 @@ int fs_read_sandbox(const char *filename, void *buf, int offset, int len)
return len_read;
}
+
+int fs_write_sandbox(const char *filename, void *buf, int offset, int len)
+{
+ int len_written;
+
+ len_written = sandbox_fs_write_at(filename, offset, buf, len);
+ if (len_written == -1) {
+ printf("** Unable to write file %s **\n", filename);
+ return -1;
+ }
+
+ return len_written;
+}
diff --git a/include/altera.h b/include/altera.h
index 7a2bece..6aad5ee 100644
--- a/include/altera.h
+++ b/include/altera.h
@@ -27,23 +27,6 @@
#ifndef _ALTERA_H_
#define _ALTERA_H_
-/* Altera Model definitions
- *********************************************************************/
-#define CONFIG_SYS_ACEX1K CONFIG_SYS_FPGA_DEV( 0x1 )
-#define CONFIG_SYS_CYCLON2 CONFIG_SYS_FPGA_DEV( 0x2 )
-#define CONFIG_SYS_STRATIX_II CONFIG_SYS_FPGA_DEV( 0x4 )
-
-#define CONFIG_SYS_ALTERA_ACEX1K (CONFIG_SYS_FPGA_ALTERA | CONFIG_SYS_ACEX1K)
-#define CONFIG_SYS_ALTERA_CYCLON2 (CONFIG_SYS_FPGA_ALTERA | CONFIG_SYS_CYCLON2)
-#define CONFIG_SYS_ALTERA_STRATIX_II (CONFIG_SYS_FPGA_ALTERA | CONFIG_SYS_STRATIX_II)
-/* Add new models here */
-
-/* Altera Interface definitions
- *********************************************************************/
-#define CONFIG_SYS_ALTERA_IF_PS CONFIG_SYS_FPGA_IF( 0x1 ) /* passive serial */
-#define CONFIG_SYS_ALTERA_IF_FPP CONFIG_SYS_FPGA_IF( 0x2 ) /* fast passive parallel */
-/* Add new interfaces here */
-
typedef enum { /* typedef Altera_iface */
min_altera_iface_type, /* insert all new types after this */
passive_serial, /* serial data and external clock */
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index cca1edb..4b39844 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -29,7 +29,7 @@ extern char _data[], _sdata[], _edata[];
extern char __bss_start[], __bss_stop[];
extern char __init_begin[], __init_end[];
extern char _sinittext[], _einittext[];
-extern char _end[];
+extern char _end[], _init[];
extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
extern char __kprobes_text_start[], __kprobes_text_end[];
extern char __entry_text_start[], __entry_text_end[];
diff --git a/include/common.h b/include/common.h
index 0cfa6a8..8a1f3e4 100644
--- a/include/common.h
+++ b/include/common.h
@@ -352,6 +352,19 @@ int envmatch (uchar *, int);
char *getenv (const char *);
int getenv_f (const char *name, char *buf, unsigned len);
ulong getenv_ulong(const char *name, int base, ulong default_val);
+
+/**
+ * getenv_hex() - Return an environment variable as a hex value
+ *
+ * Decode an environment as a hex number (it may or may not have a 0x
+ * prefix). If the environment variable cannot be found, or does not start
+ * with hex digits, the default value is returned.
+ *
+ * @varname: Variable to decode
+ * @default_val: Value to return on error
+ */
+ulong getenv_hex(const char *varname, ulong default_val);
+
/*
* Read an environment variable as a boolean
* Return -1 if variable does not exist (default to true)
@@ -635,9 +648,6 @@ int prt_8260_clks (void);
#elif defined(CONFIG_MPC5xxx)
int prt_mpc5xxx_clks (void);
#endif
-#if defined(CONFIG_MPC512X)
-int prt_mpc512xxx_clks (void);
-#endif
#if defined(CONFIG_MPC8220)
int prt_mpc8220_clks (void);
#endif
@@ -897,6 +907,11 @@ static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
static inline void unmap_sysmem(const void *vaddr)
{
}
+
+static inline phys_addr_t map_to_sysmem(void *ptr)
+{
+ return (phys_addr_t)(uintptr_t)ptr;
+}
# endif
#endif /* __ASSEMBLY__ */
@@ -993,10 +1008,17 @@ static inline void unmap_sysmem(const void *vaddr)
* of a function scoped static buffer. It can not be used to create a cache
* line aligned global buffer.
*/
-#define ALLOC_ALIGN_BUFFER(type, name, size, align) \
- char __##name[ROUND(size * sizeof(type), align) + (align - 1)]; \
+#define PAD_COUNT(s, pad) ((s - 1) / pad + 1)
+#define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) * pad)
+#define ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad) \
+ char __##name[ROUND(PAD_SIZE(size * sizeof(type), pad), align) \
+ + (align - 1)]; \
\
type *name = (type *) ALIGN((uintptr_t)__##name, align)
+#define ALLOC_ALIGN_BUFFER(type, name, size, align) \
+ ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, 1)
+#define ALLOC_CACHE_ALIGN_BUFFER_PAD(type, name, size, pad) \
+ ALLOC_ALIGN_BUFFER_PAD(type, name, size, ARCH_DMA_MINALIGN, pad)
#define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \
ALLOC_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN)
@@ -1007,7 +1029,7 @@ static inline void unmap_sysmem(const void *vaddr)
*/
#define DEFINE_ALIGN_BUFFER(type, name, size, align) \
static char __##name[roundup(size * sizeof(type), align)] \
- __attribute__((aligned(align))); \
+ __aligned(align); \
\
static type *name = (type *)__##name
#define DEFINE_CACHE_ALIGN_BUFFER(type, name, size) \
diff --git a/include/config_cmd_default.h b/include/config_cmd_default.h
index a521103..73c9544 100644
--- a/include/config_cmd_default.h
+++ b/include/config_cmd_default.h
@@ -31,7 +31,6 @@
#define CONFIG_CMD_LOADB /* loadb */
#define CONFIG_CMD_LOADS /* loads */
#define CONFIG_CMD_MEMORY /* md mm nm mw cp cmp crc base loop */
-#define CONFIG_CMD_MEMTEST /* mtest */
#define CONFIG_CMD_MISC /* Misc functions like sleep etc*/
#define CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */
#define CONFIG_CMD_NFS /* NFS support */
diff --git a/include/configs/M54455EVB.h b/include/configs/M54455EVB.h
index 1bc2c5a..536b755 100644
--- a/include/configs/M54455EVB.h
+++ b/include/configs/M54455EVB.h
@@ -238,7 +238,7 @@
/* FPGA - Spartan 2 */
/* experiment
-#define CONFIG_FPGA CONFIG_SYS_SPARTAN3
+#define CONFIG_FPGA
#define CONFIG_FPGA_COUNT 1
#define CONFIG_SYS_FPGA_PROG_FEEDBACK
#define CONFIG_SYS_FPGA_CHECK_CTRLC
diff --git a/include/configs/MERGERBOX.h b/include/configs/MERGERBOX.h
index c296e3c..30fb6c2 100644
--- a/include/configs/MERGERBOX.h
+++ b/include/configs/MERGERBOX.h
@@ -606,7 +606,7 @@
* FPGA
*/
#define CONFIG_FPGA_COUNT 1
-#define CONFIG_FPGA CONFIG_SYS_ALTERA_CYCLON2
+#define CONFIG_FPGA
#define CONFIG_FPGA_ALTERA
#define CONFIG_FPGA_CYCLON2
diff --git a/include/configs/MVBC_P.h b/include/configs/MVBC_P.h
index 6850965..7271468 100644
--- a/include/configs/MVBC_P.h
+++ b/include/configs/MVBC_P.h
@@ -310,7 +310,7 @@
#undef FPGA_DEBUG
#undef CONFIG_SYS_FPGA_PROG_FEEDBACK
-#define CONFIG_FPGA CONFIG_SYS_ALTERA_CYCLON2
+#define CONFIG_FPGA
#define CONFIG_FPGA_ALTERA 1
#define CONFIG_FPGA_CYCLON2 1
#define CONFIG_FPGA_COUNT 1
diff --git a/include/configs/MVBLM7.h b/include/configs/MVBLM7.h
index a99ad3c..a9c00ac 100644
--- a/include/configs/MVBLM7.h
+++ b/include/configs/MVBLM7.h
@@ -499,7 +499,7 @@
""
#define CONFIG_FPGA_COUNT 1
-#define CONFIG_FPGA CONFIG_SYS_ALTERA_CYCLON2
+#define CONFIG_FPGA
#define CONFIG_FPGA_ALTERA
#define CONFIG_FPGA_CYCLON2
diff --git a/include/configs/MVSMR.h b/include/configs/MVSMR.h
index bf2f44e..5d2ff14 100644
--- a/include/configs/MVSMR.h
+++ b/include/configs/MVSMR.h
@@ -280,7 +280,7 @@
#undef FPGA_DEBUG
#undef CONFIG_SYS_FPGA_PROG_FEEDBACK
-#define CONFIG_FPGA CONFIG_SYS_XILINX_SPARTAN2
+#define CONFIG_FPGA
#define CONFIG_FPGA_XILINX 1
#define CONFIG_FPGA_SPARTAN2 1
#define CONFIG_FPGA_COUNT 1
diff --git a/include/configs/P1022DS.h b/include/configs/P1022DS.h
index 14d597a..8b13b10 100644
--- a/include/configs/P1022DS.h
+++ b/include/configs/P1022DS.h
@@ -34,6 +34,29 @@
#define CONFIG_RESET_VECTOR_ADDRESS 0x1107fffc
#endif
+#define CONFIG_NAND_FSL_ELBC
+
+#ifdef CONFIG_NAND
+#define CONFIG_SPL
+#define CONFIG_SPL_INIT_MINIMAL
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_MINIMAL
+#define CONFIG_SPL_FLUSH_IMAGE
+#define CONFIG_SPL_TARGET "u-boot-with-spl.bin"
+
+#define CONFIG_SYS_TEXT_BASE 0x00201000
+#define CONFIG_SPL_TEXT_BASE 0xfffff000
+#define CONFIG_SPL_MAX_SIZE 4096
+#define CONFIG_SPL_RELOC_TEXT_BASE 0x00100000
+#define CONFIG_SPL_RELOC_STACK 0x00100000
+#define CONFIG_SYS_NAND_U_BOOT_SIZE ((512 << 10) + CONFIG_SPL_MAX_SIZE)
+#define CONFIG_SYS_NAND_U_BOOT_DST (0x00200000 - CONFIG_SPL_MAX_SIZE)
+#define CONFIG_SYS_NAND_U_BOOT_START 0x00200000
+#define CONFIG_SYS_NAND_U_BOOT_OFFS 0
+#define CONFIG_SYS_LDSCRIPT "arch/powerpc/cpu/mpc85xx/u-boot-nand.lds"
+#endif
+
/* High Level Configuration Options */
#define CONFIG_BOOKE /* BOOKE */
#define CONFIG_E500 /* BOOKE e500 family */
@@ -84,6 +107,13 @@
#define CONFIG_SYS_CCSRBAR 0xffe00000
#define CONFIG_SYS_CCSRBAR_PHYS_LOW CONFIG_SYS_CCSRBAR
+/* IN case of NAND bootloader relocate CCSRBAR in RAMboot code not in the 4k
+ SPL code*/
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_CCSR_DO_NOT_RELOCATE
+#endif
+
+
/* DDR Setup */
#define CONFIG_DDR_SPD
#define CONFIG_VERY_BIG_RAM
@@ -105,6 +135,30 @@
#define CONFIG_SYS_SPD_BUS_NUM 1
#define SPD_EEPROM_ADDRESS 0x51 /* CTLR 0 DIMM 0 */
+/* These are used when DDR doesn't use SPD. */
+#define CONFIG_SYS_SDRAM_SIZE 2048
+#define CONFIG_SYS_SDRAM_SIZE_LAW LAW_SIZE_2G
+#define CONFIG_SYS_DDR_CS0_BNDS 0x0000003F
+#define CONFIG_SYS_DDR_CS0_CONFIG 0x80014202
+#define CONFIG_SYS_DDR_CS1_BNDS 0x0040007F
+#define CONFIG_SYS_DDR_CS1_CONFIG 0x80014202
+#define CONFIG_SYS_DDR_TIMING_3 0x00010000
+#define CONFIG_SYS_DDR_TIMING_0 0x40110104
+#define CONFIG_SYS_DDR_TIMING_1 0x5c5bd746
+#define CONFIG_SYS_DDR_TIMING_2 0x0fa8d4ca
+#define CONFIG_SYS_DDR_MODE_1 0x00441221
+#define CONFIG_SYS_DDR_MODE_2 0x00000000
+#define CONFIG_SYS_DDR_INTERVAL 0x0a280100
+#define CONFIG_SYS_DDR_DATA_INIT 0xdeadbeef
+#define CONFIG_SYS_DDR_CLK_CTRL 0x02800000
+#define CONFIG_SYS_DDR_CONTROL 0xc7000008
+#define CONFIG_SYS_DDR_CONTROL_2 0x24401041
+#define CONFIG_SYS_DDR_TIMING_4 0x00220001
+#define CONFIG_SYS_DDR_TIMING_5 0x02401400
+#define CONFIG_SYS_DDR_ZQ_CONTROL 0x89080600
+#define CONFIG_SYS_DDR_WRLVL_CONTROL 0x8675f608
+
+
/*
* Memory map
*
@@ -118,6 +172,7 @@
* Localbus non-cacheable
* 0xe000_0000 0xe80f_ffff Promjet/free 128M non-cacheable
* 0xe800_0000 0xefff_ffff FLASH 128M non-cacheable
+ * 0xff80_0000 0xff80_7fff NAND 32K non-cacheable
* 0xffdf_0000 0xffdf_7fff PIXIS 32K non-cacheable TLB0
* 0xffd0_0000 0xffd0_3fff L1 for stack 16K Cacheable TLB0
* 0xffe0_0000 0xffef_ffff CCSR 1M non-cacheable
@@ -126,38 +181,84 @@
/*
* Local Bus Definitions
*/
-#define CONFIG_SYS_FLASH_BASE 0xe0000000 /* start of FLASH 128M */
+#define CONFIG_SYS_FLASH_BASE 0xe8000000 /* start of FLASH 128M */
#ifdef CONFIG_PHYS_64BIT
-#define CONFIG_SYS_FLASH_BASE_PHYS 0xfe0000000ull
+#define CONFIG_SYS_FLASH_BASE_PHYS 0xfe8000000ull
#else
#define CONFIG_SYS_FLASH_BASE_PHYS CONFIG_SYS_FLASH_BASE
#endif
#define CONFIG_FLASH_BR_PRELIM \
- (BR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS + 0x8000000) | BR_PS_16 | BR_V)
+ (BR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | BR_PS_16 | BR_V)
#define CONFIG_FLASH_OR_PRELIM (OR_AM_128MB | 0xff7)
+#ifdef CONFIG_NAND
+#define CONFIG_SYS_BR1_PRELIM CONFIG_FLASH_BR_PRELIM /* NOR Base Address */
+#define CONFIG_SYS_OR1_PRELIM CONFIG_FLASH_OR_PRELIM /* NOR Options */
+#else
#define CONFIG_SYS_BR0_PRELIM CONFIG_FLASH_BR_PRELIM /* NOR Base Address */
#define CONFIG_SYS_OR0_PRELIM CONFIG_FLASH_OR_PRELIM /* NOR Options */
+#endif
-#define CONFIG_SYS_BR1_PRELIM \
- (BR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | BR_PS_16 | BR_V)
-#define CONFIG_SYS_OR1_PRELIM CONFIG_FLASH_OR_PRELIM
-
-#define CONFIG_SYS_FLASH_BANKS_LIST \
- {CONFIG_SYS_FLASH_BASE_PHYS + 0x8000000, CONFIG_SYS_FLASH_BASE_PHYS}
+#define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE_PHYS}
#define CONFIG_SYS_FLASH_QUIET_TEST
#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */
-#define CONFIG_SYS_MAX_FLASH_BANKS 2
+#define CONFIG_SYS_MAX_FLASH_BANKS 1
#define CONFIG_SYS_MAX_FLASH_SECT 1024
+#ifndef CONFIG_SYS_MONITOR_BASE
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SPL_TEXT_BASE
+#else
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE /* start of monitor */
+#endif
+#endif
#define CONFIG_FLASH_CFI_DRIVER
#define CONFIG_SYS_FLASH_CFI
#define CONFIG_SYS_FLASH_EMPTY_INFO
+/* Nand Flash */
+#if defined(CONFIG_NAND_FSL_ELBC)
+#define CONFIG_SYS_NAND_BASE 0xff800000
+#ifdef CONFIG_PHYS_64BIT
+#define CONFIG_SYS_NAND_BASE_PHYS 0xfff800000ull
+#else
+#define CONFIG_SYS_NAND_BASE_PHYS CONFIG_SYS_NAND_BASE
+#endif
+
+#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE, }
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_MTD_NAND_VERIFY_WRITE
+#define CONFIG_CMD_NAND 1
+#define CONFIG_SYS_NAND_BLOCK_SIZE (256 * 1024)
+#define CONFIG_ELBC_NAND_SPL_STATIC_PGSIZE
+
+/* NAND flash config */
+#define CONFIG_SYS_NAND_BR_PRELIM (BR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \
+ | (2<<BR_DECC_SHIFT) /* Use HW ECC */ \
+ | BR_PS_8 /* Port Size = 8 bit */ \
+ | BR_MS_FCM /* MSEL = FCM */ \
+ | BR_V) /* valid */
+#define CONFIG_SYS_NAND_OR_PRELIM (OR_AM_32KB /* length 256K */ \
+ | OR_FCM_PGS /* Large Page*/ \
+ | OR_FCM_CSCT \
+ | OR_FCM_CST \
+ | OR_FCM_CHT \
+ | OR_FCM_SCY_1 \
+ | OR_FCM_TRLX \
+ | OR_FCM_EHTR)
+#ifdef CONFIG_NAND
+#define CONFIG_SYS_BR0_PRELIM CONFIG_SYS_NAND_BR_PRELIM /* NAND Base Address */
+#define CONFIG_SYS_OR0_PRELIM CONFIG_SYS_NAND_OR_PRELIM /* NAND Options */
+#else
+#define CONFIG_SYS_BR1_PRELIM CONFIG_SYS_NAND_BR_PRELIM /* NAND Base Address */
+#define CONFIG_SYS_OR1_PRELIM CONFIG_SYS_NAND_OR_PRELIM /* NAND Options */
+#endif
+
+#endif /* CONFIG_NAND_FSL_ELBC */
+
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_BOARD_EARLY_INIT_R
#define CONFIG_MISC_INIT_R
@@ -177,6 +278,8 @@
#define PIXIS_LBMAP_SWITCH 7
#define PIXIS_LBMAP_MASK 0xF0
#define PIXIS_LBMAP_ALTBANK 0x20
+#define PIXIS_SPD 0x07
+#define PIXIS_SPD_SYSCLK_MASK 0x07
#define PIXIS_ELBC_SPI_MASK 0xc0
#define PIXIS_SPI 0x80
@@ -199,6 +302,9 @@
#define CONFIG_SYS_NS16550_SERIAL
#define CONFIG_SYS_NS16550_REG_SIZE 1
#define CONFIG_SYS_NS16550_CLK get_bus_freq(0)
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_NS16550_MIN_FUNCTIONS
+#endif
#define CONFIG_SYS_BAUDRATE_TABLE \
{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}
@@ -419,7 +525,6 @@
/*
* Environment
*/
-#ifdef CONFIG_SYS_RAMBOOT
#ifdef CONFIG_RAMBOOT_SPIFLASH
#define CONFIG_ENV_IS_IN_SPI_FLASH
#define CONFIG_ENV_SPI_BUS 0
@@ -433,16 +538,15 @@
#define CONFIG_ENV_IS_IN_MMC
#define CONFIG_ENV_SIZE 0x2000
#define CONFIG_SYS_MMC_ENV_DEV 0
-#elif defined(CONFIG_NAND_U_BOOT)
+#elif defined(CONFIG_NAND)
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_SIZE CONFIG_SYS_NAND_BLOCK_SIZE
#define CONFIG_ENV_OFFSET ((512 * 1024) + CONFIG_SYS_NAND_BLOCK_SIZE)
#define CONFIG_ENV_RANGE (3 * CONFIG_ENV_SIZE)
-#else
+#elif defined(CONFIG_SYS_RAMBOOT)
#define CONFIG_ENV_IS_NOWHERE /* Store ENV in memory only */
#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - 0x1000)
#define CONFIG_ENV_SIZE 0x2000
-#endif
#else
#define CONFIG_ENV_IS_IN_FLASH
#if CONFIG_SYS_MONITOR_BASE > 0xfff80000
diff --git a/include/configs/a3m071.h b/include/configs/a3m071.h
index 13f3226..e9af825 100644
--- a/include/configs/a3m071.h
+++ b/include/configs/a3m071.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Stefan Roese <sr@denx.de>
+ * Copyright 2012-2013 Stefan Roese <sr@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -59,6 +59,38 @@
#define CONFIG_CMD_CACHE
#define CONFIG_CMD_MII
#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_DHCP
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_BOOTP_SERVERIP
+#define CONFIG_BOOTP_MAY_FAIL
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_SERVERIP
+#define CONFIG_NET_RETRY_COUNT 3
+#define CONFIG_CMD_LINK_LOCAL
+#define CONFIG_NETCONSOLE
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_CMD_PING
+#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS /* needed for UBI */
+#define CONFIG_FLASH_CFI_MTD
+#define MTDIDS_DEFAULT "nor0=fc000000.flash"
+#define MTDPARTS_DEFAULT "mtdparts=fc000000.flash:512k(u-boot)," \
+ "256k(env)," \
+ "128k(hwinfo)," \
+ "1M(nvramsim)," \
+ "128k(dtb)," \
+ "5M(kernel)," \
+ "128k(sysinfo)," \
+ "7552k(root)," \
+ "4M(app)," \
+ "13568k(data)"
+#define CONFIG_LZO /* needed for UBI */
+#define CONFIG_RBTREE /* needed for UBI */
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_FIT
/*
* IPB Bus clocking configuration.
@@ -88,7 +120,7 @@
*/
#define CONFIG_SYS_FLASH_BASE 0xfc000000
#define CONFIG_SYS_FLASH_SIZE 0x02000000
-#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x40000)
+#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x80000)
#define CONFIG_SYS_MAX_FLASH_BANKS 1
#define CONFIG_SYS_MAX_FLASH_SECT 256
@@ -101,6 +133,7 @@
#define CONFIG_SYS_FLASH_CFI
#define CONFIG_SYS_FLASH_EMPTY_INFO
#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
+#define CONFIG_FLASH_VERIFY
/*
* Environment settings
@@ -109,6 +142,8 @@
#define CONFIG_ENV_SIZE 0x10000
#define CONFIG_ENV_SECT_SIZE 0x20000
#define CONFIG_ENV_OVERWRITE
+#define CONFIG_ENV_ADDR_REDUND (CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE)
+#define CONFIG_ENV_SIZE_REDUND (CONFIG_ENV_SIZE)
/*
* Memory map
@@ -121,16 +156,14 @@
#define CONFIG_SYS_INIT_RAM_ADDR MPC5XXX_SRAM
#define CONFIG_SYS_INIT_RAM_END MPC5XXX_SRAM_SIZE
-
-#define CONFIG_SYS_GBL_DATA_SIZE 128
#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_END - \
- CONFIG_SYS_GBL_DATA_SIZE)
+ GENERATED_GBL_DATA_SIZE)
#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
-#define CONFIG_SYS_MONITOR_LEN (256 << 10)
-#define CONFIG_SYS_MALLOC_LEN (1 << 20)
+#define CONFIG_SYS_MONITOR_LEN (512 << 10)
+#define CONFIG_SYS_MALLOC_LEN (4 << 20)
#define CONFIG_SYS_BOOTMAPSZ (8 << 20)
/*
@@ -156,14 +189,14 @@
*/
#ifdef CONFIG_A4M2K
-#define CONFIG_SYS_GPS_PORT_CONFIG 0x0005C805
+#define CONFIG_SYS_GPS_PORT_CONFIG 0x1005C805
#else
/* for failsave-level 0 - full failsave */
#define CONFIG_SYS_GPS_PORT_CONFIG 0x1005C005
/* for failsave-level 1 - only digiboard ok */
-#define CONFIG_SYS_GPS_PORT_CONFIG_1 0x1005C005
+#define CONFIG_SYS_GPS_PORT_CONFIG_1 0x1005C065
/* for failsave-level 2 - all ok */
-#define CONFIG_SYS_GPS_PORT_CONFIG_2 0x1005C005
+#define CONFIG_SYS_GPS_PORT_CONFIG_2 0x1005C065
#endif
#define CONFIG_WDOG_GPIO_PIN GPIO_WKUP_7
@@ -173,10 +206,10 @@
/*
* Configuration matrix
- * MSB LSB
+ * MSB LSB
* failsave 0 0x1005C005 00010000000001011100000000000101 ( full failsave )
- * failsave 1 0x1005C005 00010000000001011100000000000101 ( digib.-ver ok )
- * failsave 2 0x1005C005 00010000000001011100000000000101 ( all ok )
+ * failsave 1 0x1005C065 00010000000001011100000001100101 ( digib.-ver ok )
+ * failsave 2 0x1005C065 00010000000001011100000001100101 ( all ok )
* || ||| || | ||| | | | |
* || ||| || | ||| | | | | bit rev name
* ++-+++-++--+---+++-+---+---+---+- 0 31 CS1
@@ -312,10 +345,12 @@
* Environment Configuration
*/
-#define CONFIG_BOOTDELAY 0 /* -1 disables auto-boot */
+#define CONFIG_BOOTDELAY 3 /* -1 disables auto-boot */
#undef CONFIG_BOOTARGS
#define CONFIG_ZERO_BOOTDELAY_CHECK
+#define CONFIG_SYS_AUTOLOAD "n"
+
#define CONFIG_PREBOOT "echo;" \
"echo Type \"run flash_mtd\" to boot from flash with mtd filesystem;" \
"echo Type \"run net_nfs\" to boot from tftp with nfs filesystem;" \
@@ -323,11 +358,10 @@
#undef CONFIG_BOOTARGS
-#define CONFIG_SYS_OS_BASE 0xfc080000
-#define CONFIG_SYS_FDT_BASE 0xfc060000
+#define CONFIG_SYS_OS_BASE 0xfc200000
+#define CONFIG_SYS_FDT_BASE 0xfc1e0000
#define CONFIG_EXTRA_ENV_SETTINGS \
- "hostname=" __stringify(CONFIG_HOSTNAME) "\0" \
"netdev=eth0\0" \
"verify=no\0" \
"loadaddr=200000\0" \
@@ -344,29 +378,31 @@
"nfsargs=setenv bootargs root=/dev/nfs rw " \
"nfsroot=${serverip}:${rootpath}\0" \
"ramargs=setenv bootargs root=/dev/ram rw\0" \
- "mtdargs=setenv bootargs root=/dev/mtdblock4 rw rootfstype=jffs2\0" \
+ "mtdargs=setenv bootargs root=/dev/mtdblock7 " \
+ "rootfstype=squashfs,jffs2\0" \
+ "addhost=setenv bootargs ${bootargs} " \
+ "hostname=${hostname}\0" \
"addip=setenv bootargs ${bootargs} " \
"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \
":${hostname}:${netdev}:off panic=1\0" \
"addtty=setenv bootargs ${bootargs} " \
"console=${consoledev},${baudrate}\0" \
- "flash_nfs=run nfsargs addip addtty;" \
- "bootm ${kernel_addr} - ${fdtaddr}\0" \
- "flash_mtd=run mtdargs addip addtty;" \
- "bootm ${kernel_addr} - ${fdtaddr}\0" \
- "flash_self=run ramargs addip addtty;" \
+ "flash_nfs=run nfsargs addip addtty addhost;" \
+ "bootm ${kernel_addr} - ${fdt_addr}\0" \
+ "flash_mtd=run mtdargs addip addtty addhost;" \
+ "bootm ${kernel_addr} - ${fdt_addr}\0" \
+ "flash_self=run ramargs addip addtty addhost;" \
"bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}\0" \
"net_nfs=tftp ${kernel_addr_r} ${bootfile};" \
"tftp ${fdt_addr_r} ${fdtfile};" \
- "run nfsargs addip addtty;" \
+ "run nfsargs addip addtty addhost;" \
"bootm ${kernel_addr_r} - ${fdt_addr_r}\0" \
"load=tftp ${loadaddr} " __stringify(CONFIG_HOSTNAME) \
"/u-boot-img.bin\0" \
- "update=protect off fc000000 fc03ffff; " \
- "era fc000000 fc03ffff; cp.b ${loadaddr} fc000000 40000\0" \
+ "update=protect off fc000000 fc07ffff; " \
+ "era fc000000 fc07ffff;" \
+ "cp.b ${loadaddr} fc000000 ${filesize}\0" \
"upd=run load;run update\0" \
- "bootdelay=3\0" \
- "bootcmd=run net_nfs\0" \
""
#define CONFIG_BOOTCOMMAND "run flash_mtd"
diff --git a/include/configs/amcc-common.h b/include/configs/amcc-common.h
index f2f522d..80e5735 100644
--- a/include/configs/amcc-common.h
+++ b/include/configs/amcc-common.h
@@ -71,6 +71,7 @@
#define CONFIG_CMD_DIAG
#define CONFIG_CMD_EEPROM
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_GREPENV
#define CONFIG_CMD_I2C
#define CONFIG_CMD_IRQ
#define CONFIG_CMD_MII
@@ -78,6 +79,7 @@
#define CONFIG_CMD_NFS
#define CONFIG_CMD_PING
#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_SETEXPR
/*
* Miscellaneous configurable options
@@ -108,13 +110,14 @@
#define CONFIG_MX_CYCLIC /* enable mdc/mwc commands */
#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
#define CONFIG_VERSION_VARIABLE /* include version env variable */
-#define CONFIG_SYS_CONSOLE_INFO_QUIET /* don't print console @ startup*/
+#define CONFIG_SYS_CONSOLE_INFO_QUIET /* don't print console @ startup*/
-#define CONFIG_SYS_HUSH_PARSER /* Use the HUSH parser */
+#define CONFIG_SYS_HUSH_PARSER /* Use the HUSH parser */
#define CONFIG_LOADS_ECHO /* echo on for serial download */
-#define CONFIG_SYS_LOADS_BAUD_CHANGE /* allow baudrate change */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE /* allow baudrate change */
+#define CONFIG_REGEX /* Enable regular expression support */
/*
* BOOTP options
*/
diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h
index a4aa8f7..5bacc77 100644
--- a/include/configs/coreboot.h
+++ b/include/configs/coreboot.h
@@ -41,6 +41,7 @@
#define CONFIG_INTEL_CORE_ARCH /* Sandy bridge and ivy bridge chipsets. */
#define CONFIG_ZBOOT_32
#define CONFIG_PHYSMEM
+#define CONFIG_SYS_EARLY_PCI_INIT
#define CONFIG_LMB
#define CONFIG_OF_LIBFDT
diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h
index 3f42cd9..5cc9b5a 100644
--- a/include/configs/corenet_ds.h
+++ b/include/configs/corenet_ds.h
@@ -714,6 +714,7 @@
#define CONFIG_EXTRA_ENV_SETTINGS \
"hwconfig=fsl_ddr:ctlr_intlv=cacheline," \
"bank_intlv=cs0_cs1;" \
+ "usb2:dr_mode=peripheral,phy_type=" __stringify(__USB_PHY_TYPE) ";"\
"usb1:dr_mode=host,phy_type=" __stringify(__USB_PHY_TYPE) "\0"\
"netdev=eth0\0" \
"uboot=" __stringify(CONFIG_UBOOTPATH) "\0" \
diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
index 4514e7a..8a82892 100644
--- a/include/configs/exynos5250-dt.h
+++ b/include/configs/exynos5250-dt.h
@@ -139,6 +139,13 @@
#define EXYNOS_USB_SECONDARY_BOOT 0xfeed0002
#define EXYNOS_IRAM_SECONDARY_BASE 0x02020018
+/* TPM */
+#define CONFIG_TPM
+#define CONFIG_CMD_TPM
+#define CONFIG_INFINEON_TPM_I2C
+#define CONFIG_INFINEON_TPM_I2C_BUS 3
+#define CONFIG_INFINEON_TPM_I2C_ADDR 0x20
+
/* MMC SPL */
#define CONFIG_SPL
#define COPY_BL2_FNPTR_ADDR 0x02020030
diff --git a/include/configs/lwmon5.h b/include/configs/lwmon5.h
index 2ebcd16..ba613e3 100644
--- a/include/configs/lwmon5.h
+++ b/include/configs/lwmon5.h
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2007-2010
+ * (C) Copyright 2007-2013
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* This program is free software; you can redistribute it and/or
@@ -37,8 +37,12 @@
#define CONFIG_440 1 /* ... PPC440 family */
#define CONFIG_4xx 1 /* ... PPC4xx family */
-#ifndef CONFIG_SYS_TEXT_BASE
+#ifdef CONFIG_LCD4_LWMON5
+#define CONFIG_SYS_TEXT_BASE 0x01000000 /* SPL U-Boot TEXT_BASE */
+#define CONFIG_HOSTNAME lcd4_lwmon5
+#else
#define CONFIG_SYS_TEXT_BASE 0xFFF80000
+#define CONFIG_HOSTNAME lwmon5
#endif
#define CONFIG_SYS_CLK_FREQ 33300000 /* external freq to pll */
@@ -56,7 +60,7 @@
* actual resources get mapped (not physical addresses)
*/
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE /* Start of U-Boot */
-#define CONFIG_SYS_MONITOR_LEN (0xFFFFFFFF - CONFIG_SYS_MONITOR_BASE + 1)
+#define CONFIG_SYS_MONITOR_LEN 0x80000
#define CONFIG_SYS_MALLOC_LEN (1 << 20) /* Reserved for malloc */
#define CONFIG_SYS_BOOT_BASE_ADDR 0xf0000000
@@ -75,9 +79,11 @@
#define CONFIG_SYS_PCI_MEMBASE2 (CONFIG_SYS_PCI_MEMBASE1 + 0x10000000)
#define CONFIG_SYS_PCI_MEMBASE3 (CONFIG_SYS_PCI_MEMBASE2 + 0x10000000)
+#ifndef CONFIG_LCD4_LWMON5
#define CONFIG_SYS_USB2D0_BASE 0xe0000100
#define CONFIG_SYS_USB_DEVICE 0xe0000000
#define CONFIG_SYS_USB_HOST 0xe0000400
+#endif
/*
* Initial RAM & stack pointer
@@ -87,12 +93,20 @@
* content during reset (GPT0_COMP6). This way we reserve the OCM (16k)
* for logbuffer only. (GPT0_COMP1-COMP5 are reserved for logbuffer header.)
*/
+#ifndef CONFIG_LCD4_LWMON5
#define CONFIG_SYS_INIT_RAM_DCACHE 1 /* d-cache as init ram */
#define CONFIG_SYS_INIT_RAM_ADDR 0x70000000 /* DCache */
#define CONFIG_SYS_INIT_RAM_SIZE (4 << 10)
#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_SIZE - \
GENERATED_GBL_DATA_SIZE)
#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET
+#else
+#define CONFIG_SYS_INIT_RAM_ADDR CONFIG_SYS_OCM_BASE
+#define CONFIG_SYS_INIT_RAM_SIZE (4 << 10)
+#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_SIZE - \
+ GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_OFFSET (CONFIG_SYS_GBL_DATA_OFFSET - 0x4)
+#endif
/* unused GPT0 COMP reg */
#define CONFIG_SYS_POST_WORD_ADDR (CONFIG_SYS_PERIPHERAL_BASE + GPT0_COMP6)
#define CONFIG_SYS_OCM_SIZE (16 << 10)
@@ -166,8 +180,11 @@
#define CONFIG_SYS_MBYTES_SDRAM 256
#define CONFIG_SYS_DDR_CACHED_ADDR 0x40000000 /* setup 2nd TLB cached here */
#define CONFIG_DDR_DATA_EYE /* use DDR2 optimization */
+#ifndef CONFIG_LCD4_LWMON5
#define CONFIG_DDR_ECC /* enable ECC */
+#endif
+#ifndef CONFIG_LCD4_LWMON5
/* POST support */
#define CONFIG_POST (CONFIG_SYS_POST_CACHE | \
CONFIG_SYS_POST_CPU | \
@@ -276,6 +293,7 @@
#define CONFIG_ALT_LH_ADDR (CONFIG_SYS_PERIPHERAL_BASE + GPT0_COMP1)
#define CONFIG_ALT_LB_ADDR (CONFIG_SYS_OCM_BASE)
#define CONFIG_SYS_CONSOLE_IS_IN_ENV /* Otherwise it catches logbuffer as output */
+#endif
/*
* I2C
@@ -395,6 +413,7 @@
#define CONFIG_VIDEO_SW_CURSOR
#define CONFIG_SPLASH_SCREEN
+#ifndef CONFIG_LCD4_LWMON5
/*
* USB/EHCI
*/
@@ -410,6 +429,7 @@
#define CONFIG_MAC_PARTITION
#define CONFIG_DOS_PARTITION
#define CONFIG_ISO_PARTITION
+#endif
/*
* BOOTP options
@@ -444,9 +464,11 @@
#define CONFIG_CMD_BMP
#endif
+#ifndef CONFIG_LCD4_LWMON5
#ifdef CONFIG_440EPX
#define CONFIG_CMD_USB
#endif
+#endif
/*
* Miscellaneous configurable options
@@ -480,11 +502,15 @@
#define CONFIG_MX_CYCLIC 1 /* enable mdc/mwc commands */
#define CONFIG_VERSION_VARIABLE 1 /* include version env variable */
+#define CONFIG_SYS_CONSOLE_INFO_QUIET /* don't print console @ startup*/
+
+#ifndef CONFIG_LCD4_LWMON5
#ifndef DEBUG
#define CONFIG_HW_WATCHDOG 1 /* Use external HW-Watchdog */
#endif
#define CONFIG_WD_PERIOD 40000 /* in usec */
#define CONFIG_WD_MAX_RATE 66600 /* in ticks */
+#endif
/*
* For booting Linux, the board info and command line data
@@ -644,4 +670,40 @@
#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */
#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */
#endif
+
+/*
+ * SPL related defines
+ */
+#ifdef CONFIG_LCD4_LWMON5
+#define CONFIG_SPL
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_NOR_SUPPORT
+#define CONFIG_SPL_TEXT_BASE 0xffff0000 /* last 64 KiB for SPL */
+#define CONFIG_SYS_SPL_MAX_LEN (64 << 10)
+#define CONFIG_UBOOT_PAD_TO 458752 /* decimal for 'dd' */
+#define CONFIG_SPL_START_S_PATH "arch/powerpc/cpu/ppc4xx"
+#define CONFIG_SPL_LDSCRIPT "arch/powerpc/cpu/ppc4xx/u-boot-spl.lds"
+#define CONFIG_SPL_LIBCOMMON_SUPPORT /* image.c */
+#define CONFIG_SPL_LIBGENERIC_SUPPORT /* string.c */
+#define CONFIG_SPL_SERIAL_SUPPORT
+
+/* Place BSS for SPL near end of SDRAM */
+#define CONFIG_SPL_BSS_START_ADDR ((256 - 1) << 20)
+#define CONFIG_SPL_BSS_MAX_SIZE (64 << 10)
+
+#define CONFIG_SPL_OS_BOOT
+/* Place patched DT blob (fdt) at this address */
+#define CONFIG_SYS_SPL_ARGS_ADDR 0x01800000
+
+#define CONFIG_SPL_TARGET "u-boot-img-spl-at-end.bin"
+
+/* Settings for real U-Boot to be loaded from NOR flash */
+#define CONFIG_SYS_UBOOT_BASE (-CONFIG_SYS_MONITOR_LEN)
+#define CONFIG_SYS_UBOOT_START 0x01002100
+
+#define CONFIG_SYS_OS_BASE 0xf8000000
+#define CONFIG_SYS_FDT_BASE 0xf87c0000
+#endif
+
#endif /* __CONFIG_H */
diff --git a/include/configs/m28evk.h b/include/configs/m28evk.h
index a7d3ae6..5b3fa43 100644
--- a/include/configs/m28evk.h
+++ b/include/configs/m28evk.h
@@ -23,72 +23,75 @@
/*
* SoC configurations
*/
-#define CONFIG_MX28 /* i.MX28 SoC */
-#define CONFIG_MXS_GPIO /* GPIO control */
-#define CONFIG_SYS_HZ 1000 /* Ticks per second */
+#define CONFIG_MX28 /* i.MX28 SoC */
+#define CONFIG_MXS_GPIO /* GPIO control */
+#define CONFIG_SYS_HZ 1000 /* Ticks per second */
/*
* Define M28EVK machine type by hand until it lands in mach-types
*/
-#define MACH_TYPE_M28EVK 3613
+#define MACH_TYPE_M28EVK 3613
-#define CONFIG_MACH_TYPE MACH_TYPE_M28EVK
+#define CONFIG_MACH_TYPE MACH_TYPE_M28EVK
#include <asm/arch/regs-base.h>
-#define CONFIG_SYS_NO_FLASH
-#define CONFIG_BOARD_EARLY_INIT_F
-#define CONFIG_ARCH_MISC_INIT
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_ARCH_MISC_INIT
/*
* SPL
*/
-#define CONFIG_SPL
-#define CONFIG_SPL_NO_CPU_SUPPORT_CODE
-#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/arm926ejs/mxs"
-#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds"
-#define CONFIG_SPL_LIBCOMMON_SUPPORT
-#define CONFIG_SPL_LIBGENERIC_SUPPORT
-#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SPL
+#define CONFIG_SPL_NO_CPU_SUPPORT_CODE
+#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/arm926ejs/mxs"
+#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds"
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
/*
* U-Boot Commands
*/
#include <config_cmd_default.h>
-#define CONFIG_DISPLAY_CPUINFO
-#define CONFIG_DOS_PARTITION
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DOS_PARTITION
-#define CONFIG_CMD_CACHE
-#define CONFIG_CMD_DATE
-#define CONFIG_CMD_DHCP
-#define CONFIG_CMD_EEPROM
-#define CONFIG_CMD_EXT2
-#define CONFIG_CMD_FAT
-#define CONFIG_CMD_GPIO
-#define CONFIG_CMD_I2C
-#define CONFIG_CMD_MII
-#define CONFIG_CMD_MMC
-#define CONFIG_CMD_NAND
-#define CONFIG_CMD_NET
-#define CONFIG_CMD_NFS
-#define CONFIG_CMD_PING
-#define CONFIG_CMD_SETEXPR
-#define CONFIG_CMD_SF
-#define CONFIG_CMD_SPI
-#define CONFIG_CMD_USB
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_EEPROM
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_GPIO
+#define CONFIG_CMD_GREPENV
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_NFS
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SETEXPR
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SPI
+#define CONFIG_CMD_USB
#define CONFIG_VIDEO
+#define CONFIG_REGEX /* Enable regular expression support */
+
/*
* Memory configurations
*/
-#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */
-#define PHYS_SDRAM_1 0x40000000 /* Base address */
-#define PHYS_SDRAM_1_SIZE 0x20000000 /* Max 512 MB RAM */
-#define CONFIG_SYS_MALLOC_LEN 0x00400000 /* 4 MB for malloc */
-#define CONFIG_SYS_GBL_DATA_SIZE 128 /* Initial data */
-#define CONFIG_SYS_MEMTEST_START 0x40000000 /* Memtest start adr */
-#define CONFIG_SYS_MEMTEST_END 0x40400000 /* 4 MB RAM test */
-#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */
+#define PHYS_SDRAM_1 0x40000000 /* Base address */
+#define PHYS_SDRAM_1_SIZE 0x20000000 /* Max 512 MB RAM */
+#define CONFIG_SYS_MALLOC_LEN 0x00400000 /* 4 MB for malloc */
+#define CONFIG_SYS_GBL_DATA_SIZE 128 /* Initial data */
+#define CONFIG_SYS_MEMTEST_START 0x40000000 /* Memtest start adr */
+#define CONFIG_SYS_MEMTEST_END 0x40400000 /* 4 MB RAM test */
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
/* Point initial SP in SRAM so SPL can use it too. */
#define CONFIG_SYS_INIT_RAM_ADDR 0x00000000
@@ -103,42 +106,42 @@
* strange BUG in ROM corrupting first 4 bytes of RAM when loading U-Boot
* binary. In case there was more of this mess, 0x100 bytes are skipped.
*/
-#define CONFIG_SYS_TEXT_BASE 0x40000100
+#define CONFIG_SYS_TEXT_BASE 0x40000100
/*
* U-Boot general configurations
*/
-#define CONFIG_SYS_LONGHELP
-#define CONFIG_SYS_PROMPT "=> "
-#define CONFIG_SYS_CBSIZE 1024 /* Console I/O buffer size */
-#define CONFIG_SYS_PBSIZE \
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT "=> "
+#define CONFIG_SYS_CBSIZE 1024 /* Console I/O buffer size */
+#define CONFIG_SYS_PBSIZE \
(CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
/* Print buffer size */
-#define CONFIG_SYS_MAXARGS 32 /* Max number of command args */
-#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+#define CONFIG_SYS_MAXARGS 32 /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
/* Boot argument buffer size */
-#define CONFIG_VERSION_VARIABLE /* U-BOOT version */
-#define CONFIG_AUTO_COMPLETE /* Command auto complete */
-#define CONFIG_CMDLINE_EDITING /* Command history etc */
-#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_VERSION_VARIABLE /* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE /* Command auto complete */
+#define CONFIG_CMDLINE_EDITING /* Command history etc */
+#define CONFIG_SYS_HUSH_PARSER
/*
* Serial Driver
*/
-#define CONFIG_PL011_SERIAL
-#define CONFIG_PL011_CLOCK 24000000
-#define CONFIG_PL01x_PORTS { (void *)MXS_UARTDBG_BASE }
-#define CONFIG_CONS_INDEX 0
-#define CONFIG_BAUDRATE 115200 /* Default baud rate */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_PL011_CLOCK 24000000
+#define CONFIG_PL01x_PORTS { (void *)MXS_UARTDBG_BASE }
+#define CONFIG_CONS_INDEX 0
+#define CONFIG_BAUDRATE 115200 /* Default baud rate */
/*
* MMC Driver
*/
#ifdef CONFIG_CMD_MMC
-#define CONFIG_MMC
-#define CONFIG_BOUNCE_BUFFER
-#define CONFIG_GENERIC_MMC
-#define CONFIG_MXS_MMC
+#define CONFIG_MMC
+#define CONFIG_BOUNCE_BUFFER
+#define CONFIG_GENERIC_MMC
+#define CONFIG_MXS_MMC
#endif
/*
@@ -149,31 +152,31 @@
/*
* NAND
*/
-#define CONFIG_ENV_SIZE (16 * 1024)
+#define CONFIG_ENV_SIZE (16 * 1024)
#ifdef CONFIG_CMD_NAND
-#define CONFIG_NAND_MXS
-#define CONFIG_SYS_MAX_NAND_DEVICE 1
-#define CONFIG_SYS_NAND_BASE 0x60000000
-#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define CONFIG_NAND_MXS
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_SYS_NAND_BASE 0x60000000
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
/* Environment is in NAND */
-#define CONFIG_ENV_IS_IN_NAND
-#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
-#define CONFIG_ENV_SECT_SIZE (128 * 1024)
-#define CONFIG_ENV_RANGE (512 * 1024)
-#define CONFIG_ENV_OFFSET 0x300000
-#define CONFIG_ENV_OFFSET_REDUND \
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
+#define CONFIG_ENV_SECT_SIZE (128 * 1024)
+#define CONFIG_ENV_RANGE (512 * 1024)
+#define CONFIG_ENV_OFFSET 0x300000
+#define CONFIG_ENV_OFFSET_REDUND \
(CONFIG_ENV_OFFSET + CONFIG_ENV_RANGE)
-#define CONFIG_CMD_UBI
-#define CONFIG_CMD_UBIFS
-#define CONFIG_CMD_MTDPARTS
-#define CONFIG_RBTREE
-#define CONFIG_LZO
-#define CONFIG_MTD_DEVICE
-#define CONFIG_MTD_PARTITIONS
-#define MTDIDS_DEFAULT "nand0=gpmi-nand"
-#define MTDPARTS_DEFAULT \
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+#define MTDIDS_DEFAULT "nand0=gpmi-nand"
+#define MTDPARTS_DEFAULT \
"mtdparts=gpmi-nand:" \
"3m(bootloader)ro," \
"512k(environment)," \
@@ -183,34 +186,34 @@
"8m(ramdisk)," \
"-(filesystem)"
#else
-#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_IS_NOWHERE
#endif
/*
* Ethernet on SOC (FEC)
*/
#ifdef CONFIG_CMD_NET
-#define CONFIG_ETHPRIME "FEC0"
-#define CONFIG_FEC_MXC
-#define CONFIG_MII
-#define CONFIG_FEC_XCV_TYPE RMII
+#define CONFIG_ETHPRIME "FEC0"
+#define CONFIG_FEC_MXC
+#define CONFIG_MII
+#define CONFIG_FEC_XCV_TYPE RMII
#endif
/*
* I2C
*/
#ifdef CONFIG_CMD_I2C
-#define CONFIG_I2C_MXS
-#define CONFIG_HARD_I2C
-#define CONFIG_SYS_I2C_SPEED 400000
+#define CONFIG_I2C_MXS
+#define CONFIG_HARD_I2C
+#define CONFIG_SYS_I2C_SPEED 400000
#endif
/*
* EEPROM
*/
#ifdef CONFIG_CMD_EEPROM
-#define CONFIG_SYS_I2C_MULTI_EEPROMS
-#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
+#define CONFIG_SYS_I2C_MULTI_EEPROMS
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
#endif
/*
@@ -218,13 +221,13 @@
*/
#ifdef CONFIG_CMD_DATE
/* Use the internal RTC in the MXS chip */
-#define CONFIG_RTC_INTERNAL
+#define CONFIG_RTC_INTERNAL
#ifdef CONFIG_RTC_INTERNAL
-#define CONFIG_RTC_MXS
+#define CONFIG_RTC_MXS
#else
-#define CONFIG_RTC_M41T62
-#define CONFIG_SYS_I2C_RTC_ADDR 0x68
-#define CONFIG_SYS_M41T11_BASE_YEAR 2000
+#define CONFIG_RTC_M41T62
+#define CONFIG_SYS_I2C_RTC_ADDR 0x68
+#define CONFIG_SYS_M41T11_BASE_YEAR 2000
#endif
#endif
@@ -232,39 +235,39 @@
* USB
*/
#ifdef CONFIG_CMD_USB
-#define CONFIG_USB_EHCI
-#define CONFIG_USB_EHCI_MXS
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_MXS
#define CONFIG_EHCI_MXS_PORT0
#define CONFIG_EHCI_MXS_PORT1
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
-#define CONFIG_EHCI_IS_TDI
-#define CONFIG_USB_STORAGE
+#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_STORAGE
#endif
/*
* SPI
*/
#ifdef CONFIG_CMD_SPI
-#define CONFIG_HARD_SPI
-#define CONFIG_MXS_SPI
-#define CONFIG_SPI_HALF_DUPLEX
-#define CONFIG_DEFAULT_SPI_BUS 2
-#define CONFIG_DEFAULT_SPI_CS 0
-#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0
+#define CONFIG_HARD_SPI
+#define CONFIG_MXS_SPI
+#define CONFIG_SPI_HALF_DUPLEX
+#define CONFIG_DEFAULT_SPI_BUS 2
+#define CONFIG_DEFAULT_SPI_CS 0
+#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0
/* SPI FLASH */
#ifdef CONFIG_CMD_SF
-#define CONFIG_SPI_FLASH
-#define CONFIG_SPI_FLASH_STMICRO
-#define CONFIG_SF_DEFAULT_BUS 2
-#define CONFIG_SF_DEFAULT_CS 0
-#define CONFIG_SF_DEFAULT_SPEED 40000000
-#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_SF_DEFAULT_BUS 2
+#define CONFIG_SF_DEFAULT_CS 0
+#define CONFIG_SF_DEFAULT_SPEED 40000000
+#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
-#define CONFIG_ENV_SPI_BUS 2
-#define CONFIG_ENV_SPI_CS 0
-#define CONFIG_ENV_SPI_MAX_HZ 40000000
-#define CONFIG_ENV_SPI_MODE SPI_MODE_0
+#define CONFIG_ENV_SPI_BUS 2
+#define CONFIG_ENV_SPI_CS 0
+#define CONFIG_ENV_SPI_MAX_HZ 40000000
+#define CONFIG_ENV_SPI_MODE SPI_MODE_0
#endif
#endif
@@ -289,20 +292,20 @@
/*
* Boot Linux
*/
-#define CONFIG_CMDLINE_TAG
-#define CONFIG_SETUP_MEMORY_TAGS
-#define CONFIG_BOOTDELAY 3
-#define CONFIG_BOOTFILE "uImage"
-#define CONFIG_BOOTARGS "console=ttyAMA0,115200n8 "
-#define CONFIG_BOOTCOMMAND "run bootcmd_net"
-#define CONFIG_LOADADDR 0x42000000
-#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
-#define CONFIG_OF_LIBFDT
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTDELAY 3
+#define CONFIG_BOOTFILE "uImage"
+#define CONFIG_BOOTARGS "console=ttyAMA0,115200n8 "
+#define CONFIG_BOOTCOMMAND "run bootcmd_net"
+#define CONFIG_LOADADDR 0x42000000
+#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+#define CONFIG_OF_LIBFDT
/*
* Extra Environments
*/
-#define CONFIG_EXTRA_ENV_SETTINGS \
+#define CONFIG_EXTRA_ENV_SETTINGS \
"update_nand_full_filename=u-boot.nand\0" \
"update_nand_firmware_filename=u-boot.sb\0" \
"update_sd_firmware_filename=u-boot.sd\0" \
diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h
index d172e56..0c4e719 100644
--- a/include/configs/microblaze-generic.h
+++ b/include/configs/microblaze-generic.h
@@ -120,6 +120,14 @@
# define CONFIG_SYS_TIMER_0_IRQ XILINX_TIMER_IRQ
#endif
+/* watchdog */
+#if defined(XILINX_WATCHDOG_BASEADDR) && defined(XILINX_WATCHDOG_IRQ)
+# define CONFIG_WATCHDOG_BASEADDR XILINX_WATCHDOG_BASEADDR
+# define CONFIG_WATCHDOG_IRQ XILINX_WATCHDOG_IRQ
+# define CONFIG_HW_WATCHDOG
+# define CONFIG_XILINX_TB_WATCHDOG
+#endif
+
/*
* memory layout - Example
* CONFIG_SYS_TEXT_BASE = 0x1200_0000; defined in config.mk
@@ -414,10 +422,17 @@
"nor0=flash-0\0"\
"mtdparts=mtdparts=flash-0:"\
"256k(u-boot),256k(env),3m(kernel),"\
- "1m(romfs),1m(cramfs),-(jffs2)\0"
+ "1m(romfs),1m(cramfs),-(jffs2)\0"\
+ "nc=setenv stdout nc;"\
+ "setenv stdin nc\0" \
+ "serial=setenv stdout serial;"\
+ "setenv stdin serial\0"
#define CONFIG_CMDLINE_EDITING
+#define CONFIG_NETCONSOLE
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+
/* Use the HUSH parser */
#define CONFIG_SYS_HUSH_PARSER
diff --git a/include/configs/mx28evk.h b/include/configs/mx28evk.h
index b22a20b..54d01f9 100644
--- a/include/configs/mx28evk.h
+++ b/include/configs/mx28evk.h
@@ -139,14 +139,14 @@
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
/* Environment is in NAND */
+#ifdef CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
#define CONFIG_ENV_SECT_SIZE (128 * 1024)
#define CONFIG_ENV_RANGE (512 * 1024)
-#ifndef CONFIG_ENV_OFFSET
#define CONFIG_ENV_OFFSET 0x300000
-#endif
#define CONFIG_ENV_OFFSET_REDUND \
(CONFIG_ENV_OFFSET + CONFIG_ENV_RANGE)
+#endif
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
diff --git a/include/configs/mx31pdk.h b/include/configs/mx31pdk.h
index 1754595..82ea4fa 100644
--- a/include/configs/mx31pdk.h
+++ b/include/configs/mx31pdk.h
@@ -50,6 +50,7 @@
#define CONFIG_SPL_LDSCRIPT "arch/$(ARCH)/cpu/u-boot-spl.lds"
#define CONFIG_SPL_MAX_SIZE 2048
#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
#define CONFIG_SPL_TEXT_BASE 0x87dc0000
#define CONFIG_SYS_TEXT_BASE 0x87e00000
diff --git a/include/configs/omap3_mvblx.h b/include/configs/omap3_mvblx.h
index 376a3d0..f9adc01 100644
--- a/include/configs/omap3_mvblx.h
+++ b/include/configs/omap3_mvblx.h
@@ -273,7 +273,7 @@
#endif /* (CONFIG_CMD_NET) */
#define CONFIG_FPGA_COUNT 1
-#define CONFIG_FPGA CONFIG_SYS_ALTERA_CYCLON2
+#define CONFIG_FPGA
#define CONFIG_FPGA_ALTERA
#define CONFIG_FPGA_CYCLON2
#define CONFIG_SYS_FPGA_PROG_FEEDBACK
diff --git a/include/configs/omap5_uevm.h b/include/configs/omap5_uevm.h
index 240fdfc..550cabd 100644
--- a/include/configs/omap5_uevm.h
+++ b/include/configs/omap5_uevm.h
@@ -44,6 +44,8 @@
#define CONFIG_ENV_IS_IN_MMC
#define CONFIG_SYS_MMC_ENV_DEV 1 /* SLOT2: eMMC(1) */
#define CONFIG_ENV_OFFSET 0xE0000
+#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
+#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
#define CONFIG_CMD_SAVEENV
/* Enhance our eMMC support / experience. */
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 406da43..788207d 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -22,15 +22,15 @@
#ifndef __CONFIG_H
#define __CONFIG_H
-#define CONFIG_NR_DRAM_BANKS 1
-#define CONFIG_DRAM_SIZE (128 << 20)
-
/* Number of bits in a C 'long' on this architecture */
#define CONFIG_SANDBOX_BITS_PER_LONG 64
#define CONFIG_OF_CONTROL
+#define CONFIG_OF_HOSTFILE
#define CONFIG_OF_LIBFDT
#define CONFIG_LMB
+#define CONFIG_FIT
+#define CONFIG_CMD_FDT
#define CONFIG_FS_FAT
#define CONFIG_FS_EXT4
@@ -74,9 +74,14 @@
#define CONFIG_SYS_MEMTEST_START 0x00100000
#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 0x1000)
#define CONFIG_PHYS_64BIT
+#define CONFIG_SYS_FDT_LOAD_ADDR 0x1000000
/* Size of our emulated memory */
+#define CONFIG_SYS_SDRAM_BASE 0
#define CONFIG_SYS_SDRAM_SIZE (128 << 20)
+#define CONFIG_SYS_TEXT_BASE 0
+#define CONFIG_SYS_MONITOR_BASE 0
+#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_BAUDRATE 115200
#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
diff --git a/include/configs/tx25.h b/include/configs/tx25.h
index e72f8f6..d61a218 100644
--- a/include/configs/tx25.h
+++ b/include/configs/tx25.h
@@ -37,6 +37,7 @@
#define CONFIG_SPL_LDSCRIPT "arch/$(ARCH)/cpu/u-boot-spl.lds"
#define CONFIG_SPL_MAX_SIZE 2048
#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
#define CONFIG_SPL_TEXT_BASE 0x810c0000
#define CONFIG_SYS_TEXT_BASE 0x81200000
diff --git a/include/configs/zynq.h b/include/configs/zynq.h
index 2989e72..38f04f6 100644
--- a/include/configs/zynq.h
+++ b/include/configs/zynq.h
@@ -50,19 +50,50 @@
#define CONFIG_ZYNQ_SERIAL_BAUDRATE0 CONFIG_BAUDRATE
#define CONFIG_ZYNQ_SERIAL_CLOCK0 50000000
-/* SCU timer address is hardcoded */
-#define CONFIG_SCUTIMER_BASEADDR 0xF8F00600
-
/* Ethernet driver */
#define CONFIG_NET_MULTI
#define CONFIG_ZYNQ_GEM
-#define CONFIG_ZYNQ_GEM_BASEADDR0 0xE000B000
+#define CONFIG_ZYNQ_GEM0
+#define CONFIG_ZYNQ_GEM_PHY_ADDR0 7
+
+#define CONFIG_ZYNQ_SDHCI
+#define CONFIG_ZYNQ_SDHCI0
+
+/* MMC */
+#if defined(CONFIG_ZYNQ_SDHCI0) || defined(CONFIG_ZYNQ_SDHCI1)
+# define CONFIG_MMC
+# define CONFIG_GENERIC_MMC
+# define CONFIG_SDHCI
+# define CONFIG_ZYNQ_SDHCI
+# define CONFIG_CMD_MMC
+# define CONFIG_CMD_FAT
+# define CONFIG_SUPPORT_VFAT
+# define CONFIG_CMD_EXT2
+# define CONFIG_DOS_PARTITION
+#endif
+
+#define CONFIG_ZYNQ_I2C0
+
+/* I2C */
+#if defined(CONFIG_ZYNQ_I2C0) || defined(CONFIG_ZYNQ_I2C1)
+# define CONFIG_CMD_I2C
+# define CONFIG_ZYNQ_I2C
+# define CONFIG_HARD_I2C
+# define CONFIG_SYS_I2C_SPEED 100000
+# define CONFIG_SYS_I2C_SLAVE 1
+#endif
#if defined(CONFIG_ZYNQ_DCC)
# define CONFIG_ARM_DCC
# define CONFIG_CPU_V6 /* Required by CONFIG_ARM_DCC */
#endif
+/* Enable the PL to be downloaded */
+#define CONFIG_FPGA
+#define CONFIG_FPGA_XILINX
+#define CONFIG_FPGA_ZYNQPL
+#define CONFIG_CMD_FPGA
+
#define CONFIG_BOOTP_SERVERIP
#define CONFIG_BOOTP_BOOTPATH
#define CONFIG_BOOTP_GATEWAY
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 844991e..4e8032b 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -92,6 +92,7 @@ enum fdt_compat_id {
COMPAT_MAXIM_MAX77686_PMIC, /* MAX77686 PMIC */
COMPAT_GENERIC_SPI_FLASH, /* Generic SPI Flash chip */
COMPAT_MAXIM_98095_CODEC, /* MAX98095 Codec */
+ COMPAT_INFINEON_SLB9635_TPM, /* Infineon SLB9635 TPM */
COMPAT_COUNT,
};
diff --git a/include/fpga.h b/include/fpga.h
index 30a4e6a..38e9018 100644
--- a/include/fpga.h
+++ b/include/fpga.h
@@ -31,16 +31,6 @@
#define CONFIG_MAX_FPGA_DEVICES 5
#endif
-/* CONFIG_FPGA bit assignments */
-#define CONFIG_SYS_FPGA_MAN(x) (x)
-#define CONFIG_SYS_FPGA_DEV(x) ((x) << 8 )
-#define CONFIG_SYS_FPGA_IF(x) ((x) << 16 )
-
-/* FPGA Manufacturer bits in CONFIG_FPGA */
-#define CONFIG_SYS_FPGA_XILINX CONFIG_SYS_FPGA_MAN( 0x1 )
-#define CONFIG_SYS_FPGA_ALTERA CONFIG_SYS_FPGA_MAN( 0x2 )
-
-
/* fpga_xxxx function return value definitions */
#define FPGA_SUCCESS 0
#define FPGA_FAIL -1
@@ -68,7 +58,10 @@ extern void fpga_init(void);
extern int fpga_add(fpga_type devtype, void *desc);
extern int fpga_count(void);
extern int fpga_load(int devnum, const void *buf, size_t bsize);
+extern int fpga_loadbitstream(int devnum, char *fpgadata, size_t size);
extern int fpga_dump(int devnum, const void *buf, size_t bsize);
extern int fpga_info(int devnum);
+extern const fpga_desc *const fpga_validate(int devnum, const void *buf,
+ size_t bsize, char *fn);
#endif /* _FPGA_H_ */
diff --git a/include/fs.h b/include/fs.h
index b6d69e5..c837bae 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -62,5 +62,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
int fstype, int cmdline_base);
int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
int fstype);
+int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+ int fstype, int cmdline_base);
#endif /* _FS_H */
diff --git a/include/lattice.h b/include/lattice.h
index 6a2cf93..49871da 100644
--- a/include/lattice.h
+++ b/include/lattice.h
@@ -278,9 +278,6 @@ typedef struct {
char *desc; /* description string */
} Lattice_desc; /* end, typedef Altera_desc */
-/* Lattice Model Type */
-#define CONFIG_SYS_XP2 CONFIG_SYS_FPGA_DEV(0x1)
-
/* Board specific implementation specific function types */
typedef void (*Lattice_jtag_init)(void);
typedef void (*Lattice_jtag_set_tdi)(int v);
diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h
new file mode 100644
index 0000000..a61d956
--- /dev/null
+++ b/include/linux/bitrev.h
@@ -0,0 +1,23 @@
+/*
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ *
+ * Based on bitrev from the Linux kernel, by Akinobu Mita
+ */
+
+#ifndef _LINUX_BITREV_H
+#define _LINUX_BITREV_H
+
+#include <linux/types.h>
+
+extern u8 const byte_rev_table[256];
+
+static inline u8 bitrev8(u8 byte)
+{
+ return byte_rev_table[byte];
+}
+
+u16 bitrev16(u16 in);
+u32 bitrev32(u32 in);
+
+#endif /* _LINUX_BITREV_H */
diff --git a/include/linux/mtd/docg4.h b/include/linux/mtd/docg4.h
new file mode 100644
index 0000000..982f5ad
--- /dev/null
+++ b/include/linux/mtd/docg4.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ *
+ */
+
+#ifndef __DOCG4_H__
+#define __DOCG4_H__
+
+#include <common.h>
+#include <linux/mtd/nand.h>
+
+extern int docg4_nand_init(struct mtd_info *mtd,
+ struct nand_chip *nand, int devnum);
+
+/* SPL-related definitions */
+#define DOCG4_IPL_LOAD_BLOCK_COUNT 2 /* number of blocks that IPL loads */
+#define DOCG4_BLOCK_CAPACITY_SPL 0x10000 /* reliable mode; redundant pages */
+
+#define DOC_IOSPACE_DATA 0x0800
+
+/* register offsets */
+#define DOC_CHIPID 0x1000
+#define DOC_DEVICESELECT 0x100a
+#define DOC_ASICMODE 0x100c
+#define DOC_DATAEND 0x101e
+#define DOC_NOP 0x103e
+
+#define DOC_FLASHSEQUENCE 0x1032
+#define DOC_FLASHCOMMAND 0x1034
+#define DOC_FLASHADDRESS 0x1036
+#define DOC_FLASHCONTROL 0x1038
+#define DOC_ECCCONF0 0x1040
+#define DOC_ECCCONF1 0x1042
+#define DOC_HAMMINGPARITY 0x1046
+#define DOC_BCH_SYNDROM(idx) (0x1048 + idx)
+
+#define DOC_ASICMODECONFIRM 0x1072
+#define DOC_CHIPID_INV 0x1074
+#define DOC_POWERMODE 0x107c
+
+#define DOCG4_MYSTERY_REG 0x1050
+
+/* apparently used only to write oob bytes 6 and 7 */
+#define DOCG4_OOB_6_7 0x1052
+
+/* DOC_FLASHSEQUENCE register commands */
+#define DOC_SEQ_RESET 0x00
+#define DOCG4_SEQ_PAGE_READ 0x03
+#define DOCG4_SEQ_FLUSH 0x29
+#define DOCG4_SEQ_PAGEWRITE 0x16
+#define DOCG4_SEQ_PAGEPROG 0x1e
+#define DOCG4_SEQ_BLOCKERASE 0x24
+
+/* DOC_FLASHCOMMAND register commands */
+#define DOCG4_CMD_PAGE_READ 0x00
+#define DOC_CMD_ERASECYCLE2 0xd0
+#define DOCG4_CMD_FLUSH 0x70
+#define DOCG4_CMD_READ2 0x30
+#define DOC_CMD_PROG_BLOCK_ADDR 0x60
+#define DOCG4_CMD_PAGEWRITE 0x80
+#define DOC_CMD_PROG_CYCLE2 0x10
+#define DOC_CMD_RESET 0xff
+
+/* DOC_POWERMODE register bits */
+#define DOC_POWERDOWN_READY 0x80
+
+/* DOC_FLASHCONTROL register bits */
+#define DOC_CTRL_CE 0x10
+#define DOC_CTRL_UNKNOWN 0x40
+#define DOC_CTRL_FLASHREADY 0x01
+
+/* DOC_ECCCONF0 register bits */
+#define DOC_ECCCONF0_READ_MODE 0x8000
+#define DOC_ECCCONF0_UNKNOWN 0x2000
+#define DOC_ECCCONF0_ECC_ENABLE 0x1000
+#define DOC_ECCCONF0_DATA_BYTES_MASK 0x07ff
+
+/* DOC_ECCCONF1 register bits */
+#define DOC_ECCCONF1_BCH_SYNDROM_ERR 0x80
+#define DOC_ECCCONF1_ECC_ENABLE 0x07
+#define DOC_ECCCONF1_PAGE_IS_WRITTEN 0x20
+
+/* DOC_ASICMODE register bits */
+#define DOC_ASICMODE_RESET 0x00
+#define DOC_ASICMODE_NORMAL 0x01
+#define DOC_ASICMODE_POWERDOWN 0x02
+#define DOC_ASICMODE_MDWREN 0x04
+#define DOC_ASICMODE_BDETCT_RESET 0x08
+#define DOC_ASICMODE_RSTIN_RESET 0x10
+#define DOC_ASICMODE_RAM_WE 0x20
+
+/* good status values read after read/write/erase operations */
+#define DOCG4_PROGSTATUS_GOOD 0x51
+#define DOCG4_PROGSTATUS_GOOD_2 0xe0
+
+/*
+ * On read operations (page and oob-only), the first byte read from I/O reg is a
+ * status. On error, it reads 0x73; otherwise, it reads either 0x71 (first read
+ * after reset only) or 0x51, so bit 1 is presumed to be an error indicator.
+ */
+#define DOCG4_READ_ERROR 0x02 /* bit 1 indicates read error */
+
+/* anatomy of the device */
+#define DOCG4_CHIP_SIZE 0x8000000
+#define DOCG4_PAGE_SIZE 0x200
+#define DOCG4_PAGES_PER_BLOCK 0x200
+#define DOCG4_BLOCK_SIZE (DOCG4_PAGES_PER_BLOCK * DOCG4_PAGE_SIZE)
+#define DOCG4_NUMBLOCKS (DOCG4_CHIP_SIZE / DOCG4_BLOCK_SIZE)
+#define DOCG4_OOB_SIZE 0x10
+#define DOCG4_CHIP_SHIFT 27 /* log_2(DOCG4_CHIP_SIZE) */
+#define DOCG4_PAGE_SHIFT 9 /* log_2(DOCG4_PAGE_SIZE) */
+#define DOCG4_ERASE_SHIFT 18 /* log_2(DOCG4_BLOCK_SIZE) */
+
+/* all but the last byte is included in ecc calculation */
+#define DOCG4_BCH_SIZE (DOCG4_PAGE_SIZE + DOCG4_OOB_SIZE - 1)
+
+#define DOCG4_USERDATA_LEN 520 /* 512 byte page plus 8 oob avail to user */
+
+/* expected values from the ID registers */
+#define DOCG4_IDREG1_VALUE 0x0400
+#define DOCG4_IDREG2_VALUE 0xfbff
+
+/* primitive polynomial used to build the Galois field used by hw ecc gen */
+#define DOCG4_PRIMITIVE_POLY 0x4443
+
+#define DOCG4_M 14 /* Galois field is of order 2^14 */
+#define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */
+
+#define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */
+
+#endif /* __DOCG4_H__ */
diff --git a/include/mmc.h b/include/mmc.h
index de6d497..8bbc6b6 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -30,16 +30,22 @@
#include <linux/compiler.h>
#define SD_VERSION_SD 0x20000
-#define SD_VERSION_2 (SD_VERSION_SD | 0x20)
-#define SD_VERSION_1_0 (SD_VERSION_SD | 0x10)
-#define SD_VERSION_1_10 (SD_VERSION_SD | 0x1a)
+#define SD_VERSION_3 (SD_VERSION_SD | 0x300)
+#define SD_VERSION_2 (SD_VERSION_SD | 0x200)
+#define SD_VERSION_1_0 (SD_VERSION_SD | 0x100)
+#define SD_VERSION_1_10 (SD_VERSION_SD | 0x10a)
#define MMC_VERSION_MMC 0x10000
#define MMC_VERSION_UNKNOWN (MMC_VERSION_MMC)
-#define MMC_VERSION_1_2 (MMC_VERSION_MMC | 0x12)
-#define MMC_VERSION_1_4 (MMC_VERSION_MMC | 0x14)
-#define MMC_VERSION_2_2 (MMC_VERSION_MMC | 0x22)
-#define MMC_VERSION_3 (MMC_VERSION_MMC | 0x30)
-#define MMC_VERSION_4 (MMC_VERSION_MMC | 0x40)
+#define MMC_VERSION_1_2 (MMC_VERSION_MMC | 0x102)
+#define MMC_VERSION_1_4 (MMC_VERSION_MMC | 0x104)
+#define MMC_VERSION_2_2 (MMC_VERSION_MMC | 0x202)
+#define MMC_VERSION_3 (MMC_VERSION_MMC | 0x300)
+#define MMC_VERSION_4 (MMC_VERSION_MMC | 0x400)
+#define MMC_VERSION_4_1 (MMC_VERSION_MMC | 0x401)
+#define MMC_VERSION_4_2 (MMC_VERSION_MMC | 0x402)
+#define MMC_VERSION_4_3 (MMC_VERSION_MMC | 0x403)
+#define MMC_VERSION_4_41 (MMC_VERSION_MMC | 0x429)
+#define MMC_VERSION_4_5 (MMC_VERSION_MMC | 0x405)
#define MMC_MODE_HS 0x001
#define MMC_MODE_HS_52MHz 0x010
@@ -201,6 +207,9 @@
#define PART_ACCESS_MASK (0x7)
#define PART_SUPPORT (0x1)
+/* Maximum block size for MMC */
+#define MMC_MAX_BLOCK_LEN 512
+
struct mmc_cid {
unsigned long psn;
unsigned short oid;
diff --git a/include/mtd/cfi_flash.h b/include/mtd/cfi_flash.h
index 9bd76eb..966b5e0 100644
--- a/include/mtd/cfi_flash.h
+++ b/include/mtd/cfi_flash.h
@@ -78,30 +78,29 @@
#define FLASH_CONTINUATION_CODE 0x7F
#define FLASH_OFFSET_MANUFACTURER_ID 0x00
-#define FLASH_OFFSET_DEVICE_ID 0x02
-#define FLASH_OFFSET_DEVICE_ID2 0x1C
-#define FLASH_OFFSET_DEVICE_ID3 0x1E
-#define FLASH_OFFSET_CFI 0xAA
-
+#define FLASH_OFFSET_DEVICE_ID 0x01
+#define FLASH_OFFSET_DEVICE_ID2 0x0E
+#define FLASH_OFFSET_DEVICE_ID3 0x0F
+#define FLASH_OFFSET_CFI 0x55
#define FLASH_OFFSET_CFI_ALT 0x555
-#define FLASH_OFFSET_CFI_RESP 0x20
-#define FLASH_OFFSET_PRIMARY_VENDOR 0x26
+#define FLASH_OFFSET_CFI_RESP 0x10
+#define FLASH_OFFSET_PRIMARY_VENDOR 0x13
/* extended query table primary address */
-#define FLASH_OFFSET_EXT_QUERY_T_P_ADDR 0x2A
+#define FLASH_OFFSET_EXT_QUERY_T_P_ADDR 0x15
#define FLASH_OFFSET_WTOUT 0x1F
-#define FLASH_OFFSET_WBTOUT 0x40
-#define FLASH_OFFSET_ETOUT 0x4A
-#define FLASH_OFFSET_CETOUT 0x44
-#define FLASH_OFFSET_WMAX_TOUT 0x46
-#define FLASH_OFFSET_WBMAX_TOUT 0x48
-#define FLASH_OFFSET_EMAX_TOUT 0x4A
-#define FLASH_OFFSET_CEMAX_TOUT 0x4C
-#define FLASH_OFFSET_SIZE 0x4E
-#define FLASH_OFFSET_INTERFACE 0x50
-#define FLASH_OFFSET_BUFFER_SIZE 0x54
-#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x58
-#define FLASH_OFFSET_ERASE_REGIONS 0x5A
-#define FLASH_OFFSET_PROTECT 0x04
+#define FLASH_OFFSET_WBTOUT 0x20
+#define FLASH_OFFSET_ETOUT 0x21
+#define FLASH_OFFSET_CETOUT 0x22
+#define FLASH_OFFSET_WMAX_TOUT 0x23
+#define FLASH_OFFSET_WBMAX_TOUT 0x24
+#define FLASH_OFFSET_EMAX_TOUT 0x25
+#define FLASH_OFFSET_CEMAX_TOUT 0x26
+#define FLASH_OFFSET_SIZE 0x27
+#define FLASH_OFFSET_INTERFACE 0x28
+#define FLASH_OFFSET_BUFFER_SIZE 0x2A
+#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x2C
+#define FLASH_OFFSET_ERASE_REGIONS 0x2D
+#define FLASH_OFFSET_PROTECT 0x02
#define FLASH_OFFSET_USER_PROTECTION 0x85
#define FLASH_OFFSET_INTEL_PROTECTION 0x81
diff --git a/include/netdev.h b/include/netdev.h
index fd3e243..516b351 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -104,7 +104,7 @@ int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr,
int txpp, int rxpp);
int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags,
unsigned long ctrl_addr);
-int zynq_gem_initialize(bd_t *bis, int base_addr);
+int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio);
/*
* As long as the Xilinx xps_ll_temac ethernet driver has not its own interface
* exported by a public hader file, we need a global definition at this point.
diff --git a/include/part.h b/include/part.h
index c58a734..f7c7cc5 100644
--- a/include/part.h
+++ b/include/part.h
@@ -38,6 +38,7 @@ typedef struct block_dev_desc {
#endif
lbaint_t lba; /* number of blocks */
unsigned long blksz; /* block size */
+ int log2blksz; /* for convenience: log2(blksz) */
char vendor [40+1]; /* IDE model, SCSI Vendor */
char product[20+1]; /* IDE Serial no, SCSI product */
char revision[8+1]; /* firmware revision */
@@ -55,6 +56,14 @@ typedef struct block_dev_desc {
void *priv; /* driver private struct pointer */
}block_dev_desc_t;
+#define BLOCK_CNT(size, block_dev_desc) (PAD_COUNT(size, block_dev_desc->blksz))
+#define PAD_TO_BLOCKSIZE(size, block_dev_desc) \
+ (PAD_SIZE(size, block_dev_desc->blksz))
+#define LOG2(x) (((x & 0xaaaaaaaa) ? 1 : 0) + ((x & 0xcccccccc) ? 2 : 0) + \
+ ((x & 0xf0f0f0f0) ? 4 : 0) + ((x & 0xff00ff00) ? 8 : 0) + \
+ ((x & 0xffff0000) ? 16 : 0))
+#define LOG2_INVALID(type) ((type)((sizeof(type)<<3)-1))
+
/* Interface types: */
#define IF_TYPE_UNKNOWN 0
#define IF_TYPE_IDE 1
diff --git a/include/part_efi.h b/include/part_efi.h
index 6de0a32..95e4c8f 100644
--- a/include/part_efi.h
+++ b/include/part_efi.h
@@ -38,7 +38,6 @@
#define EFI_PMBR_OSTYPE_EFI 0xEF
#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
-#define GPT_BLOCK_SIZE 512
#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
#define GPT_HEADER_REVISION_V1 0x00010000
#define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
@@ -112,7 +111,6 @@ typedef struct _gpt_header {
__le32 num_partition_entries;
__le32 sizeof_partition_entry;
__le32 partition_entry_array_crc32;
- u8 reserved2[GPT_BLOCK_SIZE - 92];
} __packed gpt_header;
typedef union _gpt_entry_attributes {
diff --git a/include/sandboxfs.h b/include/sandboxfs.h
index f5213ac..8ea8cb7 100644
--- a/include/sandboxfs.h
+++ b/include/sandboxfs.h
@@ -26,5 +26,6 @@ long sandbox_fs_read_at(const char *filename, unsigned long pos,
void sandbox_fs_close(void);
int sandbox_fs_ls(const char *dirname);
int fs_read_sandbox(const char *filename, void *buf, int offset, int len);
+int fs_write_sandbox(const char *filename, void *buf, int offset, int len);
#endif
diff --git a/include/search.h b/include/search.h
index 13d3be6..d9ac8df 100644
--- a/include/search.h
+++ b/include/search.h
@@ -22,7 +22,7 @@
/*
* Based on code from uClibc-0.9.30.3
* Extensions for use within U-Boot
- * Copyright (C) 2010 Wolfgang Denk <wd@denx.de>
+ * Copyright (C) 2010-2013 Wolfgang Denk <wd@denx.de>
*/
#ifndef _SEARCH_H
@@ -98,12 +98,6 @@ extern int hsearch_r(ENTRY __item, ACTION __action, ENTRY ** __retval,
*/
extern int hmatch_r(const char *__match, int __last_idx, ENTRY ** __retval,
struct hsearch_data *__htab);
-/*
- * Search for an entry whose key or data contains `MATCH'. Otherwise,
- * Same semantics as hsearch_r().
- */
-extern int hstrstr_r(const char *__match, int __last_idx, ENTRY ** __retval,
- struct hsearch_data *__htab);
/* Search and delete entry matching ITEM.key in internal hash table. */
extern int hdelete_r(const char *__key, struct hsearch_data *__htab,
@@ -131,5 +125,12 @@ extern int hwalk_r(struct hsearch_data *__htab, int (*callback)(ENTRY *));
#define H_FORCE (1 << 1) /* overwrite read-only/write-once variables */
#define H_INTERACTIVE (1 << 2) /* indicate that an import is user directed */
#define H_HIDE_DOT (1 << 3) /* don't print env vars that begin with '.' */
+#define H_MATCH_KEY (1 << 4) /* search/grep key = variable names */
+#define H_MATCH_DATA (1 << 5) /* search/grep data = variable values */
+#define H_MATCH_BOTH (H_MATCH_KEY | H_MATCH_DATA) /* search/grep both */
+#define H_MATCH_IDENT (1 << 6) /* search for indentical strings */
+#define H_MATCH_SUBSTR (1 << 7) /* search for substring matches */
+#define H_MATCH_REGEX (1 << 8) /* search for regular expression matches */
+#define H_MATCH_METHOD (H_MATCH_IDENT | H_MATCH_SUBSTR | H_MATCH_REGEX)
#endif /* search.h */
diff --git a/include/slre.h b/include/slre.h
new file mode 100644
index 0000000..4b41a4b
--- /dev/null
+++ b/include/slre.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
+ * All rights reserved
+ *
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * Sergey Lyubka wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.
+ */
+
+/*
+ * Downloaded Sat Nov 5 17:42:08 CET 2011 at
+ * http://slre.sourceforge.net/1.0/slre.h
+ */
+
+/*
+ * This is a regular expression library that implements a subset of Perl RE.
+ * Please refer to http://slre.sourceforge.net for detailed description.
+ *
+ * Usage example (parsing HTTP request):
+ *
+ * struct slre slre;
+ * struct cap captures[4 + 1]; // Number of braket pairs + 1
+ * ...
+ *
+ * slre_compile(&slre,"^(GET|POST) (\S+) HTTP/(\S+?)\r\n");
+ *
+ * if (slre_match(&slre, buf, len, captures)) {
+ * printf("Request line length: %d\n", captures[0].len);
+ * printf("Method: %.*s\n", captures[1].len, captures[1].ptr);
+ * printf("URI: %.*s\n", captures[2].len, captures[2].ptr);
+ * }
+ *
+ * Supported syntax:
+ * ^ Match beginning of a buffer
+ * $ Match end of a buffer
+ * () Grouping and substring capturing
+ * [...] Match any character from set
+ * [^...] Match any character but ones from set
+ * \s Match whitespace
+ * \S Match non-whitespace
+ * \d Match decimal digit
+ * \r Match carriage return
+ * \n Match newline
+ * + Match one or more times (greedy)
+ * +? Match one or more times (non-greedy)
+ * * Match zero or more times (greedy)
+ * *? Match zero or more times (non-greedy)
+ * ? Match zero or once
+ * \xDD Match byte with hex value 0xDD
+ * \meta Match one of the meta character: ^$().[*+?\
+ */
+
+#ifndef SLRE_HEADER_DEFINED
+#define SLRE_HEADER_DEFINED
+
+/*
+ * Compiled regular expression
+ */
+struct slre {
+ unsigned char code[256];
+ unsigned char data[256];
+ int code_size;
+ int data_size;
+ int num_caps; /* Number of bracket pairs */
+ int anchored; /* Must match from string start */
+ const char *err_str; /* Error string */
+};
+
+/*
+ * Captured substring
+ */
+struct cap {
+ const char *ptr; /* Pointer to the substring */
+ int len; /* Substring length */
+};
+
+/*
+ * Compile regular expression. If success, 1 is returned.
+ * If error, 0 is returned and slre.err_str points to the error message.
+ */
+int slre_compile(struct slre *, const char *re);
+
+/*
+ * Return 1 if match, 0 if no match.
+ * If `captured_substrings' array is not NULL, then it is filled with the
+ * values of captured substrings. captured_substrings[0] element is always
+ * a full matched substring. The round bracket captures start from
+ * captured_substrings[1].
+ * It is assumed that the size of captured_substrings array is enough to
+ * hold all captures. The caller function must make sure it is! So, the
+ * array_size = number_of_round_bracket_pairs + 1
+ */
+int slre_match(const struct slre *, const char *buf, int buf_len,
+ struct cap *captured_substrings);
+
+#ifdef SLRE_TEST
+void slre_dump(const struct slre *r, FILE *fp);
+#endif /* SLRE_TEST */
+#endif /* SLRE_HEADER_DEFINED */
diff --git a/include/tis.h b/include/tis.h
new file mode 100644
index 0000000..89e5730
--- /dev/null
+++ b/include/tis.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011 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 __TIS_H
+#define __TIS_H
+
+#include <common.h>
+
+/* Low-level interface to access TPM */
+
+/*
+ * tis_init()
+ *
+ * Initialize the TPM device. Returns 0 on success or -1 on
+ * failure (in case device probing did not succeed).
+ */
+int tis_init(void);
+
+/*
+ * tis_open()
+ *
+ * Requests access to locality 0 for the caller. After all commands have been
+ * completed the caller is supposed to call tis_close().
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int tis_open(void);
+
+/*
+ * tis_close()
+ *
+ * terminate the currect session with the TPM by releasing the locked
+ * locality. Returns 0 on success of -1 on failure (in case lock
+ * removal did not succeed).
+ */
+int tis_close(void);
+
+/*
+ * tis_sendrecv()
+ *
+ * Send the requested data to the TPM and then try to get its response
+ *
+ * @sendbuf - buffer of the data to send
+ * @send_size size of the data to send
+ * @recvbuf - memory to save the response to
+ * @recv_len - pointer to the size of the response buffer
+ *
+ * Returns 0 on success (and places the number of response bytes at recv_len)
+ * or -1 on failure.
+ */
+int tis_sendrecv(const uint8_t *sendbuf, size_t send_size, uint8_t *recvbuf,
+ size_t *recv_len);
+
+#endif /* __TIS_H */
diff --git a/include/tpm.h b/include/tpm.h
index 6b21e9c..7219b73 100644
--- a/include/tpm.h
+++ b/include/tpm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 The Chromium OS Authors.
+ * Copyright (c) 2013 The Chromium OS Authors.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -20,52 +20,185 @@
* MA 02111-1307 USA
*/
-#ifndef _INCLUDE_TPM_H_
-#define _INCLUDE_TPM_H_
+#ifndef __TPM_H
+#define __TPM_H
-#include <common.h>
+#include <tis.h>
/*
- * tis_init()
+ * Here is a partial implementation of TPM commands. Please consult TCG Main
+ * Specification for definitions of TPM commands.
+ */
+
+enum tpm_startup_type {
+ TPM_ST_CLEAR = 0x0001,
+ TPM_ST_STATE = 0x0002,
+ TPM_ST_DEACTIVATED = 0x0003,
+};
+
+enum tpm_physical_presence {
+ TPM_PHYSICAL_PRESENCE_HW_DISABLE = 0x0200,
+ TPM_PHYSICAL_PRESENCE_CMD_DISABLE = 0x0100,
+ TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK = 0x0080,
+ TPM_PHYSICAL_PRESENCE_HW_ENABLE = 0x0040,
+ TPM_PHYSICAL_PRESENCE_CMD_ENABLE = 0x0020,
+ TPM_PHYSICAL_PRESENCE_NOTPRESENT = 0x0010,
+ TPM_PHYSICAL_PRESENCE_PRESENT = 0x0008,
+ TPM_PHYSICAL_PRESENCE_LOCK = 0x0004,
+};
+
+enum tpm_nv_index {
+ TPM_NV_INDEX_LOCK = 0xffffffff,
+ TPM_NV_INDEX_0 = 0x00000000,
+ TPM_NV_INDEX_DIR = 0x10000001,
+};
+
+/**
+ * Initialize TPM device. It must be called before any TPM commands.
*
- * Initialize the TPM device. Returns 0 on success or -1 on
- * failure (in case device probing did not succeed).
+ * @return 0 on success, non-0 on error.
*/
-int tis_init(void);
+uint32_t tpm_init(void);
-/*
- * tis_open()
+/**
+ * Issue a TPM_Startup command.
*
- * Requests access to locality 0 for the caller. After all commands have been
- * completed the caller is supposed to call tis_close().
+ * @param mode TPM startup mode
+ * @return return code of the operation
+ */
+uint32_t tpm_startup(enum tpm_startup_type mode);
+
+/**
+ * Issue a TPM_SelfTestFull command.
*
- * Returns 0 on success, -1 on failure.
+ * @return return code of the operation
*/
-int tis_open(void);
+uint32_t tpm_self_test_full(void);
-/*
- * tis_close()
+/**
+ * Issue a TPM_ContinueSelfTest command.
*
- * terminate the currect session with the TPM by releasing the locked
- * locality. Returns 0 on success of -1 on failure (in case lock
- * removal did not succeed).
+ * @return return code of the operation
*/
-int tis_close(void);
+uint32_t tpm_continue_self_test(void);
-/*
- * tis_sendrecv()
+/**
+ * Issue a TPM_NV_DefineSpace command. The implementation is limited
+ * to specify TPM_NV_ATTRIBUTES and size of the area. The area index
+ * could be one of the special value listed in enum tpm_nv_index.
*
- * Send the requested data to the TPM and then try to get its response
+ * @param index index of the area
+ * @param perm TPM_NV_ATTRIBUTES of the area
+ * @param size size of the area
+ * @return return code of the operation
+ */
+uint32_t tpm_nv_define_space(uint32_t index, uint32_t perm, uint32_t size);
+
+/**
+ * Issue a TPM_NV_ReadValue command. This implementation is limited
+ * to read the area from offset 0. The area index could be one of
+ * the special value listed in enum tpm_nv_index.
+ *
+ * @param index index of the area
+ * @param data output buffer of the area contents
+ * @param count size of output buffer
+ * @return return code of the operation
+ */
+uint32_t tpm_nv_read_value(uint32_t index, void *data, uint32_t count);
+
+/**
+ * Issue a TPM_NV_WriteValue command. This implementation is limited
+ * to write the area from offset 0. The area index could be one of
+ * the special value listed in enum tpm_nv_index.
+ *
+ * @param index index of the area
+ * @param data input buffer to be wrote to the area
+ * @param length length of data bytes of input buffer
+ * @return return code of the operation
+ */
+uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length);
+
+/**
+ * Issue a TPM_Extend command.
+ *
+ * @param index index of the PCR
+ * @param in_digest 160-bit value representing the event to be
+ * recorded
+ * @param out_digest 160-bit PCR value after execution of the
+ * command
+ * @return return code of the operation
+ */
+uint32_t tpm_extend(uint32_t index, const void *in_digest, void *out_digest);
+
+/**
+ * Issue a TPM_PCRRead command.
*
- * @sendbuf - buffer of the data to send
- * @send_size size of the data to send
- * @recvbuf - memory to save the response to
- * @recv_len - pointer to the size of the response buffer
+ * @param index index of the PCR
+ * @param data output buffer for contents of the named PCR
+ * @param count size of output buffer
+ * @return return code of the operation
+ */
+uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count);
+
+/**
+ * Issue a TSC_PhysicalPresence command. TPM physical presence flag
+ * is bit-wise OR'ed of flags listed in enum tpm_physical_presence.
+ *
+ * @param presence TPM physical presence flag
+ * @return return code of the operation
+ */
+uint32_t tpm_tsc_physical_presence(uint16_t presence);
+
+/**
+ * Issue a TPM_ReadPubek command.
+ *
+ * @param data output buffer for the public endorsement key
+ * @param count size of ouput buffer
+ * @return return code of the operation
+ */
+uint32_t tpm_read_pubek(void *data, size_t count);
+
+/**
+ * Issue a TPM_ForceClear command.
+ *
+ * @return return code of the operation
+ */
+uint32_t tpm_force_clear(void);
+
+/**
+ * Issue a TPM_PhysicalEnable command.
+ *
+ * @return return code of the operation
+ */
+uint32_t tpm_physical_enable(void);
+
+/**
+ * Issue a TPM_PhysicalDisable command.
+ *
+ * @return return code of the operation
+ */
+uint32_t tpm_physical_disable(void);
+
+/**
+ * Issue a TPM_PhysicalSetDeactivated command.
+ *
+ * @param state boolean state of the deactivated flag
+ * @return return code of the operation
+ */
+uint32_t tpm_physical_set_deactivated(uint8_t state);
+
+/**
+ * Issue a TPM_GetCapability command. This implementation is limited
+ * to query sub_cap index that is 4-byte wide.
*
- * Returns 0 on success (and places the number of response bytes at recv_len)
- * or -1 on failure.
+ * @param cap_area partition of capabilities
+ * @param sub_cap further definition of capability, which is
+ * limited to be 4-byte wide
+ * @param cap output buffer for capability information
+ * @param count size of ouput buffer
+ * @return return code of the operation
*/
-int tis_sendrecv(const uint8_t *sendbuf, size_t send_size, uint8_t *recvbuf,
- size_t *recv_len);
+uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap,
+ void *cap, size_t count);
-#endif /* _INCLUDE_TPM_H_ */
+#endif /* __TPM_H */
diff --git a/include/xilinx.h b/include/xilinx.h
index 5f25b7a..9a64771 100644
--- a/include/xilinx.h
+++ b/include/xilinx.h
@@ -27,28 +27,6 @@
#ifndef _XILINX_H_
#define _XILINX_H_
-/* Xilinx Model definitions
- *********************************************************************/
-#define CONFIG_SYS_SPARTAN2 CONFIG_SYS_FPGA_DEV( 0x1 )
-#define CONFIG_SYS_VIRTEX_E CONFIG_SYS_FPGA_DEV( 0x2 )
-#define CONFIG_SYS_VIRTEX2 CONFIG_SYS_FPGA_DEV( 0x4 )
-#define CONFIG_SYS_SPARTAN3 CONFIG_SYS_FPGA_DEV( 0x8 )
-#define CONFIG_SYS_XILINX_SPARTAN2 (CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_SPARTAN2)
-#define CONFIG_SYS_XILINX_VIRTEX_E (CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_VIRTEX_E)
-#define CONFIG_SYS_XILINX_VIRTEX2 (CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_VIRTEX2)
-#define CONFIG_SYS_XILINX_SPARTAN3 (CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_SPARTAN3)
-/* XXX - Add new models here */
-
-
-/* Xilinx Interface definitions
- *********************************************************************/
-#define CONFIG_SYS_XILINX_IF_SS CONFIG_SYS_FPGA_IF( 0x1 ) /* slave serial */
-#define CONFIG_SYS_XILINX_IF_MS CONFIG_SYS_FPGA_IF( 0x2 ) /* master serial */
-#define CONFIG_SYS_XILINX_IF_SP CONFIG_SYS_FPGA_IF( 0x4 ) /* slave parallel */
-#define CONFIG_SYS_XILINX_IF_JTAG CONFIG_SYS_FPGA_IF( 0x8 ) /* jtag */
-#define CONFIG_SYS_XILINX_IF_MSM CONFIG_SYS_FPGA_IF( 0x10 ) /* master selectmap */
-#define CONFIG_SYS_XILINX_IF_SSM CONFIG_SYS_FPGA_IF( 0x20 ) /* slave selectmap */
-
/* Xilinx types
*********************************************************************/
typedef enum { /* typedef Xilinx_iface */
@@ -59,6 +37,7 @@ typedef enum { /* typedef Xilinx_iface */
jtag_mode, /* jtag/tap serial (not used ) */
master_selectmap, /* master SelectMap (virtex2) */
slave_selectmap, /* slave SelectMap (virtex2) */
+ devcfg, /* devcfg interface (zynq) */
max_xilinx_iface_type /* insert all new types before this */
} Xilinx_iface; /* end, typedef Xilinx_iface */
@@ -68,6 +47,7 @@ typedef enum { /* typedef Xilinx_Family */
Xilinx_VirtexE, /* Virtex-E Family */
Xilinx_Virtex2, /* Virtex2 Family */
Xilinx_Spartan3, /* Spartan-III Family */
+ xilinx_zynq, /* Zynq Family */
max_xilinx_type /* insert all new types before this */
} Xilinx_Family; /* end, typedef Xilinx_Family */
@@ -77,6 +57,7 @@ typedef struct { /* typedef Xilinx_desc */
size_t size; /* bytes of data part can accept */
void *iface_fns; /* interface function table */
int cookie; /* implementation specific cookie */
+ char *name; /* device name in bitstream */
} Xilinx_desc; /* end, typedef Xilinx_desc */
/* Generic Xilinx Functions
diff --git a/include/zynqpl.h b/include/zynqpl.h
new file mode 100644
index 0000000..0247ef6
--- /dev/null
+++ b/include/zynqpl.h
@@ -0,0 +1,59 @@
+/*
+ * (C) Copyright 2012-2013, Xilinx, Michal Simek
+ *
+ * (C) Copyright 2012
+ * Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * 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 _ZYNQPL_H_
+#define _ZYNQPL_H_
+
+#include <xilinx.h>
+
+extern int zynq_load(Xilinx_desc *desc, const void *image, size_t size);
+extern int zynq_dump(Xilinx_desc *desc, const void *buf, size_t bsize);
+extern int zynq_info(Xilinx_desc *desc);
+
+#define XILINX_ZYNQ_7010 0x2
+#define XILINX_ZYNQ_7020 0x7
+#define XILINX_ZYNQ_7030 0xc
+#define XILINX_ZYNQ_7045 0x11
+
+/* Device Image Sizes */
+#define XILINX_XC7Z010_SIZE 16669920/8
+#define XILINX_XC7Z020_SIZE 32364512/8
+#define XILINX_XC7Z030_SIZE 47839328/8
+#define XILINX_XC7Z045_SIZE 106571232/8
+
+/* Descriptor Macros */
+#define XILINX_XC7Z010_DESC(cookie) \
+{ xilinx_zynq, devcfg, XILINX_XC7Z010_SIZE, NULL, cookie, "7z010" }
+
+#define XILINX_XC7Z020_DESC(cookie) \
+{ xilinx_zynq, devcfg, XILINX_XC7Z020_SIZE, NULL, cookie, "7z020" }
+
+#define XILINX_XC7Z030_DESC(cookie) \
+{ xilinx_zynq, devcfg, XILINX_XC7Z030_SIZE, NULL, cookie, "7z030" }
+
+#define XILINX_XC7Z045_DESC(cookie) \
+{ xilinx_zynq, devcfg, XILINX_XC7Z045_SIZE, NULL, cookie, "7z045" }
+
+#endif /* _ZYNQPL_H_ */
diff --git a/lib/Makefile b/lib/Makefile
index 5d71b80..5d58609 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -53,7 +53,9 @@ COBJS-y += qsort.o
COBJS-$(CONFIG_SHA1) += sha1.o
COBJS-$(CONFIG_SHA256) += sha256.o
COBJS-y += strmhz.o
+COBJS-$(CONFIG_TPM) += tpm.o
COBJS-$(CONFIG_RBTREE) += rbtree.o
+COBJS-$(CONFIG_BITREVERSE) += bitrev.o
endif
ifdef CONFIG_SPL_BUILD
@@ -70,7 +72,9 @@ COBJS-$(CONFIG_BCH) += bch.o
COBJS-y += crc32.o
COBJS-y += ctype.o
COBJS-y += div64.o
+COBJS-y += hang.o
COBJS-y += linux_string.o
+COBJS-$(CONFIG_REGEX) += slre.o
COBJS-y += string.o
COBJS-y += time.o
COBJS-$(CONFIG_BOOTP_PXE) += uuid.o
diff --git a/lib/bitrev.c b/lib/bitrev.c
new file mode 100644
index 0000000..160021a
--- /dev/null
+++ b/lib/bitrev.c
@@ -0,0 +1,59 @@
+/*
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ *
+ * Based on bitrev from the Linux kernel, by Akinobu Mita
+ */
+
+
+#include <linux/types.h>
+#include <linux/bitrev.h>
+
+const u8 byte_rev_table[256] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
+};
+
+u16 bitrev16(u16 x)
+{
+ return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8);
+}
+
+/**
+ * bitrev32 - reverse the order of bits in a u32 value
+ * @x: value to be bit-reversed
+ */
+u32 bitrev32(u32 x)
+{
+ return (bitrev16(x & 0xffff) << 16) | bitrev16(x >> 16);
+}
diff --git a/lib/crc32.c b/lib/crc32.c
index 76205da..9759212 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -8,7 +8,9 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-#ifndef USE_HOSTCC
+#ifdef USE_HOSTCC
+#include <arpa/inet.h>
+#else
#include <common.h>
#endif
#include <compiler.h>
@@ -256,5 +258,6 @@ void crc32_wd_buf(const unsigned char *input, unsigned int ilen,
uint32_t crc;
crc = crc32_wd(0, input, ilen, chunk_sz);
+ crc = htonl(crc);
memcpy(output, &crc, sizeof(crc));
}
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 403babd..ac1fe0b 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -65,6 +65,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"),
+ COMPAT(INFINEON_SLB9635_TPM, "infineon,slb9635-tpm"),
};
const char *fdtdec_get_compatible(enum fdt_compat_id id)
@@ -353,10 +354,11 @@ int fdtdec_check_fdt(void)
*/
int fdtdec_prepare_fdt(void)
{
- if (((uintptr_t)gd->fdt_blob & 3) || fdt_check_header(gd->fdt_blob)) {
+ if (!gd->fdt_blob || ((uintptr_t)gd->fdt_blob & 3) ||
+ fdt_check_header(gd->fdt_blob)) {
printf("No valid FDT found - please append one to U-Boot "
"binary, use u-boot-dtb.bin or define "
- "CONFIG_OF_EMBED\n");
+ "CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n");
return -1;
}
return 0;
diff --git a/lib/hang.c b/lib/hang.c
new file mode 100644
index 0000000..fc1286c
--- /dev/null
+++ b/lib/hang.c
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2013
+ * Andreas Bießmann <andreas.devel@googlemail.com>
+ *
+ * This file consolidates all the different hang() functions implemented in
+ * u-boot.
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <bootstage.h>
+
+/**
+ * hang - stop processing by staying in an endless loop
+ *
+ * The purpose of this function is to stop further execution of code cause
+ * something went completely wrong. To catch this and give some feedback to
+ * the user one needs to catch the bootstage_error (see show_boot_progress())
+ * in the board code.
+ */
+void hang(void)
+{
+#if !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
+ defined(CONFIG_SPL_SERIAL_SUPPORT))
+ puts("### ERROR ### Please RESET the board ###\n");
+#endif
+ bootstage_error(BOOTSTAGE_ID_NEED_RESET);
+ for (;;)
+ ;
+}
diff --git a/lib/hashtable.c b/lib/hashtable.c
index 07ebfb2..6050dd0 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -2,7 +2,7 @@
* This implementation is based on code from uClibc-0.9.30.3 but was
* modified and extended for use within U-Boot.
*
- * Copyright (C) 2010 Wolfgang Denk <wd@denx.de>
+ * Copyright (C) 2010-2013 Wolfgang Denk <wd@denx.de>
*
* Original license header:
*
@@ -57,6 +57,7 @@
#include <env_callback.h>
#include <env_flags.h>
#include <search.h>
+#include <slre.h>
/*
* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
@@ -210,29 +211,6 @@ void hdestroy_r(struct hsearch_data *htab)
* example for functions like hdelete().
*/
-/*
- * hstrstr_r - return index to entry whose key and/or data contains match
- */
-int hstrstr_r(const char *match, int last_idx, ENTRY ** retval,
- struct hsearch_data *htab)
-{
- unsigned int idx;
-
- for (idx = last_idx + 1; idx < htab->size; ++idx) {
- if (htab->table[idx].used <= 0)
- continue;
- if (strstr(htab->table[idx].entry.key, match) ||
- strstr(htab->table[idx].entry.data, match)) {
- *retval = &htab->table[idx].entry;
- return idx;
- }
- }
-
- __set_errno(ESRCH);
- *retval = NULL;
- return 0;
-}
-
int hmatch_r(const char *match, int last_idx, ENTRY ** retval,
struct hsearch_data *htab)
{
@@ -563,6 +541,65 @@ static int cmpkey(const void *p1, const void *p2)
return (strcmp(e1->key, e2->key));
}
+static int match_string(int flag, const char *str, const char *pat, void *priv)
+{
+ switch (flag & H_MATCH_METHOD) {
+ case H_MATCH_IDENT:
+ if (strcmp(str, pat) == 0)
+ return 1;
+ break;
+ case H_MATCH_SUBSTR:
+ if (strstr(str, pat))
+ return 1;
+ break;
+#ifdef CONFIG_REGEX
+ case H_MATCH_REGEX:
+ {
+ struct slre *slrep = (struct slre *)priv;
+ struct cap caps[slrep->num_caps + 2];
+
+ if (slre_match(slrep, str, strlen(str), caps))
+ return 1;
+ }
+ break;
+#endif
+ default:
+ printf("## ERROR: unsupported match method: 0x%02x\n",
+ flag & H_MATCH_METHOD);
+ break;
+ }
+ return 0;
+}
+
+static int match_entry(ENTRY *ep, int flag,
+ int argc, char * const argv[])
+{
+ int arg;
+ void *priv = NULL;
+
+ for (arg = 1; arg < argc; ++arg) {
+#ifdef CONFIG_REGEX
+ struct slre slre;
+
+ if (slre_compile(&slre, argv[arg]) == 0) {
+ printf("Error compiling regex: %s\n", slre.err_str);
+ return 0;
+ }
+
+ priv = (void *)&slre;
+#endif
+ if (flag & H_MATCH_KEY) {
+ if (match_string(flag, ep->key, argv[arg], priv))
+ return 1;
+ }
+ if (flag & H_MATCH_DATA) {
+ if (match_string(flag, ep->data, argv[arg], priv))
+ return 1;
+ }
+ }
+ return 0;
+}
+
ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,
char **resp, size_t size,
int argc, char * const argv[])
@@ -589,14 +626,8 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,
if (htab->table[i].used > 0) {
ENTRY *ep = &htab->table[i].entry;
- int arg, found = 0;
+ int found = match_entry(ep, flag, argc, argv);
- for (arg = 0; arg < argc; ++arg) {
- if (strcmp(argv[arg], ep->key) == 0) {
- found = 1;
- break;
- }
- }
if ((argc > 0) && (found == 0))
continue;
diff --git a/lib/slre.c b/lib/slre.c
new file mode 100644
index 0000000..8cdd192
--- /dev/null
+++ b/lib/slre.c
@@ -0,0 +1,724 @@
+/*
+ * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
+ * All rights reserved
+ *
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * Sergey Lyubka wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.
+ */
+
+/*
+ * Downloaded Sat Nov 5 17:43:06 CET 2011 at
+ * http://slre.sourceforge.net/1.0/slre.c
+ */
+
+#ifdef SLRE_TEST
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#else
+#include <common.h>
+#include <linux/ctype.h>
+#endif /* SLRE_TEST */
+
+#include <errno.h>
+
+#include <slre.h>
+
+enum {END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL,
+ STAR, PLUS, STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT};
+
+#ifdef SLRE_TEST
+static struct {
+ const char *name;
+ int narg;
+ const char *flags;
+} opcodes[] = {
+ {"END", 0, ""}, /* End of code block or program */
+ {"BRANCH", 2, "oo"}, /* Alternative operator, "|" */
+ {"ANY", 0, ""}, /* Match any character, "." */
+ {"EXACT", 2, "d"}, /* Match exact string */
+ {"ANYOF", 2, "D"}, /* Match any from set, "[]" */
+ {"ANYBUT", 2, "D"}, /* Match any but from set, "[^]"*/
+ {"OPEN ", 1, "i"}, /* Capture start, "(" */
+ {"CLOSE", 1, "i"}, /* Capture end, ")" */
+ {"BOL", 0, ""}, /* Beginning of string, "^" */
+ {"EOL", 0, ""}, /* End of string, "$" */
+ {"STAR", 1, "o"}, /* Match zero or more times "*" */
+ {"PLUS", 1, "o"}, /* Match one or more times, "+" */
+ {"STARQ", 1, "o"}, /* Non-greedy STAR, "*?" */
+ {"PLUSQ", 1, "o"}, /* Non-greedy PLUS, "+?" */
+ {"QUEST", 1, "o"}, /* Match zero or one time, "?" */
+ {"SPACE", 0, ""}, /* Match whitespace, "\s" */
+ {"NONSPACE", 0, ""}, /* Match non-space, "\S" */
+ {"DIGIT", 0, ""} /* Match digit, "\d" */
+};
+#endif /* SLRE_TEST */
+
+/*
+ * Commands and operands are all unsigned char (1 byte long). All code offsets
+ * are relative to current address, and positive (always point forward). Data
+ * offsets are absolute. Commands with operands:
+ *
+ * BRANCH offset1 offset2
+ * Try to match the code block that follows the BRANCH instruction
+ * (code block ends with END). If no match, try to match code block that
+ * starts at offset1. If either of these match, jump to offset2.
+ *
+ * EXACT data_offset data_length
+ * Try to match exact string. String is recorded in data section from
+ * data_offset, and has length data_length.
+ *
+ * OPEN capture_number
+ * CLOSE capture_number
+ * If the user have passed 'struct cap' array for captures, OPEN
+ * records the beginning of the matched substring (cap->ptr), CLOSE
+ * sets the length (cap->len) for respective capture_number.
+ *
+ * STAR code_offset
+ * PLUS code_offset
+ * QUEST code_offset
+ * *, +, ?, respectively. Try to gobble as much as possible from the
+ * matched buffer, until code block that follows these instructions
+ * matches. When the longest possible string is matched,
+ * jump to code_offset
+ *
+ * STARQ, PLUSQ are non-greedy versions of STAR and PLUS.
+ */
+
+static const char *meta_chars = "|.^$*+?()[\\";
+
+#ifdef SLRE_TEST
+
+static void
+print_character_set(FILE *fp, const unsigned char *p, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (i > 0)
+ (void) fputc(',', fp);
+ if (p[i] == 0) {
+ i++;
+ if (p[i] == 0)
+ (void) fprintf(fp, "\\x%02x", p[i]);
+ else
+ (void) fprintf(fp, "%s", opcodes[p[i]].name);
+ } else if (isprint(p[i])) {
+ (void) fputc(p[i], fp);
+ } else {
+ (void) fprintf(fp, "\\x%02x", p[i]);
+ }
+ }
+}
+
+void
+slre_dump(const struct slre *r, FILE *fp)
+{
+ int i, j, ch, op, pc;
+
+ for (pc = 0; pc < r->code_size; pc++) {
+
+ op = r->code[pc];
+ (void) fprintf(fp, "%3d %s ", pc, opcodes[op].name);
+
+ for (i = 0; opcodes[op].flags[i] != '\0'; i++)
+ switch (opcodes[op].flags[i]) {
+ case 'i':
+ (void) fprintf(fp, "%d ", r->code[pc + 1]);
+ pc++;
+ break;
+ case 'o':
+ (void) fprintf(fp, "%d ",
+ pc + r->code[pc + 1] - i);
+ pc++;
+ break;
+ case 'D':
+ print_character_set(fp, r->data +
+ r->code[pc + 1], r->code[pc + 2]);
+ pc += 2;
+ break;
+ case 'd':
+ (void) fputc('"', fp);
+ for (j = 0; j < r->code[pc + 2]; j++) {
+ ch = r->data[r->code[pc + 1] + j];
+ if (isprint(ch)) {
+ (void) fputc(ch, fp);
+ } else {
+ (void) fprintf(fp,
+ "\\x%02x", ch);
+ }
+ }
+ (void) fputc('"', fp);
+ pc += 2;
+ break;
+ }
+
+ (void) fputc('\n', fp);
+ }
+}
+#endif /* SLRE_TEST */
+
+static void
+set_jump_offset(struct slre *r, int pc, int offset)
+{
+ assert(offset < r->code_size);
+
+ if (r->code_size - offset > 0xff)
+ r->err_str = "Jump offset is too big";
+ else
+ r->code[pc] = (unsigned char) (r->code_size - offset);
+}
+
+static void
+emit(struct slre *r, int code)
+{
+ if (r->code_size >= (int) (sizeof(r->code) / sizeof(r->code[0])))
+ r->err_str = "RE is too long (code overflow)";
+ else
+ r->code[r->code_size++] = (unsigned char) code;
+}
+
+static void
+store_char_in_data(struct slre *r, int ch)
+{
+ if (r->data_size >= (int) sizeof(r->data))
+ r->err_str = "RE is too long (data overflow)";
+ else
+ r->data[r->data_size++] = ch;
+}
+
+static void
+exact(struct slre *r, const char **re)
+{
+ int old_data_size = r->data_size;
+
+ while (**re != '\0' && (strchr(meta_chars, **re)) == NULL)
+ store_char_in_data(r, *(*re)++);
+
+ emit(r, EXACT);
+ emit(r, old_data_size);
+ emit(r, r->data_size - old_data_size);
+}
+
+static int
+get_escape_char(const char **re)
+{
+ int res;
+
+ switch (*(*re)++) {
+ case 'n':
+ res = '\n';
+ break;
+ case 'r':
+ res = '\r';
+ break;
+ case 't':
+ res = '\t';
+ break;
+ case '0':
+ res = 0;
+ break;
+ case 'S':
+ res = NONSPACE << 8;
+ break;
+ case 's':
+ res = SPACE << 8;
+ break;
+ case 'd':
+ res = DIGIT << 8;
+ break;
+ default:
+ res = (*re)[-1];
+ break;
+ }
+
+ return res;
+}
+
+static void
+anyof(struct slre *r, const char **re)
+{
+ int esc, old_data_size = r->data_size, op = ANYOF;
+
+ if (**re == '^') {
+ op = ANYBUT;
+ (*re)++;
+ }
+
+ while (**re != '\0')
+
+ switch (*(*re)++) {
+ case ']':
+ emit(r, op);
+ emit(r, old_data_size);
+ emit(r, r->data_size - old_data_size);
+ return;
+ /* NOTREACHED */
+ break;
+ case '\\':
+ esc = get_escape_char(re);
+ if ((esc & 0xff) == 0) {
+ store_char_in_data(r, 0);
+ store_char_in_data(r, esc >> 8);
+ } else {
+ store_char_in_data(r, esc);
+ }
+ break;
+ default:
+ store_char_in_data(r, (*re)[-1]);
+ break;
+ }
+
+ r->err_str = "No closing ']' bracket";
+}
+
+static void
+relocate(struct slre *r, int begin, int shift)
+{
+ emit(r, END);
+ memmove(r->code + begin + shift, r->code + begin, r->code_size - begin);
+ r->code_size += shift;
+}
+
+static void
+quantifier(struct slre *r, int prev, int op)
+{
+ if (r->code[prev] == EXACT && r->code[prev + 2] > 1) {
+ r->code[prev + 2]--;
+ emit(r, EXACT);
+ emit(r, r->code[prev + 1] + r->code[prev + 2]);
+ emit(r, 1);
+ prev = r->code_size - 3;
+ }
+ relocate(r, prev, 2);
+ r->code[prev] = op;
+ set_jump_offset(r, prev + 1, prev);
+}
+
+static void
+exact_one_char(struct slre *r, int ch)
+{
+ emit(r, EXACT);
+ emit(r, r->data_size);
+ emit(r, 1);
+ store_char_in_data(r, ch);
+}
+
+static void
+fixup_branch(struct slre *r, int fixup)
+{
+ if (fixup > 0) {
+ emit(r, END);
+ set_jump_offset(r, fixup, fixup - 2);
+ }
+}
+
+static void
+compile(struct slre *r, const char **re)
+{
+ int op, esc, branch_start, last_op, fixup, cap_no, level;
+
+ fixup = 0;
+ level = r->num_caps;
+ branch_start = last_op = r->code_size;
+
+ for (;;)
+ switch (*(*re)++) {
+ case '\0':
+ (*re)--;
+ return;
+ /* NOTREACHED */
+ break;
+ case '^':
+ emit(r, BOL);
+ break;
+ case '$':
+ emit(r, EOL);
+ break;
+ case '.':
+ last_op = r->code_size;
+ emit(r, ANY);
+ break;
+ case '[':
+ last_op = r->code_size;
+ anyof(r, re);
+ break;
+ case '\\':
+ last_op = r->code_size;
+ esc = get_escape_char(re);
+ if (esc & 0xff00)
+ emit(r, esc >> 8);
+ else
+ exact_one_char(r, esc);
+ break;
+ case '(':
+ last_op = r->code_size;
+ cap_no = ++r->num_caps;
+ emit(r, OPEN);
+ emit(r, cap_no);
+
+ compile(r, re);
+ if (*(*re)++ != ')') {
+ r->err_str = "No closing bracket";
+ return;
+ }
+
+ emit(r, CLOSE);
+ emit(r, cap_no);
+ break;
+ case ')':
+ (*re)--;
+ fixup_branch(r, fixup);
+ if (level == 0) {
+ r->err_str = "Unbalanced brackets";
+ return;
+ }
+ return;
+ /* NOTREACHED */
+ break;
+ case '+':
+ case '*':
+ op = (*re)[-1] == '*' ? STAR : PLUS;
+ if (**re == '?') {
+ (*re)++;
+ op = op == STAR ? STARQ : PLUSQ;
+ }
+ quantifier(r, last_op, op);
+ break;
+ case '?':
+ quantifier(r, last_op, QUEST);
+ break;
+ case '|':
+ fixup_branch(r, fixup);
+ relocate(r, branch_start, 3);
+ r->code[branch_start] = BRANCH;
+ set_jump_offset(r, branch_start + 1, branch_start);
+ fixup = branch_start + 2;
+ r->code[fixup] = 0xff;
+ break;
+ default:
+ (*re)--;
+ last_op = r->code_size;
+ exact(r, re);
+ break;
+ }
+}
+
+int
+slre_compile(struct slre *r, const char *re)
+{
+ r->err_str = NULL;
+ r->code_size = r->data_size = r->num_caps = r->anchored = 0;
+
+ if (*re == '^')
+ r->anchored++;
+
+ emit(r, OPEN); /* This will capture what matches full RE */
+ emit(r, 0);
+
+ while (*re != '\0')
+ compile(r, &re);
+
+ if (r->code[2] == BRANCH)
+ fixup_branch(r, 4);
+
+ emit(r, CLOSE);
+ emit(r, 0);
+ emit(r, END);
+
+ return (r->err_str == NULL ? 1 : 0);
+}
+
+static int match(const struct slre *, int,
+ const char *, int, int *, struct cap *);
+
+static void
+loop_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs)
+{
+ int saved_offset, matched_offset;
+
+ saved_offset = matched_offset = *ofs;
+
+ while (match(r, pc + 2, s, len, ofs, NULL)) {
+ saved_offset = *ofs;
+ if (match(r, pc + r->code[pc + 1], s, len, ofs, NULL))
+ matched_offset = saved_offset;
+ *ofs = saved_offset;
+ }
+
+ *ofs = matched_offset;
+}
+
+static void
+loop_non_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs)
+{
+ int saved_offset = *ofs;
+
+ while (match(r, pc + 2, s, len, ofs, NULL)) {
+ saved_offset = *ofs;
+ if (match(r, pc + r->code[pc + 1], s, len, ofs, NULL))
+ break;
+ }
+
+ *ofs = saved_offset;
+}
+
+static int
+is_any_of(const unsigned char *p, int len, const char *s, int *ofs)
+{
+ int i, ch;
+
+ ch = s[*ofs];
+
+ for (i = 0; i < len; i++)
+ if (p[i] == ch) {
+ (*ofs)++;
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+is_any_but(const unsigned char *p, int len, const char *s, int *ofs)
+{
+ int i, ch;
+
+ ch = s[*ofs];
+
+ for (i = 0; i < len; i++) {
+ if (p[i] == ch)
+ return 0;
+ }
+
+ (*ofs)++;
+ return 1;
+}
+
+static int
+match(const struct slre *r, int pc, const char *s, int len,
+ int *ofs, struct cap *caps)
+{
+ int n, saved_offset, res = 1;
+
+ while (res && r->code[pc] != END) {
+
+ assert(pc < r->code_size);
+ assert(pc < (int) (sizeof(r->code) / sizeof(r->code[0])));
+
+ switch (r->code[pc]) {
+ case BRANCH:
+ saved_offset = *ofs;
+ res = match(r, pc + 3, s, len, ofs, caps);
+ if (res == 0) {
+ *ofs = saved_offset;
+ res = match(r, pc + r->code[pc + 1],
+ s, len, ofs, caps);
+ }
+ pc += r->code[pc + 2];
+ break;
+ case EXACT:
+ res = 0;
+ n = r->code[pc + 2]; /* String length */
+ if (n <= len - *ofs && !memcmp(s + *ofs, r->data +
+ r->code[pc + 1], n)) {
+ (*ofs) += n;
+ res = 1;
+ }
+ pc += 3;
+ break;
+ case QUEST:
+ res = 1;
+ saved_offset = *ofs;
+ if (!match(r, pc + 2, s, len, ofs, caps))
+ *ofs = saved_offset;
+ pc += r->code[pc + 1];
+ break;
+ case STAR:
+ res = 1;
+ loop_greedy(r, pc, s, len, ofs);
+ pc += r->code[pc + 1];
+ break;
+ case STARQ:
+ res = 1;
+ loop_non_greedy(r, pc, s, len, ofs);
+ pc += r->code[pc + 1];
+ break;
+ case PLUS:
+ res = match(r, pc + 2, s, len, ofs, caps);
+ if (res == 0)
+ break;
+
+ loop_greedy(r, pc, s, len, ofs);
+ pc += r->code[pc + 1];
+ break;
+ case PLUSQ:
+ res = match(r, pc + 2, s, len, ofs, caps);
+ if (res == 0)
+ break;
+
+ loop_non_greedy(r, pc, s, len, ofs);
+ pc += r->code[pc + 1];
+ break;
+ case SPACE:
+ res = 0;
+ if (*ofs < len && isspace(((unsigned char *)s)[*ofs])) {
+ (*ofs)++;
+ res = 1;
+ }
+ pc++;
+ break;
+ case NONSPACE:
+ res = 0;
+ if (*ofs < len &&
+ !isspace(((unsigned char *)s)[*ofs])) {
+ (*ofs)++;
+ res = 1;
+ }
+ pc++;
+ break;
+ case DIGIT:
+ res = 0;
+ if (*ofs < len && isdigit(((unsigned char *)s)[*ofs])) {
+ (*ofs)++;
+ res = 1;
+ }
+ pc++;
+ break;
+ case ANY:
+ res = 0;
+ if (*ofs < len) {
+ (*ofs)++;
+ res = 1;
+ }
+ pc++;
+ break;
+ case ANYOF:
+ res = 0;
+ if (*ofs < len)
+ res = is_any_of(r->data + r->code[pc + 1],
+ r->code[pc + 2], s, ofs);
+ pc += 3;
+ break;
+ case ANYBUT:
+ res = 0;
+ if (*ofs < len)
+ res = is_any_but(r->data + r->code[pc + 1],
+ r->code[pc + 2], s, ofs);
+ pc += 3;
+ break;
+ case BOL:
+ res = *ofs == 0 ? 1 : 0;
+ pc++;
+ break;
+ case EOL:
+ res = *ofs == len ? 1 : 0;
+ pc++;
+ break;
+ case OPEN:
+ if (caps != NULL)
+ caps[r->code[pc + 1]].ptr = s + *ofs;
+ pc += 2;
+ break;
+ case CLOSE:
+ if (caps != NULL)
+ caps[r->code[pc + 1]].len = (s + *ofs) -
+ caps[r->code[pc + 1]].ptr;
+ pc += 2;
+ break;
+ case END:
+ pc++;
+ break;
+ default:
+ printf("unknown cmd (%d) at %d\n", r->code[pc], pc);
+ assert(0);
+ break;
+ }
+ }
+
+ return res;
+}
+
+int
+slre_match(const struct slre *r, const char *buf, int len,
+ struct cap *caps)
+{
+ int i, ofs = 0, res = 0;
+
+ if (r->anchored) {
+ res = match(r, 0, buf, len, &ofs, caps);
+ } else {
+ for (i = 0; i < len && res == 0; i++) {
+ ofs = i;
+ res = match(r, 0, buf, len, &ofs, caps);
+ }
+ }
+
+ return res;
+}
+
+#ifdef SLRE_TEST
+#define N_CAPS 5
+
+int main(int argc, char *argv[])
+{
+ struct slre slre;
+ struct cap caps[N_CAPS];
+ unsigned char data[1 * 1024 * 1024];
+ FILE *fp;
+ int i, res, len;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s 'slre' <file>\n", argv[0]);
+ return 1;
+ }
+
+ fp = fopen(argv[2], "rb");
+ if (fp == NULL) {
+ fprintf(stderr, "Error: cannot open %s:%s\n",
+ argv[2], strerror(errno));
+ return 1;
+ }
+
+ if (!slre_compile(&slre, argv[1])) {
+ fprintf(stderr, "Error compiling slre: %s\n", slre.err_str);
+ return 1;
+ }
+
+ slre_dump(&slre, stderr);
+
+ while (fgets(data, sizeof(data), fp) != NULL) {
+ len = strlen(data);
+
+ if ((len > 0) && (data[len-1] == '\n')) {
+ data[len-1] = '\0';
+ --len;
+ }
+
+ printf("Data = \"%s\"\n", data);
+
+ (void) memset(caps, 0, sizeof(caps));
+
+ res = 0;
+
+ res = slre_match(&slre, data, len, caps);
+ printf("Result [%d]: %d\n", i, res);
+
+ for (i = 0; i < N_CAPS; i++) {
+ if (caps[i].len > 0) {
+ printf("Substring %d: len=%d [%.*s]\n", i,
+ caps[i].len,
+ caps[i].len, caps[i].ptr);
+ }
+ }
+ printf("----------------------------------------------------\n");
+ }
+ (void) fclose(fp);
+
+ return 0;
+}
+#endif /* SLRE_TEST */
diff --git a/lib/tpm.c b/lib/tpm.c
new file mode 100644
index 0000000..42c9bea
--- /dev/null
+++ b/lib/tpm.c
@@ -0,0 +1,581 @@
+/*
+ * Copyright (c) 2013 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
+ */
+
+#include <common.h>
+#include <stdarg.h>
+#include <tpm.h>
+#include <asm/unaligned.h>
+
+/* Internal error of TPM command library */
+#define TPM_LIB_ERROR ((uint32_t)~0u)
+
+/* Useful constants */
+enum {
+ COMMAND_BUFFER_SIZE = 256,
+ TPM_PUBEK_SIZE = 256,
+ TPM_REQUEST_HEADER_LENGTH = 10,
+ TPM_RESPONSE_HEADER_LENGTH = 10,
+ PCR_DIGEST_LENGTH = 20,
+};
+
+/**
+ * Pack data into a byte string. The data types are specified in
+ * the format string: 'b' means unsigned byte, 'w' unsigned word,
+ * 'd' unsigned double word, and 's' byte string. The data are a
+ * series of offsets and values (for type byte string there are also
+ * lengths). The data values are packed into the byte string
+ * sequentially, and so a latter value could over-write a former
+ * value.
+ *
+ * @param str output string
+ * @param size size of output string
+ * @param format format string
+ * @param ... data points
+ * @return 0 on success, non-0 on error
+ */
+int pack_byte_string(uint8_t *str, size_t size, const char *format, ...)
+{
+ va_list args;
+ size_t offset = 0, length = 0;
+ uint8_t *data = NULL;
+ uint32_t value = 0;
+
+ va_start(args, format);
+ for (; *format; format++) {
+ switch (*format) {
+ case 'b':
+ offset = va_arg(args, size_t);
+ value = va_arg(args, int);
+ length = 1;
+ break;
+ case 'w':
+ offset = va_arg(args, size_t);
+ value = va_arg(args, int);
+ length = 2;
+ break;
+ case 'd':
+ offset = va_arg(args, size_t);
+ value = va_arg(args, uint32_t);
+ length = 4;
+ break;
+ case 's':
+ offset = va_arg(args, size_t);
+ data = va_arg(args, uint8_t *);
+ length = va_arg(args, uint32_t);
+ break;
+ default:
+ debug("Couldn't recognize format string\n");
+ return -1;
+ }
+
+ if (offset + length > size)
+ return -1;
+
+ switch (*format) {
+ case 'b':
+ str[offset] = value;
+ break;
+ case 'w':
+ put_unaligned_be16(value, str + offset);
+ break;
+ case 'd':
+ put_unaligned_be32(value, str + offset);
+ break;
+ case 's':
+ memcpy(str + offset, data, length);
+ break;
+ }
+ }
+ va_end(args);
+
+ return 0;
+}
+
+/**
+ * Unpack data from a byte string. The data types are specified in
+ * the format string: 'b' means unsigned byte, 'w' unsigned word,
+ * 'd' unsigned double word, and 's' byte string. The data are a
+ * series of offsets and pointers (for type byte string there are also
+ * lengths).
+ *
+ * @param str output string
+ * @param size size of output string
+ * @param format format string
+ * @param ... data points
+ * @return 0 on success, non-0 on error
+ */
+int unpack_byte_string(const uint8_t *str, size_t size, const char *format, ...)
+{
+ va_list args;
+ size_t offset = 0, length = 0;
+ uint8_t *ptr8 = NULL;
+ uint16_t *ptr16 = NULL;
+ uint32_t *ptr32 = NULL;
+
+ va_start(args, format);
+ for (; *format; format++) {
+ switch (*format) {
+ case 'b':
+ offset = va_arg(args, size_t);
+ ptr8 = va_arg(args, uint8_t *);
+ length = 1;
+ break;
+ case 'w':
+ offset = va_arg(args, size_t);
+ ptr16 = va_arg(args, uint16_t *);
+ length = 2;
+ break;
+ case 'd':
+ offset = va_arg(args, size_t);
+ ptr32 = va_arg(args, uint32_t *);
+ length = 4;
+ break;
+ case 's':
+ offset = va_arg(args, size_t);
+ ptr8 = va_arg(args, uint8_t *);
+ length = va_arg(args, uint32_t);
+ break;
+ default:
+ debug("Couldn't recognize format string\n");
+ return -1;
+ }
+
+ if (offset + length > size)
+ return -1;
+
+ switch (*format) {
+ case 'b':
+ *ptr8 = str[offset];
+ break;
+ case 'w':
+ *ptr16 = get_unaligned_be16(str + offset);
+ break;
+ case 'd':
+ *ptr32 = get_unaligned_be32(str + offset);
+ break;
+ case 's':
+ memcpy(ptr8, str + offset, length);
+ break;
+ }
+ }
+ va_end(args);
+
+ return 0;
+}
+
+/**
+ * Get TPM command size.
+ *
+ * @param command byte string of TPM command
+ * @return command size of the TPM command
+ */
+static uint32_t tpm_command_size(const void *command)
+{
+ const size_t command_size_offset = 2;
+ return get_unaligned_be32(command + command_size_offset);
+}
+
+/**
+ * Get TPM response return code, which is one of TPM_RESULT values.
+ *
+ * @param response byte string of TPM response
+ * @return return code of the TPM response
+ */
+static uint32_t tpm_return_code(const void *response)
+{
+ const size_t return_code_offset = 6;
+ return get_unaligned_be32(response + return_code_offset);
+}
+
+/**
+ * Send a TPM command and return response's return code, and optionally
+ * return response to caller.
+ *
+ * @param command byte string of TPM command
+ * @param response output buffer for TPM response, or NULL if the
+ * caller does not care about it
+ * @param size_ptr output buffer size (input parameter) and TPM
+ * response length (output parameter); this parameter
+ * is a bidirectional
+ * @return return code of the TPM response
+ */
+static uint32_t tpm_sendrecv_command(const void *command,
+ void *response, size_t *size_ptr)
+{
+ uint8_t response_buffer[COMMAND_BUFFER_SIZE];
+ size_t response_length;
+ uint32_t err;
+
+ if (response) {
+ response_length = *size_ptr;
+ } else {
+ response = response_buffer;
+ response_length = sizeof(response_buffer);
+ }
+ err = tis_sendrecv(command, tpm_command_size(command),
+ response, &response_length);
+ if (err)
+ return TPM_LIB_ERROR;
+ if (response)
+ *size_ptr = response_length;
+
+ return tpm_return_code(response);
+}
+
+uint32_t tpm_init(void)
+{
+ uint32_t err;
+
+ err = tis_init();
+ if (err)
+ return err;
+
+ return tis_open();
+}
+
+uint32_t tpm_startup(enum tpm_startup_type mode)
+{
+ const uint8_t command[12] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
+ };
+ const size_t mode_offset = 10;
+ uint8_t buf[COMMAND_BUFFER_SIZE];
+
+ if (pack_byte_string(buf, sizeof(buf), "sw",
+ 0, command, sizeof(command),
+ mode_offset, mode))
+ return TPM_LIB_ERROR;
+
+ return tpm_sendrecv_command(buf, NULL, NULL);
+}
+
+uint32_t tpm_self_test_full(void)
+{
+ const uint8_t command[10] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50,
+ };
+ return tpm_sendrecv_command(command, NULL, NULL);
+}
+
+uint32_t tpm_continue_self_test(void)
+{
+ const uint8_t command[10] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53,
+ };
+ return tpm_sendrecv_command(command, NULL, NULL);
+}
+
+uint32_t tpm_nv_define_space(uint32_t index, uint32_t perm, uint32_t size)
+{
+ const uint8_t command[101] = {
+ 0x0, 0xc1, /* TPM_TAG */
+ 0x0, 0x0, 0x0, 0x65, /* parameter size */
+ 0x0, 0x0, 0x0, 0xcc, /* TPM_COMMAND_CODE */
+ /* TPM_NV_DATA_PUBLIC->... */
+ 0x0, 0x18, /* ...->TPM_STRUCTURE_TAG */
+ 0, 0, 0, 0, /* ...->TPM_NV_INDEX */
+ /* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
+ 0x0, 0x3,
+ 0, 0, 0,
+ 0x1f,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
+ 0x0, 0x3,
+ 0, 0, 0,
+ 0x1f,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* TPM_NV_ATTRIBUTES->... */
+ 0x0, 0x17, /* ...->TPM_STRUCTURE_TAG */
+ 0, 0, 0, 0, /* ...->attributes */
+ /* End of TPM_NV_ATTRIBUTES */
+ 0, /* bReadSTClear */
+ 0, /* bWriteSTClear */
+ 0, /* bWriteDefine */
+ 0, 0, 0, 0, /* size */
+ };
+ const size_t index_offset = 12;
+ const size_t perm_offset = 70;
+ const size_t size_offset = 77;
+ uint8_t buf[COMMAND_BUFFER_SIZE];
+
+ if (pack_byte_string(buf, sizeof(buf), "sddd",
+ 0, command, sizeof(command),
+ index_offset, index,
+ perm_offset, perm,
+ size_offset, size))
+ return TPM_LIB_ERROR;
+
+ return tpm_sendrecv_command(buf, NULL, NULL);
+}
+
+uint32_t tpm_nv_read_value(uint32_t index, void *data, uint32_t count)
+{
+ const uint8_t command[22] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf,
+ };
+ const size_t index_offset = 10;
+ const size_t length_offset = 18;
+ const size_t data_size_offset = 10;
+ const size_t data_offset = 14;
+ uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+ size_t response_length = sizeof(response);
+ uint32_t data_size;
+ uint32_t err;
+
+ if (pack_byte_string(buf, sizeof(buf), "sdd",
+ 0, command, sizeof(command),
+ index_offset, index,
+ length_offset, count))
+ return TPM_LIB_ERROR;
+ err = tpm_sendrecv_command(buf, response, &response_length);
+ if (err)
+ return err;
+ if (unpack_byte_string(response, response_length, "d",
+ data_size_offset, &data_size))
+ return TPM_LIB_ERROR;
+ if (data_size > count)
+ return TPM_LIB_ERROR;
+ if (unpack_byte_string(response, response_length, "s",
+ data_offset, data, data_size))
+ return TPM_LIB_ERROR;
+
+ return 0;
+}
+
+uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length)
+{
+ const uint8_t command[256] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd,
+ };
+ const size_t command_size_offset = 2;
+ const size_t index_offset = 10;
+ const size_t length_offset = 18;
+ const size_t data_offset = 22;
+ const size_t write_info_size = 12;
+ const uint32_t total_length =
+ TPM_REQUEST_HEADER_LENGTH + write_info_size + length;
+ uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+ size_t response_length = sizeof(response);
+ uint32_t err;
+
+ if (pack_byte_string(buf, sizeof(buf), "sddds",
+ 0, command, sizeof(command),
+ command_size_offset, total_length,
+ index_offset, index,
+ length_offset, length,
+ data_offset, data, length))
+ return TPM_LIB_ERROR;
+ err = tpm_sendrecv_command(buf, response, &response_length);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+uint32_t tpm_extend(uint32_t index, const void *in_digest, void *out_digest)
+{
+ const uint8_t command[34] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14,
+ };
+ const size_t index_offset = 10;
+ const size_t in_digest_offset = 14;
+ const size_t out_digest_offset = 10;
+ uint8_t buf[COMMAND_BUFFER_SIZE];
+ uint8_t response[TPM_RESPONSE_HEADER_LENGTH + PCR_DIGEST_LENGTH];
+ size_t response_length = sizeof(response);
+ uint32_t err;
+
+ if (pack_byte_string(buf, sizeof(buf), "sds",
+ 0, command, sizeof(command),
+ index_offset, index,
+ in_digest_offset, in_digest,
+ PCR_DIGEST_LENGTH))
+ return TPM_LIB_ERROR;
+ err = tpm_sendrecv_command(buf, response, &response_length);
+ if (err)
+ return err;
+
+ if (unpack_byte_string(response, response_length, "s",
+ out_digest_offset, out_digest,
+ PCR_DIGEST_LENGTH))
+ return TPM_LIB_ERROR;
+
+ return 0;
+}
+
+uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count)
+{
+ const uint8_t command[14] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15,
+ };
+ const size_t index_offset = 10;
+ const size_t out_digest_offset = 10;
+ uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+ size_t response_length = sizeof(response);
+ uint32_t err;
+
+ if (count < PCR_DIGEST_LENGTH)
+ return TPM_LIB_ERROR;
+
+ if (pack_byte_string(buf, sizeof(buf), "sd",
+ 0, command, sizeof(command),
+ index_offset, index))
+ return TPM_LIB_ERROR;
+ err = tpm_sendrecv_command(buf, response, &response_length);
+ if (err)
+ return err;
+ if (unpack_byte_string(response, response_length, "s",
+ out_digest_offset, data, PCR_DIGEST_LENGTH))
+ return TPM_LIB_ERROR;
+
+ return 0;
+}
+
+uint32_t tpm_tsc_physical_presence(uint16_t presence)
+{
+ const uint8_t command[12] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
+ };
+ const size_t presence_offset = 10;
+ uint8_t buf[COMMAND_BUFFER_SIZE];
+
+ if (pack_byte_string(buf, sizeof(buf), "sw",
+ 0, command, sizeof(command),
+ presence_offset, presence))
+ return TPM_LIB_ERROR;
+
+ return tpm_sendrecv_command(buf, NULL, NULL);
+}
+
+uint32_t tpm_read_pubek(void *data, size_t count)
+{
+ const uint8_t command[30] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c,
+ };
+ const size_t response_size_offset = 2;
+ const size_t data_offset = 10;
+ const size_t header_and_checksum_size = TPM_RESPONSE_HEADER_LENGTH + 20;
+ uint8_t response[COMMAND_BUFFER_SIZE + TPM_PUBEK_SIZE];
+ size_t response_length = sizeof(response);
+ uint32_t data_size;
+ uint32_t err;
+
+ err = tpm_sendrecv_command(command, response, &response_length);
+ if (err)
+ return err;
+ if (unpack_byte_string(response, response_length, "d",
+ response_size_offset, &data_size))
+ return TPM_LIB_ERROR;
+ if (data_size < header_and_checksum_size)
+ return TPM_LIB_ERROR;
+ data_size -= header_and_checksum_size;
+ if (data_size > count)
+ return TPM_LIB_ERROR;
+ if (unpack_byte_string(response, response_length, "s",
+ data_offset, data, data_size))
+ return TPM_LIB_ERROR;
+
+ return 0;
+}
+
+uint32_t tpm_force_clear(void)
+{
+ const uint8_t command[10] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
+ };
+
+ return tpm_sendrecv_command(command, NULL, NULL);
+}
+
+uint32_t tpm_physical_enable(void)
+{
+ const uint8_t command[10] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
+ };
+
+ return tpm_sendrecv_command(command, NULL, NULL);
+}
+
+uint32_t tpm_physical_disable(void)
+{
+ const uint8_t command[10] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
+ };
+
+ return tpm_sendrecv_command(command, NULL, NULL);
+}
+
+uint32_t tpm_physical_set_deactivated(uint8_t state)
+{
+ const uint8_t command[11] = {
+ 0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
+ };
+ const size_t state_offset = 10;
+ uint8_t buf[COMMAND_BUFFER_SIZE];
+
+ if (pack_byte_string(buf, sizeof(buf), "sb",
+ 0, command, sizeof(command),
+ state_offset, state))
+ return TPM_LIB_ERROR;
+
+ return tpm_sendrecv_command(buf, NULL, NULL);
+}
+
+uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap,
+ void *cap, size_t count)
+{
+ const uint8_t command[22] = {
+ 0x0, 0xc1, /* TPM_TAG */
+ 0x0, 0x0, 0x0, 0x16, /* parameter size */
+ 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
+ 0x0, 0x0, 0x0, 0x0, /* TPM_CAPABILITY_AREA */
+ 0x0, 0x0, 0x0, 0x4, /* subcap size */
+ 0x0, 0x0, 0x0, 0x0, /* subcap value */
+ };
+ const size_t cap_area_offset = 10;
+ const size_t sub_cap_offset = 18;
+ const size_t cap_offset = 14;
+ const size_t cap_size_offset = 10;
+ uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+ size_t response_length = sizeof(response);
+ uint32_t cap_size;
+ uint32_t err;
+
+ if (pack_byte_string(buf, sizeof(buf), "sdd",
+ 0, command, sizeof(command),
+ cap_area_offset, cap_area,
+ sub_cap_offset, sub_cap))
+ return TPM_LIB_ERROR;
+ err = tpm_sendrecv_command(buf, response, &response_length);
+ if (err)
+ return err;
+ if (unpack_byte_string(response, response_length, "d",
+ cap_size_offset, &cap_size))
+ return TPM_LIB_ERROR;
+ if (cap_size > response_length || cap_size > count)
+ return TPM_LIB_ERROR;
+ if (unpack_byte_string(response, response_length, "s",
+ cap_offset, cap, cap_size))
+ return TPM_LIB_ERROR;
+
+ return 0;
+}
diff --git a/post/drivers/i2c.c b/post/drivers/i2c.c
index 4cbd9f3..c93ae25 100644
--- a/post/drivers/i2c.c
+++ b/post/drivers/i2c.c
@@ -100,6 +100,8 @@ int i2c_post_test (int flags)
for (i = 0; i < sizeof(i2c_addr_list); ++i) {
if (i2c_addr_list[i] == 0xff)
continue;
+ if (i2c_ignore_device(i2c_addr_list[i]))
+ continue;
post_log("I2C: addr %02x did not respond\n", i2c_addr_list[i]);
ret = -1;
}
diff --git a/tools/Makefile b/tools/Makefile
index c5952fc..889c897 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -164,7 +164,8 @@ NOPEDOBJS := $(addprefix $(obj),$(NOPED_OBJ_FILES-y))
# Use native tools and options
# Define __KERNEL_STRICT_NAMES to prevent typedef overlaps
#
-HOSTCPPFLAGS = -idirafter $(SRCTREE)/include \
+HOSTCPPFLAGS = -include $(SRCTREE)/include/libfdt_env.h \
+ -idirafter $(SRCTREE)/include \
-idirafter $(OBJTREE)/include2 \
-idirafter $(OBJTREE)/include \
-I $(SRCTREE)/lib/libfdt \
diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py
index f485750..e31da15 100644
--- a/tools/patman/gitutil.py
+++ b/tools/patman/gitutil.py
@@ -39,7 +39,8 @@ def CountCommitsToBranch():
Return:
Number of patches that exist on top of the branch
"""
- pipe = [['git', 'log', '--no-color', '--oneline', '@{upstream}..'],
+ pipe = [['git', 'log', '--no-color', '--oneline', '--no-decorate',
+ '@{upstream}..'],
['wc', '-l']]
stdout = command.RunPipe(pipe, capture=True, oneline=True).stdout
patch_count = int(stdout)
@@ -92,7 +93,8 @@ def CountCommitsInBranch(git_dir, branch, include_upstream=False):
Number of patches that exist on top of the branch
"""
range_expr = GetRangeInBranch(git_dir, branch, include_upstream)
- pipe = [['git', '--git-dir', git_dir, 'log', '--oneline', range_expr],
+ pipe = [['git', '--git-dir', git_dir, 'log', '--oneline', '--no-decorate',
+ range_expr],
['wc', '-l']]
result = command.RunPipe(pipe, capture=True, oneline=True)
patch_count = int(result.stdout)
@@ -106,7 +108,7 @@ def CountCommits(commit_range):
Return:
Number of patches that exist on top of the branch
"""
- pipe = [['git', 'log', '--oneline', commit_range],
+ pipe = [['git', 'log', '--oneline', '--no-decorate', commit_range],
['wc', '-l']]
stdout = command.RunPipe(pipe, capture=True, oneline=True).stdout
patch_count = int(stdout)
diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py
index 7334ed3..b4337cc 100644
--- a/tools/patman/patchstream.py
+++ b/tools/patman/patchstream.py
@@ -359,7 +359,8 @@ def GetMetaDataForList(commit_range, git_dir=None, count=None,
Returns:
A Series object containing information about the commits.
"""
- params = ['git', 'log', '--no-color', '--reverse', commit_range]
+ params = ['git', 'log', '--no-color', '--reverse', '--no-decorate',
+ commit_range]
if count is not None:
params[2:2] = ['-n%d' % count]
if git_dir: