From: Wolfgang Denk Date: Thu, 27 Oct 2011 22:14:16 +0000 (+0200) Subject: Merge branch 'master' of git://git.denx.de/u-boot-microblaze X-Git-Tag: v2011.12-rc1~344 X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=commitdiff_plain;h=606a76f8ef479e42ae4d06f8f3ce87e9a1c72acf;hp=1fbd0c36daeb2340210bbd68ee2f62f26a8bdfa0 Merge branch 'master' of git://git.denx.de/u-boot-microblaze * 'master' of git://git.denx.de/u-boot-microblaze: microblaze: Fix strict-aliasing rules for in_be32 microblaze: Wire up axi_ethernet driver initialization --- diff --git a/.gitignore b/.gitignore index 320d21e6c4..70a11f7850 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ /u-boot.dis /u-boot.lds /u-boot.ubl +/u-boot.dtb # # Generated files diff --git a/Makefile b/Makefile index 400ef0b581..684cdb6aaf 100644 --- a/Makefile +++ b/Makefile @@ -229,6 +229,9 @@ endif 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 \ @@ -356,9 +359,17 @@ ALL-$(CONFIG_ONENAND_U_BOOT) += $(obj)u-boot-onenand.bin 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 $< $@ @@ -879,6 +890,7 @@ clobber: clean @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 @@ -886,6 +898,7 @@ clobber: clean @[ ! -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 diff --git a/README b/README index c6b179cb62..58e582d022 100644 --- a/README +++ b/README @@ -134,7 +134,7 @@ Additional fields (if present) indicate release candidates or bug fix 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 @@ -769,7 +769,7 @@ The following options need to be configured: 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 @@ -788,6 +788,7 @@ The following options need to be configured: 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 @@ -815,6 +816,36 @@ The following options need to be configured: 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 -.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 @@ -1144,6 +1175,11 @@ The following options need to be configured: 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 @@ -1396,18 +1432,37 @@ The following options need to be configured: 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 @@ -1694,24 +1749,24 @@ The following options need to be configured: 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 @@ -1830,7 +1885,7 @@ The following options need to be configured: 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 @@ -2145,7 +2200,7 @@ Legacy uImage format: 13 common/image.c Start multifile image verification 14 common/image.c No initial ramdisk, no multifile, continue. - 15 arch//lib/bootm.c All preparation done, transferring control to OS + 15 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() @@ -2392,6 +2447,20 @@ Modem Support: 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: ----------------------- @@ -2509,7 +2578,7 @@ 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. @@ -2799,7 +2868,7 @@ to save the current settings. 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): @@ -2893,7 +2962,7 @@ Low Level (hardware related) configuration options: - 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: @@ -3344,6 +3413,7 @@ bootp - boot image via network using BootP/TFTP protocol 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 @@ -3424,7 +3494,7 @@ List of environment variables (most likely not complete): 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 @@ -3467,6 +3537,10 @@ List of environment variables (most likely not complete): 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 @@ -3574,12 +3648,12 @@ flash or offset in NAND flash. 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"), @@ -3694,7 +3768,7 @@ o If neither SROM nor the environment contain a MAC address, an error 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. diff --git a/arch/arm/cpu/armv7/omap4/clocks.c b/arch/arm/cpu/armv7/omap4/clocks.c index 4f0e0cd881..095ba39aeb 100644 --- a/arch/arm/cpu/armv7/omap4/clocks.c +++ b/arch/arm/cpu/armv7/omap4/clocks.c @@ -603,7 +603,7 @@ static inline void enable_clock_domain(u32 *const clkctrl_reg, u32 enable_mode) { 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) @@ -630,7 +630,7 @@ static inline void enable_clock_module(u32 *const clkctrl_addr, u32 enable_mode, { 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); } diff --git a/arch/arm/cpu/armv7/tegra2/board.c b/arch/arm/cpu/armv7/tegra2/board.c index 9061d181d5..751102d180 100644 --- a/arch/arm/cpu/armv7/tegra2/board.c +++ b/arch/arm/cpu/armv7/tegra2/board.c @@ -40,7 +40,7 @@ unsigned int query_sdram_size(void) 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) { diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index fac98d559a..c3ff789999 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -76,6 +76,7 @@ typedef struct global_data { #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) diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index c7648449b0..368fc5d6b3 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -48,6 +48,8 @@ #include #include #include +#include +#include #include #include @@ -233,6 +235,9 @@ init_fnc_t *init_sequence[] = { #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 @@ -274,6 +279,16 @@ void board_init_f(ulong bootflag) 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) { @@ -477,13 +492,14 @@ void board_init_r(gd_t *id, ulong dest_addr) 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, @@ -566,12 +582,15 @@ void board_init_r(gd_t *id, ulong dest_addr) /* 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 diff --git a/arch/powerpc/cpu/mpc512x/serial.c b/arch/powerpc/cpu/mpc512x/serial.c index 5ee9ceff49..7c53346ea0 100644 --- a/arch/powerpc/cpu/mpc512x/serial.c +++ b/arch/powerpc/cpu/mpc512x/serial.c @@ -140,7 +140,7 @@ void serial_setbrg_dev(unsigned int idx) 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 */ diff --git a/arch/powerpc/cpu/mpc86xx/interrupts.c b/arch/powerpc/cpu/mpc86xx/interrupts.c index 14821f4243..aff1f6db5d 100644 --- a/arch/powerpc/cpu/mpc86xx/interrupts.c +++ b/arch/powerpc/cpu/mpc86xx/interrupts.c @@ -59,28 +59,28 @@ int interrupt_init_cpu(unsigned long *decrementer_count) 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 */ diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr1_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr1_dimm_params.c index 9184764418..376be2fb37 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr1_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr1_dimm_params.c @@ -41,7 +41,7 @@ compute_ranksize(unsigned int mem_type, unsigned char row_dens) /* 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; } diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr2_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr2_dimm_params.c index b565e338ad..f637f3d045 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr2_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr2_dimm_params.c @@ -40,7 +40,7 @@ compute_ranksize(unsigned int mem_type, unsigned char row_dens) /* 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; } diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c index 838cebed57..ffb503a777 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c @@ -71,7 +71,7 @@ compute_ranksize(const ddr3_spd_eeprom_t *spd) 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; } diff --git a/arch/powerpc/cpu/ppc4xx/44x_spd_ddr.c b/arch/powerpc/cpu/ppc4xx/44x_spd_ddr.c index ec7291f9c8..e05daf23b7 100644 --- a/arch/powerpc/cpu/ppc4xx/44x_spd_ddr.c +++ b/arch/powerpc/cpu/ppc4xx/44x_spd_ddr.c @@ -820,7 +820,7 @@ static void program_tr0(unsigned long *dimm_populated, break; } - debug("tr0: %x\n", tr0); + debug("tr0: %lx\n", tr0); mtsdram(SDRAM0_TR0, tr0); } @@ -1051,7 +1051,7 @@ static void program_tr1(void) } tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average); - debug("tr1: %x\n", tr1); + debug("tr1: %lx\n", tr1); /* * program SDRAM Timing Register 1 TR1 @@ -1124,7 +1124,7 @@ static unsigned long program_bxcr(unsigned long *dimm_populated, 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); /* @@ -1193,9 +1193,11 @@ static unsigned long program_bxcr(unsigned long *dimm_populated, 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); } } } @@ -1239,7 +1241,8 @@ static unsigned long program_bxcr(unsigned long *dimm_populated, 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); } } diff --git a/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c b/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c index b909fcab0d..4b8e65a51d 100644 --- a/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c +++ b/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c @@ -907,8 +907,8 @@ static u32 DQS_calibration_methodB(struct ddrautocal *cal) 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) { @@ -1214,7 +1214,7 @@ u32 DQS_autocalibration(void) 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) @@ -1227,7 +1227,7 @@ u32 DQS_autocalibration(void) #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); diff --git a/arch/powerpc/cpu/ppc4xx/4xx_pcie.c b/arch/powerpc/cpu/ppc4xx/4xx_pcie.c index b76890e099..a87e93b80c 100644 --- a/arch/powerpc/cpu/ppc4xx/4xx_pcie.c +++ b/arch/powerpc/cpu/ppc4xx/4xx_pcie.c @@ -265,7 +265,8 @@ static int pcie_read_config(struct pci_controller *hose, unsigned int devfn, */ 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); diff --git a/arch/powerpc/cpu/ppc4xx/denali_data_eye.c b/arch/powerpc/cpu/ppc4xx/denali_data_eye.c index 9bba0caec7..19b65be61c 100644 --- a/arch/powerpc/cpu/ppc4xx/denali_data_eye.c +++ b/arch/powerpc/cpu/ppc4xx/denali_data_eye.c @@ -317,7 +317,7 @@ void denali_core_search_data_eye(void) 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 @@ -327,7 +327,7 @@ void denali_core_search_data_eye(void) 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'. @@ -337,7 +337,7 @@ void denali_core_search_data_eye(void) 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); @@ -347,7 +347,7 @@ void denali_core_search_data_eye(void) | 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); @@ -357,7 +357,7 @@ void denali_core_search_data_eye(void) | 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. diff --git a/arch/powerpc/cpu/ppc4xx/denali_spd_ddr2.c b/arch/powerpc/cpu/ppc4xx/denali_spd_ddr2.c index c35b11348a..ce769a7156 100644 --- a/arch/powerpc/cpu/ppc4xx/denali_spd_ddr2.c +++ b/arch/powerpc/cpu/ppc4xx/denali_spd_ddr2.c @@ -360,7 +360,7 @@ static void get_spd_info(unsigned long dimm_ranks[], 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); } /*------------------------------------------------------------------ @@ -387,7 +387,7 @@ static void check_frequency(unsigned long *dimm_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)) { /* @@ -470,10 +470,10 @@ static void get_dimm_size(unsigned long dimm_ranks[], } } } - 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); @@ -568,7 +568,7 @@ static void program_ddr0_03(unsigned long dimm_ranks[], /*------------------------------------------------------------------ * 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 @@ -601,7 +601,7 @@ static void program_ddr0_03(unsigned long dimm_ranks[], 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: @@ -640,10 +640,10 @@ static void program_ddr0_03(unsigned long dimm_ranks[], 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; @@ -673,7 +673,7 @@ static void program_ddr0_03(unsigned long dimm_ranks[], 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); } @@ -728,11 +728,11 @@ static void program_ddr0_04(unsigned long dimm_ranks[], 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) | @@ -769,9 +769,9 @@ static void program_ddr0_05(unsigned long dimm_ranks[], 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)); @@ -828,9 +828,9 @@ static void program_ddr0_06(unsigned long dimm_ranks[], 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)); @@ -857,7 +857,7 @@ static void program_ddr0_11(unsigned long sdram_freq) 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) | @@ -928,9 +928,9 @@ static void program_ddr0_26(unsigned long sdram_freq) 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)); @@ -941,7 +941,7 @@ static void program_ddr0_27(unsigned long sdram_freq) 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) | @@ -975,7 +975,7 @@ static void program_ddr0_43(unsigned long dimm_ranks[], 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)); } @@ -1003,7 +1003,7 @@ static void program_ddr0_44(unsigned long dimm_ranks[], 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)); } diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index 6cb0ed6344..508075fa88 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -623,7 +623,6 @@ void board_init_f (ulong bootflag) */ void board_init_r (gd_t *id, ulong dest_addr) { - char *s; bd_t *bd; ulong malloc_start; @@ -727,6 +726,8 @@ void board_init_r (gd_t *id, ulong dest_addr) 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' @@ -927,8 +928,11 @@ void board_init_r (gd_t *id, ulong dest_addr) /* 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 diff --git a/arch/sandbox/lib/board.c b/arch/sandbox/lib/board.c index 1fd8fa651d..ae5a517605 100644 --- a/arch/sandbox/lib/board.c +++ b/arch/sandbox/lib/board.c @@ -250,7 +250,7 @@ void board_init_r(gd_t *id, ulong dest_addr) /* enable exceptions */ enable_interrupts(); -#ifdef BOARD_LATE_INIT +#ifdef CONFIG_BOARD_LATE_INIT board_late_init(); #endif diff --git a/arch/sh/lib/board.c b/arch/sh/lib/board.c index 6148e6baff..d9c0c228e0 100644 --- a/arch/sh/lib/board.c +++ b/arch/sh/lib/board.c @@ -141,7 +141,7 @@ init_fnc_t *init_sequence[] = 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) diff --git a/board/Marvell/include/mv_gen_reg.h b/board/Marvell/include/mv_gen_reg.h index 03fcd88651..008185ec78 100644 --- a/board/Marvell/include/mv_gen_reg.h +++ b/board/Marvell/include/mv_gen_reg.h @@ -1864,6 +1864,14 @@ #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 */ /* diff --git a/board/altera/nios2-generic/nios2-generic.c b/board/altera/nios2-generic/nios2-generic.c index 220a4c44a4..49ef80de96 100644 --- a/board/altera/nios2-generic/nios2-generic.c +++ b/board/altera/nios2-generic/nios2-generic.c @@ -74,7 +74,15 @@ int board_eth_init(bd_t *bis) 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); diff --git a/board/cpc45/pd67290.c b/board/cpc45/pd67290.c index 0d8ef23368..815e4bae45 100644 --- a/board/cpc45/pd67290.c +++ b/board/cpc45/pd67290.c @@ -225,11 +225,7 @@ static u_int cirrus_set_opts (socket_info_t * s) { 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; diff --git a/board/dave/PPChameleonEVB/flash.c b/board/dave/PPChameleonEVB/flash.c index 2e1a9abc08..3d5b20d223 100644 --- a/board/dave/PPChameleonEVB/flash.c +++ b/board/dave/PPChameleonEVB/flash.c @@ -51,7 +51,8 @@ unsigned long flash_init (void) 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; ibd->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)); diff --git a/board/esd/pmc440/cmd_pmc440.c b/board/esd/pmc440/cmd_pmc440.c index 200d7ee30d..02028768f9 100644 --- a/board/esd/pmc440/cmd_pmc440.c +++ b/board/esd/pmc440/cmd_pmc440.c @@ -368,7 +368,7 @@ int do_painit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) */ 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)); diff --git a/board/freescale/mpc5121ads/mpc5121ads.c b/board/freescale/mpc5121ads/mpc5121ads.c index b356a478b3..97eeab3a23 100644 --- a/board/freescale/mpc5121ads/mpc5121ads.c +++ b/board/freescale/mpc5121ads/mpc5121ads.c @@ -253,14 +253,14 @@ int misc_init_r(void) /* 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; } diff --git a/board/freescale/mpc8610hpcd/mpc8610hpcd.c b/board/freescale/mpc8610hpcd/mpc8610hpcd.c index 1854e27dac..5b3b560426 100644 --- a/board/freescale/mpc8610hpcd/mpc8610hpcd.c +++ b/board/freescale/mpc8610hpcd/mpc8610hpcd.c @@ -76,14 +76,14 @@ int misc_init_r(void) /* 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; } diff --git a/board/freescale/mx35pdk/mx35pdk.c b/board/freescale/mx35pdk/mx35pdk.c index 8f9b857334..2ce6e8e340 100644 --- a/board/freescale/mx35pdk/mx35pdk.c +++ b/board/freescale/mx35pdk/mx35pdk.c @@ -38,8 +38,8 @@ #include #include -#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 diff --git a/board/freescale/mx51evk/mx51evk.c b/board/freescale/mx51evk/mx51evk.c index 8da1ee8b1a..f998610577 100644 --- a/board/freescale/mx51evk/mx51evk.c +++ b/board/freescale/mx51evk/mx51evk.c @@ -409,7 +409,7 @@ int board_init(void) return 0; } -#ifdef BOARD_LATE_INIT +#ifdef CONFIG_BOARD_LATE_INIT int board_late_init(void) { #ifdef CONFIG_MXC_SPI diff --git a/board/freescale/p1022ds/diu.c b/board/freescale/p1022ds/diu.c index cef81ce030..d5428ea16d 100644 --- a/board/freescale/p1022ds/diu.c +++ b/board/freescale/p1022ds/diu.c @@ -74,7 +74,7 @@ void diu_set_pixel_clock(unsigned int pixclock) 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; diff --git a/board/hymod/bsp.c b/board/hymod/bsp.c index 2cd3707d72..cd9c4e2076 100644 --- a/board/hymod/bsp.c +++ b/board/hymod/bsp.c @@ -200,7 +200,7 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) 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; diff --git a/board/hymod/fetch.c b/board/hymod/fetch.c index e121d5565e..f5f9582e95 100644 --- a/board/hymod/fetch.c +++ b/board/hymod/fetch.c @@ -55,7 +55,7 @@ fetch_and_parse (char *fn, ulong addr, int (*cback)(uchar *, uchar *)) load_addr = addr; NetBootFileXferSize = 0; - if (NetLoop (TFTP) == 0) { + if (NetLoop(TFTPGET) == 0) { printf ("tftp transfer of file '%s' failed\n", fn); return (0); } diff --git a/board/imx31_phycore/imx31_phycore.c b/board/imx31_phycore/imx31_phycore.c index 773900e3c9..47f1a8d1c0 100644 --- a/board/imx31_phycore/imx31_phycore.c +++ b/board/imx31_phycore/imx31_phycore.c @@ -74,7 +74,7 @@ int board_early_init_f(void) return 0; } -#ifdef BOARD_LATE_INIT +#ifdef CONFIG_BOARD_LATE_INIT int board_late_init(void) { #ifdef CONFIG_S6E63D6 diff --git a/board/keymile/km_arm/km_arm.c b/board/keymile/km_arm/km_arm.c index f78f754f37..67f158c1eb 100644 --- a/board/keymile/km_arm/km_arm.c +++ b/board/keymile/km_arm/km_arm.c @@ -481,38 +481,6 @@ int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset) } #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) { diff --git a/board/r360mpi/flash.c b/board/r360mpi/flash.c index 45cccf712b..26ec11d5d2 100644 --- a/board/r360mpi/flash.c +++ b/board/r360mpi/flash.c @@ -219,7 +219,7 @@ static ulong flash_get_size (FPW * addr, flash_info_t * info) 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: @@ -235,7 +235,7 @@ static ulong flash_get_size (FPW * addr, flash_info_t * info) 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: diff --git a/board/spc1920/hpi.c b/board/spc1920/hpi.c index 26d0f9c33d..9d8ec1006d 100644 --- a/board/spc1920/hpi.c +++ b/board/spc1920/hpi.c @@ -234,13 +234,13 @@ static int hpi_write_inc(u32 addr, u32 *data, u32 count) 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> 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)); } @@ -273,7 +273,7 @@ static int hpi_read_inc(u32 addr, u32 *buf, u32 count) for(i=0; i> 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; @@ -333,7 +333,7 @@ static long int get_ddr_bank_size(short cs, long *base) */ 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 { @@ -351,7 +351,7 @@ static void set_cs_bounds(short cs, long base, long size) */ 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; } diff --git a/common/cmd_elf.c b/common/cmd_elf.c index bf3261256f..11ffc1b8aa 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -133,10 +133,10 @@ int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* 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 diff --git a/common/cmd_ide.c b/common/cmd_ide.c index da5189c37e..74e6504b2d 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -1224,7 +1224,7 @@ ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, void *buffer) 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 */ diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c index 2c2e4e0973..b7c833b149 100644 --- a/common/cmd_mtdparts.c +++ b/common/cmd_mtdparts.c @@ -839,9 +839,7 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ 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; diff --git a/common/cmd_net.c b/common/cmd_net.c index 872f4a69c8..f89a24bfd4 100644 --- a/common/cmd_net.c +++ b/common/cmd_net.c @@ -28,7 +28,7 @@ #include #include -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[]) { @@ -43,7 +43,7 @@ U_BOOT_CMD( 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( @@ -52,6 +52,22 @@ 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[]) { @@ -167,8 +183,8 @@ static void netboot_update_env (void) #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; @@ -203,6 +219,13 @@ netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char * const argv[]) 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); diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index fa99c44b01..396a17135e 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -79,6 +79,8 @@ SPI_FLASH|MG_DISK|NVRAM|MMC} or CONFIG_ENV_IS_NOWHERE #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) @@ -377,6 +379,36 @@ int setenv(const char *varname, const char *varvalue) 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) diff --git a/common/hush.c b/common/hush.c index 940889b898..2495a6d592 100644 --- a/common/hush.c +++ b/common/hush.c @@ -17,7 +17,6 @@ * 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 @@ -922,20 +921,6 @@ static int b_addqchr(o_string *o, int ch, int quote) 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) { diff --git a/common/update.c b/common/update.c index a19f136647..5b1a064c29 100644 --- a/common/update.c +++ b/common/update.c @@ -86,7 +86,7 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr) /* download the update file */ load_addr = addr; copy_filename(BootFile, filename, sizeof(BootFile)); - size = NetLoop(TFTP); + size = NetLoop(TFTPGET); if (size < 0) rv = 1; diff --git a/common/usb.c b/common/usb.c index 2cd50db999..bed5116505 100644 --- a/common/usb.c +++ b/common/usb.c @@ -56,16 +56,16 @@ #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]; @@ -968,13 +968,6 @@ void usb_scan_devices(void) * 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; diff --git a/common/usb_storage.c b/common/usb_storage.c index 16667f3948..d9a2585d58 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -56,16 +56,17 @@ #include #include -#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 /* direction table -- this indicates the direction of the data * transfer for each command code -- a 1 indicates input @@ -372,7 +373,7 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length) 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 @@ -384,12 +385,12 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length) } 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; @@ -437,19 +438,19 @@ static int usb_stor_BBB_reset(struct us_data *us) /* 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"); @@ -477,7 +478,7 @@ static int usb_stor_CB_reset(struct us_data *us) /* 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)); @@ -568,7 +569,7 @@ int usb_stor_CB_comdat(ccb *srb, struct us_data *us) 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) { @@ -580,7 +581,7 @@ int usb_stor_CB_comdat(ccb *srb, struct us_data *us) 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; } @@ -777,7 +778,7 @@ again: 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) { @@ -802,7 +803,7 @@ int usb_stor_CB_transport(ccb *srb, struct us_data *us) /* 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) { @@ -825,7 +826,7 @@ do_retry: /* 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; } @@ -852,7 +853,7 @@ do_retry: 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; } diff --git a/config.mk b/config.mk index bad72b7689..11b67e540e 100644 --- a/config.mk +++ b/config.mk @@ -124,6 +124,7 @@ STRIP = $(CROSS_COMPILE)strip OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump RANLIB = $(CROSS_COMPILE)RANLIB +DTC = dtc ######################################################################### diff --git a/disk/part_efi.c b/disk/part_efi.c index 0a513c6ed0..e7f27147f1 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -120,92 +120,86 @@ static char *print_efiname(gpt_entry *pte) 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; @@ -271,7 +265,7 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba, 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; } @@ -349,9 +343,7 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba, le32_to_int(pgpt_head->partition_entry_array_crc32), calc_crc32); - if (*pgpt_pte != NULL) { - free(*pgpt_pte); - } + free(*pgpt_pte); return 0; } @@ -375,25 +367,25 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc, 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; } @@ -421,7 +413,7 @@ static int is_pte_valid(gpt_entry * pte) efi_guid_t unused_guid; if (!pte) { - printf("%s: Invalid Argument(s)\n", __FUNCTION__); + printf("%s: Invalid Argument(s)\n", __func__); return 0; } @@ -433,7 +425,7 @@ static int is_pte_valid(gpt_entry * pte) 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; diff --git a/doc/README.arm-caches b/doc/README.arm-caches index cd2b4587c2..f6a52e3e38 100644 --- a/doc/README.arm-caches +++ b/doc/README.arm-caches @@ -40,6 +40,8 @@ Buffer Requirements: - 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 diff --git a/doc/README.fdt-control b/doc/README.fdt-control new file mode 100644 index 0000000000..85bda03504 --- /dev/null +++ b/doc/README.fdt-control @@ -0,0 +1,184 @@ +# +# 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//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 "" + +to set the filename of the device tree source. Then put your device tree +file into + + board//dts/.dts + +This should include your CPU or SOC's device tree file, placed in +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 +1-Sep-11 diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index 64f52bb019..015b341d9e 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -398,7 +398,7 @@ static int ahci_port_start(u8 port) * 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); /* diff --git a/drivers/block/sata_sil3114.c b/drivers/block/sata_sil3114.c index d43064e0f1..1e60636ec2 100644 --- a/drivers/block/sata_sil3114.c +++ b/drivers/block/sata_sil3114.c @@ -171,7 +171,7 @@ static void sata_identify (int num, int dev) 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)) { diff --git a/drivers/fpga/lattice.c b/drivers/fpga/lattice.c index 50d9e542d7..d8b642a6bc 100644 --- a/drivers/fpga/lattice.c +++ b/drivers/fpga/lattice.c @@ -317,7 +317,7 @@ int lattice_load(Lattice_desc *desc, const void *buf, size_t bsize) 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) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 391bc2bafa..e5fedb3951 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -618,7 +618,7 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) int mmc_change_freq(struct mmc *mmc) { - char ext_csd[512]; + ALLOC_CACHE_ALIGN_BUFFER(char, ext_csd, 512); char cardtype; int err; @@ -702,8 +702,8 @@ int sd_change_freq(struct mmc *mmc) { 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; @@ -731,7 +731,7 @@ int sd_change_freq(struct mmc *mmc) timeout = 3; retry_scr: - data.dest = (char *)&scr; + data.dest = (char *)scr; data.blocksize = 8; data.blocks = 1; data.flags = MMC_DATA_READ; @@ -773,7 +773,7 @@ retry_scr: timeout = 4; while (timeout--) { err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1, - (u8 *)&switch_status); + (u8 *)switch_status); if (err) return err; @@ -787,7 +787,7 @@ retry_scr: 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; @@ -860,7 +860,7 @@ int mmc_startup(struct mmc *mmc) 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 diff --git a/drivers/mmc/pxa_mmc.c b/drivers/mmc/pxa_mmc.c index 48e21ef7a5..3c2905c3c6 100644 --- a/drivers/mmc/pxa_mmc.c +++ b/drivers/mmc/pxa_mmc.c @@ -55,7 +55,7 @@ mmc_cmd(ushort cmd, ushort argh, ushort argl, ushort cmdat) /****************************************************/ { 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, @@ -97,7 +97,7 @@ mmc_cmd(ushort cmd, ushort argh, ushort argl, ushort cmdat) int /****************************************************/ -mmc_block_read(uchar * dst, ulong src, ulong len) +mmc_block_read(uchar * dst, uint32_t src, int len) /****************************************************/ { ushort argh, argl; @@ -107,7 +107,7 @@ mmc_block_read(uchar * dst, ulong src, ulong len) 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; @@ -298,7 +298,7 @@ pxa_mmc_read(long src, uchar * dst, int size) 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; @@ -325,14 +325,14 @@ pxa_mmc_write(uchar * src, ulong dst, int size) /* 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) { @@ -347,26 +347,26 @@ pxa_mmc_write(uchar * src, ulong dst, int size) 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; diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index ac91dfd953..5494bcffa7 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -2149,7 +2149,7 @@ void flash_protect_default(void) #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, diff --git a/drivers/mtd/jedec_flash.c b/drivers/mtd/jedec_flash.c index da8c9b15b7..36d30c3b68 100644 --- a/drivers/mtd/jedec_flash.c +++ b/drivers/mtd/jedec_flash.c @@ -390,7 +390,8 @@ static inline void fill_info(flash_info_t *info, const struct amd_flash_info *je 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; @@ -399,7 +400,7 @@ static inline void fill_info(flash_info_t *info, const struct amd_flash_info *je 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) { diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c index 27351fb7a0..e1a459b009 100644 --- a/drivers/mtd/nand/s3c2410_nand.c +++ b/drivers/mtd/nand/s3c2410_nand.c @@ -56,7 +56,7 @@ static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) 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; @@ -83,7 +83,7 @@ static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) 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; } @@ -91,7 +91,7 @@ static int s3c2410_dev_ready(struct mtd_info *mtd) 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); } @@ -102,7 +102,7 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, 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; @@ -128,7 +128,7 @@ int board_nand_init(struct nand_chip *nand) 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); @@ -183,7 +183,7 @@ int board_nand_init(struct nand_chip *nand) nand->options = 0; #endif - debugX(1, "end of nand_init\n"); + debug("end of nand_init\n"); return 0; } diff --git a/drivers/net/4xx_enet.c b/drivers/net/4xx_enet.c index 9ab5c8028c..8013ad9976 100644 --- a/drivers/net/4xx_enet.c +++ b/drivers/net/4xx_enet.c @@ -1349,7 +1349,7 @@ get_speed: 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++) { @@ -1362,7 +1362,7 @@ get_speed: 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++) { @@ -1373,7 +1373,7 @@ get_speed: 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; diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c index 54a944bfc4..5b00717d11 100644 --- a/drivers/net/altera_tse.c +++ b/drivers/net/altera_tse.c @@ -198,6 +198,12 @@ static int alt_sgdma_do_async_transfer(volatile struct alt_sgdma_registers *dev, 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. @@ -317,6 +323,8 @@ static int tse_eth_rx(struct eth_device *dev) /* setup the sgdma */ alt_sgdma_do_async_transfer(priv->sgdma_rx, &rx_desc[0]); + + return packet_length; } return -1; @@ -351,8 +359,8 @@ static void tse_eth_reset(struct eth_device *dev) 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; @@ -364,8 +372,8 @@ static void tse_eth_reset(struct eth_device *dev) 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; @@ -577,7 +585,11 @@ static uint mii_m88e1111s_setmode_sr(uint mii_reg, struct altera_tse_priv *priv) { 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; } @@ -585,7 +597,9 @@ static uint mii_m88e1111s_setmode_cr(uint mii_reg, struct altera_tse_priv *priv) { 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; } @@ -876,7 +890,8 @@ static int tse_eth_init(struct eth_device *dev, bd_t * bd) /* 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; @@ -897,8 +912,20 @@ int altera_tse_initialize(u8 dev_num, int mac_base, 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); diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index cfe2176b33..0c0c7cd2c7 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -109,7 +109,7 @@ static void fec_mii_setspeed(struct fec_priv *fec) */ 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, @@ -629,7 +629,7 @@ static int fec_recv(struct eth_device *dev) */ 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); diff --git a/drivers/net/ks8695eth.c b/drivers/net/ks8695eth.c index cd368808f2..8e988d1423 100644 --- a/drivers/net/ks8695eth.c +++ b/drivers/net/ks8695eth.c @@ -196,7 +196,7 @@ static int ks8695_eth_send(struct eth_device *dev, volatile void *packet, 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]; diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index 7f601d4895..bff1314a9d 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -305,10 +305,10 @@ void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info) 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); @@ -344,7 +344,7 @@ void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info) 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); diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 1bcb3a52eb..1cde83a763 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -272,11 +272,7 @@ static u_int cirrus_set_opts (socket_info_t * s) { 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; diff --git a/drivers/pcmcia/tqm8xx_pcmcia.c b/drivers/pcmcia/tqm8xx_pcmcia.c index 859cbe0575..dda7d37445 100644 --- a/drivers/pcmcia/tqm8xx_pcmcia.c +++ b/drivers/pcmcia/tqm8xx_pcmcia.c @@ -43,19 +43,28 @@ static inline void power_config(int slot) {} 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 diff --git a/drivers/spi/fsl_espi.c b/drivers/spi/fsl_espi.c index f872cd84f6..a1ebd330d7 100644 --- a/drivers/spi/fsl_espi.c +++ b/drivers/spi/fsl_espi.c @@ -97,8 +97,8 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, 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); @@ -234,7 +234,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out, 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); diff --git a/drivers/spi/kirkwood_spi.c b/drivers/spi/kirkwood_spi.c index a1c307059c..135895fa24 100644 --- a/drivers/spi/kirkwood_spi.c +++ b/drivers/spi/kirkwood_spi.c @@ -122,7 +122,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, 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) @@ -158,7 +158,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, 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) { diff --git a/drivers/usb/eth/smsc95xx.c b/drivers/usb/eth/smsc95xx.c index 97f2729076..7ee4f87eaa 100644 --- a/drivers/usb/eth/smsc95xx.c +++ b/drivers/usb/eth/smsc95xx.c @@ -377,7 +377,7 @@ static int smsc95xx_write_hwaddr(struct eth_device *eth) /* 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) { diff --git a/drivers/video/bus_vcxk.c b/drivers/video/bus_vcxk.c index 67a59a75d6..7aecb92f69 100644 --- a/drivers/video/bus_vcxk.c +++ b/drivers/video/bus_vcxk.c @@ -164,7 +164,7 @@ int vcxk_init(unsigned long width, unsigned long height) #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 diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index 4e653b8279..1863563ce4 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -1152,7 +1152,7 @@ int video_display_bitmap(ulong bmp_image, int x, int y) 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 diff --git a/dts/Makefile b/dts/Makefile new file mode 100644 index 0000000000..5792afd271 --- /dev/null +++ b/dts/Makefile @@ -0,0 +1,103 @@ +# +# 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 + +######################################################################### diff --git a/fs/ext2/dev.c b/fs/ext2/dev.c index 78851d0a5d..874e21161e 100644 --- a/fs/ext2/dev.c +++ b/fs/ext2/dev.c @@ -52,7 +52,7 @@ int ext2fs_set_blk_dev(block_dev_desc_t *rbdd, int part) 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; /* diff --git a/fs/fat/Makefile b/fs/fat/Makefile index 93b6f07389..9635d36fcf 100644 --- a/fs/fat/Makefile +++ b/fs/fat/Makefile @@ -25,6 +25,7 @@ LIB = $(obj)libfat.o AOBJS = COBJS-$(CONFIG_CMD_FAT) := fat.o +COBJS-$(CONFIG_FAT_WRITE):= fat_write.o ifndef CONFIG_SPL_BUILD COBJS-$(CONFIG_CMD_FAT) += file.o diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 756ac64a8b..28baa546ab 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -572,8 +572,8 @@ static dir_entry *get_dentfromdir (fsdata *mydata, int startsect, } 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, @@ -897,7 +897,7 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize, } 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; diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c new file mode 100644 index 0000000000..4f1772f29a --- /dev/null +++ b/fs/fat/fat_write.c @@ -0,0 +1,1090 @@ +/* + * 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 +#include +#include +#include +#include +#include +#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); +} diff --git a/fs/yaffs2/yaffs_guts.c b/fs/yaffs2/yaffs_guts.c index c67a08517b..c4329afbd5 100644 --- a/fs/yaffs2/yaffs_guts.c +++ b/fs/yaffs2/yaffs_guts.c @@ -78,8 +78,6 @@ static int yaffs_UpdateObjectHeader(yaffs_Object * in, const YCHAR * name, 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); @@ -595,55 +593,6 @@ static void yaffs_VerifyObjectHeader(yaffs_Object *obj, yaffs_ObjectHeader *oh, 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<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; @@ -1546,104 +1495,6 @@ static int yaffs_FindChunkInGroup(yaffs_Device * dev, int theChunk, 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) { @@ -4605,8 +4456,8 @@ int yaffs_ReadDataFromFile(yaffs_Object * in, __u8 * buffer, loff_t offset, int nBytes) { - __u32 chunk; - __u32 start; + __u32 chunk = 0; + __u32 start = 0; int nToCopy; int n = nBytes; int nDone = 0; @@ -4725,8 +4576,8 @@ int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, loff_t offset, int nBytes, int writeThrough) { - __u32 chunk; - __u32 start; + __u32 chunk = 0; + __u32 start = 0; int nToCopy; int n = nBytes; int nDone = 0; @@ -4960,8 +4811,8 @@ int yaffs_ResizeFile(yaffs_Object * in, loff_t newSize) { int oldFileSize = in->variant.fileVariant.fileSize; - __u32 newSizeOfPartialChunk; - __u32 newFullChunks; + __u32 newSizeOfPartialChunk = 0; + __u32 newFullChunks = 0; yaffs_Device *dev = in->myDev; diff --git a/include/common.h b/include/common.h index a1683a20aa..5ca8820898 100644 --- a/include/common.h +++ b/include/common.h @@ -116,20 +116,26 @@ typedef volatile unsigned char vu_char; #include #include -#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, @@ -276,6 +282,7 @@ int checkdram (void); 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); @@ -284,6 +291,8 @@ 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); @@ -303,6 +312,8 @@ int saveenv (void); 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 @@ -723,6 +734,7 @@ void panic(const char *fmt, ...) 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); @@ -843,6 +855,64 @@ int cpu_release(int nr, int argc, char * const argv[]); #include #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 diff --git a/include/configs/PCIPPC2.h b/include/configs/PCIPPC2.h index fb485b03ee..77cedc06d6 100644 --- a/include/configs/PCIPPC2.h +++ b/include/configs/PCIPPC2.h @@ -55,6 +55,10 @@ #define CONFIG_PREBOOT "" #define CONFIG_BOOTDELAY 5 +#ifndef __ASSEMBLY__ +#include +#endif + /* * BOOTP options */ diff --git a/include/configs/PCIPPC6.h b/include/configs/PCIPPC6.h index 16d6450d91..a8d20ca920 100644 --- a/include/configs/PCIPPC6.h +++ b/include/configs/PCIPPC6.h @@ -55,6 +55,10 @@ #define CONFIG_PREBOOT "" #define CONFIG_BOOTDELAY 5 +#ifndef __ASSEMBLY__ +#include +#endif + /* * BOOTP options */ diff --git a/include/configs/VCMA9.h b/include/configs/VCMA9.h index 183045b460..8b8113df51 100644 --- a/include/configs/VCMA9.h +++ b/include/configs/VCMA9.h @@ -76,7 +76,7 @@ #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 "> " diff --git a/include/configs/cerf250.h b/include/configs/cerf250.h index be325e8c26..70427daca2 100644 --- a/include/configs/cerf250.h +++ b/include/configs/cerf250.h @@ -36,7 +36,7 @@ */ #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 diff --git a/include/configs/colibri_pxa270.h b/include/configs/colibri_pxa270.h index 011731b874..8a3446efd1 100644 --- a/include/configs/colibri_pxa270.h +++ b/include/configs/colibri_pxa270.h @@ -28,7 +28,7 @@ #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 diff --git a/include/configs/efikamx.h b/include/configs/efikamx.h index 54f48e446d..ce96b78839 100644 --- a/include/configs/efikamx.h +++ b/include/configs/efikamx.h @@ -79,7 +79,7 @@ #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 diff --git a/include/configs/imx31_phycore.h b/include/configs/imx31_phycore.h index 48bd50bb7f..f4bfee490b 100644 --- a/include/configs/imx31_phycore.h +++ b/include/configs/imx31_phycore.h @@ -192,7 +192,7 @@ /* EET platform additions */ #ifdef CONFIG_IMX31_PHYCORE_EET -#define BOARD_LATE_INIT +#define CONFIG_BOARD_LATE_INIT #define CONFIG_MXC_GPIO diff --git a/include/configs/jadecpu.h b/include/configs/jadecpu.h index 20e1087dae..a239efce2e 100644 --- a/include/configs/jadecpu.h +++ b/include/configs/jadecpu.h @@ -51,7 +51,7 @@ #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 diff --git a/include/configs/km/km_arm.h b/include/configs/km/km_arm.h index c78fed4ad9..c117943f28 100644 --- a/include/configs/km/km_arm.h +++ b/include/configs/km/km_arm.h @@ -277,10 +277,4 @@ int get_scl(void); #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 */ diff --git a/include/configs/lubbock.h b/include/configs/lubbock.h index bbdae3c551..90c5bf8974 100644 --- a/include/configs/lubbock.h +++ b/include/configs/lubbock.h @@ -41,7 +41,7 @@ #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 */ diff --git a/include/configs/mpc7448hpc2.h b/include/configs/mpc7448hpc2.h index 61d758e639..3e7377511c 100644 --- a/include/configs/mpc7448hpc2.h +++ b/include/configs/mpc7448hpc2.h @@ -54,6 +54,10 @@ #undef CONFIG_ECC /* disable ECC support */ +#ifndef __ASSEMBLY__ +#include +#endif + /* Board-specific Initialization Functions to be called */ #define CONFIG_SYS_BOARD_ASM_INIT #define CONFIG_BOARD_EARLY_INIT_F diff --git a/include/configs/ms7750se.h b/include/configs/ms7750se.h index 16fb0d4fe8..03f52f3905 100644 --- a/include/configs/ms7750se.h +++ b/include/configs/ms7750se.h @@ -45,7 +45,7 @@ #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" diff --git a/include/configs/mx1ads.h b/include/configs/mx1ads.h index 0643312baf..9c1b255e65 100644 --- a/include/configs/mx1ads.h +++ b/include/configs/mx1ads.h @@ -45,7 +45,7 @@ /* #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 diff --git a/include/configs/mx31pdk.h b/include/configs/mx31pdk.h index 8c5730ac21..044b766cbc 100644 --- a/include/configs/mx31pdk.h +++ b/include/configs/mx31pdk.h @@ -102,7 +102,7 @@ */ #undef CONFIG_CMD_IMLS -#define BOARD_LATE_INIT +#define CONFIG_BOARD_LATE_INIT #define CONFIG_BOOTDELAY 3 diff --git a/include/configs/mx35pdk.h b/include/configs/mx35pdk.h index 670e76dacc..6f42fc7f90 100644 --- a/include/configs/mx35pdk.h +++ b/include/configs/mx35pdk.h @@ -42,7 +42,7 @@ #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 diff --git a/include/configs/mx51evk.h b/include/configs/mx51evk.h index 0c108703c0..fd7f4ce2bc 100644 --- a/include/configs/mx51evk.h +++ b/include/configs/mx51evk.h @@ -54,7 +54,7 @@ */ #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024) -#define BOARD_LATE_INIT +#define CONFIG_BOARD_LATE_INIT /* * Hardware drivers diff --git a/include/configs/mx53evk.h b/include/configs/mx53evk.h index 2033492961..034fa87e82 100644 --- a/include/configs/mx53evk.h +++ b/include/configs/mx53evk.h @@ -44,7 +44,7 @@ #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 diff --git a/include/configs/nhk8815.h b/include/configs/nhk8815.h index 13d1e6637b..20db3972f6 100644 --- a/include/configs/nhk8815.h +++ b/include/configs/nhk8815.h @@ -96,7 +96,7 @@ #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... */ diff --git a/include/configs/p3mx.h b/include/configs/p3mx.h index 94a69927ed..e44009e8b1 100644 --- a/include/configs/p3mx.h +++ b/include/configs/p3mx.h @@ -447,4 +447,8 @@ #define L2_ENABLE (L2_INIT | L2CR_L2E) +#ifndef __ASSEMBLY__ +#include <../board/Marvell/include/core.h> +#endif + #endif /* __CONFIG_H */ diff --git a/include/configs/pleb2.h b/include/configs/pleb2.h index 7dd6246f11..2aeb7fb34e 100644 --- a/include/configs/pleb2.h +++ b/include/configs/pleb2.h @@ -38,7 +38,7 @@ #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 */ diff --git a/include/configs/ppmc7xx.h b/include/configs/ppmc7xx.h index d3c8990857..4ceee17cd2 100644 --- a/include/configs/ppmc7xx.h +++ b/include/configs/ppmc7xx.h @@ -51,6 +51,10 @@ #define CONFIG_SYS_TEXT_BASE 0xFFF00000 +#ifndef __ASSEMBLY__ +#include +#endif + /* * Monitor configuration * diff --git a/include/configs/pxa255_idp.h b/include/configs/pxa255_idp.h index cd95081a99..620d270893 100644 --- a/include/configs/pxa255_idp.h +++ b/include/configs/pxa255_idp.h @@ -64,7 +64,7 @@ #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 */ diff --git a/include/configs/qong.h b/include/configs/qong.h index b1fc80c527..8c68d1eb6b 100644 --- a/include/configs/qong.h +++ b/include/configs/qong.h @@ -135,7 +135,7 @@ #define CONFIG_CMD_SETEXPR #define CONFIG_CMD_SPI -#define BOARD_LATE_INIT +#define CONFIG_BOARD_LATE_INIT #define CONFIG_BOOTDELAY 5 diff --git a/include/configs/r2dplus.h b/include/configs/r2dplus.h index a7a92f798c..0ce3fa864c 100644 --- a/include/configs/r2dplus.h +++ b/include/configs/r2dplus.h @@ -30,7 +30,7 @@ #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" diff --git a/include/configs/sh7757lcr.h b/include/configs/sh7757lcr.h index 4a5fd0d292..2d6eb3320f 100644 --- a/include/configs/sh7757lcr.h +++ b/include/configs/sh7757lcr.h @@ -107,7 +107,7 @@ #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 diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h index 73e0f05cda..a9c665c8d8 100644 --- a/include/configs/tegra2-common.h +++ b/include/configs/tegra2-common.h @@ -33,6 +33,8 @@ #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 /* get chip and board defs */ diff --git a/include/configs/trizepsiv.h b/include/configs/trizepsiv.h index 6ec9b8036e..2d55044ede 100644 --- a/include/configs/trizepsiv.h +++ b/include/configs/trizepsiv.h @@ -43,7 +43,7 @@ #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 */ diff --git a/include/configs/tx25.h b/include/configs/tx25.h index 6380bb8979..8cb57ffc1a 100644 --- a/include/configs/tx25.h +++ b/include/configs/tx25.h @@ -137,7 +137,7 @@ #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 diff --git a/include/configs/u8500_href.h b/include/configs/u8500_href.h index 636922c2f9..4747fbd351 100644 --- a/include/configs/u8500_href.h +++ b/include/configs/u8500_href.h @@ -35,7 +35,7 @@ #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 diff --git a/include/configs/vision2.h b/include/configs/vision2.h index 3b42afc923..56cbe3feb8 100644 --- a/include/configs/vision2.h +++ b/include/configs/vision2.h @@ -39,7 +39,7 @@ #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 diff --git a/include/configs/xaeniax.h b/include/configs/xaeniax.h index 8a41416305..6dce8aeaf1 100644 --- a/include/configs/xaeniax.h +++ b/include/configs/xaeniax.h @@ -45,7 +45,7 @@ #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 */ diff --git a/include/configs/zipitz2.h b/include/configs/zipitz2.h index ade40b54e8..9505007a8e 100644 --- a/include/configs/zipitz2.h +++ b/include/configs/zipitz2.h @@ -29,7 +29,7 @@ #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 diff --git a/include/configs/zmx25.h b/include/configs/zmx25.h index 0d5ee141f3..9a7a27ac1d 100644 --- a/include/configs/zmx25.h +++ b/include/configs/zmx25.h @@ -46,7 +46,7 @@ #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 diff --git a/include/fat.h b/include/fat.h index 15dbf1094c..4c92442fd3 100644 --- a/include/fat.h +++ b/include/fat.h @@ -99,6 +99,8 @@ #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))) @@ -210,4 +212,5 @@ long file_fat_read(const char *filename, void *buffer, unsigned long maxsize); 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_ */ diff --git a/include/fdtdec.h b/include/fdtdec.h new file mode 100644 index 0000000000..d871cdd1c1 --- /dev/null +++ b/include/fdtdec.h @@ -0,0 +1,128 @@ +/* + * 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 + +/* + * 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__ where 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/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); diff --git a/include/i2c.h b/include/i2c.h index 8ceb4c8521..ee31034c7a 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -46,16 +46,16 @@ */ #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 */ @@ -236,4 +236,18 @@ int i2c_set_bus_speed(unsigned int); 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_ */ diff --git a/include/image.h b/include/image.h index 1ba866e475..c56a18df70 100644 --- a/include/image.h +++ b/include/image.h @@ -615,7 +615,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p); #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 */ diff --git a/include/lcd.h b/include/lcd.h index 0e098d925e..89cc90c0b9 100644 --- a/include/lcd.h +++ b/include/lcd.h @@ -159,8 +159,8 @@ typedef struct vidinfo { #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 */ diff --git a/include/net.h b/include/net.h index d5d37b6506..ad9afbf417 100644 --- a/include/net.h +++ b/include/net.h @@ -48,6 +48,19 @@ typedef void rxhand_f(uchar *pkt, unsigned dport, 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. */ @@ -244,6 +257,7 @@ typedef struct * 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 */ @@ -251,6 +265,9 @@ typedef struct #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; @@ -265,6 +282,7 @@ typedef struct icmphdr { ushort __unused; ushort mtu; } frag; + uchar data[0]; } un; } ICMP_t; @@ -347,8 +365,10 @@ extern int NetState; /* Network loop state */ 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 */ @@ -374,7 +394,7 @@ extern int NetTimeOffset; /* offset time from UTC */ #endif /* Initialize the network adapter */ -extern int NetLoop(proto_t); +extern int NetLoop(enum proto_t); /* Shutdown adapters and cleanup */ extern void NetStop(void); @@ -397,6 +417,7 @@ extern uint NetCksum(uchar *, int); /* Calculate the checksum */ /* 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" */ @@ -408,6 +429,12 @@ extern int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, i /* 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. diff --git a/include/netdev.h b/include/netdev.h index 54b52a51df..04d9f75b77 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -42,7 +42,8 @@ int cpu_eth_init(bd_t *bis); /* 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); diff --git a/lib/Makefile b/lib/Makefile index 075bb8c284..54708c261c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -38,6 +38,7 @@ COBJS-y += crc16.o 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 diff --git a/lib/fdtdec.c b/lib/fdtdec.c new file mode 100644 index 0000000000..0f871638c6 --- /dev/null +++ b/lib/fdtdec.c @@ -0,0 +1,147 @@ +/* + * 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 +#include +#include +#include + +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; +} diff --git a/lib/lzma/LzmaTools.c b/lib/lzma/LzmaTools.c index 8860bfbf3d..2eafad246e 100644 --- a/lib/lzma/LzmaTools.c +++ b/lib/lzma/LzmaTools.c @@ -67,11 +67,11 @@ int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize, 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)); @@ -107,8 +107,8 @@ int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize, } } - 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; diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 79dead3996..e497a8686e 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -7,6 +7,8 @@ /* 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 @@ -738,3 +740,17 @@ void __assert_fail(const char *assertion, const char *file, unsigned line, 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; +} diff --git a/net/bootp.c b/net/bootp.c index 73470f2d46..b789eec0d7 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -138,36 +138,6 @@ static int truncate_sz (const char *name, int maxlen, int curlen) 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) @@ -354,7 +324,7 @@ BootpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, debug("Got good BOOTP\n"); - auto_load(); + net_auto_load(); } #endif @@ -979,7 +949,7 @@ DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, dhcp_state = BOUND; printf ("DHCP client bound to address %pI4\n", &NetOurIP); - auto_load(); + net_auto_load(); return; } break; diff --git a/net/net.c b/net/net.c index 5e67886b68..8f55281f40 100644 --- a/net/net.c +++ b/net/net.c @@ -215,6 +215,9 @@ volatile uchar *NetRxPackets[PKTBUFSRX]; /* 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 */ @@ -224,7 +227,7 @@ static ulong timeDelta; /* 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; @@ -243,7 +246,6 @@ int NetArpWaitTry; void ArpRequest(void) { - int i; volatile uchar *pkt; ARP_t *arp; @@ -265,11 +267,8 @@ void ArpRequest(void) 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) { @@ -310,8 +309,37 @@ void ArpTimeoutCheck(void) } } -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; @@ -340,10 +368,10 @@ NetInitLoop(proto_t protocol) * 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; @@ -405,10 +433,14 @@ restart: 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: @@ -470,7 +502,6 @@ restart: break; } - NetBootFileXferSize = 0; break; } @@ -512,7 +543,7 @@ restart: if (ctrlc()) { eth_halt(); puts("\nAbort\n"); - return -1; + goto done; } ArpTimeoutCheck(); @@ -564,12 +595,21 @@ restart: 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; } /**********************************************************************/ @@ -643,6 +683,12 @@ NetSetHandler(rxhand_f *f) 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) @@ -1331,6 +1377,68 @@ static inline IP_t *NetDefragment(IP_t *ip, int *lenp) } #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) { @@ -1615,51 +1723,14 @@ 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 : 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; } @@ -1728,7 +1799,7 @@ NetReceive(volatile uchar *inpkt, int len) /**********************************************************************/ -static int net_check_prereq(proto_t protocol) +static int net_check_prereq(enum proto_t protocol) { switch (protocol) { /* Fall through */ @@ -1759,7 +1830,8 @@ static int net_check_prereq(proto_t protocol) #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; diff --git a/net/rarp.c b/net/rarp.c index 94c86d3429..097f970f44 100644 --- a/net/rarp.c +++ b/net/rarp.c @@ -46,24 +46,8 @@ static void 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(); } diff --git a/net/tftp.c b/net/tftp.c index da8eeaa58d..4999707387 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -81,6 +81,12 @@ static int TftpTsize; /* 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 @@ -88,6 +94,7 @@ static short TftpNumchars; #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 @@ -190,15 +197,119 @@ store_block(unsigned block, uchar *src, unsigned len) 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; @@ -214,14 +325,19 @@ TftpSend(void) * 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; @@ -233,8 +349,8 @@ TftpSend(void) 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", @@ -265,9 +381,19 @@ TftpSend(void) 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; @@ -275,7 +401,8 @@ TftpSend(void) 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; @@ -298,6 +425,16 @@ TftpSend(void) 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, @@ -315,7 +452,7 @@ 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) @@ -328,8 +465,30 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, 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; @@ -339,9 +498,7 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, TftpRemoteIP = sip; TftpRemotePort = src; TftpOurPort = 1024 + (get_timer(0) % 3072); - TftpLastBlock = 0; - TftpBlockWrap = 0; - TftpBlockWrapOffset = 0; + new_transfer(); TftpSend(); /* Send ACK(0) */ break; #endif @@ -380,7 +537,14 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, 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) @@ -388,34 +552,7 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, 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"); @@ -425,9 +562,7 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, /* 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 */ @@ -498,21 +633,8 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, } 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: @@ -548,11 +670,7 @@ static void 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); @@ -562,8 +680,7 @@ TftpTimeout(void) } -void -TftpStart(void) +void TftpStart(enum proto_t protocol) { char *ep; /* Environment pointer */ @@ -616,8 +733,13 @@ TftpStart(void) } 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) { @@ -638,19 +760,32 @@ TftpStart(void) } 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); diff --git a/net/tftp.h b/net/tftp.h index 3abdf7bc26..c51aa253c4 100644 --- a/net/tftp.h +++ b/net/tftp.h @@ -16,7 +16,7 @@ */ /* 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 */