/u-boot.dis
/u-boot.lds
/u-boot.ubl
+/u-boot.dtb
#
# Generated files
ifeq ($(CPU),ixp)
LIBS += arch/arm/cpu/ixp/npe/libnpe.o
endif
+ifeq ($(CONFIG_OF_EMBED),y)
+LIBS += dts/libdts.o
+endif
LIBS += arch/$(ARCH)/lib/lib$(ARCH).o
LIBS += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \
fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \
ONENAND_BIN ?= $(obj)onenand_ipl/onenand-ipl-2k.bin
ALL-$(CONFIG_MMC_U_BOOT) += $(obj)mmc_spl/u-boot-mmc-spl.bin
ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin
+ALL-$(CONFIG_OF_SEPARATE) += $(obj)u-boot.dtb $(obj)u-boot-dtb.bin
all: $(ALL-y) $(SUBDIR_EXAMPLES)
+$(obj)u-boot.dtb: $(obj)u-boot
+ $(MAKE) -C dts binary
+ mv $(obj)dts/dt.dtb $@
+
+$(obj)u-boot-dtb.bin: $(obj)u-boot.bin $(obj)u-boot.dtb
+ cat $^ >$@
+
$(obj)u-boot.hex: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@
@rm -f $(obj)u-boot.kwb
@rm -f $(obj)u-boot.imx
@rm -f $(obj)u-boot.ubl
+ @rm -f $(obj)u-boot.dtb
@rm -f $(obj)tools/{env/crc32.c,inca-swap-bytes}
@rm -f $(obj)arch/powerpc/cpu/mpc824x/bedbug_603e.c
@rm -fr $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -name "*" -type l -print | xargs rm -f
@[ ! -d $(obj)onenand_ipl ] || find $(obj)onenand_ipl -name "*" -type l -print | xargs rm -f
@[ ! -d $(obj)mmc_spl ] || find $(obj)mmc_spl -name "*" -type l -print | xargs rm -f
+ @rm -f $(obj)dts/*.tmp
mrproper \
distclean: clobber unconfig
releases in "stable" maintenance trees.
Examples:
- U-Boot v2009.11 - Release November 2009
+ U-Boot v2009.11 - Release November 2009
U-Boot v2009.11.1 - Release 1 in version November 2009 stable tree
U-Boot v2010.09-rc1 - Release candiate 1 for September 2010 release
CONFIG_CMD_NAND * NAND support
CONFIG_CMD_NET bootp, tftpboot, rarpboot
CONFIG_CMD_PCA953X * PCA953x I2C gpio commands
- CONFIG_CMD_PCA953X_INFO * PCA953x I2C gpio info command
+ CONFIG_CMD_PCA953X_INFO * PCA953x I2C gpio info command
CONFIG_CMD_PCI * pciinfo
CONFIG_CMD_PCMCIA * PCMCIA support
CONFIG_CMD_PING * send ICMP ECHO_REQUEST to network
CONFIG_CMD_SOURCE "source" command Support
CONFIG_CMD_SPI * SPI serial bus support
CONFIG_CMD_TFTPSRV * TFTP transfer in server mode
+ CONFIG_CMD_TFTPPUT * TFTP put command (upload)
CONFIG_CMD_TIME * run command and report execution time
CONFIG_CMD_USB * USB support
CONFIG_CMD_CDP * Cisco Discover Protocol support
XXX - this list needs to get updated!
+- Device tree:
+ CONFIG_OF_CONTROL
+ If this variable is defined, U-Boot will use a device tree
+ to configure its devices, instead of relying on statically
+ compiled #defines in the board file. This option is
+ experimental and only available on a few boards. The device
+ tree is available in the global data as gd->fdt_blob.
+
+ U-Boot needs to get its device tree from somewhere. This can
+ be done using one of the two options below:
+
+ CONFIG_OF_EMBED
+ If this variable is defined, U-Boot will embed a device tree
+ binary in its image. This device tree file should be in the
+ board directory and called <soc>-<board>.dts. The binary file
+ is then picked up in board_init_f() and made available through
+ the global data structure as gd->blob.
+
+ CONFIG_OF_SEPARATE
+ If this variable is defined, U-Boot will build a device tree
+ binary. It will be called u-boot.dtb. Architecture-specific
+ code will locate it at run-time. Generally this works by:
+
+ cat u-boot.bin u-boot.dtb >image.bin
+
+ and in fact, U-Boot does this for you, creating a file called
+ u-boot-dtb.bin which is useful in the common case. You can
+ still use the individual files if you need something more
+ exotic.
+
- Watchdog:
CONFIG_WATCHDOG
If this variable is defined, it enables watchdog
to disable the command chpart. This is the default when you
have not defined a custom partition
+- FAT(File Allocation Table) filesystem write function support:
+ CONFIG_FAT_WRITE
+ Support for saving memory data as a file
+ in FAT formatted partition
+
- Keyboard Support:
CONFIG_ISA_KEYBOARD
Define a default value for the IP address to use for
the default Ethernet interface, in case this is not
determined through e.g. bootp.
+ (Environment variable "ipaddr")
- Server IP address:
CONFIG_SERVERIP
Defines a default value for the IP address of a TFTP
server to contact when using the "tftboot" command.
+ (Environment variable "serverip")
CONFIG_KEEP_SERVERADDR
Keeps the server's MAC address, in the env 'serveraddr'
for passing to bootargs (like Linux's netconsole option)
+- Gateway IP address:
+ CONFIG_GATEWAYIP
+
+ Defines a default value for the IP address of the
+ default router where packets to other networks are
+ sent to.
+ (Environment variable "gatewayip")
+
+- Subnet mask:
+ CONFIG_NETMASK
+
+ Defines a default value for the subnet mask (or
+ routing prefix) which is used to determine if an IP
+ address belongs to the local subnet or needs to be
+ forwarded through a router.
+ (Environment variable "netmask")
+
- Multicast TFTP Mode:
CONFIG_MCAST_TFTP
CONFIG_I2C_MULTI_BUS
This option allows the use of multiple I2C buses, each of which
- must have a controller. At any point in time, only one bus is
- active. To switch to a different bus, use the 'i2c dev' command.
+ must have a controller. At any point in time, only one bus is
+ active. To switch to a different bus, use the 'i2c dev' command.
Note that bus numbering is zero-based.
CONFIG_SYS_I2C_NOPROBES
This option specifies a list of I2C devices that will be skipped
- when the 'i2c probe' command is issued. If CONFIG_I2C_MULTI_BUS
+ when the 'i2c probe' command is issued. If CONFIG_I2C_MULTI_BUS
is set, specify a list of bus-device pairs. Otherwise, specify
a 1D array of device addresses
e.g.
#undef CONFIG_I2C_MULTI_BUS
- #define CONFIG_SYS_I2C_NOPROBES {0x50,0x68}
+ #define CONFIG_SYS_I2C_NOPROBES {0x50,0x68}
will skip addresses 0x50 and 0x68 on a board with one I2C bus
- #define CONFIG_I2C_MULTI_BUS
+ #define CONFIG_I2C_MULTI_BUS
#define CONFIG_SYS_I2C_MULTI_NOPROBES {{0,0x50},{0,0x68},{1,0x54}}
will skip addresses 0x50 and 0x68 on bus 0 and address 0x54 on bus 1
Enables a hardware SPI driver for general-purpose reads
and writes. As with CONFIG_SOFT_SPI, the board configuration
must define a list of chip-select function pointers.
- Currently supported on some MPC8xxx processors. For an
+ Currently supported on some MPC8xxx processors. For an
example, see include/configs/mpc8349emds.h.
CONFIG_MXC_SPI
13 common/image.c Start multifile image verification
14 common/image.c No initial ramdisk, no multifile, continue.
- 15 arch/<arch>/lib/bootm.c All preparation done, transferring control to OS
+ 15 arch/<arch>/lib/bootm.c All preparation done, transferring control to OS
-30 arch/powerpc/lib/board.c Fatal error, hang the system
-31 post/post.c POST test failed, detected by post_output_backlog()
See also: doc/README.Modem
+Board initialization settings:
+------------------------------
+
+During Initialization u-boot calls a number of board specific functions
+to allow the preparation of board specific prerequisites, e.g. pin setup
+before drivers are initialized. To enable these callbacks the
+following configuration macros have to be defined. Currently this is
+architecture specific, so please check arch/your_architecture/lib/board.c
+typically in board_init_f() and board_init_r().
+
+- CONFIG_BOARD_EARLY_INIT_F: Call board_early_init_f()
+- CONFIG_BOARD_EARLY_INIT_R: Call board_early_init_r()
+- CONFIG_BOARD_LATE_INIT: Call board_late_init()
+- CONFIG_BOARD_POSTCLK_INIT: Call board_postclk_init()
Configuration Settings:
-----------------------
used) must be put below this limit, unless "bootm_low"
enviroment variable is defined and non-zero. In such case
all data for the Linux kernel must be between "bootm_low"
- and "bootm_low" + CONFIG_SYS_BOOTMAPSZ. The environment
+ and "bootm_low" + CONFIG_SYS_BOOTMAPSZ. The environment
variable "bootm_mapsize" will override the value of
CONFIG_SYS_BOOTMAPSZ. If CONFIG_SYS_BOOTMAPSZ is undefined,
then the value in "bootm_size" will be used instead.
This setting describes a second storage area of CONFIG_ENV_SIZE
size used to hold a redundant copy of the environment data, so
that there is a valid backup copy in case there is a power failure
- during a "saveenv" operation. CONFIG_ENV_OFFSET_RENDUND must be
+ during a "saveenv" operation. CONFIG_ENV_OFFSET_RENDUND must be
aligned to an erase block boundary.
- CONFIG_ENV_RANGE (optional):
- CONFIG_SYS_CCSRBAR_PHYS:
Physical address of CCSR. CCSR can be relocated to a new
physical address, if desired. In this case, this macro should
- be set to that address. Otherwise, it should be set to the
+ be set to that address. Otherwise, it should be set to the
same value as CONFIG_SYS_CCSRBAR_DEFAULT. For example, CCSR
is typically relocated on 36-bit builds. It is recommended
that this macro be defined via the _HIGH and _LOW macros:
tftpboot- boot image via network using TFTP protocol
and env variables "ipaddr" and "serverip"
(and eventually "gatewayip")
+tftpput - upload a file via network using TFTP protocol
rarpboot- boot image via network using RARP/TFTP protocol
diskboot- boot from IDE devicebootd - boot default, i.e., run 'bootcmd'
loads - load S-Record file over serial line
kernel -- see the description of CONFIG_SYS_BOOTMAPSZ and
bootm_mapsize.
- bootm_mapsize - Size of the initial memory mapping for the Linux kernel.
+ bootm_mapsize - Size of the initial memory mapping for the Linux kernel.
This variable is given as a hexadecimal number and it
defines the size of the memory region starting at base
address bootm_low that is accessible by the Linux kernel
add the information it needs into it, and the memory
must be accessible by the kernel.
+ fdtcontroladdr- if set this is the address of the control flattened
+ device tree used by U-Boot when CONFIG_OF_CONTROL is
+ defined.
+
i2cfast - (PPC405GP|PPC405EP only)
if set to 'y' configures Linux I2C driver for fast
mode (400kHZ). This environment variable is used in
boards currenlty use other variables for these purposes, and some
boards use these variables for other purposes.
-Image File Name RAM Address Flash Location
------ --------- ----------- --------------
-u-boot u-boot u-boot_addr_r u-boot_addr
-Linux kernel bootfile kernel_addr_r kernel_addr
-device tree blob fdtfile fdt_addr_r fdt_addr
-ramdisk ramdiskfile ramdisk_addr_r ramdisk_addr
+Image File Name RAM Address Flash Location
+----- --------- ----------- --------------
+u-boot u-boot u-boot_addr_r u-boot_addr
+Linux kernel bootfile kernel_addr_r kernel_addr
+device tree blob fdtfile fdt_addr_r fdt_addr
+ramdisk ramdiskfile ramdisk_addr_r ramdisk_addr
The following environment variables may be used and automatically
updated by the network boot commands ("bootp" and "rarpboot"),
is raised.
If Ethernet drivers implement the 'write_hwaddr' function, valid MAC addresses
-will be programmed into hardware as part of the initialization process. This
+will be programmed into hardware as part of the initialization process. This
may be skipped by setting the appropriate 'ethmacskip' environment variable.
The naming convention is as follows:
"ethmacskip" (=>eth0), "eth1macskip" (=>eth1) etc.
{
clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK,
enable_mode << CD_CLKCTRL_CLKTRCTRL_SHIFT);
- debug("Enable clock domain - 0x%08x\n", clkctrl_reg);
+ debug("Enable clock domain - %p\n", clkctrl_reg);
}
static inline void wait_for_clk_enable(u32 *clkctrl_addr)
{
clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK,
enable_mode << MODULE_CLKCTRL_MODULEMODE_SHIFT);
- debug("Enable clock module - 0x%08x\n", clkctrl_addr);
+ debug("Enable clock module - %p\n", clkctrl_addr);
if (wait_for_enable)
wait_for_clk_enable(clkctrl_addr);
}
u32 reg;
reg = readl(&pmc->pmc_scratch20);
- debug("pmc->pmc_scratch20 (ODMData) = 0x%08lX\n", reg);
+ debug("pmc->pmc_scratch20 (ODMData) = 0x%08x\n", reg);
/* bits 31:28 in OdmData are used for RAM size */
switch ((reg) >> 28) {
#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
unsigned long tlb_addr;
#endif
+ const void *fdt_blob; /* Our device tree, NULL if none */
void **jt; /* jump table */
char env_buf[32]; /* buffer for getenv() before reloc. */
#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
#include <nand.h>
#include <onenand_uboot.h>
#include <mmc.h>
+#include <libfdt.h>
+#include <fdtdec.h>
#include <post.h>
#include <logbuff.h>
#endif
#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f,
+#endif
+#ifdef CONFIG_OF_CONTROL
+ fdtdec_check_fdt,
#endif
timer_init, /* initialize timer */
#ifdef CONFIG_FSL_ESDHC
memset((void *)gd, 0, sizeof(gd_t));
gd->mon_len = _bss_end_ofs;
+#ifdef 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
+ /* Allow the early environment to override the fdt address */
+ gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
+ (uintptr_t)gd->fdt_blob);
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
flash_size = flash_init();
if (flash_size > 0) {
# ifdef CONFIG_SYS_FLASH_CHECKSUM
+ char *s = getenv("flashchecksum");
+
print_size(flash_size, "");
/*
* Compute and print flash CRC if flashchecksum is set to 'y'
*
* NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
*/
- s = getenv("flashchecksum");
if (s && (*s == 'y')) {
printf(" CRC: %08X", crc32(0,
(const unsigned char *) CONFIG_SYS_FLASH_BASE,
/* Initialize from environment */
load_addr = getenv_ulong("loadaddr", 16, load_addr);
#if defined(CONFIG_CMD_NET)
- s = getenv("bootfile");
- if (s != NULL)
- copy_filename(BootFile, s, sizeof(BootFile));
+ {
+ char *s = getenv("bootfile");
+
+ if (s != NULL)
+ copy_filename(BootFile, s, sizeof(BootFile));
+ }
#endif
-#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_BOARD_LATE_INIT
board_late_init();
#endif
if (br_env)
baudrate = simple_strtoul(br_env, NULL, 10);
- debug("%s: idx %d, baudrate %d\n", __func__, idx, baudrate);
+ debug("%s: idx %d, baudrate %ld\n", __func__, idx, baudrate);
}
/* calculate divisor for setting PSC CTUR and CTLR registers */
pic->gcr = MPC86xx_PICGCR_MODE;
*decrementer_count = get_tbclk() / CONFIG_SYS_HZ;
- debug("interrupt init: tbclk() = %d MHz, decrementer_count = %ld\n",
+ debug("interrupt init: tbclk() = %ld MHz, decrementer_count = %ld\n",
(get_tbclk() / 1000000),
*decrementer_count);
#ifdef CONFIG_INTERRUPTS
pic->iivpr1 = 0x810001; /* 50220 enable mcm interrupts */
- debug("iivpr1@%x = %x\n", &pic->iivpr1, pic->iivpr1);
+ debug("iivpr1@%p = %x\n", &pic->iivpr1, pic->iivpr1);
pic->iivpr2 = 0x810002; /* 50240 enable ddr interrupts */
- debug("iivpr2@%x = %x\n", &pic->iivpr2, pic->iivpr2);
+ debug("iivpr2@%p = %x\n", &pic->iivpr2, pic->iivpr2);
pic->iivpr3 = 0x810003; /* 50260 enable lbc interrupts */
- debug("iivpr3@%x = %x\n", &pic->iivpr3, pic->iivpr3);
+ debug("iivpr3@%p = %x\n", &pic->iivpr3, pic->iivpr3);
#if defined(CONFIG_PCI1) || defined(CONFIG_PCIE1)
pic->iivpr8 = 0x810008; /* enable pcie1 interrupts */
- debug("iivpr8@%x = %x\n", &pic->iivpr8, pic->iivpr8);
+ debug("iivpr8@%p = %x\n", &pic->iivpr8, pic->iivpr8);
#endif
#if defined(CONFIG_PCI2) || defined(CONFIG_PCIE2)
pic->iivpr9 = 0x810009; /* enable pcie2 interrupts */
- debug("iivpr9@%x = %x\n", &pic->iivpr9, pic->iivpr9);
+ debug("iivpr9@%p = %x\n", &pic->iivpr9, pic->iivpr9);
#endif
pic->ctpr = 0; /* 40080 clear current task priority register */
/* Bottom 2 bits up to the top. */
bsize = ((row_dens >> 2) | ((row_dens & 3) << 6));
bsize <<= 24ULL;
- debug("DDR: DDR I rank density = 0x%08x\n", bsize);
+ debug("DDR: DDR I rank density = 0x%16llx\n", bsize);
return bsize;
}
/* Bottom 5 bits up to the top. */
bsize = ((row_dens >> 5) | ((row_dens & 31) << 3));
bsize <<= 27ULL;
- debug("DDR: DDR II rank density = 0x%08x\n", bsize);
+ debug("DDR: DDR II rank density = 0x%16llx\n", bsize);
return bsize;
}
bsize = 1ULL << (nbit_sdram_cap_bsize - 3
+ nbit_primary_bus_width - nbit_sdram_width);
- debug("DDR: DDR III rank density = 0x%16lx\n", bsize);
+ debug("DDR: DDR III rank density = 0x%16llx\n", bsize);
return bsize;
}
break;
}
- debug("tr0: %x\n", tr0);
+ debug("tr0: %lx\n", tr0);
mtsdram(SDRAM0_TR0, tr0);
}
}
tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average);
- debug("tr1: %x\n", tr1);
+ debug("tr1: %lx\n", tr1);
/*
* program SDRAM Timing Register 1 TR1
num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4);
num_banks = spd_read(iic0_dimm_addr[dimm_num], 5);
bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31);
- debug("DIMM%d: row=%d col=%d banks=%d\n", dimm_num,
+ debug("DIMM%ld: row=%d col=%d banks=%d\n", dimm_num,
num_row_addr, num_col_addr, num_banks);
/*
bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes =
(4 << 20) * bank_size_id;
bank_parms[ctrl_bank_num[dimm_num]+i].cr = cr;
- debug("DIMM%d-bank %d (SDRAM0_B%dCR): bank_size_bytes=%d\n",
- dimm_num, i, ctrl_bank_num[dimm_num]+i,
- bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes);
+ debug("DIMM%ld-bank %ld (SDRAM0_B%ldCR): "
+ "bank_size_bytes=%ld\n",
+ dimm_num, i,
+ ctrl_bank_num[dimm_num] + i,
+ bank_parms[ctrl_bank_num[dimm_num] + i].bank_size_bytes);
}
}
}
bank_parms[sorted_bank_num[bx_cr_num]].cr;
mtdcr(SDRAM0_CFGDATA, temp);
bank_base_addr += bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes;
- debug("SDRAM0_B%dCR=0x%08lx\n", sorted_bank_num[bx_cr_num], temp);
+ debug("SDRAM0_B%ldCR=0x%08lx\n",
+ sorted_bank_num[bx_cr_num], temp);
}
}
mtsdram(SDRAM_RQDC, rqdc_reg);
mtsdram(SDRAM_RFDC, rfdc_reg);
- debug("RQDC: 0x%08X\n", rqdc_reg);
- debug("RFDC: 0x%08X\n", rfdc_reg);
+ debug("RQDC: 0x%08lX\n", rqdc_reg);
+ debug("RFDC: 0x%08lX\n", rfdc_reg);
/* if something passed, then return the size of the largest window */
if (passed != 0) {
SDRAM_RQDC_RQFD_ENCODE(tcal.autocal.rqfd));
mfsdram(SDRAM_RQDC, rqdc_reg);
- debug("*** best_result: read value SDRAM_RQDC 0x%08x\n",
+ debug("*** best_result: read value SDRAM_RQDC 0x%08lx\n",
rqdc_reg);
#if defined(CONFIG_DDR_RFDC_FIXED)
#endif /* CONFIG_DDR_RFDC_FIXED */
mfsdram(SDRAM_RFDC, rfdc_reg);
- debug("*** best_result: read value SDRAM_RFDC 0x%08x\n",
+ debug("*** best_result: read value SDRAM_RFDC 0x%08lx\n",
rfdc_reg);
mfsdram(SDRAM_RDCC, val);
debug("*** SDRAM_RDCC 0x%08x\n", val);
*/
pcie_dmer_disable ();
- debug("%s: cfg_data=%08x offset=%08x\n", __func__, hose->cfg_data, offset);
+ debug("%s: cfg_data=%p offset=%08x\n", __func__,
+ hose->cfg_data, offset);
switch (len) {
case 1:
*val = in_8(hose->cfg_data + offset);
val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK)
| DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
mtdcr(ddrcfgd, val);
- debug("DDR0_09=0x%08lx\n", val);
+ debug("DDR0_09=0x%08x\n", val);
/* -----------------------------------------------------------+
* Set 'dqs_out_shift' = wr_dqs_shift + 32
val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK)
| DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
mtdcr(ddrcfgd, val);
- debug("DDR0_22=0x%08lx\n", val);
+ debug("DDR0_22=0x%08x\n", val);
/* -----------------------------------------------------------+
* Set 'dll_dqs_delay_X'.
val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
| DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
mtdcr(ddrcfgd, val);
- debug("DDR0_17=0x%08lx\n", val);
+ debug("DDR0_17=0x%08x\n", val);
/* dll_dqs_delay_1 to dll_dqs_delay_4 */
mtdcr(ddrcfga, DDR0_18);
| DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
| DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
mtdcr(ddrcfgd, val);
- debug("DDR0_18=0x%08lx\n", val);
+ debug("DDR0_18=0x%08x\n", val);
/* dll_dqs_delay_5 to dll_dqs_delay_8 */
mtdcr(ddrcfga, DDR0_19);
| DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
| DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
mtdcr(ddrcfgd, val);
- debug("DDR0_19=0x%08lx\n", val);
+ debug("DDR0_19=0x%08x\n", val);
/* -----------------------------------------------------------+
* Assert 'start' parameter.
printf("Install at least one DDR2 DIMM.\n\n");
spd_ddr_init_hang();
}
- debug("Total number of ranks = %d\n", *ranks);
+ debug("Total number of ranks = %ld\n", *ranks);
}
/*------------------------------------------------------------------
if (dimm_ranks[dimm_num]) {
cycle_time =
get_tcyc(spd_read(iic0_dimm_addr[dimm_num], 9));
- debug("cycle_time=%d ps\n", cycle_time);
+ debug("cycle_time=%ld ps\n", cycle_time);
if (cycle_time > (calc_cycle_time + 10)) {
/*
}
}
}
- debug("Number of rows = %d\n", *rows);
- debug("Number of columns = %d\n", *cols);
- debug("Number of banks = %d\n", *banks);
- debug("Data width = %d\n", *width);
+ debug("Number of rows = %ld\n", *rows);
+ debug("Number of columns = %ld\n", *cols);
+ debug("Number of banks = %ld\n", *banks);
+ debug("Data width = %ld\n", *width);
if (*rows > 14) {
printf("ERROR: DRAM DIMM modules have %lu address rows.\n",
*rows);
/*------------------------------------------------------------------
* Get the board configuration info.
*-----------------------------------------------------------------*/
- debug("sdram_freq = %d\n", sdram_freq);
+ debug("sdram_freq = %ld\n", sdram_freq);
/*------------------------------------------------------------------
* Handle the timing. We need to find the worst case timing of all
get_tcyc(spd_read(iic0_dimm_addr[dimm_num],
tcyc_addr[cas_index]));
- debug("cas_index = %d: cycle_time_ps = %d\n",
+ debug("cas_index = %ld: cycle_time_ps = %ld\n",
cas_index, cycle_time_ps);
/*
* DDR2 devices use the following bitmask for CAS latency:
cycle_3_0_clk = MULDIV64(ONE_BILLION, 1000, max_3_0_tcyc_ps) + 10;
cycle_4_0_clk = MULDIV64(ONE_BILLION, 1000, max_4_0_tcyc_ps) + 10;
cycle_5_0_clk = MULDIV64(ONE_BILLION, 1000, max_5_0_tcyc_ps) + 10;
- debug("cycle_2_0_clk = %d\n", cycle_2_0_clk);
- debug("cycle_3_0_clk = %d\n", cycle_3_0_clk);
- debug("cycle_4_0_clk = %d\n", cycle_4_0_clk);
- debug("cycle_5_0_clk = %d\n", cycle_5_0_clk);
+ debug("cycle_2_0_clk = %ld\n", cycle_2_0_clk);
+ debug("cycle_3_0_clk = %ld\n", cycle_3_0_clk);
+ debug("cycle_4_0_clk = %ld\n", cycle_4_0_clk);
+ debug("cycle_5_0_clk = %ld\n", cycle_5_0_clk);
if ((cas_available & 0x04) && (sdram_freq <= cycle_2_0_clk)) {
*cas_latency = 2;
cycle_3_0_clk, cycle_4_0_clk, cycle_5_0_clk);
spd_ddr_init_hang();
}
- debug("CAS latency = %d\n", *cas_latency);
+ debug("CAS latency = %ld\n", *cas_latency);
mtsdram(DDR0_03, ddr0_03);
}
t_rtp_ps = max(t_rtp_ps, ps);
}
}
- debug("t_rc_ps = %d\n", t_rc_ps);
+ debug("t_rc_ps = %ld\n", t_rc_ps);
t_rc_clk = (MULDIV64(sdram_freq, t_rc_ps, ONE_BILLION) + 999) / 1000;
- debug("t_rrd_ps = %d\n", t_rrd_ps);
+ debug("t_rrd_ps = %ld\n", t_rrd_ps);
t_rrd_clk = (MULDIV64(sdram_freq, t_rrd_ps, ONE_BILLION) + 999) / 1000;
- debug("t_rtp_ps = %d\n", t_rtp_ps);
+ debug("t_rtp_ps = %ld\n", t_rtp_ps);
t_rtp_clk = (MULDIV64(sdram_freq, t_rtp_ps, ONE_BILLION) + 999) / 1000;
mtsdram(DDR0_04, DDR0_04_TRC_ENCODE(t_rc_clk) |
DDR0_04_TRRD_ENCODE(t_rrd_clk) |
t_ras_ps = max(t_ras_ps, ps);
}
}
- debug("t_rp_ps = %d\n", t_rp_ps);
+ debug("t_rp_ps = %ld\n", t_rp_ps);
t_rp_clk = (MULDIV64(sdram_freq, t_rp_ps, ONE_BILLION) + 999) / 1000;
- debug("t_ras_ps = %d\n", t_ras_ps);
+ debug("t_ras_ps = %ld\n", t_ras_ps);
t_ras_clk = (MULDIV64(sdram_freq, t_ras_ps, ONE_BILLION) + 999) / 1000;
mtsdram(DDR0_05, ddr0_05 | DDR0_05_TRP_ENCODE(t_rp_clk) |
DDR0_05_TRAS_MIN_ENCODE(t_ras_clk));
t_rfc_ps = max(t_rfc_ps, ps);
}
}
- debug("t_wtr_ps = %d\n", t_wtr_ps);
+ debug("t_wtr_ps = %ld\n", t_wtr_ps);
t_wtr_clk = (MULDIV64(sdram_freq, t_wtr_ps, ONE_BILLION) + 999) / 1000;
- debug("t_rfc_ps = %d\n", t_rfc_ps);
+ debug("t_rfc_ps = %ld\n", t_rfc_ps);
t_rfc_clk = (MULDIV64(sdram_freq, t_rfc_ps, ONE_BILLION) + 999) / 1000;
mtsdram(DDR0_06, ddr0_06 | DDR0_06_TWTR_ENCODE(t_wtr_clk) |
DDR0_06_TRFC_ENCODE(t_rfc_clk));
unsigned long const t_xsnr_ps = 200000; /* 200 ns */
unsigned long t_xsnr_clk;
- debug("t_xsnr_ps = %d\n", t_xsnr_ps);
+ debug("t_xsnr_ps = %ld\n", t_xsnr_ps);
t_xsnr_clk =
(MULDIV64(sdram_freq, t_xsnr_ps, ONE_BILLION) + 999) / 1000;
mtsdram(DDR0_11, DDR0_11_SREFRESH_ENCODE(0) |
unsigned long t_ref_clk;
/* Round down t_ras_max_clk and t_ref_clk */
- debug("t_ras_max_ps = %d\n", t_ras_max_ps);
+ debug("t_ras_max_ps = %ld\n", t_ras_max_ps);
t_ras_max_clk = MULDIV64(sdram_freq, t_ras_max_ps, ONE_BILLION) / 1000;
- debug("t_ref_ps = %d\n", t_ref_ps);
+ debug("t_ref_ps = %ld\n", t_ref_ps);
t_ref_clk = MULDIV64(sdram_freq, t_ref_ps, ONE_BILLION) / 1000;
mtsdram(DDR0_26, DDR0_26_TRAS_MAX_ENCODE(t_ras_max_clk) |
DDR0_26_TREF_ENCODE(t_ref_clk));
unsigned long const t_init_ps = 200000000; /* 200 us. init */
unsigned long t_init_clk;
- debug("t_init_ps = %d\n", t_init_ps);
+ debug("t_init_ps = %ld\n", t_init_ps);
t_init_clk =
(MULDIV64(sdram_freq, t_init_ps, ONE_BILLION) + 999) / 1000;
mtsdram(DDR0_27, DDR0_27_EMRS_DATA_ENCODE(0x0000) |
t_wr_ps = max(t_wr_ps, ps);
}
}
- debug("t_wr_ps = %d\n", t_wr_ps);
+ debug("t_wr_ps = %ld\n", t_wr_ps);
t_wr_clk = (MULDIV64(sdram_freq, t_wr_ps, ONE_BILLION) + 999) / 1000;
mtsdram(DDR0_43, ddr0_43 | DDR0_43_TWR_ENCODE(t_wr_clk));
}
t_rcd_ps = max(t_rcd_ps, ps);
}
}
- debug("t_rcd_ps = %d\n", t_rcd_ps);
+ debug("t_rcd_ps = %ld\n", t_rcd_ps);
t_rcd_clk = (MULDIV64(sdram_freq, t_rcd_ps, ONE_BILLION) + 999) / 1000;
mtsdram(DDR0_44, DDR0_44_TRCD_ENCODE(t_rcd_clk));
}
*/
void board_init_r (gd_t *id, ulong dest_addr)
{
- char *s;
bd_t *bd;
ulong malloc_start;
flash_size = 0;
} else if ((flash_size = flash_init ()) > 0) {
# ifdef CONFIG_SYS_FLASH_CHECKSUM
+ char *s;
+
print_size (flash_size, "");
/*
* Compute and print flash CRC if flashchecksum is set to 'y'
/* Initialize from environment */
load_addr = getenv_ulong("loadaddr", 16, load_addr);
#if defined(CONFIG_CMD_NET)
- if ((s = getenv ("bootfile")) != NULL) {
- copy_filename (BootFile, s, sizeof (BootFile));
+ {
+ char *s = getenv("bootfile");
+
+ if (s != NULL)
+ copy_filename(BootFile, s, sizeof(BootFile));
}
#endif
/* enable exceptions */
enable_interrupts();
-#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_BOARD_LATE_INIT
board_late_init();
#endif
stdio_init,
console_init_r,
interrupt_init,
-#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_BOARD_LATE_INIT
board_late_init,
#endif
#if defined(CONFIG_CMD_NET)
#define ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port) (0x3500 + (port<<10))
#define ETH_DA_FILTER_UNICAST_TABLE_BASE(port) (0x3600 + (port<<10))
+/* Compat with interrupts.c */
+#define ETHERNET0_INTERRUPT_CAUSE_REGISTER ETH_INTERRUPT_CAUSE_REG(0)
+#define ETHERNET1_INTERRUPT_CAUSE_REGISTER ETH_INTERRUPT_CAUSE_REG(1)
+#define ETHERNET2_INTERRUPT_CAUSE_REGISTER ETH_INTERRUPT_CAUSE_REG(2)
+
+#define ETHERNET0_INTERRUPT_MASK_REGISTER ETH_INTERRUPT_MASK_REG(0)
+#define ETHERNET1_INTERRUPT_MASK_REGISTER ETH_INTERRUPT_MASK_REG(1)
+#define ETHERNET2_INTERRUPT_MASK_REGISTER ETH_INTERRUPT_MASK_REG(2)
/* Ethernet GT64260 */
/*
rc += altera_tse_initialize(0,
CONFIG_SYS_ALTERA_TSE_MAC_BASE,
CONFIG_SYS_ALTERA_TSE_SGDMA_RX_BASE,
- CONFIG_SYS_ALTERA_TSE_SGDMA_TX_BASE);
+ CONFIG_SYS_ALTERA_TSE_SGDMA_TX_BASE,
+#if defined(CONFIG_SYS_ALTERA_TSE_SGDMA_DESC_BASE) && \
+ (CONFIG_SYS_ALTERA_TSE_SGDMA_DESC_SIZE > 0)
+ CONFIG_SYS_ALTERA_TSE_SGDMA_DESC_BASE,
+ CONFIG_SYS_ALTERA_TSE_SGDMA_DESC_SIZE);
+#else
+ 0,
+ 0);
+#endif
#endif
#ifdef CONFIG_ETHOC
rc += ethoc_initialize(0, CONFIG_SYS_ETHOC_BASE);
{
cirrus_state_t *p = &s->c_state;
u_int mask = 0xffff;
-#if DEBUG
- char buf[200];
-
- memset (buf, 0, 200);
-#endif
+ char buf[200] = {0};
if (has_ring == -1)
has_ring = 1;
int size_val = 0;
debug("[%s, %d] Entering ...\n", __FUNCTION__, __LINE__);
- debug("[%s, %d] flash_info = 0x%08X ...\n", __FUNCTION__, __LINE__, flash_info);
+ debug("[%s, %d] flash_info = 0x%p ...\n", __func__, __LINE__,
+ flash_info);
/* Init: no FLASHes known */
for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
*/
param = base - (pram << 10);
printf("PARAM: @%08x\n", param);
- debug("memsize=0x%08x, base=0x%08x\n", gd->bd->bi_memsize, base);
+ debug("memsize=0x%08x, base=0x%08x\n", (u32)gd->bd->bi_memsize, base);
/* clear entire PA ram */
memset((void*)param, 0, (pram << 10));
*/
param = base - (pram << 10);
printf("PARAM: @%08x\n", param);
- debug("memsize=0x%08x, base=0x%08x\n", gd->bd->bi_memsize, base);
+ debug("memsize=0x%08x, base=0x%08x\n", (u32)gd->bd->bi_memsize, base);
/* clear entire PA ram */
memset((void*)param, 0, (pram << 10));
/* Verify if enabled */
tmp_val = 0;
i2c_read(0x38, 0x08, 1, &tmp_val, sizeof(tmp_val));
- debug("DVI Encoder Read: 0x%02lx\n", tmp_val);
+ debug("DVI Encoder Read: 0x%02x\n", tmp_val);
tmp_val = 0x10;
i2c_write(0x38, 0x0A, 1, &tmp_val, sizeof(tmp_val));
/* Verify if enabled */
tmp_val = 0;
i2c_read(0x38, 0x0A, 1, &tmp_val, sizeof(tmp_val));
- debug("DVI Encoder Read: 0x%02lx\n", tmp_val);
+ debug("DVI Encoder Read: 0x%02x\n", tmp_val);
return 0;
}
/* Verify if enabled */
tmp_val = 0;
i2c_read(0x38, 0x08, 1, &tmp_val, sizeof(tmp_val));
- debug("DVI Encoder Read: 0x%02lx\n",tmp_val);
+ debug("DVI Encoder Read: 0x%02x\n", tmp_val);
tmp_val = 0x10;
i2c_write(0x38, 0x0A, 1, &tmp_val, sizeof(tmp_val));
/* Verify if enabled */
tmp_val = 0;
i2c_read(0x38, 0x0A, 1, &tmp_val, sizeof(tmp_val));
- debug("DVI Encoder Read: 0x%02lx\n",tmp_val);
+ debug("DVI Encoder Read: 0x%02x\n", tmp_val);
return 0;
}
#include <asm/arch/sys_proto.h>
#include <netdev.h>
-#ifndef BOARD_LATE_INIT
-#error "BOARD_LATE_INIT must be set for this board"
+#ifndef CONFIG_BOARD_LATE_INIT
+#error "CONFIG_BOARD_LATE_INIT must be set for this board"
#endif
#ifndef CONFIG_BOARD_EARLY_INIT_F
return 0;
}
-#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_BOARD_LATE_INIT
int board_late_init(void)
{
#ifdef CONFIG_MXC_SPI
temp = 1000000000 / pixclock;
temp *= 1000;
pixval = speed_ccb / temp;
- debug("DIU pixval = %lu\n", pixval);
+ debug("DIU pixval = %u\n", pixval);
/* Modify PXCLK in GUTS CLKDVDR */
temp = in_be32(&gur->clkdvdr) & 0x2000FFFF;
load_addr = simple_strtoul (argv[3], NULL, 16);
NetBootFileXferSize = 0;
- if (NetLoop (TFTP) <= 0) {
+ if (NetLoop(TFTPGET) <= 0) {
printf ("tftp transfer failed - aborting "
"fgpa load\n");
return 1;
load_addr = addr;
NetBootFileXferSize = 0;
- if (NetLoop (TFTP) == 0) {
+ if (NetLoop(TFTPGET) == 0) {
printf ("tftp transfer of file '%s' failed\n", fn);
return (0);
}
return 0;
}
-#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_BOARD_LATE_INIT
int board_late_init(void)
{
#ifdef CONFIG_S6E63D6
}
#endif
-#if defined(CONFIG_POST)
-
-#define KM_POST_EN_L 44
-
-int post_hotkeys_pressed(void)
-{
- return !kw_gpio_get_value(KM_POST_EN_L);
-}
-
-ulong post_word_load(void)
-{
- volatile void* addr = (void *) (gd->ram_size - BOOTCOUNT_ADDR + 4);
- return in_le32(addr);
-
-}
-void post_word_store(ulong value)
-{
- volatile void* addr = (void *) (gd->ram_size - BOOTCOUNT_ADDR + 4);
- out_le32(addr, value);
-}
-
-int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
-{
- *vstart = CONFIG_SYS_SDRAM_BASE;
-
- /* we go up to relocation plus a 1 MB margin */
- *size = CONFIG_SYS_TEXT_BASE - (1<<20);
-
- return 0;
-}
-#endif
-
#if defined(CONFIG_SYS_EEPROM_WREN)
int eeprom_write_enable(unsigned dev_addr, int state)
{
value = addr[0];
- debug ("Manuf. ID @ 0x%08lx: 0x%08lx\n", (ulong)addr, value);
+ debug("Manuf. ID @ 0x%08lx: 0x%08x\n", (ulong)addr, value);
switch (value) {
case (FPW) INTEL_MANUFACT:
value = addr[1]; /* device ID */
- debug ("Device ID @ 0x%08lx: 0x%08lx\n", (ulong)(&addr[1]), value);
+ debug("Device ID @ 0x%08lx: 0x%08x\n", (ulong)(&addr[1]), value);
switch (value) {
case (FPW) INTEL_ID_28F320J3A:
HPI_HPIA_1 = addr1;
HPI_HPIA_2 = addr2;
- debugX(4, "writing from data=0x%lx to 0x%lx\n",
+ debug("writing from data=0x%lx to 0x%lx\n",
(ulong)data, (ulong)(data+count));
for(i=0; i<count; i++) {
HPI_HPID_INC_1 = (u16) ((data[i] >> 16) & 0xffff);
HPI_HPID_INC_2 = (u16) (data[i] & 0xffff);
- debugX(4, "hpi_write_inc: data1=0x%x, data2=0x%x\n",
+ debug("hpi_write_inc: data1=0x%x, data2=0x%x\n",
(u16) ((data[i] >> 16) & 0xffff),
(u16) (data[i] & 0xffff));
}
for(i=0; i<count; i++) {
data1 = HPI_HPID_INC_1;
data2 = HPI_HPID_INC_2;
- debugX(4, "hpi_read_inc: data1=0x%x, data2=0x%x\n", data1, data2);
+ debug("hpi_read_inc: data1=0x%x, data2=0x%x\n", data1, data2);
buf[i] = (((u32) data1) << 16) | (data2 & 0xffff);
}
u32 test_data[HPI_TEST_CHUNKSIZE];
u32 read_data[HPI_TEST_CHUNKSIZE];
- debugX(2, "hpi_test: activating hpi...");
+ debug("hpi_test: activating hpi...");
hpi_activate();
- debugX(2, "OK.\n");
+ debug("OK.\n");
#if 0
/* Dump the first 1024 bytes
/* HPIA read-write test
*
*/
- debugX(1, "hpi_test: starting HPIA read-write tests...\n");
+ debug("hpi_test: starting HPIA read-write tests...\n");
err |= hpi_write_addr_test(0xdeadc0de);
err |= hpi_write_addr_test(0xbeefd00d);
err |= hpi_write_addr_test(0xabcd1234);
err |= hpi_write_addr_test(0xaaaaaaaa);
if(err) {
- debugX(1, "hpi_test: HPIA read-write tests: *** FAILED ***\n");
+ debug("hpi_test: HPIA read-write tests: *** FAILED ***\n");
return -1;
}
- debugX(1, "hpi_test: HPIA read-write tests: OK\n");
+ debug("hpi_test: HPIA read-write tests: OK\n");
/* read write test using nonincremental data regs
*
*/
- debugX(1, "hpi_test: starting nonincremental tests...\n");
+ debug("hpi_test: starting nonincremental tests...\n");
for(i=HPI_TEST_START; i<HPI_TEST_END; i+=4) {
err |= hpi_read_write_test(i, pattern);
err |= hpi_read_write_test(i, pattern);
if(err) {
- debugX(1, "hpi_test: nonincremental tests *** FAILED ***\n");
+ debug("hpi_test: nonincremental tests *** FAILED ***\n");
return -1;
}
}
- debugX(1, "hpi_test: nonincremental test OK\n");
+ debug("hpi_test: nonincremental test OK\n");
/* read write a chunk of data using nonincremental data regs
*
*/
- debugX(1, "hpi_test: starting nonincremental chunk tests...\n");
+ debug("hpi_test: starting nonincremental chunk tests...\n");
pattern = HPI_TEST_PATTERN;
for(i=HPI_TEST_START; i<HPI_TEST_END; i+=4) {
hpi_write_noinc(i, pattern);
tmp = hpi_read_noinc(i);
if(tmp != pattern) {
- debugX(1, "hpi_test: noninc chunk test *** FAILED *** @ 0x%x, written=0x%x, read=0x%x\n", i, pattern, tmp);
+ debug("hpi_test: noninc chunk test *** FAILED *** @ 0x%x, written=0x%x, read=0x%x\n", i, pattern, tmp);
err = -1;
}
/* stolen from cmd_mem.c */
}
if(err)
return -1;
- debugX(1, "hpi_test: nonincremental chunk test OK\n");
+ debug("hpi_test: nonincremental chunk test OK\n");
#ifdef DO_TINY_TEST
/* small verbose test using autoinc and nonautoinc to compare
*
*/
- debugX(1, "hpi_test: tiny_autoinc_test...\n");
+ debug("hpi_test: tiny_autoinc_test...\n");
hpi_tiny_autoinc_test();
- debugX(1, "hpi_test: tiny_autoinc_test done\n");
+ debug("hpi_test: tiny_autoinc_test done\n");
#endif /* DO_TINY_TEST */
/* $%& write a chunk of data using the autoincremental regs
*
*/
- debugX(1, "hpi_test: starting autoinc test %d chunks with 0x%x bytes...\n",
+ debug("hpi_test: starting autoinc test %d chunks with 0x%x bytes...\n",
((HPI_TEST_END - HPI_TEST_START) / HPI_TEST_CHUNKSIZE),
HPI_TEST_CHUNKSIZE);
i < ((HPI_TEST_END - HPI_TEST_START) / HPI_TEST_CHUNKSIZE);
i++) {
/* generate the pattern data */
- debugX(3, "generating pattern data: ");
+ debug("generating pattern data: ");
for(ii = 0; ii < HPI_TEST_CHUNKSIZE; ii++) {
- debugX(3, "0x%x ", pattern);
+ debug("0x%x ", pattern);
test_data[ii] = pattern;
read_data[ii] = 0x0; /* zero to be sure */
pattern = ~pattern;
}
}
- debugX(3, "done\n");
+ debug("done\n");
- debugX(2, "Writing autoinc data @ 0x%x\n", i);
+ debug("Writing autoinc data @ 0x%x\n", i);
hpi_write_inc(i, test_data, HPI_TEST_CHUNKSIZE);
- debugX(2, "Reading autoinc data @ 0x%x\n", i);
+ debug("Reading autoinc data @ 0x%x\n", i);
hpi_read_inc(i, read_data, HPI_TEST_CHUNKSIZE);
/* compare */
for(ii = 0; ii < HPI_TEST_CHUNKSIZE; ii++) {
- debugX(3, "hpi_test_autoinc: @ 0x%x, written=0x%x, read=0x%x", i+ii, test_data[ii], read_data[ii]);
+ debug("hpi_test_autoinc: @ 0x%x, written=0x%x, read=0x%x", i+ii, test_data[ii], read_data[ii]);
if(read_data[ii] != test_data[ii]) {
- debugX(0, "hpi_test: autoinc test @ 0x%x, written=0x%x, read=0x%x *** FAILED ***\n", i+ii, test_data[ii], read_data[ii]);
+ debug("hpi_test: autoinc test @ 0x%x, written=0x%x, read=0x%x *** FAILED ***\n", i+ii, test_data[ii], read_data[ii]);
return -1;
}
}
}
- debugX(1, "hpi_test: autoinc test OK\n");
+ debug("hpi_test: autoinc test OK\n");
return 0;
}
0x0009000a, 0x000b000c, 0x000d000e, 0x000f0001
};
- debugX(0, "hpi_test: activating hpi...");
+ debug("hpi_test: activating hpi...");
hpi_activate();
- debugX(0, "OK.\n");
+ debug("OK.\n");
while(1) {
led9(1);
- debugX(0, " writing to autoinc...\n");
+ debug(" writing to autoinc...\n");
hpi_write_inc(TINY_AUTOINC_BASE_ADDR,
dummy_data, TINY_AUTOINC_DATA_SIZE);
- debugX(0, " reading from autoinc...\n");
+ debug(" reading from autoinc...\n");
hpi_read_inc(TINY_AUTOINC_BASE_ADDR,
read_data, TINY_AUTOINC_DATA_SIZE);
for(i=0; i < (TINY_AUTOINC_DATA_SIZE); i++) {
- debugX(0, " written=0x%x, read(inc)=0x%x\n",
+ debug(" written=0x%x, read(inc)=0x%x\n",
dummy_data[i], read_data[i]);
}
led9(0);
read_back = (((u32) HPI_HPIA_1)<<16) | ((u32) HPI_HPIA_2);
if(read_back == addr) {
- debugX(2, " hpi_write_addr_test OK: written=0x%x, read=0x%x\n",
+ debug(" hpi_write_addr_test OK: written=0x%x, read=0x%x\n",
addr, read_back);
return 0;
} else {
- debugX(0, " hpi_write_addr_test *** FAILED ***: written=0x%x, read=0x%x\n",
+ debug(" hpi_write_addr_test *** FAILED ***: written=0x%x, read=0x%x\n",
addr, read_back);
return -1;
}
read_back = hpi_read_noinc(addr);
if(read_back == data) {
- debugX(2, " hpi_read_write_test: OK, addr=0x%x written=0x%x, read=0x%x\n", addr, data, read_back);
+ debug(" hpi_read_write_test: OK, addr=0x%x written=0x%x, read=0x%x\n", addr, data, read_back);
return 0;
} else {
- debugX(0, " hpi_read_write_test: *** FAILED ***, addr=0x%x written=0x%x, read=0x%x\n", addr, data, read_back);
+ debug(" hpi_read_write_test: *** FAILED ***, addr=0x%x written=0x%x, read=0x%x\n", addr, data, read_back);
return -1;
}
0xA03FE024, 0x00000000 /* USB */
};
-#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_BOARD_LATE_INIT
#ifdef CONFIG_MMC
#define LDO_VAUX3_MASK 0x3
return 0;
}
-#endif /* BOARD_LATE_INIT */
+#endif /* CONFIG_BOARD_LATE_INIT */
static void early_gpio_setup(struct gpio_register *gpio_reg, u32 bits)
{
(long *)(CONFIG_SYS_DDR_BASE + size));
size += bank_size;
- debug("DDR Bank%d size: %d MiB\n\n", cs, bank_size >> 20);
+ debug("DDR Bank%d size: %ld MiB\n\n", cs, bank_size >> 20);
/* exit if less than one bank */
if(size < DDR_MAX_SIZE_PER_CS) break;
*/
static void set_cs_bounds(short cs, long base, long size)
{
- debug("Setting bounds %08x, %08x for cs %d\n", base, size, cs);
+ debug("Setting bounds %08lx, %08lx for cs %d\n", base, size, cs);
if(size == 0){
im->ddr.csbnds[cs].csbnds = 0x00000000;
} else {
*/
static void set_cs_config(short cs, long config)
{
- debug("Setting config %08x for cs %d\n", config, cs);
+ debug("Setting config %08lx for cs %d\n", config, cs);
im->ddr.cs_config[cs] = config;
SYNC;
}
/* Check to see if we need to tftp the image ourselves before starting */
if ((argc == 2) && (strcmp (argv[1], "tftp") == 0)) {
- if (NetLoop (TFTP) <= 0)
+ if (NetLoop(TFTPGET) <= 0)
return 1;
- printf ("Automatic boot of VxWorks image at address 0x%08lx ... \n",
- addr);
+ printf("Automatic boot of VxWorks image at address 0x%08lx "
+ "...\n", addr);
}
#endif
lba48 = 1;
}
#endif
- debug ("ide_read dev %d start %LX, blocks %lX buffer at %lX\n",
+ debug("ide_read dev %d start %lX, blocks %lX buffer at %lX\n",
device, blknr, blkcnt, (ulong)buffer);
ide_led (DEVICE_LED(device), 1); /* LED on */
const char *mtd_id;
unsigned int mtd_id_len;
const char *p;
-#ifdef DEBUG
const char *pend;
-#endif
LIST_HEAD(tmp_list);
struct list_head *entry, *n;
u16 num_parts;
#include <command.h>
#include <net.h>
-static int netboot_common (proto_t, cmd_tbl_t *, int , char * const []);
+static int netboot_common(enum proto_t, cmd_tbl_t *, int, char * const []);
int do_bootp (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- return netboot_common (TFTP, cmdtp, argc, argv);
+ return netboot_common(TFTPGET, cmdtp, argc, argv);
}
U_BOOT_CMD(
"[loadAddress] [[hostIPaddr:]bootfilename]"
);
+#ifdef CONFIG_CMD_TFTPPUT
+int do_tftpput(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int ret;
+
+ ret = netboot_common(TFTPPUT, cmdtp, argc, argv);
+ return ret;
+}
+
+U_BOOT_CMD(
+ tftpput, 4, 1, do_tftpput,
+ "TFTP put command, for uploading files to a server",
+ "Address Size [[hostIPaddr:]filename]"
+);
+#endif
+
#ifdef CONFIG_CMD_TFTPSRV
static int do_tftpsrv(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
#endif
}
-static int
-netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char * const argv[])
+static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
+ char * const argv[])
{
char *s;
char *end;
break;
+#ifdef CONFIG_CMD_TFTPPUT
+ case 4:
+ save_addr = strict_strtoul(argv[1], NULL, 16);
+ save_size = strict_strtoul(argv[2], NULL, 16);
+ copy_filename(BootFile, argv[3], sizeof(BootFile));
+ break;
+#endif
default:
show_boot_progress (-80);
return cmd_usage(cmdtp);
#define MAX_ENV_SIZE (1 << 20) /* 1 MiB */
ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */
+ulong save_addr; /* Default Save Address */
+ulong save_size; /* Default Save Size (in bytes) */
/*
* Table with supported baudrates (defined in config_xyz.h)
return _do_env_set(0, 3, (char * const *)argv);
}
+/**
+ * Set an environment variable to an integer value
+ *
+ * @param varname Environmet variable to set
+ * @param value Value to set it to
+ * @return 0 if ok, 1 on error
+ */
+int setenv_ulong(const char *varname, ulong value)
+{
+ /* TODO: this should be unsigned */
+ char *str = simple_itoa(value);
+
+ return setenv(varname, str);
+}
+
+/**
+ * Set an environment variable to an address in hex
+ *
+ * @param varname Environmet variable to set
+ * @param addr Value to set it to
+ * @return 0 if ok, 1 on error
+ */
+int setenv_addr(const char *varname, const void *addr)
+{
+ char str[17];
+
+ sprintf(str, "%x", (uintptr_t)addr);
+ return setenv(varname, str);
+}
+
int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
if (argc < 2)
* Erik W. Troan, which they placed in the public domain. I don't know
* how much of the Johnson/Troan code has survived the repeated rewrites.
* Other credits:
- * simple_itoa() was lifted from boa-0.93.15
* b_addchr() derived from similar w_addchar function in glibc-2.2
* setup_redirect(), redirect_opt_num(), and big chunks of main()
* and many builtins derived from contributions by Erik Andersen
return b_addchr(o, ch);
}
-/* belongs in utility.c */
-char *simple_itoa(unsigned int i)
-{
- /* 21 digits plus null terminator, good for 64-bit or smaller ints */
- static char local[22];
- char *p = &local[21];
- *p-- = '\0';
- do {
- *p-- = '0' + i % 10;
- i /= 10;
- } while (i > 0);
- return p + 1;
-}
-
#ifndef __U_BOOT__
static int b_adduint(o_string *o, unsigned int i)
{
/* download the update file */
load_addr = addr;
copy_filename(BootFile, filename, sizeof(BootFile));
- size = NetLoop(TFTP);
+ size = NetLoop(TFTPGET);
if (size < 0)
rv = 1;
#endif
#ifdef DEBUG
-#define USB_DEBUG
-#define USB_HUB_DEBUG
-#endif
-
-#ifdef USB_DEBUG
-#define USB_PRINTF(fmt, args...) printf(fmt , ##args)
+#define USB_DEBUG 1
+#define USB_HUB_DEBUG 1
#else
-#define USB_PRINTF(fmt, args...)
+#define USB_DEBUG 0
+#define USB_HUB_DEBUG 0
#endif
+#define USB_PRINTF(fmt, args...) debug_cond(USB_DEBUG, fmt, ##args)
+#define USB_HUB_PRINTF(fmt, args...) debug_cond(USB_HUB_DEBUG, fmt, ##args)
+
#define USB_BUFSIZ 512
static struct usb_device usb_dev[USB_MAX_DEVICE];
* Probes device for being a hub and configurate it
*/
-#ifdef USB_HUB_DEBUG
-#define USB_HUB_PRINTF(fmt, args...) printf(fmt , ##args)
-#else
-#define USB_HUB_PRINTF(fmt, args...)
-#endif
-
-
static struct usb_hub_device hub_dev[USB_MAX_HUB];
static int usb_hub_index;
#include <part.h>
#include <usb.h>
-#undef USB_STOR_DEBUG
#undef BBB_COMDAT_TRACE
#undef BBB_XPORT_TRACE
#ifdef USB_STOR_DEBUG
-#define USB_STOR_PRINTF(fmt, args...) printf(fmt , ##args)
+#define USB_BLK_DEBUG 1
#else
-#define USB_STOR_PRINTF(fmt, args...)
+#define USB_BLK_DEBUG 0
#endif
+#define USB_STOR_PRINTF(fmt, args...) debug_cond(USB_BLK_DEBUG, fmt, ##args)
+
#include <scsi.h>
/* direction table -- this indicates the direction of the data
* transfer for each command code -- a 1 indicates input
usb_clear_halt(us->pusb_dev, pipe);
us->pusb_dev->status = stat;
if (this_xfer == partial) {
- USB_STOR_PRINTF("bulk transferred with error %X, but data ok\n", us->pusb_dev->status);
+ USB_STOR_PRINTF("bulk transferred with error %lX, but data ok\n", us->pusb_dev->status);
return 0;
}
else
}
USB_STOR_PRINTF("bulk transferred with error");
if (this_xfer == partial) {
- USB_STOR_PRINTF(" %d, but data ok\n",
+ USB_STOR_PRINTF(" %ld, but data ok\n",
us->pusb_dev->status);
return 0;
}
/* if our try counter reaches 0, bail out */
- USB_STOR_PRINTF(" %d, data %d\n",
+ USB_STOR_PRINTF(" %ld, data %d\n",
us->pusb_dev->status, partial);
if (!maxtry--)
return result;
/* long wait for reset */
wait_ms(150);
- USB_STOR_PRINTF("BBB_reset result %d: status %X reset\n", result,
+ USB_STOR_PRINTF("BBB_reset result %d: status %lX reset\n", result,
us->pusb_dev->status);
pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
result = usb_clear_halt(us->pusb_dev, pipe);
/* long wait for reset */
wait_ms(150);
- USB_STOR_PRINTF("BBB_reset result %d: status %X clearing IN endpoint\n",
+ USB_STOR_PRINTF("BBB_reset result %d: status %lX clearing IN endpoint\n",
result, us->pusb_dev->status);
/* long wait for reset */
pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
result = usb_clear_halt(us->pusb_dev, pipe);
wait_ms(150);
- USB_STOR_PRINTF("BBB_reset result %d: status %X"
+ USB_STOR_PRINTF("BBB_reset result %d: status %lX"
" clearing OUT endpoint\n", result,
us->pusb_dev->status);
USB_STOR_PRINTF("BBB_reset done\n");
/* long wait for reset */
wait_ms(1500);
- USB_STOR_PRINTF("CB_reset result %d: status %X"
+ USB_STOR_PRINTF("CB_reset result %d: status %lX"
" clearing endpoint halt\n", result,
us->pusb_dev->status);
usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
srb->cmd, srb->cmdlen,
USB_CNTL_TIMEOUT * 5);
USB_STOR_PRINTF("CB_transport: control msg returned %d,"
- " status %X\n", result, us->pusb_dev->status);
+ " status %lX\n", result, us->pusb_dev->status);
/* check the return code for the command */
if (result < 0) {
if (us->pusb_dev->status & USB_ST_STALLED) {
us->pusb_dev->status = status;
}
USB_STOR_PRINTF(" error during command %02X"
- " Stat = %X\n", srb->cmd[0],
+ " Stat = %lX\n", srb->cmd[0],
us->pusb_dev->status);
return result;
}
usb_stor_BBB_reset(us);
return USB_STOR_TRANSPORT_FAILED;
} else if (data_actlen > srb->datalen) {
- USB_STOR_PRINTF("transferred %dB instead of %dB\n",
+ USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
data_actlen, srb->datalen);
return USB_STOR_TRANSPORT_FAILED;
} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
/* issue the command */
do_retry:
result = usb_stor_CB_comdat(srb, us);
- USB_STOR_PRINTF("command / Data returned %d, status %X\n",
+ USB_STOR_PRINTF("command / Data returned %d, status %lX\n",
result, us->pusb_dev->status);
/* if this is an CBI Protocol, get IRQ */
if (us->protocol == US_PR_CBI) {
/* do we have to issue an auto request? */
/* HERE we have to check the result */
if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
- USB_STOR_PRINTF("ERROR %X\n", us->pusb_dev->status);
+ USB_STOR_PRINTF("ERROR %lX\n", us->pusb_dev->status);
us->transport_reset(us);
return USB_STOR_TRANSPORT_ERROR;
}
status = usb_stor_CBI_get_status(psrb, us);
if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
- USB_STOR_PRINTF(" AUTO REQUEST ERROR %d\n",
+ USB_STOR_PRINTF(" AUTO REQUEST ERROR %ld\n",
us->pusb_dev->status);
return USB_STOR_TRANSPORT_ERROR;
}
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
RANLIB = $(CROSS_COMPILE)RANLIB
+DTC = dtc
#########################################################################
void print_part_efi(block_dev_desc_t * dev_desc)
{
- gpt_header gpt_head;
- gpt_entry **pgpt_pte = NULL;
+ ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
+ gpt_entry *gpt_pte = NULL;
int i = 0;
if (!dev_desc) {
- printf("%s: Invalid Argument(s)\n", __FUNCTION__);
+ printf("%s: Invalid Argument(s)\n", __func__);
return;
}
/* This function validates AND fills in the GPT header and PTE */
if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
- &(gpt_head), pgpt_pte) != 1) {
- printf("%s: *** ERROR: Invalid GPT ***\n", __FUNCTION__);
+ &(gpt_head), &gpt_pte) != 1) {
+ printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
return;
}
- debug("%s: gpt-entry at 0x%08X\n", __FUNCTION__, (unsigned int)*pgpt_pte);
+ debug("%s: gpt-entry at %p\n", __func__, gpt_pte);
printf("Part\tName\t\t\tStart LBA\tEnd LBA\n");
- for (i = 0; i < le32_to_int(gpt_head.num_partition_entries); i++) {
+ for (i = 0; i < le32_to_int(gpt_head->num_partition_entries); i++) {
- if (is_pte_valid(&(*pgpt_pte)[i])) {
+ if (is_pte_valid(&gpt_pte[i])) {
printf("%3d\t%-18s\t0x%08llX\t0x%08llX\n", (i + 1),
- print_efiname(&(*pgpt_pte)[i]),
- le64_to_int((*pgpt_pte)[i].starting_lba),
- le64_to_int((*pgpt_pte)[i].ending_lba));
+ print_efiname(&gpt_pte[i]),
+ le64_to_int(gpt_pte[i].starting_lba),
+ le64_to_int(gpt_pte[i].ending_lba));
} else {
break; /* Stop at the first non valid PTE */
}
}
/* Remember to free pte */
- if (*pgpt_pte != NULL) {
- debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
- free(*pgpt_pte);
- }
+ free(gpt_pte);
return;
}
int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
disk_partition_t * info)
{
- gpt_header gpt_head;
- gpt_entry **pgpt_pte = NULL;
+ ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
+ gpt_entry *gpt_pte = NULL;
/* "part" argument must be at least 1 */
if (!dev_desc || !info || part < 1) {
- printf("%s: Invalid Argument(s)\n", __FUNCTION__);
+ printf("%s: Invalid Argument(s)\n", __func__);
return -1;
}
/* This function validates AND fills in the GPT header and PTE */
if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
- &(gpt_head), pgpt_pte) != 1) {
- printf("%s: *** ERROR: Invalid GPT ***\n", __FUNCTION__);
+ &(gpt_head), &gpt_pte) != 1) {
+ printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
return -1;
}
/* The ulong casting limits the maximum disk size to 2 TB */
- info->start = (ulong) le64_to_int((*pgpt_pte)[part - 1].starting_lba);
+ info->start = (ulong) le64_to_int(gpt_pte[part - 1].starting_lba);
/* The ending LBA is inclusive, to calculate size, add 1 to it */
- info->size = ((ulong)le64_to_int((*pgpt_pte)[part - 1].ending_lba) + 1)
+ info->size = ((ulong)le64_to_int(gpt_pte[part - 1].ending_lba) + 1)
- info->start;
info->blksz = GPT_BLOCK_SIZE;
sprintf((char *)info->name, "%s",
- print_efiname(&(*pgpt_pte)[part - 1]));
+ print_efiname(&gpt_pte[part - 1]));
sprintf((char *)info->type, "U-Boot");
- debug("%s: start 0x%lX, size 0x%lX, name %s", __FUNCTION__,
+ debug("%s: start 0x%lX, size 0x%lX, name %s", __func__,
info->start, info->size, info->name);
/* Remember to free pte */
- if (*pgpt_pte != NULL) {
- debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
- free(*pgpt_pte);
- }
+ free(gpt_pte);
return 0;
}
int test_part_efi(block_dev_desc_t * dev_desc)
{
- legacy_mbr legacymbr;
+ ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, legacymbr, 1);
/* Read legacy MBR from block 0 and validate it */
- if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) & legacymbr) != 1)
- || (is_pmbr_valid(&legacymbr) != 1)) {
+ if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)legacymbr) != 1)
+ || (is_pmbr_valid(legacymbr) != 1)) {
return -1;
}
return 0;
unsigned long long lastlba;
if (!dev_desc || !pgpt_head) {
- printf("%s: Invalid Argument(s)\n", __FUNCTION__);
+ printf("%s: Invalid Argument(s)\n", __func__);
return 0;
}
le32_to_int(pgpt_head->partition_entry_array_crc32),
calc_crc32);
- if (*pgpt_pte != NULL) {
- free(*pgpt_pte);
- }
+ free(*pgpt_pte);
return 0;
}
gpt_entry *pte = NULL;
if (!dev_desc || !pgpt_head) {
- printf("%s: Invalid Argument(s)\n", __FUNCTION__);
+ printf("%s: Invalid Argument(s)\n", __func__);
return NULL;
}
count = le32_to_int(pgpt_head->num_partition_entries) *
le32_to_int(pgpt_head->sizeof_partition_entry);
- debug("%s: count = %lu * %lu = %u\n", __FUNCTION__,
+ debug("%s: count = %lu * %lu = %u\n", __func__,
le32_to_int(pgpt_head->num_partition_entries),
le32_to_int(pgpt_head->sizeof_partition_entry), count);
/* Allocate memory for PTE, remember to FREE */
if (count != 0) {
- pte = malloc(count);
+ pte = memalign(CONFIG_SYS_CACHELINE_SIZE, count);
}
if (count == 0 || pte == NULL) {
printf("%s: ERROR: Can't allocate 0x%X bytes for GPT Entries\n",
- __FUNCTION__, count);
+ __func__, count);
return NULL;
}
efi_guid_t unused_guid;
if (!pte) {
- printf("%s: Invalid Argument(s)\n", __FUNCTION__);
+ printf("%s: Invalid Argument(s)\n", __func__);
return 0;
}
if (memcmp(pte->partition_type_guid.b, unused_guid.b,
sizeof(unused_guid.b)) == 0) {
- debug("%s: Found an unused PTE GUID at 0x%08X\n", __FUNCTION__,
+ debug("%s: Found an unused PTE GUID at 0x%08X\n", __func__,
(unsigned int)pte);
return 0;
- If the buffer is not cache-line aligned invalidation will be restricted
to the aligned part. That is, one cache-line at the respective boundary
may be left out while doing invalidation.
+- A suitable buffer can be alloced on the stack using the
+ ALLOC_CACHE_ALIGN_BUFFER macro.
Cleanup Before Linux:
- cleanup_before_linux() should flush the D-cache, invalidate I-cache, and
--- /dev/null
+#
+# 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 Foundatio; 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
+#
+
+Device Tree Control in U-Boot
+=============================
+
+This feature provides for run-time configuration of U-Boot via a flat
+device tree (fdt). U-Boot configuration has traditionally been done
+using CONFIG options in the board config file. This feature aims to
+make it possible for a single U-Boot binary to support multiple boards,
+with the exact configuration of each board controlled by a flat device
+tree (fdt). This is the approach recently taken by the ARM Linux kernel
+and has been used by PowerPC for some time.
+
+The fdt is a convenient vehicle for implementing run-time configuration
+for three reasons. Firstly it is easy to use, being a simple text file.
+It is extensible since it consists of nodes and properties in a nice
+hierarchical format.
+
+Finally, there is already excellent infrastructure for the fdt: a
+compiler checks the text file and converts it to a compact binary
+format, and a library is already available in U-Boot (libfdt) for
+handling this format.
+
+The dts directory contains a Makefile for building the device tree blob
+and embedding it in your U-Boot image. This is useful since it allows
+U-Boot to configure itself according to what it finds there. If you have
+a number of similar boards with different peripherals, you can describe
+the features of each board in the device tree file, and have a single
+generic source base.
+
+To enable this feature, add CONFIG_OF_CONTROL to your board config file.
+
+
+What is a Flat Device Tree?
+---------------------------
+
+An fdt can be specified in source format as a text file. To read about
+the fdt syntax, take a look at the specification here:
+
+https://www.power.org/resources/downloads/Power_ePAPR_APPROVED_v1.0.pdf
+
+You also might find this section of the Linux kernel documentation
+useful: (access this in the Linux kernel source code)
+
+ Documentation/devicetree/booting-without-of.txt
+
+There is also a mailing list:
+
+ http://lists.ozlabs.org/listinfo/devicetree-discuss
+
+In case you are wondering, OF stands for Open Firmware.
+
+
+Tools
+-----
+
+To use this feature you will need to get the device tree compiler here:
+
+ git://jdl.com/software/dtc.git
+
+For example:
+
+ $ git clone git://jdl.com/software/dtc.git
+ $ cd dtc
+ $ make
+ $ sudo make install
+
+Then run the compiler (your version will vary):
+
+ $ dtc -v
+ Version: DTC 1.2.0-g2cb4b51f
+ $ make tests
+ $ cd tests
+ $ ./run_tests.sh
+ ********** TEST SUMMARY
+ * Total testcases: 1371
+ * PASS: 1371
+ * FAIL: 0
+ * Bad configuration: 0
+ * Strange test result: 0
+
+You will also find a useful ftdump utility for decoding a binary file.
+
+
+Where do I get an fdt file for my board?
+----------------------------------------
+
+You may find that the Linux kernel has a suitable file. Look in the
+kernel source in arch/<arch>/boot/dts.
+
+If not you might find other boards with suitable files that you can
+modify to your needs. Look in the board directories for files with a
+.dts extension.
+
+Failing that, you could write one from scratch yourself!
+
+
+Configuration
+-------------
+
+Use:
+
+#define CONFIG_DEFAULT_DEVICE_TREE "<name>"
+
+to set the filename of the device tree source. Then put your device tree
+file into
+
+ board/<vendor>/dts/<name>.dts
+
+This should include your CPU or SOC's device tree file, placed in
+arch/<arch>/dts, and then make any adjustments required. The name of this
+is CONFIG_ARCH_DEVICE_TREE.dts.
+
+If CONFIG_OF_EMBED is defined, then it will be picked up and built into
+the U-Boot image (including u-boot.bin).
+
+If CONFIG_OF_SEPARATE is defined, then it will be built and placed in
+a u-boot.dtb file alongside u-boot.bin. A common approach is then to
+join the two:
+
+ cat u-boot.bin u-boot.dtb >image.bin
+
+and then flash image.bin onto your board.
+
+You cannot use both 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
+address of the fdt binary blob, and will override either of the options.
+Be aware that this environment variable is checked prior to relocation,
+when only the compiled-in environment is available. Therefore it is not
+possible to define this variable in the saved SPI/NAND flash
+environment, for example (it will be ignored).
+
+To use this, put something like this in your board header file:
+
+#define CONFIG_EXTRA_ENV_SETTINGS "fdtcontroladdr=10000\0"
+
+
+Limitations
+-----------
+
+U-Boot is designed to build with a single architecture type and CPU
+type. So for example it is not possible to build a single ARM binary
+which runs on your AT91 and OMAP boards, relying on an fdt to configure
+the various features. This is because you must select one of
+the CPU families within arch/arm/cpu/arm926ejs (omap or at91) at build
+time. Similarly you cannot build for multiple cpu types or
+architectures.
+
+That said the complexity reduction by using fdt to support variants of
+boards which use the same SOC / CPU can be substantial.
+
+It is important to understand that the fdt only selects options
+available in the platform / drivers. It cannot add new drivers (yet). So
+you must still have the CONFIG option to enable the driver. For example,
+you need to define CONFIG_SYS_NS16550 to bring in the NS16550 driver,
+but can use the fdt to specific the UART clock, peripheral address, etc.
+In very broad terms, the CONFIG options in general control *what* driver
+files are pulled in, and the fdt controls *how* those files work.
+
+--
+Simon Glass <sjg@chromium.org>
+1-Sep-11
* 32 bytes each in size
*/
pp->cmd_slot = (struct ahci_cmd_hdr *)mem;
- debug("cmd_slot = 0x%x\n", pp->cmd_slot);
+ debug("cmd_slot = %p\n", pp->cmd_slot);
mem += (AHCI_CMD_SLOT_SZ + 224);
/*
sata_dev_desc[devno].removable = 0;
sata_dev_desc[devno].lba = (u32) n_sectors;
- debug ("lba=0x%x\n", sata_dev_desc[devno].lba);
+ debug("lba=0x%lx\n", sata_dev_desc[devno].lba);
#ifdef CONFIG_LBA48
if (iobuf[83] & (1 << 10)) {
read_bytes = 0;
bufsize = bsize;
debug("%s: Launching the Lattice ISPVME Loader:"
- " addr 0x%x size 0x%x...\n",
+ " addr %p size 0x%lx...\n",
__func__, fpga_image, bufsize);
ret_val = ispVM();
if (ret_val)
int mmc_change_freq(struct mmc *mmc)
{
- char ext_csd[512];
+ ALLOC_CACHE_ALIGN_BUFFER(char, ext_csd, 512);
char cardtype;
int err;
{
int err;
struct mmc_cmd cmd;
- uint scr[2];
- uint switch_status[16];
+ ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2);
+ ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
struct mmc_data data;
int timeout;
timeout = 3;
retry_scr:
- data.dest = (char *)&scr;
+ data.dest = (char *)scr;
data.blocksize = 8;
data.blocks = 1;
data.flags = MMC_DATA_READ;
timeout = 4;
while (timeout--) {
err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
- (u8 *)&switch_status);
+ (u8 *)switch_status);
if (err)
return err;
if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
return 0;
- err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)&switch_status);
+ err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
if (err)
return err;
uint mult, freq;
u64 cmult, csize, capacity;
struct mmc_cmd cmd;
- char ext_csd[512];
+ ALLOC_CACHE_ALIGN_BUFFER(char, ext_csd, 512);
int timeout = 1000;
#ifdef CONFIG_MMC_SPI_CRC_ON
/****************************************************/
{
static uint32_t resp[4], a, b, c;
- ulong status;
+ uint32_t status;
int i;
debug("mmc_cmd %u 0x%04x 0x%04x 0x%04x\n", cmd, argh, argl,
int
/****************************************************/
-mmc_block_read(uchar * dst, ulong src, ulong len)
+mmc_block_read(uchar * dst, uint32_t src, int len)
/****************************************************/
{
ushort argh, argl;
return 0;
}
- debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong) dst, src, len);
+ debug("mmc_block_rd dst %p src %08x len %d\n", dst, src, len);
argh = len >> 16;
argl = len & 0xffff;
int
/****************************************************/
-pxa_mmc_write(uchar * src, ulong dst, int size)
+pxa_mmc_write(uchar * src, uint32_t dst, int size)
/****************************************************/
{
ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
/* all block aligned accesses */
debug
- ("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
- src, (ulong) dst, end, part_start, part_end, aligned_start,
+ ("src %p dst %08x end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, dst, end, part_start, part_end, aligned_start,
aligned_end);
if (part_start) {
part_len = mmc_block_size - part_start;
debug
- ("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
- (ulong) src, dst, end, part_start, part_end, aligned_start,
+ ("ps src %p dst %08x end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, dst, end, part_start, part_end, aligned_start,
aligned_end);
if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) <
0) {
src += part_len;
}
debug
- ("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
- src, (ulong) dst, end, part_start, part_end, aligned_start,
+ ("src %p dst %08x end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, dst, end, part_start, part_end, aligned_start,
aligned_end);
for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
debug
- ("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
- src, (ulong) dst, end, part_start, part_end, aligned_start,
+ ("al src %p dst %08x end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, dst, end, part_start, part_end, aligned_start,
aligned_end);
if ((mmc_block_write(dst, (uchar *) src, mmc_block_size)) < 0) {
return -1;
}
}
debug
- ("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
- src, (ulong) dst, end, part_start, part_end, aligned_start,
+ ("src %p dst %08x end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, dst, end, part_start, part_end, aligned_start,
aligned_end);
if (part_end && dst < end) {
debug
- ("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
- src, (ulong) dst, end, part_start, part_end, aligned_start,
+ ("pe src %p dst %08x end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, dst, end, part_start, part_end, aligned_start,
aligned_end);
if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
return -1;
#if defined(CONFIG_SYS_FLASH_AUTOPROTECT_LIST)
for (i = 0; i < (sizeof(apl) / sizeof(struct apl_s)); i++) {
- debug("autoprotecting from %08x to %08x\n",
+ debug("autoprotecting from %08lx to %08lx\n",
apl[i].start, apl[i].start + apl[i].size - 1);
flash_protect(FLAG_PROTECT_SET,
apl[i].start,
debug("unlock address index %d\n", uaddr_idx);
info->addr_unlock1 = unlock_addrs[uaddr_idx].addr1;
info->addr_unlock2 = unlock_addrs[uaddr_idx].addr2;
- debug("unlock addresses are 0x%x/0x%x\n", info->addr_unlock1, info->addr_unlock2);
+ debug("unlock addresses are 0x%lx/0x%lx\n",
+ info->addr_unlock1, info->addr_unlock2);
sect_cnt = 0;
total_size = 0;
ulong erase_region_count = (jedec_entry->regions[i] & 0xff) + 1;
total_size += erase_region_size * erase_region_count;
- debug ("erase_region_count = %d erase_region_size = %d\n",
+ debug("erase_region_count = %ld erase_region_size = %ld\n",
erase_region_count, erase_region_size);
for (j = 0; j < erase_region_count; j++) {
if (sect_cnt >= CONFIG_SYS_MAX_FLASH_SECT) {
struct nand_chip *chip = mtd->priv;
struct s3c2410_nand *nand = s3c2410_get_base_nand();
- debugX(1, "hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
+ debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
if (ctrl & NAND_CTRL_CHANGE) {
ulong IO_ADDR_W = (ulong)nand;
static int s3c2410_dev_ready(struct mtd_info *mtd)
{
struct s3c2410_nand *nand = s3c2410_get_base_nand();
- debugX(1, "dev_ready\n");
+ debug("dev_ready\n");
return readl(&nand->nfstat) & 0x01;
}
void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
struct s3c2410_nand *nand = s3c2410_get_base_nand();
- debugX(1, "s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);
+ debug("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);
writel(readl(&nand->nfconf) | S3C2410_NFCONF_INITECC, &nand->nfconf);
}
ecc_code[0] = readb(&nand->nfecc);
ecc_code[1] = readb(&nand->nfecc + 1);
ecc_code[2] = readb(&nand->nfecc + 2);
- debugX(1, "s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n",
+ debug("s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n",
mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
return 0;
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
struct s3c2410_nand *nand_reg = s3c2410_get_base_nand();
- debugX(1, "board_nand_init()\n");
+ debug("board_nand_init()\n");
writel(readl(&clk_power->clkcon) | (1 << 4), &clk_power->clkcon);
nand->options = 0;
#endif
- debugX(1, "end of nand_init\n");
+ debug("end of nand_init\n");
return 0;
}
hw_p->rx_phys = bd_cached + MAL_TX_DESC_SIZE;
hw_p->tx = (mal_desc_t *)(bd_uncached);
hw_p->rx = (mal_desc_t *)(bd_uncached + MAL_TX_DESC_SIZE);
- debug("hw_p->tx=%08x, hw_p->rx=%08x\n", hw_p->tx, hw_p->rx);
+ debug("hw_p->tx=%p, hw_p->rx=%p\n", hw_p->tx, hw_p->rx);
}
for (i = 0; i < NUM_TX_BUFF; i++) {
if ((NUM_TX_BUFF - 1) == i)
hw_p->tx[i].ctrl |= MAL_TX_CTRL_WRAP;
hw_p->tx_run[i] = -1;
- debug("TX_BUFF %d @ 0x%08lx\n", i, (u32)hw_p->tx[i].data_ptr);
+ debug("TX_BUFF %d @ 0x%08x\n", i, (u32)hw_p->tx[i].data_ptr);
}
for (i = 0; i < NUM_RX_BUFF; i++) {
hw_p->rx[i].ctrl |= MAL_RX_CTRL_WRAP;
hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR;
hw_p->rx_ready[i] = -1;
- debug("RX_BUFF %d @ 0x%08lx\n", i, (u32)hw_p->rx[i].data_ptr);
+ debug("RX_BUFF %d @ 0x%08x\n", i, (u32)hw_p->rx[i].data_ptr);
}
reg = 0x00000000;
if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR)
debug("Timeout waiting sgdma in do async!\n");
+ /*
+ * Clear the RUN bit in the control register. This is needed
+ * to restart the SGDMA engine later on.
+ */
+ dev->control = 0;
+
/*
* Clear any (previous) status register information
* that might occlude our error checking later.
/* setup the sgdma */
alt_sgdma_do_async_transfer(priv->sgdma_rx, &rx_desc[0]);
+
+ return packet_length;
}
return -1;
if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) {
debug("Timeout waiting for rx sgdma!\n");
- rx_sgdma->control &= ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
- rx_sgdma->control &= ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
+ rx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
+ rx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
}
counter = 0;
if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) {
debug("Timeout waiting for tx sgdma!\n");
- tx_sgdma->control &= ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
- tx_sgdma->control &= ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
+ tx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
+ tx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
}
/* reset the mac */
mac_dev->command_config.bits.transmit_enable = 1;
{
uint mii_data = tse_mdio_read(priv, mii_reg);
mii_data &= 0xfff0;
- mii_data |= 0xb;
+ if ((priv->flags >= 1) && (priv->flags <= 4))
+ mii_data |= 0xb;
+ else if (priv->flags == 5)
+ mii_data |= 0x4;
+
return mii_data;
}
{
uint mii_data = tse_mdio_read(priv, mii_reg);
mii_data &= ~0x82;
- mii_data |= 0x82;
+ if ((priv->flags >= 1) && (priv->flags <= 4))
+ mii_data |= 0x82;
+
return mii_data;
}
/* TSE init code */
int altera_tse_initialize(u8 dev_num, int mac_base,
- int sgdma_rx_base, int sgdma_tx_base)
+ int sgdma_rx_base, int sgdma_tx_base,
+ u32 sgdma_desc_base, u32 sgdma_desc_size)
{
struct altera_tse_priv *priv;
struct eth_device *dev;
free(dev);
return 0;
}
- tx_desc = dma_alloc_coherent(sizeof(*tx_desc) * (3 + PKTBUFSRX),
- &dma_handle);
+ if (sgdma_desc_size) {
+ if (sgdma_desc_size < (sizeof(*tx_desc) * (3 + PKTBUFSRX))) {
+ printf("ALTERA_TSE-%hu: "
+ "descriptor memory is too small\n", dev_num);
+ free(priv);
+ free(dev);
+ return 0;
+ }
+ tx_desc = (struct alt_sgdma_descriptor *)sgdma_desc_base;
+ } else {
+ tx_desc = dma_alloc_coherent(sizeof(*tx_desc) * (3 + PKTBUFSRX),
+ &dma_handle);
+ }
+
rx_desc = tx_desc + 2;
debug("tx desc: address = 0x%x\n", (unsigned int)tx_desc);
debug("rx desc: address = 0x%x\n", (unsigned int)rx_desc);
*/
writel((((imx_get_fecclk() / 1000000) + 2) / 5) << 1,
&fec->eth->mii_speed);
- debug("fec_init: mii_speed %#lx\n",
+ debug("fec_init: mii_speed %08x\n",
readl(&fec->eth->mii_speed));
}
static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr,
*/
ievent = readl(&fec->eth->ievent);
writel(ievent, &fec->eth->ievent);
- debug("fec_recv: ievent 0x%x\n", ievent);
+ debug("fec_recv: ievent 0x%lx\n", ievent);
if (ievent & FEC_IEVENT_BABR) {
fec_halt(dev);
fec_init(dev, fec->bd);
volatile struct ks8695_txdesc *dp;
static int next = 0;
- debug ("%s(%d): eth_send(packet=%x,len=%d)\n", __FILE__, __LINE__,
+ debug ("%s(%d): eth_send(packet=%p,len=%d)\n", __FILE__, __LINE__,
packet, len);
dp = &ks8695_tx[next];
inbound = fsl_pci_setup_inbound_windows(hose, out_lo, pcie_cap, pi);
for (r = 0; r < hose->region_count; r++)
- debug("PCI reg:%d %016llx:%016llx %016llx %08x\n", r,
+ debug("PCI reg:%d %016llx:%016llx %016llx %08lx\n", r,
(u64)hose->regions[r].phys_start,
- hose->regions[r].bus_start,
- hose->regions[r].size,
+ (u64)hose->regions[r].bus_start,
+ (u64)hose->regions[r].size,
hose->regions[r].flags);
pci_register_hose(hose);
setbits_be32(&pci->pdb_stat, 0x08000000);
(void) in_be32(&pci->pdb_stat);
udelay(100);
- debug(" Asserting PCIe reset @%x = %x\n",
+ debug(" Asserting PCIe reset @%p = %x\n",
&pci->pdb_stat, in_be32(&pci->pdb_stat));
/* clear PCIe reset */
clrbits_be32(&pci->pdb_stat, 0x08000000);
{
cirrus_state_t *p = &s->c_state;
u_int mask = 0xffff;
-#if DEBUG
- char buf[200];
-
- memset (buf, 0, 200);
-#endif
+ char buf[200] = {0};
if (has_ring == -1)
has_ring = 1;
static inline void power_off(int slot)
{
- out_be32(PCMCIA_CTRL, 0);
+ volatile unsigned __iomem *addr;
+ addr = (volatile unsigned __iomem *)PCMCIA_CTRL;
+
+ out_be32(addr, 0);
}
static inline void power_on_5_0(int slot)
{
+ volatile unsigned __iomem *addr;
+ addr = (volatile unsigned __iomem *)PCMCIA_CTRL;
+
/* Enable 5V Vccout */
- out_be32(PCMCIA_CTRL, 2);
+ out_be32(addr, 2);
}
static inline void power_on_3_3(int slot)
{
+ volatile unsigned __iomem *addr;
+ addr = (volatile unsigned __iomem *)PCMCIA_CTRL;
+
/* Enable 3.3V Vccout */
- out_be32(PCMCIA_CTRL, 1);
+ out_be32(addr, 1);
}
#else
pm = spibrg / (max_hz * 16 * 2);
if (pm > 16) {
pm = 16;
- debug("Requested speed is too low: %d Hz, "
- "%d Hz is used.\n", max_hz, spibrg / (32 * 16));
+ debug("Requested speed is too low: %d Hz, %ld Hz "
+ "is used.\n", max_hz, spibrg / (32 * 16));
}
} else
pm = spibrg / (max_hz * 2);
break;
}
- debug("spi_xfer: slave %u:%u dout %08X(%08x) din %08X(%08x) len %u\n",
+ debug("spi_xfer: slave %u:%u dout %08X(%p) din %08X(%p) len %u\n",
slave->bus, slave->cs, *(uint *) dout,
dout, *(uint *) din, din, len);
unsigned int tmpdout, tmpdin;
int tm, isread = 0;
- debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
+ debug("spi_xfer: slave %u:%u dout %p din %p bitlen %u\n",
slave->bus, slave->cs, dout, din, bitlen);
if (flags & SPI_XFER_BEGIN)
isread = 1;
tmpdin = readl(&spireg->din);
debug
- ("spi_xfer: din %08x..%08x read\n",
+ ("spi_xfer: din %p..%08x read\n",
din, tmpdin);
if (din) {
/* set hardware address */
debug("** %s()\n", __func__);
- addr_lo = cpu_to_le32(*((u32 *)eth->enetaddr));
+ addr_lo = cpu_to_le32(*eth->enetaddr);
addr_hi = cpu_to_le16(*((u16 *)(eth->enetaddr + 4)));
ret = smsc95xx_write_reg(dev, ADDRL, addr_lo);
if (ret < 0) {
#else
#error CONFIG_SYS_VCXK_DEFAULT_LINEALIGN is invalid
#endif
- debug("linesize ((%d + 15) / 8 & ~0x1) = %d\n",
+ debug("linesize ((%ld + 15) / 8 & ~0x1) = %ld\n",
display_width, display_bwidth);
#ifdef CONFIG_SYS_VCXK_AUTODETECT
colors = le32_to_cpu(bmp->header.colors_used);
compression = le32_to_cpu(bmp->header.compression);
- debug("Display-bmp: %d x %d with %d colors\n",
+ debug("Display-bmp: %ld x %ld with %d colors\n",
width, height, colors);
if (compression != BMP_BI_RGB
--- /dev/null
+#
+# 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 Foundatio; 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 Makefile builds the internal U-Boot fdt if CONFIG_OF_CONTROL is
+# enabled. See doc/README.fdt-control for more details.
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)libdts.o
+
+$(if $(CONFIG_DEFAULT_DEVICE_TREE),,\
+$(error Please define CONFIG_DEFAULT_DEVICE_TREE in your board header file))
+DEVICE_TREE = $(subst ",,$(CONFIG_DEFAULT_DEVICE_TREE))
+
+$(if $(CONFIG_ARCH_DEVICE_TREE),,\
+$(error Your architecture does not have device tree support enabled. \
+Please define CONFIG_ARCH_DEVICE_TREE))
+
+# We preprocess the device tree file provide a useful define
+DTS_CPPFLAGS := -DARCH_CPU_DTS=\"../arch/$(ARCH)/dts/$(CONFIG_ARCH_DEVICE_TREE).dtsi\"
+
+all: $(obj).depend $(LIB)
+
+# Use a constant name for this so we can access it from C code.
+# objcopy doesn't seem to allow us to set the symbol name independently of
+# the filename.
+DT_BIN := $(obj)dt.dtb
+
+$(DT_BIN): $(TOPDIR)/board/$(VENDOR)/dts/$(DEVICE_TREE).dts
+ cat $< | $(CPP) -P $(DTS_CPPFLAGS) - >$@.tmp
+ $(DTC) -R 4 -p 0x1000 -O dtb -o ${DT_BIN} $@.tmp
+ rm $@.tmp
+
+process_lds = \
+ $(1) | sed -r -n 's/^OUTPUT_$(2)[ ("]*([^")]*).*/\1/p'
+
+# Run the compiler and get the link script from the linker
+GET_LDS = $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--verbose 2>&1
+
+$(obj)dt.o: $(DT_BIN)
+ # We want the output format and arch.
+ # We also hope to win a prize for ugliest Makefile / shell interaction
+ # We look in the LDSCRIPT first.
+ # Then try the linker which should give us the answer.
+ # Then check it worked.
+ oformat=`$(call process_lds,cat $(LDSCRIPT),FORMAT)` ;\
+ oarch=`$(call process_lds,cat $(LDSCRIPT),ARCH)` ;\
+ \
+ [ -z $${oformat} ] && \
+ oformat=`$(call process_lds,$(GET_LDS),FORMAT)` ;\
+ [ -z $${oarch} ] && \
+ oarch=`$(call process_lds,$(GET_LDS),ARCH)` ;\
+ \
+ [ -z $${oformat} ] && \
+ echo "Cannot read OUTPUT_FORMAT from lds file $(LDSCRIPT)" && \
+ exit 1 || true ;\
+ [ -z $${oarch} ] && \
+ echo "Cannot read OUTPUT_ARCH from lds file $(LDSCRIPT)" && \
+ exit 1 || true ;\
+ \
+ cd $(dir ${DT_BIN}) && \
+ $(OBJCOPY) -I binary -O $${oformat} -B $${oarch} \
+ $(notdir ${DT_BIN}) $@
+ rm $(DT_BIN)
+
+OBJS-$(CONFIG_OF_EMBED) := dt.o
+
+COBJS := $(OBJS-y)
+
+OBJS := $(addprefix $(obj),$(COBJS))
+
+binary: $(DT_BIN)
+
+$(LIB): $(OBJS) $(DTB)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
int ext2fs_devread(int sector, int byte_offset, int byte_len, char *buf)
{
- char sec_buf[SECTOR_SIZE];
+ ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, SECTOR_SIZE);
unsigned sectors;
/*
AOBJS =
COBJS-$(CONFIG_CMD_FAT) := fat.o
+COBJS-$(CONFIG_FAT_WRITE):= fat_write.o
ifndef CONFIG_SPL_BUILD
COBJS-$(CONFIG_CMD_FAT) += file.o
}
if ((dentptr->attr & ATTR_VOLUME)) {
#ifdef CONFIG_SUPPORT_VFAT
- if ((dentptr->attr & ATTR_VFAT) &&
- (dentptr-> name[0] & LAST_LONG_ENTRY_MASK)) {
+ if ((dentptr->attr & ATTR_VFAT) == ATTR_VFAT &&
+ (dentptr->name[0] & LAST_LONG_ENTRY_MASK)) {
prevcksum = ((dir_slot *)dentptr)->alias_checksum;
get_vfatname(mydata, curclust,
get_dentfromdir_block,
}
if ((dentptr->attr & ATTR_VOLUME)) {
#ifdef CONFIG_SUPPORT_VFAT
- if ((dentptr->attr & ATTR_VFAT) &&
+ if ((dentptr->attr & ATTR_VFAT) == ATTR_VFAT &&
(dentptr->name[0] & LAST_LONG_ENTRY_MASK)) {
prevcksum =
((dir_slot *)dentptr)->alias_checksum;
--- /dev/null
+/*
+ * fat_write.c
+ *
+ * R/W (V)FAT 12/16/32 filesystem implementation by Donggeun Kim
+ *
+ * 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 <command.h>
+#include <config.h>
+#include <fat.h>
+#include <asm/byteorder.h>
+#include <part.h>
+#include "fat.c"
+
+static void uppercase(char *str, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ TOUPPER(*str);
+ str++;
+ }
+}
+
+static int total_sector;
+static int disk_write(__u32 startblock, __u32 getsize, __u8 *bufptr)
+{
+ if (cur_dev == NULL)
+ return -1;
+
+ if (startblock + getsize > total_sector) {
+ printf("error: overflow occurs\n");
+ return -1;
+ }
+
+ startblock += part_offset;
+
+ if (cur_dev->block_read) {
+ return cur_dev->block_write(cur_dev->dev, startblock, getsize,
+ (unsigned long *) bufptr);
+ }
+ return -1;
+}
+
+/*
+ * Set short name in directory entry
+ */
+static void set_name(dir_entry *dirent, const char *filename)
+{
+ char s_name[VFAT_MAXLEN_BYTES];
+ char *period;
+ int period_location, len, i, ext_num;
+
+ if (filename == NULL)
+ return;
+
+ len = strlen(filename);
+ if (len == 0)
+ return;
+
+ memcpy(s_name, filename, len);
+ uppercase(s_name, len);
+
+ period = strchr(s_name, '.');
+ if (period == NULL) {
+ period_location = len;
+ ext_num = 0;
+ } else {
+ period_location = period - s_name;
+ ext_num = len - period_location - 1;
+ }
+
+ /* Pad spaces when the length of file name is shorter than eight */
+ if (period_location < 8) {
+ memcpy(dirent->name, s_name, period_location);
+ for (i = period_location; i < 8; i++)
+ dirent->name[i] = ' ';
+ } else if (period_location == 8) {
+ memcpy(dirent->name, s_name, period_location);
+ } else {
+ memcpy(dirent->name, s_name, 6);
+ dirent->name[6] = '~';
+ dirent->name[7] = '1';
+ }
+
+ if (ext_num < 3) {
+ memcpy(dirent->ext, s_name + period_location + 1, ext_num);
+ for (i = ext_num; i < 3; i++)
+ dirent->ext[i] = ' ';
+ } else
+ memcpy(dirent->ext, s_name + period_location + 1, 3);
+
+ debug("name : %s\n", dirent->name);
+ debug("ext : %s\n", dirent->ext);
+}
+
+/*
+ * Write fat buffer into block device
+ */
+static int flush_fat_buffer(fsdata *mydata)
+{
+ int getsize = FATBUFBLOCKS;
+ __u32 fatlength = mydata->fatlength;
+ __u8 *bufptr = mydata->fatbuf;
+ __u32 startblock = mydata->fatbufnum * FATBUFBLOCKS;
+
+ fatlength *= mydata->sect_size;
+ startblock += mydata->fat_sect;
+
+ if (getsize > fatlength)
+ getsize = fatlength;
+
+ /* Write FAT buf */
+ if (disk_write(startblock, getsize, bufptr) < 0) {
+ debug("error: writing FAT blocks\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Get the entry at index 'entry' in a FAT (12/16/32) table.
+ * On failure 0x00 is returned.
+ * When bufnum is changed, write back the previous fatbuf to the disk.
+ */
+static __u32 get_fatent_value(fsdata *mydata, __u32 entry)
+{
+ __u32 bufnum;
+ __u32 off16, offset;
+ __u32 ret = 0x00;
+ __u16 val1, val2;
+
+ switch (mydata->fatsize) {
+ case 32:
+ bufnum = entry / FAT32BUFSIZE;
+ offset = entry - bufnum * FAT32BUFSIZE;
+ break;
+ case 16:
+ bufnum = entry / FAT16BUFSIZE;
+ offset = entry - bufnum * FAT16BUFSIZE;
+ break;
+ case 12:
+ bufnum = entry / FAT12BUFSIZE;
+ offset = entry - bufnum * FAT12BUFSIZE;
+ break;
+
+ default:
+ /* Unsupported FAT size */
+ return ret;
+ }
+
+ debug("FAT%d: entry: 0x%04x = %d, offset: 0x%04x = %d\n",
+ mydata->fatsize, entry, entry, offset, offset);
+
+ /* Read a new block of FAT entries into the cache. */
+ if (bufnum != mydata->fatbufnum) {
+ int getsize = FATBUFBLOCKS;
+ __u8 *bufptr = mydata->fatbuf;
+ __u32 fatlength = mydata->fatlength;
+ __u32 startblock = bufnum * FATBUFBLOCKS;
+
+ if (getsize > fatlength)
+ getsize = fatlength;
+
+ fatlength *= mydata->sect_size; /* We want it in bytes now */
+ startblock += mydata->fat_sect; /* Offset from start of disk */
+
+ /* Write back the fatbuf to the disk */
+ if (mydata->fatbufnum != -1) {
+ if (flush_fat_buffer(mydata) < 0)
+ return -1;
+ }
+
+ if (disk_read(startblock, getsize, bufptr) < 0) {
+ debug("Error reading FAT blocks\n");
+ return ret;
+ }
+ mydata->fatbufnum = bufnum;
+ }
+
+ /* Get the actual entry from the table */
+ switch (mydata->fatsize) {
+ case 32:
+ ret = FAT2CPU32(((__u32 *) mydata->fatbuf)[offset]);
+ break;
+ case 16:
+ ret = FAT2CPU16(((__u16 *) mydata->fatbuf)[offset]);
+ break;
+ case 12:
+ off16 = (offset * 3) / 4;
+
+ switch (offset & 0x3) {
+ case 0:
+ ret = FAT2CPU16(((__u16 *) mydata->fatbuf)[off16]);
+ ret &= 0xfff;
+ break;
+ case 1:
+ val1 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16]);
+ val1 &= 0xf000;
+ val2 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16 + 1]);
+ val2 &= 0x00ff;
+ ret = (val2 << 4) | (val1 >> 12);
+ break;
+ case 2:
+ val1 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16]);
+ val1 &= 0xff00;
+ val2 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16 + 1]);
+ val2 &= 0x000f;
+ ret = (val2 << 8) | (val1 >> 8);
+ break;
+ case 3:
+ ret = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16]);
+ ret = (ret & 0xfff0) >> 4;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ debug("FAT%d: ret: %08x, entry: %08x, offset: %04x\n",
+ mydata->fatsize, ret, entry, offset);
+
+ return ret;
+}
+
+#ifdef CONFIG_SUPPORT_VFAT
+/*
+ * Set the file name information from 'name' into 'slotptr',
+ */
+static int str2slot(dir_slot *slotptr, const char *name, int *idx)
+{
+ int j, end_idx = 0;
+
+ for (j = 0; j <= 8; j += 2) {
+ if (name[*idx] == 0x00) {
+ slotptr->name0_4[j] = 0;
+ slotptr->name0_4[j + 1] = 0;
+ end_idx++;
+ goto name0_4;
+ }
+ slotptr->name0_4[j] = name[*idx];
+ (*idx)++;
+ end_idx++;
+ }
+ for (j = 0; j <= 10; j += 2) {
+ if (name[*idx] == 0x00) {
+ slotptr->name5_10[j] = 0;
+ slotptr->name5_10[j + 1] = 0;
+ end_idx++;
+ goto name5_10;
+ }
+ slotptr->name5_10[j] = name[*idx];
+ (*idx)++;
+ end_idx++;
+ }
+ for (j = 0; j <= 2; j += 2) {
+ if (name[*idx] == 0x00) {
+ slotptr->name11_12[j] = 0;
+ slotptr->name11_12[j + 1] = 0;
+ end_idx++;
+ goto name11_12;
+ }
+ slotptr->name11_12[j] = name[*idx];
+ (*idx)++;
+ end_idx++;
+ }
+
+ if (name[*idx] == 0x00)
+ return 1;
+
+ return 0;
+/* Not used characters are filled with 0xff 0xff */
+name0_4:
+ for (; end_idx < 5; end_idx++) {
+ slotptr->name0_4[end_idx * 2] = 0xff;
+ slotptr->name0_4[end_idx * 2 + 1] = 0xff;
+ }
+ end_idx = 5;
+name5_10:
+ end_idx -= 5;
+ for (; end_idx < 6; end_idx++) {
+ slotptr->name5_10[end_idx * 2] = 0xff;
+ slotptr->name5_10[end_idx * 2 + 1] = 0xff;
+ }
+ end_idx = 11;
+name11_12:
+ end_idx -= 11;
+ for (; end_idx < 2; end_idx++) {
+ slotptr->name11_12[end_idx * 2] = 0xff;
+ slotptr->name11_12[end_idx * 2 + 1] = 0xff;
+ }
+
+ return 1;
+}
+
+static int is_next_clust(fsdata *mydata, dir_entry *dentptr);
+static void flush_dir_table(fsdata *mydata, dir_entry **dentptr);
+
+/*
+ * Fill dir_slot entries with appropriate name, id, and attr
+ * The real directory entry is returned by 'dentptr'
+ */
+static void
+fill_dir_slot(fsdata *mydata, dir_entry **dentptr, const char *l_name)
+{
+ dir_slot *slotptr = (dir_slot *)get_vfatname_block;
+ __u8 counter, checksum;
+ int idx = 0, ret;
+ char s_name[16];
+
+ /* Get short file name and checksum value */
+ strncpy(s_name, (*dentptr)->name, 16);
+ checksum = mkcksum(s_name);
+
+ do {
+ memset(slotptr, 0x00, sizeof(dir_slot));
+ ret = str2slot(slotptr, l_name, &idx);
+ slotptr->id = ++counter;
+ slotptr->attr = ATTR_VFAT;
+ slotptr->alias_checksum = checksum;
+ slotptr++;
+ } while (ret == 0);
+
+ slotptr--;
+ slotptr->id |= LAST_LONG_ENTRY_MASK;
+
+ while (counter >= 1) {
+ if (is_next_clust(mydata, *dentptr)) {
+ /* A new cluster is allocated for directory table */
+ flush_dir_table(mydata, dentptr);
+ }
+ memcpy(*dentptr, slotptr, sizeof(dir_slot));
+ (*dentptr)++;
+ slotptr--;
+ counter--;
+ }
+
+ if (is_next_clust(mydata, *dentptr)) {
+ /* A new cluster is allocated for directory table */
+ flush_dir_table(mydata, dentptr);
+ }
+}
+
+static __u32 dir_curclust;
+
+/*
+ * Extract the full long filename starting at 'retdent' (which is really
+ * a slot) into 'l_name'. If successful also copy the real directory entry
+ * into 'retdent'
+ * If additional adjacent cluster for directory entries is read into memory,
+ * then 'get_vfatname_block' is copied into 'get_dentfromdir_block' and
+ * the location of the real directory entry is returned by 'retdent'
+ * Return 0 on success, -1 otherwise.
+ */
+static int
+get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster,
+ dir_entry **retdent, char *l_name)
+{
+ dir_entry *realdent;
+ dir_slot *slotptr = (dir_slot *)(*retdent);
+ dir_slot *slotptr2 = NULL;
+ __u8 *buflimit = cluster + mydata->sect_size * ((curclust == 0) ?
+ PREFETCH_BLOCKS :
+ mydata->clust_size);
+ __u8 counter = (slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff;
+ int idx = 0, cur_position = 0;
+
+ if (counter > VFAT_MAXSEQ) {
+ debug("Error: VFAT name is too long\n");
+ return -1;
+ }
+
+ while ((__u8 *)slotptr < buflimit) {
+ if (counter == 0)
+ break;
+ if (((slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff) != counter)
+ return -1;
+ slotptr++;
+ counter--;
+ }
+
+ if ((__u8 *)slotptr >= buflimit) {
+ if (curclust == 0)
+ return -1;
+ curclust = get_fatent_value(mydata, dir_curclust);
+ if (CHECK_CLUST(curclust, mydata->fatsize)) {
+ debug("curclust: 0x%x\n", curclust);
+ printf("Invalid FAT entry\n");
+ return -1;
+ }
+
+ dir_curclust = curclust;
+
+ if (get_cluster(mydata, curclust, get_vfatname_block,
+ mydata->clust_size * mydata->sect_size) != 0) {
+ debug("Error: reading directory block\n");
+ return -1;
+ }
+
+ slotptr2 = (dir_slot *)get_vfatname_block;
+ while (counter > 0) {
+ if (((slotptr2->id & ~LAST_LONG_ENTRY_MASK)
+ & 0xff) != counter)
+ return -1;
+ slotptr2++;
+ counter--;
+ }
+
+ /* Save the real directory entry */
+ realdent = (dir_entry *)slotptr2;
+ while ((__u8 *)slotptr2 > get_vfatname_block) {
+ slotptr2--;
+ slot2str(slotptr2, l_name, &idx);
+ }
+ } else {
+ /* Save the real directory entry */
+ realdent = (dir_entry *)slotptr;
+ }
+
+ do {
+ slotptr--;
+ if (slot2str(slotptr, l_name, &idx))
+ break;
+ } while (!(slotptr->id & LAST_LONG_ENTRY_MASK));
+
+ l_name[idx] = '\0';
+ if (*l_name == DELETED_FLAG)
+ *l_name = '\0';
+ else if (*l_name == aRING)
+ *l_name = DELETED_FLAG;
+ downcase(l_name);
+
+ /* Return the real directory entry */
+ *retdent = realdent;
+
+ if (slotptr2) {
+ memcpy(get_dentfromdir_block, get_vfatname_block,
+ mydata->clust_size * mydata->sect_size);
+ cur_position = (__u8 *)realdent - get_vfatname_block;
+ *retdent = (dir_entry *) &get_dentfromdir_block[cur_position];
+ }
+
+ return 0;
+}
+
+#endif
+
+/*
+ * Set the entry at index 'entry' in a FAT (16/32) table.
+ */
+static int set_fatent_value(fsdata *mydata, __u32 entry, __u32 entry_value)
+{
+ __u32 bufnum, offset;
+
+ switch (mydata->fatsize) {
+ case 32:
+ bufnum = entry / FAT32BUFSIZE;
+ offset = entry - bufnum * FAT32BUFSIZE;
+ break;
+ case 16:
+ bufnum = entry / FAT16BUFSIZE;
+ offset = entry - bufnum * FAT16BUFSIZE;
+ break;
+ default:
+ /* Unsupported FAT size */
+ return -1;
+ }
+
+ /* Read a new block of FAT entries into the cache. */
+ if (bufnum != mydata->fatbufnum) {
+ int getsize = FATBUFBLOCKS;
+ __u8 *bufptr = mydata->fatbuf;
+ __u32 fatlength = mydata->fatlength;
+ __u32 startblock = bufnum * FATBUFBLOCKS;
+
+ fatlength *= mydata->sect_size;
+ startblock += mydata->fat_sect;
+
+ if (getsize > fatlength)
+ getsize = fatlength;
+
+ if (mydata->fatbufnum != -1) {
+ if (flush_fat_buffer(mydata) < 0)
+ return -1;
+ }
+
+ if (disk_read(startblock, getsize, bufptr) < 0) {
+ debug("Error reading FAT blocks\n");
+ return -1;
+ }
+ mydata->fatbufnum = bufnum;
+ }
+
+ /* Set the actual entry */
+ switch (mydata->fatsize) {
+ case 32:
+ ((__u32 *) mydata->fatbuf)[offset] = cpu_to_le32(entry_value);
+ break;
+ case 16:
+ ((__u16 *) mydata->fatbuf)[offset] = cpu_to_le16(entry_value);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Determine the entry value at index 'entry' in a FAT (16/32) table
+ */
+static __u32 determine_fatent(fsdata *mydata, __u32 entry)
+{
+ __u32 next_fat, next_entry = entry + 1;
+
+ while (1) {
+ next_fat = get_fatent_value(mydata, next_entry);
+ if (next_fat == 0) {
+ set_fatent_value(mydata, entry, next_entry);
+ break;
+ }
+ next_entry++;
+ }
+ debug("FAT%d: entry: %08x, entry_value: %04x\n",
+ mydata->fatsize, entry, next_entry);
+
+ return next_entry;
+}
+
+/*
+ * Write at most 'size' bytes from 'buffer' into the specified cluster.
+ * Return 0 on success, -1 otherwise.
+ */
+static int
+set_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer,
+ unsigned long size)
+{
+ int idx = 0;
+ __u32 startsect;
+
+ if (clustnum > 0)
+ startsect = mydata->data_begin +
+ clustnum * mydata->clust_size;
+ else
+ startsect = mydata->rootdir_sect;
+
+ debug("clustnum: %d, startsect: %d\n", clustnum, startsect);
+
+ if (disk_write(startsect, size / mydata->sect_size, buffer) < 0) {
+ debug("Error writing data\n");
+ return -1;
+ }
+
+ if (size % mydata->sect_size) {
+ __u8 tmpbuf[mydata->sect_size];
+
+ idx = size / mydata->sect_size;
+ buffer += idx * mydata->sect_size;
+ memcpy(tmpbuf, buffer, size % mydata->sect_size);
+
+ if (disk_write(startsect + idx, 1, tmpbuf) < 0) {
+ debug("Error writing data\n");
+ return -1;
+ }
+
+ return 0;
+ }
+
+ return 0;
+}
+
+/*
+ * Find the first empty cluster
+ */
+static int find_empty_cluster(fsdata *mydata)
+{
+ __u32 fat_val, entry = 3;
+
+ while (1) {
+ fat_val = get_fatent_value(mydata, entry);
+ if (fat_val == 0)
+ break;
+ entry++;
+ }
+
+ return entry;
+}
+
+/*
+ * Write directory entries in 'get_dentfromdir_block' to block device
+ */
+static void flush_dir_table(fsdata *mydata, dir_entry **dentptr)
+{
+ int dir_newclust = 0;
+
+ if (set_cluster(mydata, dir_curclust,
+ get_dentfromdir_block,
+ mydata->clust_size * mydata->sect_size) != 0) {
+ printf("error: wrinting directory entry\n");
+ return;
+ }
+ dir_newclust = find_empty_cluster(mydata);
+ set_fatent_value(mydata, dir_curclust, dir_newclust);
+ if (mydata->fatsize == 32)
+ set_fatent_value(mydata, dir_newclust, 0xffffff8);
+ else if (mydata->fatsize == 16)
+ set_fatent_value(mydata, dir_newclust, 0xfff8);
+
+ dir_curclust = dir_newclust;
+
+ if (flush_fat_buffer(mydata) < 0)
+ return;
+
+ memset(get_dentfromdir_block, 0x00,
+ mydata->clust_size * mydata->sect_size);
+
+ *dentptr = (dir_entry *) get_dentfromdir_block;
+}
+
+/*
+ * Set empty cluster from 'entry' to the end of a file
+ */
+static int clear_fatent(fsdata *mydata, __u32 entry)
+{
+ __u32 fat_val;
+
+ while (1) {
+ fat_val = get_fatent_value(mydata, entry);
+ if (fat_val != 0)
+ set_fatent_value(mydata, entry, 0);
+ else
+ break;
+
+ if (fat_val == 0xfffffff || fat_val == 0xffff)
+ break;
+
+ entry = fat_val;
+ }
+
+ /* Flush fat buffer */
+ if (flush_fat_buffer(mydata) < 0)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Write at most 'maxsize' bytes from 'buffer' into
+ * the file associated with 'dentptr'
+ * Return the number of bytes read or -1 on fatal errors.
+ */
+static int
+set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
+ unsigned long maxsize)
+{
+ unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0;
+ unsigned int bytesperclust = mydata->clust_size * mydata->sect_size;
+ __u32 curclust = START(dentptr);
+ __u32 endclust = 0, newclust = 0;
+ unsigned long actsize;
+
+ debug("Filesize: %ld bytes\n", filesize);
+
+ if (maxsize > 0 && filesize > maxsize)
+ filesize = maxsize;
+
+ debug("%ld bytes\n", filesize);
+
+ actsize = bytesperclust;
+ endclust = curclust;
+ do {
+ /* search for consecutive clusters */
+ while (actsize < filesize) {
+ newclust = determine_fatent(mydata, endclust);
+
+ if ((newclust - 1) != endclust)
+ goto getit;
+
+ if (CHECK_CLUST(newclust, mydata->fatsize)) {
+ debug("curclust: 0x%x\n", newclust);
+ debug("Invalid FAT entry\n");
+ return gotsize;
+ }
+ endclust = newclust;
+ actsize += bytesperclust;
+ }
+ /* actsize >= file size */
+ actsize -= bytesperclust;
+ /* set remaining clusters */
+ if (set_cluster(mydata, curclust, buffer, (int)actsize) != 0) {
+ debug("error: writing cluster\n");
+ return -1;
+ }
+
+ /* set remaining bytes */
+ gotsize += (int)actsize;
+ filesize -= actsize;
+ buffer += actsize;
+ actsize = filesize;
+
+ if (set_cluster(mydata, endclust, buffer, (int)actsize) != 0) {
+ debug("error: writing cluster\n");
+ return -1;
+ }
+ gotsize += actsize;
+
+ /* Mark end of file in FAT */
+ if (mydata->fatsize == 16)
+ newclust = 0xffff;
+ else if (mydata->fatsize == 32)
+ newclust = 0xfffffff;
+ set_fatent_value(mydata, endclust, newclust);
+
+ return gotsize;
+getit:
+ if (set_cluster(mydata, curclust, buffer, (int)actsize) != 0) {
+ debug("error: writing cluster\n");
+ return -1;
+ }
+ gotsize += (int)actsize;
+ filesize -= actsize;
+ buffer += actsize;
+
+ if (CHECK_CLUST(curclust, mydata->fatsize)) {
+ debug("curclust: 0x%x\n", curclust);
+ debug("Invalid FAT entry\n");
+ return gotsize;
+ }
+ actsize = bytesperclust;
+ curclust = endclust = newclust;
+ } while (1);
+}
+
+/*
+ * Fill dir_entry
+ */
+static void fill_dentry(fsdata *mydata, dir_entry *dentptr,
+ const char *filename, __u32 start_cluster, __u32 size, __u8 attr)
+{
+ if (mydata->fatsize == 32)
+ dentptr->starthi =
+ cpu_to_le16((start_cluster & 0xffff0000) >> 16);
+ dentptr->start = cpu_to_le16(start_cluster & 0xffff);
+ dentptr->size = cpu_to_le32(size);
+
+ dentptr->attr = attr;
+
+ set_name(dentptr, filename);
+}
+
+/*
+ * Check whether adding a file makes the file system to
+ * exceed the size of the block device
+ * Return -1 when overflow occurs, otherwise return 0
+ */
+static int check_overflow(fsdata *mydata, __u32 clustnum, unsigned long size)
+{
+ __u32 startsect, sect_num;
+
+ if (clustnum > 0) {
+ startsect = mydata->data_begin +
+ clustnum * mydata->clust_size;
+ } else {
+ startsect = mydata->rootdir_sect;
+ }
+
+ sect_num = size / mydata->sect_size;
+ if (size % mydata->sect_size)
+ sect_num++;
+
+ if (startsect + sect_num > total_sector)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Check if adding several entries exceed one cluster boundary
+ */
+static int is_next_clust(fsdata *mydata, dir_entry *dentptr)
+{
+ int cur_position;
+
+ cur_position = (__u8 *)dentptr - get_dentfromdir_block;
+
+ if (cur_position >= mydata->clust_size * mydata->sect_size)
+ return 1;
+ else
+ return 0;
+}
+
+static dir_entry *empty_dentptr;
+/*
+ * Find a directory entry based on filename or start cluster number
+ * If the directory entry is not found,
+ * the new position for writing a directory entry will be returned
+ */
+static dir_entry *find_directory_entry(fsdata *mydata, int startsect,
+ char *filename, dir_entry *retdent, __u32 start)
+{
+ __u16 prevcksum = 0xffff;
+ __u32 curclust = (startsect - mydata->data_begin) / mydata->clust_size;
+
+ debug("get_dentfromdir: %s\n", filename);
+
+ while (1) {
+ dir_entry *dentptr;
+
+ int i;
+
+ if (get_cluster(mydata, curclust, get_dentfromdir_block,
+ mydata->clust_size * mydata->sect_size) != 0) {
+ printf("Error: reading directory block\n");
+ return NULL;
+ }
+
+ dentptr = (dir_entry *)get_dentfromdir_block;
+
+ dir_curclust = curclust;
+
+ for (i = 0; i < DIRENTSPERCLUST; i++) {
+ char s_name[14], l_name[VFAT_MAXLEN_BYTES];
+
+ l_name[0] = '\0';
+ if (dentptr->name[0] == DELETED_FLAG) {
+ dentptr++;
+ if (is_next_clust(mydata, dentptr))
+ break;
+ continue;
+ }
+ if ((dentptr->attr & ATTR_VOLUME)) {
+#ifdef CONFIG_SUPPORT_VFAT
+ if ((dentptr->attr & ATTR_VFAT) &&
+ (dentptr->name[0] & LAST_LONG_ENTRY_MASK)) {
+ prevcksum =
+ ((dir_slot *)dentptr)->alias_checksum;
+ get_long_file_name(mydata, curclust,
+ get_dentfromdir_block,
+ &dentptr, l_name);
+ debug("vfatname: |%s|\n", l_name);
+ } else
+#endif
+ {
+ /* Volume label or VFAT entry */
+ dentptr++;
+ if (is_next_clust(mydata, dentptr))
+ break;
+ continue;
+ }
+ }
+ if (dentptr->name[0] == 0) {
+ debug("Dentname == NULL - %d\n", i);
+ empty_dentptr = dentptr;
+ return NULL;
+ }
+
+ get_name(dentptr, s_name);
+
+ if (strcmp(filename, s_name)
+ && strcmp(filename, l_name)) {
+ debug("Mismatch: |%s|%s|\n",
+ s_name, l_name);
+ dentptr++;
+ if (is_next_clust(mydata, dentptr))
+ break;
+ continue;
+ }
+
+ memcpy(retdent, dentptr, sizeof(dir_entry));
+
+ debug("DentName: %s", s_name);
+ debug(", start: 0x%x", START(dentptr));
+ debug(", size: 0x%x %s\n",
+ FAT2CPU32(dentptr->size),
+ (dentptr->attr & ATTR_DIR) ?
+ "(DIR)" : "");
+
+ return dentptr;
+ }
+
+ curclust = get_fatent_value(mydata, dir_curclust);
+ if ((curclust >= 0xffffff8) || (curclust >= 0xfff8)) {
+ empty_dentptr = dentptr;
+ return NULL;
+ }
+ if (CHECK_CLUST(curclust, mydata->fatsize)) {
+ debug("curclust: 0x%x\n", curclust);
+ debug("Invalid FAT entry\n");
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+static int do_fat_write(const char *filename, void *buffer,
+ unsigned long size)
+{
+ dir_entry *dentptr, *retdent;
+ dir_slot *slotptr;
+ __u32 startsect;
+ __u32 start_cluster;
+ boot_sector bs;
+ volume_info volinfo;
+ fsdata datablock;
+ fsdata *mydata = &datablock;
+ int cursect;
+ int root_cluster, ret = -1, name_len;
+ char l_filename[VFAT_MAXLEN_BYTES];
+
+ dir_curclust = 0;
+
+ if (read_bootsectandvi(&bs, &volinfo, &mydata->fatsize)) {
+ debug("error: reading boot sector\n");
+ return -1;
+ }
+
+ total_sector = bs.total_sect;
+ if (total_sector == 0)
+ total_sector = part_size;
+
+ root_cluster = bs.root_cluster;
+
+ if (mydata->fatsize == 32)
+ mydata->fatlength = bs.fat32_length;
+ else
+ mydata->fatlength = bs.fat_length;
+
+ mydata->fat_sect = bs.reserved;
+
+ cursect = mydata->rootdir_sect
+ = mydata->fat_sect + mydata->fatlength * bs.fats;
+
+ mydata->sect_size = (bs.sector_size[1] << 8) + bs.sector_size[0];
+ mydata->clust_size = bs.cluster_size;
+
+ if (mydata->fatsize == 32) {
+ mydata->data_begin = mydata->rootdir_sect -
+ (mydata->clust_size * 2);
+ } else {
+ int rootdir_size;
+
+ rootdir_size = ((bs.dir_entries[1] * (int)256 +
+ bs.dir_entries[0]) *
+ sizeof(dir_entry)) /
+ mydata->sect_size;
+ mydata->data_begin = mydata->rootdir_sect +
+ rootdir_size -
+ (mydata->clust_size * 2);
+ }
+
+ mydata->fatbufnum = -1;
+ mydata->fatbuf = malloc(FATBUFSIZE);
+ if (mydata->fatbuf == NULL) {
+ debug("Error: allocating memory\n");
+ return -1;
+ }
+
+ if (disk_read(cursect,
+ (mydata->fatsize == 32) ?
+ (mydata->clust_size) :
+ PREFETCH_BLOCKS, do_fat_read_block) < 0) {
+ debug("Error: reading rootdir block\n");
+ goto exit;
+ }
+ dentptr = (dir_entry *) do_fat_read_block;
+
+ name_len = strlen(filename);
+ memcpy(l_filename, filename, name_len);
+ downcase(l_filename);
+
+ startsect = mydata->rootdir_sect;
+ retdent = find_directory_entry(mydata, startsect,
+ l_filename, dentptr, 0);
+ if (retdent) {
+ /* Update file size and start_cluster in a directory entry */
+ retdent->size = cpu_to_le32(size);
+ start_cluster = FAT2CPU16(retdent->start);
+ if (mydata->fatsize == 32)
+ start_cluster |=
+ (FAT2CPU16(retdent->starthi) << 16);
+
+ ret = check_overflow(mydata, start_cluster, size);
+ if (ret) {
+ printf("Error: %ld overflow\n", size);
+ goto exit;
+ }
+
+ ret = clear_fatent(mydata, start_cluster);
+ if (ret) {
+ printf("Error: clearing FAT entries\n");
+ goto exit;
+ }
+
+ ret = set_contents(mydata, retdent, buffer, size);
+ if (ret) {
+ printf("Error: writing contents\n");
+ goto exit;
+ }
+
+ /* Flush fat buffer */
+ ret = flush_fat_buffer(mydata);
+ if (ret) {
+ printf("Error: flush fat buffer\n");
+ goto exit;
+ }
+
+ /* Write directory table to device */
+ ret = set_cluster(mydata, dir_curclust,
+ get_dentfromdir_block,
+ mydata->clust_size * mydata->sect_size);
+ if (ret) {
+ printf("Error: wrinting directory entry\n");
+ goto exit;
+ }
+ } else {
+ slotptr = (dir_slot *)empty_dentptr;
+
+ /* Set short name to set alias checksum field in dir_slot */
+ set_name(empty_dentptr, filename);
+ fill_dir_slot(mydata, &empty_dentptr, filename);
+
+ ret = start_cluster = find_empty_cluster(mydata);
+ if (ret < 0) {
+ printf("Error: finding empty cluster\n");
+ goto exit;
+ }
+
+ ret = check_overflow(mydata, start_cluster, size);
+ if (ret) {
+ printf("Error: %ld overflow\n", size);
+ goto exit;
+ }
+
+ /* Set attribute as archieve for regular file */
+ fill_dentry(mydata, empty_dentptr, filename,
+ start_cluster, size, 0x20);
+
+ ret = set_contents(mydata, empty_dentptr, buffer, size);
+ if (ret) {
+ printf("Error: writing contents\n");
+ goto exit;
+ }
+
+ /* Flush fat buffer */
+ ret = flush_fat_buffer(mydata);
+ if (ret) {
+ printf("Error: flush fat buffer\n");
+ goto exit;
+ }
+
+ /* Write directory table to device */
+ ret = set_cluster(mydata, dir_curclust,
+ get_dentfromdir_block,
+ mydata->clust_size * mydata->sect_size);
+ if (ret) {
+ printf("Error: writing directory entry\n");
+ goto exit;
+ }
+ }
+
+exit:
+ free(mydata->fatbuf);
+ return ret;
+}
+
+int file_fat_write(const char *filename, void *buffer, unsigned long maxsize)
+{
+ printf("writing %s\n", filename);
+ return do_fat_write(filename, buffer, maxsize);
+}
int force, int isShrink, int shadows);
static void yaffs_RemoveObjectFromDirectory(yaffs_Object * obj);
static int yaffs_CheckStructures(void);
-static int yaffs_DeleteWorker(yaffs_Object * in, yaffs_Tnode * tn, __u32 level,
- int chunkOffset, int *limit);
static int yaffs_DoGenericObjectDeletion(yaffs_Object * in);
static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blockNo);
obj->objectId));
}
-
-
-static int yaffs_VerifyTnodeWorker(yaffs_Object * obj, yaffs_Tnode * tn,
- __u32 level, int chunkOffset)
-{
- int i;
- yaffs_Device *dev = obj->myDev;
- int ok = 1;
-
- if (tn) {
- if (level > 0) {
-
- for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++){
- if (tn->internal[i]) {
- ok = yaffs_VerifyTnodeWorker(obj,
- tn->internal[i],
- level - 1,
- (chunkOffset<<YAFFS_TNODES_INTERNAL_BITS) + i);
- }
- }
- } else if (level == 0) {
- int i;
- yaffs_ExtendedTags tags;
- __u32 objectId = obj->objectId;
-
- chunkOffset <<= YAFFS_TNODES_LEVEL0_BITS;
-
- for(i = 0; i < YAFFS_NTNODES_LEVEL0; i++){
- __u32 theChunk = yaffs_GetChunkGroupBase(dev,tn,i);
-
- if(theChunk > 0){
- /* T(~0,(TSTR("verifying (%d:%d) %d"TENDSTR),tags.objectId,tags.chunkId,theChunk)); */
- yaffs_ReadChunkWithTagsFromNAND(dev,theChunk,NULL, &tags);
- if(tags.objectId != objectId || tags.chunkId != chunkOffset){
- T(~0,(TSTR("Object %d chunkId %d NAND mismatch chunk %d tags (%d:%d)"TENDSTR),
- objectId, chunkOffset, theChunk,
- tags.objectId, tags.chunkId));
- }
- }
- chunkOffset++;
- }
- }
- }
-
- return ok;
-
-}
-
-
static void yaffs_VerifyFile(yaffs_Object *obj)
{
int requiredTallness;
return -1;
}
-
-/* DeleteWorker scans backwards through the tnode tree and deletes all the
- * chunks and tnodes in the file
- * Returns 1 if the tree was deleted.
- * Returns 0 if it stopped early due to hitting the limit and the delete is incomplete.
- */
-
-static int yaffs_DeleteWorker(yaffs_Object * in, yaffs_Tnode * tn, __u32 level,
- int chunkOffset, int *limit)
-{
- int i;
- int chunkInInode;
- int theChunk;
- yaffs_ExtendedTags tags;
- int foundChunk;
- yaffs_Device *dev = in->myDev;
-
- int allDone = 1;
-
- if (tn) {
- if (level > 0) {
-
- for (i = YAFFS_NTNODES_INTERNAL - 1; allDone && i >= 0;
- i--) {
- if (tn->internal[i]) {
- if (limit && (*limit) < 0) {
- allDone = 0;
- } else {
- allDone =
- yaffs_DeleteWorker(in,
- tn->
- internal
- [i],
- level -
- 1,
- (chunkOffset
- <<
- YAFFS_TNODES_INTERNAL_BITS)
- + i,
- limit);
- }
- if (allDone) {
- yaffs_FreeTnode(dev,
- tn->
- internal[i]);
- tn->internal[i] = NULL;
- }
- }
-
- }
- return (allDone) ? 1 : 0;
- } else if (level == 0) {
- int hitLimit = 0;
-
- for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0 && !hitLimit;
- i--) {
- theChunk = yaffs_GetChunkGroupBase(dev,tn,i);
- if (theChunk) {
-
- chunkInInode =
- (chunkOffset <<
- YAFFS_TNODES_LEVEL0_BITS) + i;
-
- foundChunk =
- yaffs_FindChunkInGroup(dev,
- theChunk,
- &tags,
- in->objectId,
- chunkInInode);
-
- if (foundChunk > 0) {
- yaffs_DeleteChunk(dev,
- foundChunk, 1,
- __LINE__);
- in->nDataChunks--;
- if (limit) {
- *limit = *limit - 1;
- if (*limit <= 0) {
- hitLimit = 1;
- }
- }
-
- }
-
- yaffs_PutLevel0Tnode(dev,tn,i,0);
- }
-
- }
- return (i < 0) ? 1 : 0;
-
- }
-
- }
-
- return 1;
-
-}
-
static void yaffs_SoftDeleteChunk(yaffs_Device * dev, int chunk)
{
int nBytes)
{
- __u32 chunk;
- __u32 start;
+ __u32 chunk = 0;
+ __u32 start = 0;
int nToCopy;
int n = nBytes;
int nDone = 0;
int nBytes, int writeThrough)
{
- __u32 chunk;
- __u32 start;
+ __u32 chunk = 0;
+ __u32 start = 0;
int nToCopy;
int n = nBytes;
int nDone = 0;
{
int oldFileSize = in->variant.fileVariant.fileSize;
- __u32 newSizeOfPartialChunk;
- __u32 newFullChunks;
+ __u32 newSizeOfPartialChunk = 0;
+ __u32 newFullChunks = 0;
yaffs_Device *dev = in->myDev;
#include <flash.h>
#include <image.h>
-#ifdef DEBUG
-#define debug(fmt,args...) printf (fmt ,##args)
-#define debugX(level,fmt,args...) if (DEBUG>=level) printf(fmt,##args);
-#else
-#define debug(fmt,args...)
-#define debugX(level,fmt,args...)
-#endif /* DEBUG */
-
#ifdef DEBUG
-# define _DEBUG 1
+#define _DEBUG 1
#else
-# define _DEBUG 0
+#define _DEBUG 0
#endif
+/*
+ * Output a debug text when condition "cond" is met. The "cond" should be
+ * computed by a preprocessor in the best case, allowing for the best
+ * optimization.
+ */
+#define debug_cond(cond, fmt, args...) \
+ do { \
+ if (cond) \
+ printf(fmt, ##args); \
+ } while (0)
+
+#define debug(fmt, args...) \
+ debug_cond(_DEBUG, fmt, ##args)
+
/*
* An assertion is run-time check done in debug mode only. If DEBUG is not
* defined then it is skipped. If DEBUG is defined and the assertion fails,
int last_stage_init(void);
extern ulong monitor_flash_len;
int mac_read_from_eeprom(void);
+extern u8 _binary_dt_dtb_start[]; /* embedded device tree blob */
/* common/flash.c */
void flash_perror (int);
int source (ulong addr, const char *fit_uname);
extern ulong load_addr; /* Default Load Address */
+extern ulong save_addr; /* Default Save Address */
+extern ulong save_size; /* Default Save Size */
/* common/cmd_doc.c */
void doc_probe(unsigned long physadr);
int inline setenv (const char *, const char *);
#else
int setenv (const char *, const char *);
+int setenv_ulong(const char *varname, ulong value);
+int setenv_addr(const char *varname, const void *addr);
#endif /* CONFIG_PPC */
#ifdef CONFIG_ARM
# include <asm/mach-types.h>
int sprintf(char * buf, const char *fmt, ...)
__attribute__ ((format (__printf__, 2, 3)));
int vsprintf(char *buf, const char *fmt, va_list args);
+char *simple_itoa(ulong i);
/* lib/strmhz.c */
char * strmhz(char *buf, unsigned long hz);
#include <asm/cache.h>
#endif
+/*
+ * The ALLOC_CACHE_ALIGN_BUFFER macro is used to allocate a buffer on the
+ * stack that meets the minimum architecture alignment requirements for DMA.
+ * Such a buffer is useful for DMA operations where flushing and invalidating
+ * the cache before and after a read and/or write operation is required for
+ * correct operations.
+ *
+ * When called the macro creates an array on the stack that is sized such
+ * that:
+ *
+ * 1) The beginning of the array can be advanced enough to be aligned.
+ *
+ * 2) The size of the aligned portion of the array is a multiple of the minimum
+ * architecture alignment required for DMA.
+ *
+ * 3) The aligned portion contains enough space for the original number of
+ * elements requested.
+ *
+ * The macro then creates a pointer to the aligned portion of this array and
+ * assigns to the pointer the address of the first element in the aligned
+ * portion of the array.
+ *
+ * Calling the macro as:
+ *
+ * ALLOC_CACHE_ALIGN_BUFFER(uint32_t, buffer, 1024);
+ *
+ * Will result in something similar to saying:
+ *
+ * uint32_t buffer[1024];
+ *
+ * The following differences exist:
+ *
+ * 1) The resulting buffer is guaranteed to be aligned to the value of
+ * ARCH_DMA_MINALIGN.
+ *
+ * 2) The buffer variable created by the macro is a pointer to the specified
+ * type, and NOT an array of the specified type. This can be very important
+ * if you want the address of the buffer, which you probably do, to pass it
+ * to the DMA hardware. The value of &buffer is different in the two cases.
+ * In the macro case it will be the address of the pointer, not the address
+ * of the space reserved for the buffer. However, in the second case it
+ * would be the address of the buffer. So if you are replacing hard coded
+ * stack buffers with this macro you need to make sure you remove the & from
+ * the locations where you are taking the address of the buffer.
+ *
+ * Note that the size parameter is the number of array elements to allocate,
+ * not the number of bytes.
+ *
+ * This macro can not be used outside of function scope, or for the creation
+ * of a function scoped static buffer. It can not be used to create a cache
+ * line aligned global buffer.
+ */
+#define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \
+ char __##name[ROUND(size * sizeof(type), ARCH_DMA_MINALIGN) + \
+ ARCH_DMA_MINALIGN - 1]; \
+ \
+ type *name = (type *) ALIGN((uintptr_t)__##name, ARCH_DMA_MINALIGN)
+
/* Pull in stuff for the build system */
#ifdef DO_DEPS_ONLY
# include <environment.h>
#define CONFIG_PREBOOT ""
#define CONFIG_BOOTDELAY 5
+#ifndef __ASSEMBLY__
+#include <galileo/core.h>
+#endif
+
/*
* BOOTP options
*/
#define CONFIG_PREBOOT ""
#define CONFIG_BOOTDELAY 5
+#ifndef __ASSEMBLY__
+#include <galileo/core.h>
+#endif
+
/*
* BOOTP options
*/
#define CONFIG_CMD_BSP
#define CONFIG_CMD_NAND
-#define BOARD_LATE_INIT
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_SYS_HUSH_PARSER
#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
*/
#define CONFIG_PXA250 1 /* This is an PXA250 CPU */
#define CONFIG_CERF250 1 /* on Cerf PXA Board */
-#define BOARD_LATE_INIT 1
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_BAUDRATE 38400
#define CONFIG_SYS_TEXT_BASE 0x0
#define CONFIG_PXA27X 1 /* Marvell PXA270 CPU */
#define CONFIG_VPAC270 1 /* Toradex Colibri PXA270 board */
-#undef BOARD_LATE_INIT
+#undef CONFIG_BOARD_LATE_INIT
#undef CONFIG_USE_IRQ
#undef CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024)
#define CONFIG_BOARD_EARLY_INIT_F
-#define BOARD_LATE_INIT
+#define CONFIG_BOARD_LATE_INIT
/*
* Hardware drivers
/* EET platform additions */
#ifdef CONFIG_IMX31_PHYCORE_EET
-#define BOARD_LATE_INIT
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_MXC_GPIO
#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_INITRD_TAG 1
-#define BOARD_LATE_INIT 1
+#define CONFIG_BOARD_LATE_INIT
/*
* Compressions
#define CONFIG_POST_EXTERNAL_WORD_FUNCS
#define CONFIG_CMD_DIAG
-/* enable POST tests with log */
-#define CONFIG_POST (CONFIG_SYS_POST_MEM_REGIONS)
-#define CONFIG_POST_SKIP_ENV_FLAGS
-#define CONFIG_POST_EXTERNAL_WORD_FUNCS
-#define CONFIG_CMD_DIAG
-
#endif /* _CONFIG_KM_ARM_H */
#define CONFIG_SHARP_LM8V31
#endif
#define CONFIG_MMC
-#define BOARD_LATE_INIT 1
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_DOS_PARTITION
#define CONFIG_SYS_TEXT_BASE 0x0
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
#undef CONFIG_ECC /* disable ECC support */
+#ifndef __ASSEMBLY__
+#include <galileo/core.h>
+#endif
+
/* Board-specific Initialization Functions to be called */
#define CONFIG_SYS_BOARD_ASM_INIT
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_SCIF_CONSOLE 1
#define CONFIG_BAUDRATE 38400
#define CONFIG_CONS_SCIF1 1
-#define BOARD_LATE_INIT 1
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_BOOTDELAY -1
#define CONFIG_BOOTARGS "console=ttySC0,38400"
/* #define _CONFIG_UART2 */ /* internal uart 2 */
/* #define CONFIG_SILENT_CONSOLE */ /* use this to disable output */
-#define BOARD_LATE_INIT 1
+#define CONFIG_BOARD_LATE_INIT
#define USE_920T_MMU 1
#if 0
*/
#undef CONFIG_CMD_IMLS
-#define BOARD_LATE_INIT
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_BOOTDELAY 3
#define CONFIG_SYS_64BIT_VSPRINTF
#define CONFIG_BOARD_EARLY_INIT_F
-#define BOARD_LATE_INIT
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */
#define CONFIG_REVISION_TAG
*/
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024)
-#define BOARD_LATE_INIT
+#define CONFIG_BOARD_LATE_INIT
/*
* Hardware drivers
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024)
#define CONFIG_BOARD_EARLY_INIT_F
-#define BOARD_LATE_INIT
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_MXC_GPIO
#define CONFIG_MXC_UART
#define CONFIG_SYS_MEMTEST_END 0x0FFFFFFF
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 256 * 1024)
-#define BOARD_LATE_INIT /* call board_late_init during start up */
+#define CONFIG_BOARD_LATE_INIT /* call board_late_init during start up */
/* timing informazion */
#define CONFIG_SYS_HZ 1000 /* Mandatory... */
#define L2_ENABLE (L2_INIT | L2CR_L2E)
+#ifndef __ASSEMBLY__
+#include <../board/Marvell/include/core.h>
+#endif
+
#endif /* __CONFIG_H */
#define CONFIG_PLEB2 1 /* on an PLEB2 Board */
#undef CONFIG_LCD
#undef CONFIG_MMC
-#define BOARD_LATE_INIT 1
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_SYS_TEXT_BASE 0x0
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
#define CONFIG_SYS_TEXT_BASE 0xFFF00000
+#ifndef __ASSEMBLY__
+#include <galileo/core.h>
+#endif
+
/*
* Monitor configuration
*
#define CONFIG_MMC 1
#define CONFIG_DOS_PARTITION 1
-#define BOARD_LATE_INIT 1
+#define CONFIG_BOARD_LATE_INIT
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
#define CONFIG_CMD_SETEXPR
#define CONFIG_CMD_SPI
-#define BOARD_LATE_INIT
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_BOOTDELAY 5
#define CONFIG_SCIF_CONSOLE 1
#define CONFIG_BAUDRATE 115200
#define CONFIG_CONS_SCIF1 1
-#define BOARD_LATE_INIT 1
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_BOOTDELAY -1
#define CONFIG_BOOTARGS "console=ttySC0,115200"
#define SH7757LCR_ETHERNET_MAC_BASE SH7757LCR_ETHERNET_MAC_BASE_SPI
#define SH7757LCR_ETHERNET_MAC_SIZE 17
#define SH7757LCR_ETHERNET_NUM_CH 2
-#define BOARD_LATE_INIT 1
+#define CONFIG_BOARD_LATE_INIT
/* Gigabit Ether */
#define SH7757LCR_GIGA_ETHERNET_NUM_CH 2
#define CONFIG_MACH_TEGRA_GENERIC /* which is a Tegra generic machine */
#define CONFIG_SYS_L2CACHE_OFF /* No L2 cache */
+#define CONFIG_SYS_CACHELINE_SIZE 32
+
#define CONFIG_ENABLE_CORTEXA9 /* enable CPU (A9 complex) */
#include <asm/arch/tegra2.h> /* get chip and board defs */
#define CONFIG_PXA27X 1 /* This is an PXA27x CPU */
#define CONFIG_MMC 1
-#define BOARD_LATE_INIT 1
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_SYS_TEXT_BASE 0x0
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
#define CONFIG_FEC_MXC_PHYADDR 0x1f
#define CONFIG_MII
#define CONFIG_CMD_NET
-#define BOARD_LATE_INIT
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_ENV_OVERWRITE
#define CONFIG_BOOTDELAY 5
#define CONFIG_SYS_HZ 1000 /* must be 1000 */
#define CONFIG_BOARD_EARLY_INIT_F
-#define BOARD_LATE_INIT
+#define CONFIG_BOARD_LATE_INIT
/*
* Size of malloc() pool
#define CONFIG_REVISION_TAG
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG
-#define BOARD_LATE_INIT
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_MACH_TYPE MACH_TYPE_TTC_VISION2
#define CONFIG_SYS_TEXT_BASE 0x0
-#define BOARD_LATE_INIT 1
+#define CONFIG_BOARD_LATE_INIT
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
#define CONFIG_ZIPITZ2 1 /* Zipit Z2 board */
#define CONFIG_SYS_TEXT_BASE 0x0
-#undef BOARD_LATE_INIT
+#undef CONFIG_BOARD_LATE_INIT
#undef CONFIG_USE_IRQ
#undef CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG
-#define BOARD_LATE_INIT
+#define CONFIG_BOARD_LATE_INIT
/*
* Compressions
#endif
#define TOLOWER(c) if((c) >= 'A' && (c) <= 'Z'){(c)+=('a' - 'A');}
+#define TOUPPER(c) if ((c) >= 'a' && (c) <= 'z') \
+ (c) -= ('a' - 'A');
#define START(dent) (FAT2CPU16((dent)->start) \
+ (mydata->fatsize != 32 ? 0 : \
(FAT2CPU16((dent)->starthi) << 16)))
const char *file_getfsname(int idx);
int fat_register_device(block_dev_desc_t *dev_desc, int part_no);
+int file_fat_write(const char *filename, void *buffer, unsigned long maxsize);
#endif /* _FAT_H_ */
--- /dev/null
+/*
+ * 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
+ */
+
+
+/*
+ * This file contains convenience functions for decoding useful and
+ * enlightening information from FDTs. It is intended to be used by device
+ * drivers and board-specific code within U-Boot. It aims to reduce the
+ * amount of FDT munging required within U-Boot itself, so that driver code
+ * changes to support FDT are minimized.
+ */
+
+#include <libfdt.h>
+
+/*
+ * A typedef for a physical address. Note that fdt data is always big
+ * endian even on a litle endian machine.
+ */
+#ifdef CONFIG_PHYS_64BIT
+typedef u64 fdt_addr_t;
+#define FDT_ADDR_T_NONE (-1ULL)
+#define fdt_addr_to_cpu(reg) be64_to_cpu(reg)
+#else
+typedef u32 fdt_addr_t;
+#define FDT_ADDR_T_NONE (-1U)
+#define fdt_addr_to_cpu(reg) be32_to_cpu(reg)
+#endif
+
+/* Information obtained about memory from the FDT */
+struct fdt_memory {
+ fdt_addr_t start;
+ fdt_addr_t end;
+};
+
+/**
+ * Compat types that we know about and for which we might have drivers.
+ * Each is named COMPAT_<dir>_<filename> where <dir> is the directory
+ * within drivers.
+ */
+enum fdt_compat_id {
+ COMPAT_UNKNOWN,
+
+ COMPAT_COUNT,
+};
+
+/**
+ * Find the next numbered alias for a peripheral. This is used to enumerate
+ * all the peripherals of a certain type.
+ *
+ * Do the first call with *upto = 0. Assuming /aliases/<name>0 exists then
+ * this function will return a pointer to the node the alias points to, and
+ * then update *upto to 1. Next time you call this function, the next node
+ * will be returned.
+ *
+ * All nodes returned will match the compatible ID, as it is assumed that
+ * all peripherals use the same driver.
+ *
+ * @param blob FDT blob to use
+ * @param name Root name of alias to search for
+ * @param id Compatible ID to look for
+ * @return offset of next compatible node, or -FDT_ERR_NOTFOUND if no more
+ */
+int fdtdec_next_alias(const void *blob, const char *name,
+ enum fdt_compat_id id, int *upto);
+
+/**
+ * Look up an address property in a node and return it as an address.
+ * The property must hold either one address with no trailing data or
+ * one address with a length. This is only tested on 32-bit machines.
+ *
+ * @param blob FDT blob
+ * @param node node to examine
+ * @param prop_name name of property to find
+ * @return address, if found, or FDT_ADDR_T_NONE if not
+ */
+fdt_addr_t fdtdec_get_addr(const void *blob, int node,
+ const char *prop_name);
+
+/**
+ * Look up a 32-bit integer property in a node and return it. The property
+ * must have at least 4 bytes of data. The value of the first cell is
+ * returned.
+ *
+ * @param blob FDT blob
+ * @param node node to examine
+ * @param prop_name name of property to find
+ * @param default_val default value to return if the property is not found
+ * @return integer value, if found, or default_val if not
+ */
+s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
+ s32 default_val);
+
+/**
+ * Checks whether a node is enabled.
+ * This looks for a 'status' property. If this exists, then returns 1 if
+ * the status is 'ok' and 0 otherwise. If there is no status property,
+ * it returns the default value.
+ *
+ * @param blob FDT blob
+ * @param node node to examine
+ * @param default_val default value to return if no 'status' property exists
+ * @return integer value 0/1, if found, or default_val if not
+ */
+int fdtdec_get_is_enabled(const void *blob, int node, int default_val);
+
+/**
+ * Checks whether we have a valid fdt available to control U-Boot, and panic
+ * if not.
+ */
+int fdtdec_check_fdt(void);
*/
#define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */
-#if defined(CONFIG_I2C_MULTI_BUS)
-#if !defined(CONFIG_SYS_MAX_I2C_BUS)
-#define CONFIG_SYS_MAX_I2C_BUS 2
-#endif
-#define I2C_GET_BUS() i2c_get_bus_num()
-#define I2C_SET_BUS(a) i2c_set_bus_num(a)
+#ifdef CONFIG_I2C_MULTI_BUS
+#define MAX_I2C_BUS 2
+#define I2C_MULTI_BUS 1
#else
-#define CONFIG_SYS_MAX_I2C_BUS 1
-#define I2C_GET_BUS() 0
-#define I2C_SET_BUS(a)
+#define MAX_I2C_BUS 1
+#define I2C_MULTI_BUS 0
+#endif
+
+#if !defined(CONFIG_SYS_MAX_I2C_BUS)
+#define CONFIG_SYS_MAX_I2C_BUS MAX_I2C_BUS
#endif
/* define the I2C bus number for RTC and DTT if not already done */
unsigned int i2c_get_bus_speed(void);
+/* NOTE: These two functions MUST be always_inline to avoid code growth! */
+static inline unsigned int I2C_GET_BUS(void) __attribute__((always_inline));
+static inline unsigned int I2C_GET_BUS(void)
+{
+ return I2C_MULTI_BUS ? i2c_get_bus_num() : 0;
+}
+
+static inline void I2C_SET_BUS(unsigned int bus) __attribute__((always_inline));
+static inline void I2C_SET_BUS(unsigned int bus)
+{
+ if (I2C_MULTI_BUS)
+ i2c_set_bus_num(bus);
+}
+
#endif /* _I2C_H_ */
#ifndef USE_HOSTCC
static inline int fit_image_check_target_arch(const void *fdt, int node)
{
- return !fit_image_check_arch(fdt, node, IH_ARCH_DEFAULT);
+ return fit_image_check_arch(fdt, node, IH_ARCH_DEFAULT);
}
#endif /* USE_HOSTCC */
#elif defined(CONFIG_ATMEL_LCD)
typedef struct vidinfo {
- u_long vl_col; /* Number of columns (i.e. 640) */
- u_long vl_row; /* Number of rows (i.e. 480) */
+ ushort vl_col; /* Number of columns (i.e. 640) */
+ ushort vl_row; /* Number of rows (i.e. 480) */
u_long vl_clk; /* pixel clock in ps */
/* LCD configuration register */
IPaddr_t sip, unsigned sport,
unsigned len);
+/**
+ * An incoming ICMP packet handler.
+ * @param type ICMP type
+ * @param code ICMP code
+ * @param dport destination UDP port
+ * @param sip source IP address
+ * @param sport source UDP port
+ * @param pkt pointer to the ICMP packet data
+ * @param len packet length
+ */
+typedef void rxhand_icmp_f(unsigned type, unsigned code, unsigned dport,
+ IPaddr_t sip, unsigned sport, uchar *pkt, unsigned len);
+
/*
* A timeout handler. Called after time interval has expired.
*/
* ICMP stuff (just enough to handle (host) redirect messages)
*/
#define ICMP_ECHO_REPLY 0 /* Echo reply */
+#define ICMP_NOT_REACH 3 /* Detination unreachable */
#define ICMP_REDIRECT 5 /* Redirect (change route) */
#define ICMP_ECHO_REQUEST 8 /* Echo request */
#define ICMP_REDIR_NET 0 /* Redirect Net */
#define ICMP_REDIR_HOST 1 /* Redirect Host */
+/* Codes for NOT_REACH */
+#define ICMP_NOT_REACH_PORT 3 /* Port unreachable */
+
typedef struct icmphdr {
uchar type;
uchar code;
ushort __unused;
ushort mtu;
} frag;
+ uchar data[0];
} un;
} ICMP_t;
extern int NetRestartWrap; /* Tried all network devices */
-typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
- TFTPSRV } proto_t;
+enum proto_t {
+ BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
+ TFTPSRV, TFTPPUT
+};
/* from net/net.c */
extern char BootFile[128]; /* Boot File name */
#endif
/* Initialize the network adapter */
-extern int NetLoop(proto_t);
+extern int NetLoop(enum proto_t);
/* Shutdown adapters and cleanup */
extern void NetStop(void);
/* Set callbacks */
extern void NetSetHandler(rxhand_f *); /* Set RX packet handler */
+extern void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */
extern void NetSetTimeout(ulong, thand_f *);/* Set timeout handler */
/* Transmit "NetTxPacket" */
/* Processes a received packet */
extern void NetReceive(volatile uchar *, int);
+/*
+ * Check if autoload is enabled. If so, use either NFS or TFTP to download
+ * the boot file.
+ */
+void net_auto_load(void);
+
/*
* The following functions are a bit ugly, but necessary to deal with
* alignment restrictions on ARM.
/* Driver initialization prototypes */
int altera_tse_initialize(u8 dev_num, int mac_base,
- int sgdma_rx_base, int sgdma_tx_base);
+ int sgdma_rx_base, int sgdma_tx_base,
+ u32 sgdma_desc_base, u32 sgdma_desc_size);
int at91emac_register(bd_t *bis, unsigned long iobase);
int au1x00_enet_initialize(bd_t*);
int ax88180_initialize(bd_t *bis);
COBJS-y += crc32.o
COBJS-y += display_options.o
COBJS-y += errno.o
+COBJS-$(CONFIG_OF_CONTROL) += fdtdec.o
COBJS-$(CONFIG_GZIP) += gunzip.o
COBJS-y += hashtable.o
COBJS-$(CONFIG_LMB) += lmb.o
--- /dev/null
+/*
+ * 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
+ */
+
+#include <common.h>
+#include <serial.h>
+#include <libfdt.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Here are the type we know about. One day we might allow drivers to
+ * register. For now we just put them here. The COMPAT macro allows us to
+ * turn this into a sparse list later, and keeps the ID with the name.
+ */
+#define COMPAT(id, name) name
+static const char * const compat_names[COMPAT_COUNT] = {
+};
+
+/**
+ * Look in the FDT for an alias with the given name and return its node.
+ *
+ * @param blob FDT blob
+ * @param name alias name to look up
+ * @return node offset if found, or an error code < 0 otherwise
+ */
+static int find_alias_node(const void *blob, const char *name)
+{
+ const char *path;
+ int alias_node;
+
+ debug("find_alias_node: %s\n", name);
+ alias_node = fdt_path_offset(blob, "/aliases");
+ if (alias_node < 0)
+ return alias_node;
+ path = fdt_getprop(blob, alias_node, name, NULL);
+ if (!path)
+ return -FDT_ERR_NOTFOUND;
+ return fdt_path_offset(blob, path);
+}
+
+fdt_addr_t fdtdec_get_addr(const void *blob, int node,
+ const char *prop_name)
+{
+ const fdt_addr_t *cell;
+ int len;
+
+ debug("get_addr: %s\n", prop_name);
+ cell = fdt_getprop(blob, node, prop_name, &len);
+ if (cell && (len == sizeof(fdt_addr_t) ||
+ len == sizeof(fdt_addr_t) * 2))
+ return fdt_addr_to_cpu(*cell);
+ return FDT_ADDR_T_NONE;
+}
+
+s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
+ s32 default_val)
+{
+ const s32 *cell;
+ int len;
+
+ debug("get_size: %s\n", prop_name);
+ cell = fdt_getprop(blob, node, prop_name, &len);
+ if (cell && len >= sizeof(s32))
+ return fdt32_to_cpu(cell[0]);
+ return default_val;
+}
+
+int fdtdec_get_is_enabled(const void *blob, int node, int default_val)
+{
+ const char *cell;
+
+ cell = fdt_getprop(blob, node, "status", NULL);
+ if (cell)
+ return 0 == strcmp(cell, "ok");
+ return default_val;
+}
+
+enum fdt_compat_id fd_dec_lookup(const void *blob, int node)
+{
+ enum fdt_compat_id id;
+
+ /* Search our drivers */
+ for (id = COMPAT_UNKNOWN; id < COMPAT_COUNT; id++)
+ if (0 == fdt_node_check_compatible(blob, node,
+ compat_names[id]))
+ return id;
+ return COMPAT_UNKNOWN;
+}
+
+int fdtdec_next_compatible(const void *blob, int node,
+ enum fdt_compat_id id)
+{
+ return fdt_node_offset_by_compatible(blob, node, compat_names[id]);
+}
+
+int fdtdec_next_alias(const void *blob, const char *name,
+ enum fdt_compat_id id, int *upto)
+{
+#define MAX_STR_LEN 20
+ char str[MAX_STR_LEN + 20];
+ int node, err;
+
+ /* snprintf() is not available */
+ assert(strlen(name) < MAX_STR_LEN);
+ sprintf(str, "%.*s%d", MAX_STR_LEN, name, *upto);
+ (*upto)++;
+ node = find_alias_node(blob, str);
+ if (node < 0)
+ return node;
+ err = fdt_node_check_compatible(blob, node, compat_names[id]);
+ if (err < 0)
+ return err;
+ return err ? -FDT_ERR_NOTFOUND : node;
+}
+
+/*
+ * This function is a little odd in that it accesses global data. At some
+ * point if the architecture board.c files merge this will make more sense.
+ * Even now, it is common code.
+ */
+int fdtdec_check_fdt(void)
+{
+ /* We must have an fdt */
+ if (fdt_check_header(gd->fdt_blob))
+ panic("No valid fdt found - please append one to U-Boot\n"
+ "binary or define CONFIG_OF_EMBED\n");
+ return 0;
+}
ELzmaStatus state;
SizeT compressedSize = (SizeT)(length - LZMA_PROPS_SIZE);
- debug ("LZMA: Image address............... 0x%lx\n", inStream);
- debug ("LZMA: Properties address.......... 0x%lx\n", inStream + LZMA_PROPERTIES_OFFSET);
- debug ("LZMA: Uncompressed size address... 0x%lx\n", inStream + LZMA_SIZE_OFFSET);
- debug ("LZMA: Compressed data address..... 0x%lx\n", inStream + LZMA_DATA_OFFSET);
- debug ("LZMA: Destination address......... 0x%lx\n", outStream);
+ debug ("LZMA: Image address............... 0x%p\n", inStream);
+ debug ("LZMA: Properties address.......... 0x%p\n", inStream + LZMA_PROPERTIES_OFFSET);
+ debug ("LZMA: Uncompressed size address... 0x%p\n", inStream + LZMA_SIZE_OFFSET);
+ debug ("LZMA: Compressed data address..... 0x%p\n", inStream + LZMA_DATA_OFFSET);
+ debug ("LZMA: Destination address......... 0x%p\n", outStream);
memset(&state, 0, sizeof(state));
}
}
- debug ("LZMA: Uncompresed size............ 0x%lx\n", outSizeFull);
- debug ("LZMA: Compresed size.............. 0x%lx\n", compressedSize);
+ debug ("LZMA: Uncompresed size............ 0x%x\n", outSizeFull);
+ debug ("LZMA: Compresed size.............. 0x%x\n", compressedSize);
g_Alloc.Alloc = SzAlloc;
g_Alloc.Free = SzFree;
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
/*
* Wirzenius wrote this portably, Torvalds fucked it up :-)
+ *
+ * from hush: simple_itoa() was lifted from boa-0.93.15
*/
#include <stdarg.h>
panic("%s:%u: %s: Assertion `%s' failed.", file, line, function,
assertion);
}
+
+char *simple_itoa(ulong i)
+{
+ /* 21 digits plus null terminator, good for 64-bit or smaller ints */
+ static char local[22];
+ char *p = &local[21];
+
+ *p-- = '\0';
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ return p + 1;
+}
return (curlen);
}
-/*
- * Check if autoload is enabled. If so, use either NFS or TFTP to download
- * the boot file.
- */
-static void auto_load(void)
-{
- const char *s = getenv("autoload");
-
- if (s != NULL) {
- if (*s == 'n') {
- /*
- * Just use BOOTP to configure system;
- * Do not use TFTP to load the bootfile.
- */
- NetState = NETLOOP_SUCCESS;
- return;
- }
-#if defined(CONFIG_CMD_NFS)
- if (strcmp(s, "NFS") == 0) {
- /*
- * Use NFS to load the bootfile.
- */
- NfsStart();
- return;
- }
-#endif
- }
- TftpStart();
-}
-
#if !defined(CONFIG_CMD_DHCP)
static void BootpVendorFieldProcess (u8 * ext)
debug("Got good BOOTP\n");
- auto_load();
+ net_auto_load();
}
#endif
dhcp_state = BOUND;
printf ("DHCP client bound to address %pI4\n", &NetOurIP);
- auto_load();
+ net_auto_load();
return;
}
break;
/* Current RX packet handler */
static rxhand_f *packetHandler;
+#ifdef CONFIG_CMD_TFTPPUT
+static rxhand_icmp_f *packet_icmp_handler; /* Current ICMP rx handler */
+#endif
/* Current timeout handler */
static thand_f *timeHandler;
/* Time base value */
/* THE transmit packet */
volatile uchar *NetTxPacket;
-static int net_check_prereq(proto_t protocol);
+static int net_check_prereq(enum proto_t protocol);
static int NetTryCount;
void ArpRequest(void)
{
- int i;
volatile uchar *pkt;
ARP_t *arp;
memcpy(&arp->ar_data[0], NetOurEther, 6);
/* source IP addr */
NetWriteIP((uchar *) &arp->ar_data[6], NetOurIP);
- for (i = 10; i < 16; ++i) {
- /* dest ET addr = 0 */
- arp->ar_data[i] = 0;
- }
-
+ /* dest ET addr = 0 */
+ memset(&arp->ar_data[10], '\0', 6);
if ((NetArpWaitPacketIP & NetOurSubnetMask) !=
(NetOurIP & NetOurSubnetMask)) {
if (NetOurGatewayIP == 0) {
}
}
-static void
-NetInitLoop(proto_t protocol)
+/*
+ * Check if autoload is enabled. If so, use either NFS or TFTP to download
+ * the boot file.
+ */
+void net_auto_load(void)
+{
+ const char *s = getenv("autoload");
+
+ if (s != NULL) {
+ if (*s == 'n') {
+ /*
+ * Just use BOOTP/RARP to configure system;
+ * Do not use TFTP to load the bootfile.
+ */
+ NetState = NETLOOP_SUCCESS;
+ return;
+ }
+#if defined(CONFIG_CMD_NFS)
+ if (strcmp(s, "NFS") == 0) {
+ /*
+ * Use NFS to load the bootfile.
+ */
+ NfsStart();
+ return;
+ }
+#endif
+ }
+ TftpStart(TFTPGET);
+}
+
+static void NetInitLoop(enum proto_t protocol)
{
static int env_changed_id;
bd_t *bd = gd->bd;
* Main network processing loop.
*/
-int
-NetLoop(proto_t protocol)
+int NetLoop(enum proto_t protocol)
{
bd_t *bd = gd->bd;
+ int ret = -1;
NetRestarted = 0;
NetDevExists = 0;
case 0:
NetDevExists = 1;
+ NetBootFileXferSize = 0;
switch (protocol) {
- case TFTP:
+ case TFTPGET:
+#ifdef CONFIG_CMD_TFTPPUT
+ case TFTPPUT:
+#endif
/* always use ARP to get server ethernet address */
- TftpStart();
+ TftpStart(protocol);
break;
#ifdef CONFIG_CMD_TFTPSRV
case TFTPSRV:
break;
}
- NetBootFileXferSize = 0;
break;
}
if (ctrlc()) {
eth_halt();
puts("\nAbort\n");
- return -1;
+ goto done;
}
ArpTimeoutCheck();
setenv("fileaddr", buf);
}
eth_halt();
- return NetBootFileXferSize;
+ ret = NetBootFileXferSize;
+ goto done;
case NETLOOP_FAIL:
- return -1;
+ goto done;
}
}
+
+done:
+#ifdef CONFIG_CMD_TFTPPUT
+ /* Clear out the handlers */
+ NetSetHandler(NULL);
+ net_set_icmp_handler(NULL);
+#endif
+ return ret;
}
/**********************************************************************/
packetHandler = f;
}
+#ifdef CONFIG_CMD_TFTPPUT
+void net_set_icmp_handler(rxhand_icmp_f *f)
+{
+ packet_icmp_handler = f;
+}
+#endif
void
NetSetTimeout(ulong iv, thand_f *f)
}
#endif
+/**
+ * Receive an ICMP packet. We deal with REDIRECT and PING here, and silently
+ * drop others.
+ *
+ * @parma ip IP packet containing the ICMP
+ */
+static void receive_icmp(IP_t *ip, int len, IPaddr_t src_ip, Ethernet_t *et)
+{
+ ICMP_t *icmph = (ICMP_t *)&ip->udp_src;
+
+ switch (icmph->type) {
+ case ICMP_REDIRECT:
+ if (icmph->code != ICMP_REDIR_HOST)
+ return;
+ printf(" ICMP Host Redirect to %pI4 ",
+ &icmph->un.gateway);
+ break;
+#if defined(CONFIG_CMD_PING)
+ case ICMP_ECHO_REPLY:
+ /*
+ * IP header OK. Pass the packet to the
+ * current handler.
+ */
+ /*
+ * XXX point to ip packet - should this use
+ * packet_icmp_handler?
+ */
+ (*packetHandler)((uchar *)ip, 0, src_ip, 0, 0);
+ break;
+ case ICMP_ECHO_REQUEST:
+ debug("Got ICMP ECHO REQUEST, return %d bytes\n",
+ ETHER_HDR_SIZE + len);
+
+ memcpy(&et->et_dest[0], &et->et_src[0], 6);
+ memcpy(&et->et_src[0], NetOurEther, 6);
+
+ ip->ip_sum = 0;
+ ip->ip_off = 0;
+ NetCopyIP((void *)&ip->ip_dst, &ip->ip_src);
+ NetCopyIP((void *)&ip->ip_src, &NetOurIP);
+ ip->ip_sum = ~NetCksum((uchar *)ip,
+ IP_HDR_SIZE_NO_UDP >> 1);
+
+ icmph->type = ICMP_ECHO_REPLY;
+ icmph->checksum = 0;
+ icmph->checksum = ~NetCksum((uchar *)icmph,
+ (len - IP_HDR_SIZE_NO_UDP) >> 1);
+ (void) eth_send((uchar *)et,
+ ETHER_HDR_SIZE + len);
+ break;
+#endif
+ default:
+#ifdef CONFIG_CMD_TFTPPUT
+ if (packet_icmp_handler)
+ packet_icmp_handler(icmph->type, icmph->code,
+ ntohs(ip->udp_dst), src_ip, ntohs(ip->udp_src),
+ icmph->un.data, ntohs(ip->udp_len));
+#endif
+ break;
+ }
+}
+
void
NetReceive(volatile uchar *inpkt, int len)
{
* subnet. So this is probably a warning that your
* configuration might be wrong. But I'm not really
* sure if there aren't any other situations.
+ *
+ * Simon Glass <sjg@chromium.org>: We get an ICMP when
+ * we send a tftp packet to a dead connection, or when
+ * there is no server at the other end.
*/
if (ip->ip_p == IPPROTO_ICMP) {
- ICMP_t *icmph = (ICMP_t *)&(ip->udp_src);
-
- switch (icmph->type) {
- case ICMP_REDIRECT:
- if (icmph->code != ICMP_REDIR_HOST)
- return;
- printf(" ICMP Host Redirect to %pI4 ",
- &icmph->un.gateway);
- return;
-#if defined(CONFIG_CMD_PING)
- case ICMP_ECHO_REPLY:
- /*
- * IP header OK. Pass the packet to the
- * current handler.
- */
- /* XXX point to ip packet */
- (*packetHandler)((uchar *)ip, 0, src_ip, 0, 0);
- return;
- case ICMP_ECHO_REQUEST:
- debug("Got ICMP ECHO REQUEST, return %d bytes\n",
- ETHER_HDR_SIZE + len);
-
- memcpy(&et->et_dest[0], &et->et_src[0], 6);
- memcpy(&et->et_src[0], NetOurEther, 6);
-
- ip->ip_sum = 0;
- ip->ip_off = 0;
- NetCopyIP((void *)&ip->ip_dst, &ip->ip_src);
- NetCopyIP((void *)&ip->ip_src, &NetOurIP);
- ip->ip_sum = ~NetCksum((uchar *)ip,
- IP_HDR_SIZE_NO_UDP >> 1);
-
- icmph->type = ICMP_ECHO_REPLY;
- icmph->checksum = 0;
- icmph->checksum = ~NetCksum((uchar *)icmph,
- (len - IP_HDR_SIZE_NO_UDP) >> 1);
- (void) eth_send((uchar *)et,
- ETHER_HDR_SIZE + len);
- return;
-#endif
- default:
- return;
- }
+ receive_icmp(ip, len, src_ip, et);
+ return;
} else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */
return;
}
/**********************************************************************/
-static int net_check_prereq(proto_t protocol)
+static int net_check_prereq(enum proto_t protocol)
{
switch (protocol) {
/* Fall through */
#if defined(CONFIG_CMD_NFS)
case NFS:
#endif
- case TFTP:
+ case TFTPGET:
+ case TFTPPUT:
if (NetServerIP == 0) {
puts("*** ERROR: `serverip' not set\n");
return 1;
RarpHandler(uchar *dummi0, unsigned dummi1, IPaddr_t sip, unsigned dummi2,
unsigned dummi3)
{
- char *s;
debug("Got good RARP\n");
- if ((s = getenv("autoload")) != NULL) {
- if (*s == 'n') {
- /*
- * Just use RARP to configure system;
- * Do not use TFTP/NFS to to load the bootfile.
- */
- NetState = NETLOOP_SUCCESS;
- return;
-#if defined(CONFIG_CMD_NFS)
- } else if ((s != NULL) && !strcmp(s, "NFS")) {
- NfsStart();
- return;
-#endif
- }
- }
- TftpStart ();
+ net_auto_load();
}
/* The number of hashes we printed */
static short TftpNumchars;
#endif
+#ifdef CONFIG_CMD_TFTPPUT
+static int TftpWriting; /* 1 if writing, else 0 */
+static int TftpFinalBlock; /* 1 if we have sent the last block */
+#else
+#define TftpWriting 0
+#endif
#define STATE_SEND_RRQ 1
#define STATE_DATA 2
#define STATE_BAD_MAGIC 4
#define STATE_OACK 5
#define STATE_RECV_WRQ 6
+#define STATE_SEND_WRQ 7
/* default TFTP block size */
#define TFTP_BLOCK_SIZE 512
NetBootFileXferSize = newsize;
}
+/* Clear our state ready for a new transfer */
+static void new_transfer(void)
+{
+ TftpLastBlock = 0;
+ TftpBlockWrap = 0;
+ TftpBlockWrapOffset = 0;
+#ifdef CONFIG_CMD_TFTPPUT
+ TftpFinalBlock = 0;
+#endif
+}
+
+#ifdef CONFIG_CMD_TFTPPUT
+/**
+ * Load the next block from memory to be sent over tftp.
+ *
+ * @param block Block number to send
+ * @param dst Destination buffer for data
+ * @param len Number of bytes in block (this one and every other)
+ * @return number of bytes loaded
+ */
+static int load_block(unsigned block, uchar *dst, unsigned len)
+{
+ /* We may want to get the final block from the previous set */
+ ulong offset = ((int)block - 1) * len + TftpBlockWrapOffset;
+ ulong tosend = len;
+
+ tosend = min(NetBootFileXferSize - offset, tosend);
+ (void)memcpy(dst, (void *)(save_addr + offset), tosend);
+ debug("%s: block=%d, offset=%ld, len=%d, tosend=%ld\n", __func__,
+ block, offset, len, tosend);
+ return tosend;
+}
+#endif
+
static void TftpSend(void);
static void TftpTimeout(void);
/**********************************************************************/
+static void show_block_marker(void)
+{
+#ifdef CONFIG_TFTP_TSIZE
+ if (TftpTsize) {
+ ulong pos = TftpBlock * TftpBlkSize + TftpBlockWrapOffset;
+
+ while (TftpNumchars < pos * 50 / TftpTsize) {
+ putc('#');
+ TftpNumchars++;
+ }
+ } else
+#endif
+ {
+ if (((TftpBlock - 1) % 10) == 0)
+ putc('#');
+ else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0)
+ puts("\n\t ");
+ }
+}
+
+/**
+ * restart the current transfer due to an error
+ *
+ * @param msg Message to print for user
+ */
+static void restart(const char *msg)
+{
+ printf("\n%s; starting again\n", msg);
+#ifdef CONFIG_MCAST_TFTP
+ mcast_cleanup();
+#endif
+ NetStartAgain();
+}
+
+/*
+ * Check if the block number has wrapped, and update progress
+ *
+ * TODO: The egregious use of global variables in this file should be tidied.
+ */
+static void update_block_number(void)
+{
+ /*
+ * RFC1350 specifies that the first data packet will
+ * have sequence number 1. If we receive a sequence
+ * number of 0 this means that there was a wrap
+ * around of the (16 bit) counter.
+ */
+ if (TftpBlock == 0) {
+ TftpBlockWrap++;
+ TftpBlockWrapOffset += TftpBlkSize * TFTP_SEQUENCE_SIZE;
+ TftpTimeoutCount = 0; /* we've done well, reset thhe timeout */
+ } else {
+ show_block_marker();
+ }
+}
+
+/* The TFTP get or put is complete */
+static void tftp_complete(void)
+{
+#ifdef CONFIG_TFTP_TSIZE
+ /* Print hash marks for the last packet received */
+ while (TftpTsize && TftpNumchars < 49) {
+ putc('#');
+ TftpNumchars++;
+ }
+#endif
+ puts("\ndone\n");
+ NetState = NETLOOP_SUCCESS;
+}
+
static void
TftpSend(void)
{
- volatile uchar *pkt;
+ uchar *pkt;
volatile uchar *xp;
int len = 0;
volatile ushort *s;
* We will always be sending some sort of packet, so
* cobble together the packet headers now.
*/
- pkt = NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE;
+ pkt = (uchar *)(NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE);
switch (TftpState) {
-
case STATE_SEND_RRQ:
+ case STATE_SEND_WRQ:
xp = pkt;
s = (ushort *)pkt;
+#ifdef CONFIG_CMD_TFTPPUT
+ *s++ = htons(TftpState == STATE_SEND_RRQ ? TFTP_RRQ :
+ TFTP_WRQ);
+#else
*s++ = htons(TFTP_RRQ);
+#endif
pkt = (uchar *)s;
strcpy((char *)pkt, tftp_filename);
pkt += strlen(tftp_filename) + 1;
debug("send option \"timeout %s\"\n", (char *)pkt);
pkt += strlen((char *)pkt) + 1;
#ifdef CONFIG_TFTP_TSIZE
- memcpy((char *)pkt, "tsize\0000\0", 8);
- pkt += 8;
+ pkt += sprintf((char *)pkt, "tsize%c%lu%c",
+ 0, NetBootFileXferSize, 0);
#endif
/* try for more effic. blk size */
pkt += sprintf((char *)pkt, "blksize%c%d%c",
case STATE_DATA:
xp = pkt;
s = (ushort *)pkt;
- *s++ = htons(TFTP_ACK);
- *s++ = htons(TftpBlock);
- pkt = (uchar *)s;
+ s[0] = htons(TFTP_ACK);
+ s[1] = htons(TftpBlock);
+ pkt = (uchar *)(s + 2);
+#ifdef CONFIG_CMD_TFTPPUT
+ if (TftpWriting) {
+ int toload = TftpBlkSize;
+ int loaded = load_block(TftpBlock, pkt, toload);
+
+ s[0] = htons(TFTP_DATA);
+ pkt += loaded;
+ TftpFinalBlock = (loaded < toload);
+ }
+#endif
len = pkt - xp;
break;
xp = pkt;
s = (ushort *)pkt;
*s++ = htons(TFTP_ERROR);
- *s++ = htons(3);
+ *s++ = htons(3);
+
pkt = (uchar *)s;
strcpy((char *)pkt, "File too large");
pkt += 14 /*strlen("File too large")*/ + 1;
TftpOurPort, len);
}
+#ifdef CONFIG_CMD_TFTPPUT
+static void icmp_handler(unsigned type, unsigned code, unsigned dest,
+ IPaddr_t sip, unsigned src, uchar *pkt, unsigned len)
+{
+ if (type == ICMP_NOT_REACH && code == ICMP_NOT_REACH_PORT) {
+ /* Oh dear the other end has gone away */
+ restart("TFTP server died");
+ }
+}
+#endif
static void
TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
return;
}
if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort &&
- TftpState != STATE_RECV_WRQ)
+ TftpState != STATE_RECV_WRQ && TftpState != STATE_SEND_WRQ)
return;
if (len < 2)
switch (ntohs(proto)) {
case TFTP_RRQ:
+ break;
+
case TFTP_ACK:
+#ifdef CONFIG_CMD_TFTPPUT
+ if (TftpWriting) {
+ if (TftpFinalBlock) {
+ tftp_complete();
+ } else {
+ /*
+ * Move to the next block. We want our block
+ * count to wrap just like the other end!
+ */
+ int block = ntohs(*s);
+ int ack_ok = (TftpBlock == block);
+
+ TftpBlock = (unsigned short)(block + 1);
+ update_block_number();
+ if (ack_ok)
+ TftpSend(); /* Send next data block */
+ }
+ }
+#endif
break;
+
default:
break;
TftpRemoteIP = sip;
TftpRemotePort = src;
TftpOurPort = 1024 + (get_timer(0) % 3072);
- TftpLastBlock = 0;
- TftpBlockWrap = 0;
- TftpBlockWrapOffset = 0;
+ new_transfer();
TftpSend(); /* Send ACK(0) */
break;
#endif
TftpState = STATE_DATA; /* passive.. */
else
#endif
- TftpSend(); /* Send ACK */
+#ifdef CONFIG_CMD_TFTPPUT
+ if (TftpWriting) {
+ /* Get ready to send the first block */
+ TftpState = STATE_DATA;
+ TftpBlock++;
+ }
+#endif
+ TftpSend(); /* Send ACK or first data block */
break;
case TFTP_DATA:
if (len < 2)
len -= 2;
TftpBlock = ntohs(*(ushort *)pkt);
- /*
- * RFC1350 specifies that the first data packet will
- * have sequence number 1. If we receive a sequence
- * number of 0 this means that there was a wrap
- * around of the (16 bit) counter.
- */
- if (TftpBlock == 0) {
- TftpBlockWrap++;
- TftpBlockWrapOffset +=
- TftpBlkSize * TFTP_SEQUENCE_SIZE;
- printf("\n\t %lu MB received\n\t ",
- TftpBlockWrapOffset>>20);
- }
-#ifdef CONFIG_TFTP_TSIZE
- else if (TftpTsize) {
- while (TftpNumchars <
- NetBootFileXferSize * 50 / TftpTsize) {
- putc('#');
- TftpNumchars++;
- }
- }
-#endif
- else {
- if (((TftpBlock - 1) % 10) == 0)
- putc('#');
- else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0)
- puts("\n\t ");
- }
+ update_block_number();
if (TftpState == STATE_SEND_RRQ)
debug("Server did not acknowledge timeout option!\n");
/* first block received */
TftpState = STATE_DATA;
TftpRemotePort = src;
- TftpLastBlock = 0;
- TftpBlockWrap = 0;
- TftpBlockWrapOffset = 0;
+ new_transfer();
#ifdef CONFIG_MCAST_TFTP
if (Multicast) { /* start!=1 common if mcast */
}
else
#endif
- if (len < TftpBlkSize) {
- /*
- * We received the whole thing. Try to
- * run it.
- */
-#ifdef CONFIG_TFTP_TSIZE
- /* Print hash marks for the last packet received */
- while (TftpTsize && TftpNumchars < 49) {
- putc('#');
- TftpNumchars++;
- }
-#endif
- puts("\ndone\n");
- NetState = NETLOOP_SUCCESS;
- }
+ if (len < TftpBlkSize)
+ tftp_complete();
break;
case TFTP_ERROR:
TftpTimeout(void)
{
if (++TftpTimeoutCount > TftpTimeoutCountMax) {
- puts("\nRetry count exceeded; starting again\n");
-#ifdef CONFIG_MCAST_TFTP
- mcast_cleanup();
-#endif
- NetStartAgain();
+ restart("Retry count exceeded");
} else {
puts("T ");
NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
}
-void
-TftpStart(void)
+void TftpStart(enum proto_t protocol)
{
char *ep; /* Environment pointer */
}
printf("Using %s device\n", eth_get_name());
- printf("TFTP from server %pI4"
- "; our IP address is %pI4", &TftpRemoteIP, &NetOurIP);
+ printf("TFTP %s server %pI4; our IP address is %pI4",
+#ifdef CONFIG_CMD_TFTPPUT
+ protocol == TFTPPUT ? "to" : "from",
+#else
+ "from",
+#endif
+ &TftpRemoteIP, &NetOurIP);
/* Check if we need to send across this subnet */
if (NetOurGatewayIP && NetOurSubnetMask) {
}
putc('\n');
-
- printf("Load address: 0x%lx\n", load_addr);
-
- puts("Loading: *\b");
+#ifdef CONFIG_CMD_TFTPPUT
+ TftpWriting = (protocol == TFTPPUT);
+ if (TftpWriting) {
+ printf("Save address: 0x%lx\n", save_addr);
+ printf("Save size: 0x%lx\n", save_size);
+ NetBootFileXferSize = save_size;
+ puts("Saving: *\b");
+ TftpState = STATE_SEND_WRQ;
+ new_transfer();
+ } else
+#endif
+ {
+ printf("Load address: 0x%lx\n", load_addr);
+ puts("Loading: *\b");
+ TftpState = STATE_SEND_RRQ;
+ }
TftpTimeoutCountMax = TftpRRQTimeoutCountMax;
NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
NetSetHandler(TftpHandler);
-
+#ifdef CONFIG_CMD_TFTPPUT
+ net_set_icmp_handler(icmp_handler);
+#endif
TftpRemotePort = WELL_KNOWN_PORT;
TftpTimeoutCount = 0;
- TftpState = STATE_SEND_RRQ;
/* Use a pseudo-random port unless a specific port is set */
TftpOurPort = 1024 + (get_timer(0) % 3072);
*/
/* tftp.c */
-extern void TftpStart (void); /* Begin TFTP get */
+void TftpStart(enum proto_t protocol); /* Begin TFTP get/put */
#ifdef CONFIG_CMD_TFTPSRV
extern void TftpStartServer(void); /* Wait for incoming TFTP put */